{"version":3,"file":"ol.js","sources":["../src/ol/util.js","../src/ol/AssertionError.js","../src/ol/CollectionEventType.js","../src/ol/ObjectEventType.js","../src/ol/obj.js","../src/ol/events.js","../src/ol/functions.js","../src/ol/Disposable.js","../src/ol/events/Event.js","../src/ol/events/EventTarget.js","../src/ol/events/EventType.js","../src/ol/Observable.js","../src/ol/Object.js","../src/ol/Collection.js","../src/ol/asserts.js","../src/ol/extent/Corner.js","../src/ol/extent/Relationship.js","../src/ol/extent.js","../src/ol/geom/flat/transform.js","../src/ol/math.js","../src/ol/geom/GeometryType.js","../src/ol/sphere.js","../src/ol/proj/Units.js","../src/ol/proj/Projection.js","../src/ol/proj/epsg3857.js","../src/ol/proj/epsg4326.js","../src/ol/proj/projections.js","../src/ol/proj/transforms.js","../src/ol/proj.js","../src/ol/transform.js","../src/ol/geom/Geometry.js","../src/ol/color.js","../src/ol/colorlike.js","../src/ol/dom.js","../src/ol/webgl.js","../src/ol/has.js","../src/ol/css.js","../src/ol/ImageState.js","../src/ol/structs/LRUCache.js","../src/ol/render/canvas.js","../src/ol/style/Image.js","../src/ol/style/RegularShape.js","../src/ol/style/Circle.js","../src/ol/style/Fill.js","../src/ol/style/Stroke.js","../src/ol/style/Style.js","../src/ol/Feature.js","../src/ol/GeolocationProperty.js","../src/ol/array.js","../src/ol/geom/GeometryLayout.js","../src/ol/geom/SimpleGeometry.js","../src/ol/geom/flat/area.js","../src/ol/geom/flat/closest.js","../src/ol/geom/flat/deflate.js","../src/ol/geom/flat/inflate.js","../src/ol/geom/flat/simplify.js","../src/ol/geom/LinearRing.js","../src/ol/geom/Point.js","../src/ol/geom/flat/contains.js","../src/ol/geom/flat/interiorpoint.js","../src/ol/geom/flat/segments.js","../src/ol/geom/flat/intersectsextent.js","../src/ol/geom/flat/reverse.js","../src/ol/geom/flat/orient.js","../src/ol/geom/Polygon.js","../src/ol/Geolocation.js","../src/ol/string.js","../src/ol/coordinate.js","../src/ol/geom/flat/interpolate.js","../src/ol/geom/flat/length.js","../src/ol/geom/LineString.js","../src/ol/geom/flat/geodesic.js","../src/ol/render/EventType.js","../src/ol/style/TextPlacement.js","../src/ol/style/Text.js","../src/ol/Graticule.js","../src/ol/ImageBase.js","../src/ol/Image.js","../src/ol/TileState.js","../src/ol/easing.js","../src/ol/Tile.js","../src/ol/ImageTile.js","../src/ol/Kinetic.js","../src/ol/MapEvent.js","../src/ol/MapBrowserEvent.js","../src/ol/MapBrowserEventType.js","../src/ol/MapBrowserPointerEvent.js","../src/ol/pointer/EventType.js","../src/ol/pointer/EventSource.js","../src/ol/pointer/MouseSource.js","../src/ol/pointer/MsSource.js","../src/ol/pointer/NativeSource.js","../src/ol/pointer/PointerEvent.js","../src/ol/pointer/TouchSource.js","../src/ol/pointer/PointerEventHandler.js","../src/ol/MapBrowserEventHandler.js","../src/ol/MapEventType.js","../src/ol/MapProperty.js","../src/ol/structs/PriorityQueue.js","../src/ol/TileQueue.js","../src/ol/tilegrid/common.js","../src/ol/centerconstraint.js","../src/ol/rotationconstraint.js","../src/ol/ViewHint.js","../src/ol/ViewProperty.js","../src/ol/View.js","../src/ol/resolutionconstraint.js","../src/ol/layer/Property.js","../src/ol/layer/Base.js","../src/ol/source/State.js","../src/ol/layer/Group.js","../src/ol/size.js","../src/ol/PluggableMap.js","../src/ol/control/Control.js","../src/ol/layer/Layer.js","../src/ol/control/Attribution.js","../src/ol/control/Rotate.js","../src/ol/control/Zoom.js","../src/ol/control/util.js","../src/ol/interaction/Property.js","../src/ol/interaction/Interaction.js","../src/ol/interaction/DoubleClickZoom.js","../src/ol/events/condition.js","../src/ol/interaction/Pointer.js","../src/ol/interaction/DragPan.js","../src/ol/interaction/DragRotate.js","../src/ol/render/Box.js","../src/ol/interaction/DragBox.js","../src/ol/interaction/DragZoom.js","../src/ol/events/KeyCode.js","../src/ol/interaction/KeyboardPan.js","../src/ol/interaction/KeyboardZoom.js","../src/ol/interaction/MouseWheelZoom.js","../src/ol/interaction/PinchRotate.js","../src/ol/interaction/PinchZoom.js","../src/ol/interaction/DragAndDrop.js","../src/ol/interaction/DragRotateAndZoom.js","../src/ol/geom/Circle.js","../src/ol/geom/MultiLineString.js","../src/ol/geom/MultiPoint.js","../src/ol/geom/flat/center.js","../src/ol/geom/MultiPolygon.js","../src/ol/LayerType.js","../src/ol/layer/VectorRenderType.js","../src/ol/layer/Vector.js","../src/ol/format/FormatType.js","../src/ol/featureloader.js","../src/ol/loadingstrategy.js","../src/ol/source/Source.js","../src/ol/source/VectorEventType.js","../node_modules/quickselect/quickselect.js","../node_modules/rbush/index.js","../src/ol/structs/RBush.js","../src/ol/source/Vector.js","../src/ol/interaction/Draw.js","../src/ol/interaction/Extent.js","../src/ol/interaction/Modify.js","../src/ol/interaction/Select.js","../src/ol/interaction/Snap.js","../src/ol/interaction/Translate.js","../src/ol/interaction.js","../src/ol/reproj/common.js","../src/ol/ImageCanvas.js","../src/ol/render/Event.js","../src/ol/render/VectorContext.js","../src/ol/render/canvas/Immediate.js","../src/ol/style/IconImageCache.js","../src/ol/renderer/Map.js","../src/ol/renderer/canvas/Map.js","../src/ol/renderer/Layer.js","../src/ol/renderer/canvas/Layer.js","../src/ol/renderer/canvas/IntermediateCanvas.js","../src/ol/renderer/canvas/ImageLayer.js","../src/ol/TileRange.js","../src/ol/renderer/canvas/TileLayer.js","../src/ol/render/ReplayGroup.js","../src/ol/render/ReplayType.js","../src/ol/geom/flat/textpath.js","../src/ol/render/canvas/Instruction.js","../src/ol/render/replay.js","../src/ol/render/canvas/Replay.js","../src/ol/render/canvas/ImageReplay.js","../src/ol/render/canvas/LineStringReplay.js","../src/ol/render/canvas/PolygonReplay.js","../src/ol/geom/flat/straightchunk.js","../src/ol/render/canvas/ReplayGroup.js","../src/ol/render/canvas/TextReplay.js","../src/ol/renderer/vector.js","../src/ol/renderer/canvas/VectorLayer.js","../src/ol/layer/VectorTileRenderType.js","../src/ol/renderer/canvas/VectorTileLayer.js","../src/ol/Map.js","../src/ol/control/FullScreen.js","../src/ol/OverlayPositioning.js","../src/ol/Overlay.js","../src/ol/VectorTile.js","../src/ol/control/OverviewMap.js","../src/ol/control/ScaleLine.js","../src/ol/control/ZoomSlider.js","../src/ol/control/ZoomToExtent.js","../src/ol/webgl/Shader.js","../src/ol/webgl/Fragment.js","../src/ol/webgl/Vertex.js","../src/ol/render/webgl/circlereplay/defaultshader.js","../src/ol/render/webgl/circlereplay/defaultshader/Locations.js","../src/ol/vec/mat4.js","../src/ol/render/webgl/Replay.js","../src/ol/render/webgl.js","../src/ol/webgl/Buffer.js","../src/ol/render/webgl/CircleReplay.js","../src/ol/render/webgl/texturereplay/defaultshader.js","../src/ol/render/webgl/texturereplay/defaultshader/Locations.js","../src/ol/webgl/ContextEventType.js","../src/ol/webgl/Context.js","../src/ol/render/webgl/TextureReplay.js","../src/ol/render/webgl/ImageReplay.js","../src/ol/geom/flat/topology.js","../src/ol/render/webgl/linestringreplay/defaultshader.js","../src/ol/render/webgl/linestringreplay/defaultshader/Locations.js","../src/ol/render/webgl/LineStringReplay.js","../src/ol/render/webgl/polygonreplay/defaultshader.js","../src/ol/render/webgl/polygonreplay/defaultshader/Locations.js","../src/ol/structs/LinkedList.js","../src/ol/render/webgl/PolygonReplay.js","../src/ol/style/Atlas.js","../src/ol/style/AtlasManager.js","../src/ol/render/webgl/TextReplay.js","../src/ol/render/webgl/ReplayGroup.js","../src/ol/render/webgl/Immediate.js","../src/ol/renderer/webgl/defaultmapshader.js","../src/ol/renderer/webgl/defaultmapshader/Locations.js","../src/ol/renderer/webgl/Layer.js","../src/ol/renderer/webgl/ImageLayer.js","../src/ol/renderer/webgl/Map.js","../src/ol/renderer/webgl/tilelayershader.js","../src/ol/renderer/webgl/tilelayershader/Locations.js","../src/ol/renderer/webgl/TileLayer.js","../src/ol/renderer/webgl/VectorLayer.js","../src/ol/WebGLMap.js","../src/ol/control/MousePosition.js","../src/ol/format/Feature.js","../src/ol/format/JSONFeature.js","../src/ol/format/EsriJSON.js","../src/ol/xml.js","../src/ol/format/XMLFeature.js","../src/ol/format/GMLBase.js","../src/ol/format/xsd.js","../src/ol/format/GML3.js","../src/ol/format/GML.js","../src/ol/format/GML2.js","../src/ol/format/GPX.js","../src/ol/geom/GeometryCollection.js","../src/ol/format/GeoJSON.js","../src/ol/format/TextFeature.js","../src/ol/format/IGC.js","../src/ol/style/IconAnchorUnits.js","../src/ol/style/IconImage.js","../src/ol/format/KML.js","../src/ol/style/IconOrigin.js","../src/ol/style/Icon.js","../node_modules/ieee754/index.js","../node_modules/pbf/index.js","../src/ol/render/Feature.js","../src/ol/format/MVT.js","../src/ol/format/OSMXML.js","../src/ol/geom/flat/flip.js","../src/ol/format/Polyline.js","../src/ol/format/TopoJSON.js","../src/ol/format/filter/Filter.js","../src/ol/format/filter/LogicalNary.js","../src/ol/format/filter/And.js","../src/ol/format/filter/Bbox.js","../src/ol/format/filter/Spatial.js","../src/ol/format/filter/Contains.js","../src/ol/format/filter/Comparison.js","../src/ol/format/filter/During.js","../src/ol/format/filter/ComparisonBinary.js","../src/ol/format/filter/EqualTo.js","../src/ol/format/filter/GreaterThan.js","../src/ol/format/filter/GreaterThanOrEqualTo.js","../src/ol/format/filter/Intersects.js","../src/ol/format/filter/IsBetween.js","../src/ol/format/filter/IsLike.js","../src/ol/format/filter/IsNull.js","../src/ol/format/filter/LessThan.js","../src/ol/format/filter/LessThanOrEqualTo.js","../src/ol/format/filter/Not.js","../src/ol/format/filter/NotEqualTo.js","../src/ol/format/filter/Or.js","../src/ol/format/filter/Within.js","../src/ol/format/filter.js","../src/ol/format/WFS.js","../src/ol/format/WKT.js","../src/ol/format/XLink.js","../src/ol/format/XML.js","../src/ol/format/WMSCapabilities.js","../src/ol/format/WMSGetFeatureInfo.js","../src/ol/format/OWS.js","../src/ol/format/WMTSCapabilities.js","../src/ol/layer/Heatmap.js","../src/ol/layer/Image.js","../src/ol/layer/TileProperty.js","../src/ol/layer/Tile.js","../src/ol/layer/VectorTile.js","../src/ol/tilecoord.js","../src/ol/tileurlfunction.js","../src/ol/net.js","../src/ol/TileCache.js","../src/ol/reproj.js","../src/ol/reproj/Triangulation.js","../src/ol/reproj/Tile.js","../src/ol/tilegrid/TileGrid.js","../src/ol/tilegrid.js","../src/ol/source/Tile.js","../src/ol/source/TileEventType.js","../src/ol/source/UrlTile.js","../src/ol/source/TileImage.js","../src/ol/source/BingMaps.js","../src/ol/source/XYZ.js","../src/ol/source/CartoDB.js","../src/ol/source/Cluster.js","../src/ol/reproj/Image.js","../src/ol/source/Image.js","../src/ol/uri.js","../src/ol/source/ImageArcGISRest.js","../src/ol/source/ImageCanvas.js","../src/ol/source/ImageMapGuide.js","../src/ol/source/ImageStatic.js","../src/ol/source/common.js","../src/ol/source/WMSServerType.js","../src/ol/source/ImageWMS.js","../src/ol/source/OSM.js","../node_modules/pixelworks/lib/util.js","../node_modules/pixelworks/lib/processor.js","../src/ol/source/Raster.js","../src/ol/source/Stamen.js","../src/ol/source/TileArcGISRest.js","../src/ol/source/TileDebug.js","../src/ol/source/TileJSON.js","../src/ol/source/TileWMS.js","../src/ol/source/UTFGrid.js","../src/ol/VectorImageTile.js","../src/ol/source/VectorTile.js","../src/ol/source/WMTSRequestEncoding.js","../src/ol/tilegrid/WMTS.js","../src/ol/source/WMTS.js","../src/ol/source/Zoomify.js","index.js","../src/ol/proj/proj4.js","../src/ol/render.js"],"sourcesContent":["/**\n * @module ol/util\n */\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * Usage:\n *\n *     function ParentClass(a, b) { }\n *     ParentClass.prototype.foo = function(a) { }\n *\n *     function ChildClass(a, b, c) {\n *       // Call parent constructor\n *       ParentClass.call(this, a, b);\n *     }\n *     inherits(ChildClass, ParentClass);\n *\n *     var child = new ChildClass('a', 'b', 'see');\n *     child.foo(); // This works.\n *\n * @param {!Function} childCtor Child constructor.\n * @param {!Function} parentCtor Parent constructor.\n * @function module:ol.inherits\n * @deprecated\n * @api\n */\nexport function inherits(childCtor, parentCtor) {\n  childCtor.prototype = Object.create(parentCtor.prototype);\n  childCtor.prototype.constructor = childCtor;\n}\n\n/**\n * Counter for getUid.\n * @type {number}\n * @private\n */\nlet uidCounter_ = 0;\n\n/**\n * Gets a unique ID for an object. This mutates the object so that further calls\n * with the same object as a parameter returns the same value. Unique IDs are generated\n * as a strictly increasing sequence. Adapted from goog.getUid.\n *\n * @param {Object} obj The object to get the unique ID for.\n * @return {number} The unique ID for the object.\n */\nexport function getUid(obj) {\n  return obj.ol_uid || (obj.ol_uid = ++uidCounter_);\n}\n\n/**\n * OpenLayers version.\n * @type {string}\n */\nexport const VERSION = 'latest';\n","/**\n * @module ol/AssertionError\n */\nimport {VERSION} from './util.js';\n\n/**\n * Error object thrown when an assertion failed. This is an ECMA-262 Error,\n * extended with a `code` property.\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error.\n */\nclass AssertionError extends Error {\n\n  /**\n   * @param {number} code Error code.\n   */\n  constructor(code) {\n    const path = VERSION.split('-')[0];\n    const message = 'Assertion failed. See https://openlayers.org/en/' + path +\n    '/doc/errors/#' + code + ' for details.';\n\n    super(message);\n\n    /**\n     * Error code. The meaning of the code can be found on\n     * https://openlayers.org/en/latest/doc/errors/ (replace `latest` with\n     * the version found in the OpenLayers script's header comment if a version\n     * other than the latest is used).\n     * @type {number}\n     * @api\n     */\n    this.code = code;\n\n    /**\n     * @type {string}\n     */\n    this.name = 'AssertionError';\n\n    // Re-assign message, see https://github.com/Rich-Harris/buble/issues/40\n    this.message = message;\n  }\n\n}\n\nexport default AssertionError;\n","/**\n * @module ol/CollectionEventType\n */\n\n/**\n * @enum {string}\n */\nexport default {\n  /**\n   * Triggered when an item is added to the collection.\n   * @event module:ol/Collection~CollectionEvent#add\n   * @api\n   */\n  ADD: 'add',\n  /**\n   * Triggered when an item is removed from the collection.\n   * @event module:ol/Collection~CollectionEvent#remove\n   * @api\n   */\n  REMOVE: 'remove'\n};\n","/**\n * @module ol/ObjectEventType\n */\n\n/**\n * @enum {string}\n */\nexport default {\n  /**\n   * Triggered when a property is changed.\n   * @event module:ol/Object~ObjectEvent#propertychange\n   * @api\n   */\n  PROPERTYCHANGE: 'propertychange'\n};\n","/**\n * @module ol/obj\n */\n\n\n/**\n * Polyfill for Object.assign().  Assigns enumerable and own properties from\n * one or more source objects to a target object.\n * See https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign.\n *\n * @param {!Object} target The target object.\n * @param {...Object} var_sources The source object(s).\n * @return {!Object} The modified target object.\n */\nexport const assign = (typeof Object.assign === 'function') ? Object.assign : function(target, var_sources) {\n  if (target === undefined || target === null) {\n    throw new TypeError('Cannot convert undefined or null to object');\n  }\n\n  const output = Object(target);\n  for (let i = 1, ii = arguments.length; i < ii; ++i) {\n    const source = arguments[i];\n    if (source !== undefined && source !== null) {\n      for (const key in source) {\n        if (source.hasOwnProperty(key)) {\n          output[key] = source[key];\n        }\n      }\n    }\n  }\n  return output;\n};\n\n\n/**\n * Removes all properties from an object.\n * @param {Object} object The object to clear.\n */\nexport function clear(object) {\n  for (const property in object) {\n    delete object[property];\n  }\n}\n\n\n/**\n * Get an array of property values from an object.\n * @param {Object<K,V>} object The object from which to get the values.\n * @return {!Array<V>} The property values.\n * @template K,V\n */\nexport function getValues(object) {\n  const values = [];\n  for (const property in object) {\n    values.push(object[property]);\n  }\n  return values;\n}\n\n\n/**\n * Determine if an object has any properties.\n * @param {Object} object The object to check.\n * @return {boolean} The object is empty.\n */\nexport function isEmpty(object) {\n  let property;\n  for (property in object) {\n    return false;\n  }\n  return !property;\n}\n","/**\n * @module ol/events\n */\nimport {clear} from './obj.js';\n\n\n/**\n * Key to use with {@link module:ol/Observable~Observable#unByKey}.\n * @typedef {Object} EventsKey\n * @property {Object} [bindTo]\n * @property {module:ol/events~ListenerFunction} [boundListener]\n * @property {boolean} callOnce\n * @property {number} [deleteIndex]\n * @property {module:ol/events~ListenerFunction} listener\n * @property {EventTarget|module:ol/events/EventTarget} target\n * @property {string} type\n * @api\n */\n\n\n/**\n * Listener function. This function is called with an event object as argument.\n * When the function returns `false`, event propagation will stop.\n *\n * @typedef {function(module:ol/events/Event)|function(module:ol/events/Event): boolean} ListenerFunction\n * @api\n */\n\n\n/**\n * @param {module:ol/events~EventsKey} listenerObj Listener object.\n * @return {module:ol/events~ListenerFunction} Bound listener.\n */\nexport function bindListener(listenerObj) {\n  const boundListener = function(evt) {\n    const listener = listenerObj.listener;\n    const bindTo = listenerObj.bindTo || listenerObj.target;\n    if (listenerObj.callOnce) {\n      unlistenByKey(listenerObj);\n    }\n    return listener.call(bindTo, evt);\n  };\n  listenerObj.boundListener = boundListener;\n  return boundListener;\n}\n\n\n/**\n * Finds the matching {@link module:ol/events~EventsKey} in the given listener\n * array.\n *\n * @param {!Array<!module:ol/events~EventsKey>} listeners Array of listeners.\n * @param {!Function} listener The listener function.\n * @param {Object=} opt_this The `this` value inside the listener.\n * @param {boolean=} opt_setDeleteIndex Set the deleteIndex on the matching\n *     listener, for {@link module:ol/events~unlistenByKey}.\n * @return {module:ol/events~EventsKey|undefined} The matching listener object.\n */\nexport function findListener(listeners, listener, opt_this, opt_setDeleteIndex) {\n  let listenerObj;\n  for (let i = 0, ii = listeners.length; i < ii; ++i) {\n    listenerObj = listeners[i];\n    if (listenerObj.listener === listener &&\n        listenerObj.bindTo === opt_this) {\n      if (opt_setDeleteIndex) {\n        listenerObj.deleteIndex = i;\n      }\n      return listenerObj;\n    }\n  }\n  return undefined;\n}\n\n\n/**\n * @param {module:ol/events/EventTarget~EventTargetLike} target Target.\n * @param {string} type Type.\n * @return {Array.<module:ol/events~EventsKey>|undefined} Listeners.\n */\nexport function getListeners(target, type) {\n  const listenerMap = target.ol_lm;\n  return listenerMap ? listenerMap[type] : undefined;\n}\n\n\n/**\n * Get the lookup of listeners.  If one does not exist on the target, it is\n * created.\n * @param {module:ol/events/EventTarget~EventTargetLike} target Target.\n * @return {!Object.<string, Array.<module:ol/events~EventsKey>>} Map of\n *     listeners by event type.\n */\nfunction getListenerMap(target) {\n  let listenerMap = target.ol_lm;\n  if (!listenerMap) {\n    listenerMap = target.ol_lm = {};\n  }\n  return listenerMap;\n}\n\n\n/**\n * Clean up all listener objects of the given type.  All properties on the\n * listener objects will be removed, and if no listeners remain in the listener\n * map, it will be removed from the target.\n * @param {module:ol/events/EventTarget~EventTargetLike} target Target.\n * @param {string} type Type.\n */\nfunction removeListeners(target, type) {\n  const listeners = getListeners(target, type);\n  if (listeners) {\n    for (let i = 0, ii = listeners.length; i < ii; ++i) {\n      target.removeEventListener(type, listeners[i].boundListener);\n      clear(listeners[i]);\n    }\n    listeners.length = 0;\n    const listenerMap = target.ol_lm;\n    if (listenerMap) {\n      delete listenerMap[type];\n      if (Object.keys(listenerMap).length === 0) {\n        delete target.ol_lm;\n      }\n    }\n  }\n}\n\n\n/**\n * Registers an event listener on an event target. Inspired by\n * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html\n *\n * This function efficiently binds a `listener` to a `this` object, and returns\n * a key for use with {@link module:ol/events~unlistenByKey}.\n *\n * @param {module:ol/events/EventTarget~EventTargetLike} target Event target.\n * @param {string} type Event type.\n * @param {module:ol/events~ListenerFunction} listener Listener.\n * @param {Object=} opt_this Object referenced by the `this` keyword in the\n *     listener. Default is the `target`.\n * @param {boolean=} opt_once If true, add the listener as one-off listener.\n * @return {module:ol/events~EventsKey} Unique key for the listener.\n */\nexport function listen(target, type, listener, opt_this, opt_once) {\n  const listenerMap = getListenerMap(target);\n  let listeners = listenerMap[type];\n  if (!listeners) {\n    listeners = listenerMap[type] = [];\n  }\n  let listenerObj = findListener(listeners, listener, opt_this, false);\n  if (listenerObj) {\n    if (!opt_once) {\n      // Turn one-off listener into a permanent one.\n      listenerObj.callOnce = false;\n    }\n  } else {\n    listenerObj = /** @type {module:ol/events~EventsKey} */ ({\n      bindTo: opt_this,\n      callOnce: !!opt_once,\n      listener: listener,\n      target: target,\n      type: type\n    });\n    target.addEventListener(type, bindListener(listenerObj));\n    listeners.push(listenerObj);\n  }\n\n  return listenerObj;\n}\n\n\n/**\n * Registers a one-off event listener on an event target. Inspired by\n * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html\n *\n * This function efficiently binds a `listener` as self-unregistering listener\n * to a `this` object, and returns a key for use with\n * {@link module:ol/events~unlistenByKey} in case the listener needs to be\n * unregistered before it is called.\n *\n * When {@link module:ol/events~listen} is called with the same arguments after this\n * function, the self-unregistering listener will be turned into a permanent\n * listener.\n *\n * @param {module:ol/events/EventTarget~EventTargetLike} target Event target.\n * @param {string} type Event type.\n * @param {module:ol/events~ListenerFunction} listener Listener.\n * @param {Object=} opt_this Object referenced by the `this` keyword in the\n *     listener. Default is the `target`.\n * @return {module:ol/events~EventsKey} Key for unlistenByKey.\n */\nexport function listenOnce(target, type, listener, opt_this) {\n  return listen(target, type, listener, opt_this, true);\n}\n\n\n/**\n * Unregisters an event listener on an event target. Inspired by\n * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html\n *\n * To return a listener, this function needs to be called with the exact same\n * arguments that were used for a previous {@link module:ol/events~listen} call.\n *\n * @param {module:ol/events/EventTarget~EventTargetLike} target Event target.\n * @param {string} type Event type.\n * @param {module:ol/events~ListenerFunction} listener Listener.\n * @param {Object=} opt_this Object referenced by the `this` keyword in the\n *     listener. Default is the `target`.\n */\nexport function unlisten(target, type, listener, opt_this) {\n  const listeners = getListeners(target, type);\n  if (listeners) {\n    const listenerObj = findListener(listeners, listener, opt_this, true);\n    if (listenerObj) {\n      unlistenByKey(listenerObj);\n    }\n  }\n}\n\n\n/**\n * Unregisters event listeners on an event target. Inspired by\n * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html\n *\n * The argument passed to this function is the key returned from\n * {@link module:ol/events~listen} or {@link module:ol/events~listenOnce}.\n *\n * @param {module:ol/events~EventsKey} key The key.\n */\nexport function unlistenByKey(key) {\n  if (key && key.target) {\n    key.target.removeEventListener(key.type, key.boundListener);\n    const listeners = getListeners(key.target, key.type);\n    if (listeners) {\n      const i = 'deleteIndex' in key ? key.deleteIndex : listeners.indexOf(key);\n      if (i !== -1) {\n        listeners.splice(i, 1);\n      }\n      if (listeners.length === 0) {\n        removeListeners(key.target, key.type);\n      }\n    }\n    clear(key);\n  }\n}\n\n\n/**\n * Unregisters all event listeners on an event target. Inspired by\n * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html\n *\n * @param {module:ol/events/EventTarget~EventTargetLike} target Target.\n */\nexport function unlistenAll(target) {\n  const listenerMap = getListenerMap(target);\n  for (const type in listenerMap) {\n    removeListeners(target, type);\n  }\n}\n","/**\n * @module ol/functions\n */\n\n/**\n * Always returns true.\n * @returns {boolean} true.\n */\nexport function TRUE() {\n  return true;\n}\n\n/**\n * Always returns false.\n * @returns {boolean} false.\n */\nexport function FALSE() {\n  return false;\n}\n\n/**\n * A reusable function, used e.g. as a default for callbacks.\n *\n * @return {undefined} Nothing.\n */\nexport function UNDEFINED() {}\n","/**\n * @module ol/Disposable\n */\nimport {UNDEFINED} from './functions.js';\n\n/**\n * @classdesc\n * Objects that need to clean up after themselves.\n */\nclass Disposable {\n  /**\n   * Clean up.\n   */\n  dispose() {\n    if (!this.disposed_) {\n      this.disposed_ = true;\n      this.disposeInternal();\n    }\n  }\n}\n\n/**\n * The object has already been disposed.\n * @type {boolean}\n * @private\n */\nDisposable.prototype.disposed_ = false;\n\n/**\n * Extension point for disposable objects.\n * @protected\n */\nDisposable.prototype.disposeInternal = UNDEFINED;\nexport default Disposable;\n","/**\n * @module ol/events/Event\n */\n\n/**\n * @classdesc\n * Stripped down implementation of the W3C DOM Level 2 Event interface.\n * See https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-interface.\n *\n * This implementation only provides `type` and `target` properties, and\n * `stopPropagation` and `preventDefault` methods. It is meant as base class\n * for higher level events defined in the library, and works with\n * {@link module:ol/events/EventTarget~EventTarget}.\n */\nclass Event {\n\n  /**\n   * @param {string} type Type.\n   */\n  constructor(type) {\n\n    /**\n     * @type {boolean}\n     */\n    this.propagationStopped;\n\n    /**\n     * The event type.\n     * @type {string}\n     * @api\n     */\n    this.type = type;\n\n    /**\n     * The event target.\n     * @type {Object}\n     * @api\n     */\n    this.target = null;\n  }\n\n  /**\n   * Stop event propagation.\n   * @function\n   * @api\n   */\n  preventDefault() {\n    this.propagationStopped = true;\n  }\n\n  /**\n   * Stop event propagation.\n   * @function\n   * @api\n   */\n  stopPropagation() {\n    this.propagationStopped = true;\n  }\n\n}\n\n\n/**\n * @param {Event|module:ol/events/Event} evt Event\n */\nexport function stopPropagation(evt) {\n  evt.stopPropagation();\n}\n\n\n/**\n * @param {Event|module:ol/events/Event} evt Event\n */\nexport function preventDefault(evt) {\n  evt.preventDefault();\n}\n\nexport default Event;\n","/**\n * @module ol/events/EventTarget\n */\nimport Disposable from '../Disposable.js';\nimport {unlistenAll} from '../events.js';\nimport {UNDEFINED} from '../functions.js';\nimport Event from '../events/Event.js';\n\n\n/**\n * @typedef {EventTarget|module:ol/events/EventTarget} EventTargetLike\n */\n\n\n/**\n * @classdesc\n * A simplified implementation of the W3C DOM Level 2 EventTarget interface.\n * See https://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-EventTarget.\n *\n * There are two important simplifications compared to the specification:\n *\n * 1. The handling of `useCapture` in `addEventListener` and\n *    `removeEventListener`. There is no real capture model.\n * 2. The handling of `stopPropagation` and `preventDefault` on `dispatchEvent`.\n *    There is no event target hierarchy. When a listener calls\n *    `stopPropagation` or `preventDefault` on an event object, it means that no\n *    more listeners after this one will be called. Same as when the listener\n *    returns false.\n */\nclass EventTarget extends Disposable {\n  constructor() {\n\n    super();\n\n    /**\n     * @private\n     * @type {!Object.<string, number>}\n     */\n    this.pendingRemovals_ = {};\n\n    /**\n     * @private\n     * @type {!Object.<string, number>}\n     */\n    this.dispatching_ = {};\n\n    /**\n     * @private\n     * @type {!Object.<string, Array.<module:ol/events~ListenerFunction>>}\n     */\n    this.listeners_ = {};\n\n  }\n\n  /**\n   * @param {string} type Type.\n   * @param {module:ol/events~ListenerFunction} listener Listener.\n   */\n  addEventListener(type, listener) {\n    let listeners = this.listeners_[type];\n    if (!listeners) {\n      listeners = this.listeners_[type] = [];\n    }\n    if (listeners.indexOf(listener) === -1) {\n      listeners.push(listener);\n    }\n  }\n\n  /**\n   * Dispatches an event and calls all listeners listening for events\n   * of this type. The event parameter can either be a string or an\n   * Object with a `type` property.\n   *\n   * @param {{type: string,\n   *     target: (EventTarget|module:ol/events/EventTarget|undefined)}|\n   *     module:ol/events/Event|string} event Event object.\n   * @return {boolean|undefined} `false` if anyone called preventDefault on the\n   *     event object or if any of the listeners returned false.\n   * @function\n   * @api\n   */\n  dispatchEvent(event) {\n    const evt = typeof event === 'string' ? new Event(event) : event;\n    const type = evt.type;\n    evt.target = this;\n    const listeners = this.listeners_[type];\n    let propagate;\n    if (listeners) {\n      if (!(type in this.dispatching_)) {\n        this.dispatching_[type] = 0;\n        this.pendingRemovals_[type] = 0;\n      }\n      ++this.dispatching_[type];\n      for (let i = 0, ii = listeners.length; i < ii; ++i) {\n        if (listeners[i].call(this, evt) === false || evt.propagationStopped) {\n          propagate = false;\n          break;\n        }\n      }\n      --this.dispatching_[type];\n      if (this.dispatching_[type] === 0) {\n        let pendingRemovals = this.pendingRemovals_[type];\n        delete this.pendingRemovals_[type];\n        while (pendingRemovals--) {\n          this.removeEventListener(type, UNDEFINED);\n        }\n        delete this.dispatching_[type];\n      }\n      return propagate;\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  disposeInternal() {\n    unlistenAll(this);\n  }\n\n  /**\n   * Get the listeners for a specified event type. Listeners are returned in the\n   * order that they will be called in.\n   *\n   * @param {string} type Type.\n   * @return {Array.<module:ol/events~ListenerFunction>} Listeners.\n   */\n  getListeners(type) {\n    return this.listeners_[type];\n  }\n\n  /**\n   * @param {string=} opt_type Type. If not provided,\n   *     `true` will be returned if this EventTarget has any listeners.\n   * @return {boolean} Has listeners.\n   */\n  hasListener(opt_type) {\n    return opt_type ?\n      opt_type in this.listeners_ :\n      Object.keys(this.listeners_).length > 0;\n  }\n\n  /**\n   * @param {string} type Type.\n   * @param {module:ol/events~ListenerFunction} listener Listener.\n   */\n  removeEventListener(type, listener) {\n    const listeners = this.listeners_[type];\n    if (listeners) {\n      const index = listeners.indexOf(listener);\n      if (type in this.pendingRemovals_) {\n        // make listener a no-op, and remove later in #dispatchEvent()\n        listeners[index] = UNDEFINED;\n        ++this.pendingRemovals_[type];\n      } else {\n        listeners.splice(index, 1);\n        if (listeners.length === 0) {\n          delete this.listeners_[type];\n        }\n      }\n    }\n  }\n}\n\n\nexport default EventTarget;\n","/**\n * @module ol/events/EventType\n */\n\n/**\n * @enum {string}\n * @const\n */\nexport default {\n  /**\n   * Generic change event. Triggered when the revision counter is increased.\n   * @event module:ol/events/Event~Event#change\n   * @api\n   */\n  CHANGE: 'change',\n\n  CLEAR: 'clear',\n  CONTEXTMENU: 'contextmenu',\n  CLICK: 'click',\n  DBLCLICK: 'dblclick',\n  DRAGENTER: 'dragenter',\n  DRAGOVER: 'dragover',\n  DROP: 'drop',\n  ERROR: 'error',\n  KEYDOWN: 'keydown',\n  KEYPRESS: 'keypress',\n  LOAD: 'load',\n  MOUSEDOWN: 'mousedown',\n  MOUSEMOVE: 'mousemove',\n  MOUSEOUT: 'mouseout',\n  MOUSEUP: 'mouseup',\n  MOUSEWHEEL: 'mousewheel',\n  MSPOINTERDOWN: 'MSPointerDown',\n  RESIZE: 'resize',\n  TOUCHSTART: 'touchstart',\n  TOUCHMOVE: 'touchmove',\n  TOUCHEND: 'touchend',\n  WHEEL: 'wheel'\n};\n","/**\n * @module ol/Observable\n */\nimport {listen, unlistenByKey, unlisten, listenOnce} from './events.js';\nimport EventTarget from './events/EventTarget.js';\nimport EventType from './events/EventType.js';\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * An event target providing convenient methods for listener registration\n * and unregistration. A generic `change` event is always available through\n * {@link module:ol/Observable~Observable#changed}.\n *\n * @fires module:ol/events/Event~Event\n * @api\n */\nclass Observable extends EventTarget {\n  constructor() {\n\n    super();\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.revision_ = 0;\n\n  }\n\n  /**\n   * Increases the revision counter and dispatches a 'change' event.\n   * @api\n   */\n  changed() {\n    ++this.revision_;\n    this.dispatchEvent(EventType.CHANGE);\n  }\n\n  /**\n   * Get the version number for this object.  Each time the object is modified,\n   * its version number will be incremented.\n   * @return {number} Revision.\n   * @api\n   */\n  getRevision() {\n    return this.revision_;\n  }\n\n  /**\n   * Listen for a certain type of event.\n   * @param {string|Array.<string>} type The event type or array of event types.\n   * @param {function(?): ?} listener The listener function.\n   * @return {module:ol/events~EventsKey|Array.<module:ol/events~EventsKey>} Unique key for the listener. If\n   *     called with an array of event types as the first argument, the return\n   *     will be an array of keys.\n   * @api\n   */\n  on(type, listener) {\n    if (Array.isArray(type)) {\n      const len = type.length;\n      const keys = new Array(len);\n      for (let i = 0; i < len; ++i) {\n        keys[i] = listen(this, type[i], listener);\n      }\n      return keys;\n    } else {\n      return listen(this, /** @type {string} */ (type), listener);\n    }\n  }\n\n  /**\n   * Listen once for a certain type of event.\n   * @param {string|Array.<string>} type The event type or array of event types.\n   * @param {function(?): ?} listener The listener function.\n   * @return {module:ol/events~EventsKey|Array.<module:ol/events~EventsKey>} Unique key for the listener. If\n   *     called with an array of event types as the first argument, the return\n   *     will be an array of keys.\n   * @api\n   */\n  once(type, listener) {\n    if (Array.isArray(type)) {\n      const len = type.length;\n      const keys = new Array(len);\n      for (let i = 0; i < len; ++i) {\n        keys[i] = listenOnce(this, type[i], listener);\n      }\n      return keys;\n    } else {\n      return listenOnce(this, /** @type {string} */ (type), listener);\n    }\n  }\n\n  /**\n   * Unlisten for a certain type of event.\n   * @param {string|Array.<string>} type The event type or array of event types.\n   * @param {function(?): ?} listener The listener function.\n   * @api\n   */\n  un(type, listener) {\n    if (Array.isArray(type)) {\n      for (let i = 0, ii = type.length; i < ii; ++i) {\n        unlisten(this, type[i], listener);\n      }\n      return;\n    } else {\n      unlisten(this, /** @type {string} */ (type), listener);\n    }\n  }\n}\n\n\n/**\n * Removes an event listener using the key returned by `on()` or `once()`.\n * @param {module:ol/events~EventsKey|Array.<module:ol/events~EventsKey>} key The key returned by `on()`\n *     or `once()` (or an array of keys).\n * @api\n */\nexport function unByKey(key) {\n  if (Array.isArray(key)) {\n    for (let i = 0, ii = key.length; i < ii; ++i) {\n      unlistenByKey(key[i]);\n    }\n  } else {\n    unlistenByKey(/** @type {module:ol/events~EventsKey} */ (key));\n  }\n}\n\n\nexport default Observable;\n","/**\n * @module ol/Object\n */\nimport {getUid} from './util.js';\nimport ObjectEventType from './ObjectEventType.js';\nimport Observable from './Observable.js';\nimport Event from './events/Event.js';\nimport {assign} from './obj.js';\n\n\n/**\n * @classdesc\n * Events emitted by {@link module:ol/Object~BaseObject} instances are instances of this type.\n  */\nclass ObjectEvent extends Event {\n\n  /**\n   * @param {string} type The event type.\n   * @param {string} key The property name.\n   * @param {*} oldValue The old value for `key`.\n   */\n  constructor(type, key, oldValue) {\n    super(type);\n\n    /**\n     * The name of the property whose value is changing.\n     * @type {string}\n     * @api\n     */\n    this.key = key;\n\n    /**\n     * The old value. To get the new value use `e.target.get(e.key)` where\n     * `e` is the event object.\n     * @type {*}\n     * @api\n     */\n    this.oldValue = oldValue;\n\n  }\n\n}\n\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Most non-trivial classes inherit from this.\n *\n * This extends {@link module:ol/Observable} with observable\n * properties, where each property is observable as well as the object as a\n * whole.\n *\n * Classes that inherit from this have pre-defined properties, to which you can\n * add your owns. The pre-defined properties are listed in this documentation as\n * 'Observable Properties', and have their own accessors; for example,\n * {@link module:ol/Map~Map} has a `target` property, accessed with\n * `getTarget()` and changed with `setTarget()`. Not all properties are however\n * settable. There are also general-purpose accessors `get()` and `set()`. For\n * example, `get('target')` is equivalent to `getTarget()`.\n *\n * The `set` accessors trigger a change event, and you can monitor this by\n * registering a listener. For example, {@link module:ol/View~View} has a\n * `center` property, so `view.on('change:center', function(evt) {...});` would\n * call the function whenever the value of the center property changes. Within\n * the function, `evt.target` would be the view, so `evt.target.getCenter()`\n * would return the new center.\n *\n * You can add your own observable properties with\n * `object.set('prop', 'value')`, and retrieve that with `object.get('prop')`.\n * You can listen for changes on that property value with\n * `object.on('change:prop', listener)`. You can get a list of all\n * properties with {@link module:ol/Object~BaseObject#getProperties}.\n *\n * Note that the observable properties are separate from standard JS properties.\n * You can, for example, give your map object a title with\n * `map.title='New title'` and with `map.set('title', 'Another title')`. The\n * first will be a `hasOwnProperty`; the second will appear in\n * `getProperties()`. Only the second is observable.\n *\n * Properties can be deleted by using the unset method. E.g.\n * object.unset('foo').\n *\n * @fires module:ol/Object~ObjectEvent\n * @api\n */\nclass BaseObject extends Observable {\n\n  /**\n   * @param {Object.<string, *>=} opt_values An object with key-value pairs.\n   */\n  constructor(opt_values) {\n    super();\n\n    // Call {@link module:ol/util~getUid} to ensure that the order of objects' ids is\n    // the same as the order in which they were created.  This also helps to\n    // ensure that object properties are always added in the same order, which\n    // helps many JavaScript engines generate faster code.\n    getUid(this);\n\n    /**\n     * @private\n     * @type {!Object.<string, *>}\n     */\n    this.values_ = {};\n\n    if (opt_values !== undefined) {\n      this.setProperties(opt_values);\n    }\n  }\n\n  /**\n   * Gets a value.\n   * @param {string} key Key name.\n   * @return {*} Value.\n   * @api\n   */\n  get(key) {\n    let value;\n    if (this.values_.hasOwnProperty(key)) {\n      value = this.values_[key];\n    }\n    return value;\n  }\n\n  /**\n   * Get a list of object property names.\n   * @return {Array.<string>} List of property names.\n   * @api\n   */\n  getKeys() {\n    return Object.keys(this.values_);\n  }\n\n  /**\n   * Get an object of all property names and values.\n   * @return {Object.<string, *>} Object.\n   * @api\n   */\n  getProperties() {\n    return assign({}, this.values_);\n  }\n\n  /**\n   * @param {string} key Key name.\n   * @param {*} oldValue Old value.\n   */\n  notify(key, oldValue) {\n    let eventType;\n    eventType = getChangeEventType(key);\n    this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));\n    eventType = ObjectEventType.PROPERTYCHANGE;\n    this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));\n  }\n\n  /**\n   * Sets a value.\n   * @param {string} key Key name.\n   * @param {*} value Value.\n   * @param {boolean=} opt_silent Update without triggering an event.\n   * @api\n   */\n  set(key, value, opt_silent) {\n    if (opt_silent) {\n      this.values_[key] = value;\n    } else {\n      const oldValue = this.values_[key];\n      this.values_[key] = value;\n      if (oldValue !== value) {\n        this.notify(key, oldValue);\n      }\n    }\n  }\n\n  /**\n   * Sets a collection of key-value pairs.  Note that this changes any existing\n   * properties and adds new ones (it does not remove any existing properties).\n   * @param {Object.<string, *>} values Values.\n   * @param {boolean=} opt_silent Update without triggering an event.\n   * @api\n   */\n  setProperties(values, opt_silent) {\n    for (const key in values) {\n      this.set(key, values[key], opt_silent);\n    }\n  }\n\n  /**\n   * Unsets a property.\n   * @param {string} key Key name.\n   * @param {boolean=} opt_silent Unset without triggering an event.\n   * @api\n   */\n  unset(key, opt_silent) {\n    if (key in this.values_) {\n      const oldValue = this.values_[key];\n      delete this.values_[key];\n      if (!opt_silent) {\n        this.notify(key, oldValue);\n      }\n    }\n  }\n}\n\n\n/**\n * @type {Object.<string, string>}\n */\nconst changeEventTypeCache = {};\n\n\n/**\n * @param {string} key Key name.\n * @return {string} Change name.\n */\nexport function getChangeEventType(key) {\n  return changeEventTypeCache.hasOwnProperty(key) ?\n    changeEventTypeCache[key] :\n    (changeEventTypeCache[key] = 'change:' + key);\n}\n\n\nexport default BaseObject;\n","/**\n * @module ol/Collection\n */\nimport AssertionError from './AssertionError.js';\nimport CollectionEventType from './CollectionEventType.js';\nimport BaseObject from './Object.js';\nimport Event from './events/Event.js';\n\n\n/**\n * @enum {string}\n * @private\n */\nconst Property = {\n  LENGTH: 'length'\n};\n\n\n/**\n * @classdesc\n * Events emitted by {@link module:ol/Collection~Collection} instances are instances of this\n * type.\n */\nexport class CollectionEvent extends Event {\n\n  /**\n   * @param {module:ol/CollectionEventType} type Type.\n   * @param {*=} opt_element Element.\n   */\n  constructor(type, opt_element) {\n    super(type);\n\n    /**\n     * The element that is added to or removed from the collection.\n     * @type {*}\n     * @api\n     */\n    this.element = opt_element;\n\n  }\n\n}\n\n\n/**\n * @typedef {Object} Options\n * @property {boolean} [unique=false] Disallow the same item from being added to\n * the collection twice.\n */\n\n/**\n * @classdesc\n * An expanded version of standard JS Array, adding convenience methods for\n * manipulation. Add and remove changes to the Collection trigger a Collection\n * event. Note that this does not cover changes to the objects _within_ the\n * Collection; they trigger events on the appropriate object, not on the\n * Collection as a whole.\n *\n * @template T\n * @api\n */\nclass Collection extends BaseObject {\n\n  /**\n   * @param {Array.<T>=} opt_array Array.\n   * @param {module:ol/Collection~Options=} opt_options Collection options.\n   */\n  constructor(opt_array, opt_options) {\n\n    super();\n\n    const options = opt_options || {};\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.unique_ = !!options.unique;\n\n    /**\n     * @private\n     * @type {!Array.<T>}\n     */\n    this.array_ = opt_array ? opt_array : [];\n\n    if (this.unique_) {\n      for (let i = 0, ii = this.array_.length; i < ii; ++i) {\n        this.assertUnique_(this.array_[i], i);\n      }\n    }\n\n    this.updateLength_();\n\n  }\n\n  /**\n   * Remove all elements from the collection.\n   * @api\n   */\n  clear() {\n    while (this.getLength() > 0) {\n      this.pop();\n    }\n  }\n\n  /**\n   * Add elements to the collection.  This pushes each item in the provided array\n   * to the end of the collection.\n   * @param {!Array.<T>} arr Array.\n   * @return {module:ol/Collection.<T>} This collection.\n   * @api\n   */\n  extend(arr) {\n    for (let i = 0, ii = arr.length; i < ii; ++i) {\n      this.push(arr[i]);\n    }\n    return this;\n  }\n\n  /**\n   * Iterate over each element, calling the provided callback.\n   * @param {function(T, number, Array.<T>): *} f The function to call\n   *     for every element. This function takes 3 arguments (the element, the\n   *     index and the array). The return value is ignored.\n   * @api\n   */\n  forEach(f) {\n    const array = this.array_;\n    for (let i = 0, ii = array.length; i < ii; ++i) {\n      f(array[i], i, array);\n    }\n  }\n\n  /**\n   * Get a reference to the underlying Array object. Warning: if the array\n   * is mutated, no events will be dispatched by the collection, and the\n   * collection's \"length\" property won't be in sync with the actual length\n   * of the array.\n   * @return {!Array.<T>} Array.\n   * @api\n   */\n  getArray() {\n    return this.array_;\n  }\n\n  /**\n   * Get the element at the provided index.\n   * @param {number} index Index.\n   * @return {T} Element.\n   * @api\n   */\n  item(index) {\n    return this.array_[index];\n  }\n\n  /**\n   * Get the length of this collection.\n   * @return {number} The length of the array.\n   * @observable\n   * @api\n   */\n  getLength() {\n    return /** @type {number} */ (this.get(Property.LENGTH));\n  }\n\n  /**\n   * Insert an element at the provided index.\n   * @param {number} index Index.\n   * @param {T} elem Element.\n   * @api\n   */\n  insertAt(index, elem) {\n    if (this.unique_) {\n      this.assertUnique_(elem);\n    }\n    this.array_.splice(index, 0, elem);\n    this.updateLength_();\n    this.dispatchEvent(\n      new CollectionEvent(CollectionEventType.ADD, elem));\n  }\n\n  /**\n   * Remove the last element of the collection and return it.\n   * Return `undefined` if the collection is empty.\n   * @return {T|undefined} Element.\n   * @api\n   */\n  pop() {\n    return this.removeAt(this.getLength() - 1);\n  }\n\n  /**\n   * Insert the provided element at the end of the collection.\n   * @param {T} elem Element.\n   * @return {number} New length of the collection.\n   * @api\n   */\n  push(elem) {\n    if (this.unique_) {\n      this.assertUnique_(elem);\n    }\n    const n = this.getLength();\n    this.insertAt(n, elem);\n    return this.getLength();\n  }\n\n  /**\n   * Remove the first occurrence of an element from the collection.\n   * @param {T} elem Element.\n   * @return {T|undefined} The removed element or undefined if none found.\n   * @api\n   */\n  remove(elem) {\n    const arr = this.array_;\n    for (let i = 0, ii = arr.length; i < ii; ++i) {\n      if (arr[i] === elem) {\n        return this.removeAt(i);\n      }\n    }\n    return undefined;\n  }\n\n  /**\n   * Remove the element at the provided index and return it.\n   * Return `undefined` if the collection does not contain this index.\n   * @param {number} index Index.\n   * @return {T|undefined} Value.\n   * @api\n   */\n  removeAt(index) {\n    const prev = this.array_[index];\n    this.array_.splice(index, 1);\n    this.updateLength_();\n    this.dispatchEvent(new CollectionEvent(CollectionEventType.REMOVE, prev));\n    return prev;\n  }\n\n  /**\n   * Set the element at the provided index.\n   * @param {number} index Index.\n   * @param {T} elem Element.\n   * @api\n   */\n  setAt(index, elem) {\n    const n = this.getLength();\n    if (index < n) {\n      if (this.unique_) {\n        this.assertUnique_(elem, index);\n      }\n      const prev = this.array_[index];\n      this.array_[index] = elem;\n      this.dispatchEvent(\n        new CollectionEvent(CollectionEventType.REMOVE, prev));\n      this.dispatchEvent(\n        new CollectionEvent(CollectionEventType.ADD, elem));\n    } else {\n      for (let j = n; j < index; ++j) {\n        this.insertAt(j, undefined);\n      }\n      this.insertAt(index, elem);\n    }\n  }\n\n  /**\n   * @private\n   */\n  updateLength_() {\n    this.set(Property.LENGTH, this.array_.length);\n  }\n\n  /**\n   * @private\n   * @param {T} elem Element.\n   * @param {number=} opt_except Optional index to ignore.\n   */\n  assertUnique_(elem, opt_except) {\n    for (let i = 0, ii = this.array_.length; i < ii; ++i) {\n      if (this.array_[i] === elem && i !== opt_except) {\n        throw new AssertionError(58);\n      }\n    }\n  }\n}\n\n\nexport default Collection;\n","/**\n * @module ol/asserts\n */\nimport AssertionError from './AssertionError.js';\n\n/**\n * @param {*} assertion Assertion we expected to be truthy.\n * @param {number} errorCode Error code.\n */\nexport function assert(assertion, errorCode) {\n  if (!assertion) {\n    throw new AssertionError(errorCode);\n  }\n}\n","/**\n * @module ol/extent/Corner\n */\n\n/**\n * Extent corner.\n * @enum {string}\n */\nexport default {\n  BOTTOM_LEFT: 'bottom-left',\n  BOTTOM_RIGHT: 'bottom-right',\n  TOP_LEFT: 'top-left',\n  TOP_RIGHT: 'top-right'\n};\n","/**\n * @module ol/extent/Relationship\n */\n\n/**\n * Relationship to an extent.\n * @enum {number}\n */\nexport default {\n  UNKNOWN: 0,\n  INTERSECTING: 1,\n  ABOVE: 2,\n  RIGHT: 4,\n  BELOW: 8,\n  LEFT: 16\n};\n","/**\n * @module ol/extent\n */\nimport {assert} from './asserts.js';\nimport Corner from './extent/Corner.js';\nimport Relationship from './extent/Relationship.js';\n\n\n/**\n * An array of numbers representing an extent: `[minx, miny, maxx, maxy]`.\n * @typedef {Array.<number>} Extent\n * @api\n */\n\n/**\n * Build an extent that includes all given coordinates.\n *\n * @param {Array.<module:ol/coordinate~Coordinate>} coordinates Coordinates.\n * @return {module:ol/extent~Extent} Bounding extent.\n * @api\n */\nexport function boundingExtent(coordinates) {\n  const extent = createEmpty();\n  for (let i = 0, ii = coordinates.length; i < ii; ++i) {\n    extendCoordinate(extent, coordinates[i]);\n  }\n  return extent;\n}\n\n\n/**\n * @param {Array.<number>} xs Xs.\n * @param {Array.<number>} ys Ys.\n * @param {module:ol/extent~Extent=} opt_extent Destination extent.\n * @private\n * @return {module:ol/extent~Extent} Extent.\n */\nfunction _boundingExtentXYs(xs, ys, opt_extent) {\n  const minX = Math.min.apply(null, xs);\n  const minY = Math.min.apply(null, ys);\n  const maxX = Math.max.apply(null, xs);\n  const maxY = Math.max.apply(null, ys);\n  return createOrUpdate(minX, minY, maxX, maxY, opt_extent);\n}\n\n\n/**\n * Return extent increased by the provided value.\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {number} value The amount by which the extent should be buffered.\n * @param {module:ol/extent~Extent=} opt_extent Extent.\n * @return {module:ol/extent~Extent} Extent.\n * @api\n */\nexport function buffer(extent, value, opt_extent) {\n  if (opt_extent) {\n    opt_extent[0] = extent[0] - value;\n    opt_extent[1] = extent[1] - value;\n    opt_extent[2] = extent[2] + value;\n    opt_extent[3] = extent[3] + value;\n    return opt_extent;\n  } else {\n    return [\n      extent[0] - value,\n      extent[1] - value,\n      extent[2] + value,\n      extent[3] + value\n    ];\n  }\n}\n\n\n/**\n * Creates a clone of an extent.\n *\n * @param {module:ol/extent~Extent} extent Extent to clone.\n * @param {module:ol/extent~Extent=} opt_extent Extent.\n * @return {module:ol/extent~Extent} The clone.\n */\nexport function clone(extent, opt_extent) {\n  if (opt_extent) {\n    opt_extent[0] = extent[0];\n    opt_extent[1] = extent[1];\n    opt_extent[2] = extent[2];\n    opt_extent[3] = extent[3];\n    return opt_extent;\n  } else {\n    return extent.slice();\n  }\n}\n\n\n/**\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {number} Closest squared distance.\n */\nexport function closestSquaredDistanceXY(extent, x, y) {\n  let dx, dy;\n  if (x < extent[0]) {\n    dx = extent[0] - x;\n  } else if (extent[2] < x) {\n    dx = x - extent[2];\n  } else {\n    dx = 0;\n  }\n  if (y < extent[1]) {\n    dy = extent[1] - y;\n  } else if (extent[3] < y) {\n    dy = y - extent[3];\n  } else {\n    dy = 0;\n  }\n  return dx * dx + dy * dy;\n}\n\n\n/**\n * Check if the passed coordinate is contained or on the edge of the extent.\n *\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n * @return {boolean} The coordinate is contained in the extent.\n * @api\n */\nexport function containsCoordinate(extent, coordinate) {\n  return containsXY(extent, coordinate[0], coordinate[1]);\n}\n\n\n/**\n * Check if one extent contains another.\n *\n * An extent is deemed contained if it lies completely within the other extent,\n * including if they share one or more edges.\n *\n * @param {module:ol/extent~Extent} extent1 Extent 1.\n * @param {module:ol/extent~Extent} extent2 Extent 2.\n * @return {boolean} The second extent is contained by or on the edge of the\n *     first.\n * @api\n */\nexport function containsExtent(extent1, extent2) {\n  return extent1[0] <= extent2[0] && extent2[2] <= extent1[2] &&\n      extent1[1] <= extent2[1] && extent2[3] <= extent1[3];\n}\n\n\n/**\n * Check if the passed coordinate is contained or on the edge of the extent.\n *\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {number} x X coordinate.\n * @param {number} y Y coordinate.\n * @return {boolean} The x, y values are contained in the extent.\n * @api\n */\nexport function containsXY(extent, x, y) {\n  return extent[0] <= x && x <= extent[2] && extent[1] <= y && y <= extent[3];\n}\n\n\n/**\n * Get the relationship between a coordinate and extent.\n * @param {module:ol/extent~Extent} extent The extent.\n * @param {module:ol/coordinate~Coordinate} coordinate The coordinate.\n * @return {module:ol/extent/Relationship} The relationship (bitwise compare with\n *     module:ol/extent/Relationship~Relationship).\n */\nexport function coordinateRelationship(extent, coordinate) {\n  const minX = extent[0];\n  const minY = extent[1];\n  const maxX = extent[2];\n  const maxY = extent[3];\n  const x = coordinate[0];\n  const y = coordinate[1];\n  let relationship = Relationship.UNKNOWN;\n  if (x < minX) {\n    relationship = relationship | Relationship.LEFT;\n  } else if (x > maxX) {\n    relationship = relationship | Relationship.RIGHT;\n  }\n  if (y < minY) {\n    relationship = relationship | Relationship.BELOW;\n  } else if (y > maxY) {\n    relationship = relationship | Relationship.ABOVE;\n  }\n  if (relationship === Relationship.UNKNOWN) {\n    relationship = Relationship.INTERSECTING;\n  }\n  return relationship;\n}\n\n\n/**\n * Create an empty extent.\n * @return {module:ol/extent~Extent} Empty extent.\n * @api\n */\nexport function createEmpty() {\n  return [Infinity, Infinity, -Infinity, -Infinity];\n}\n\n\n/**\n * Create a new extent or update the provided extent.\n * @param {number} minX Minimum X.\n * @param {number} minY Minimum Y.\n * @param {number} maxX Maximum X.\n * @param {number} maxY Maximum Y.\n * @param {module:ol/extent~Extent=} opt_extent Destination extent.\n * @return {module:ol/extent~Extent} Extent.\n */\nexport function createOrUpdate(minX, minY, maxX, maxY, opt_extent) {\n  if (opt_extent) {\n    opt_extent[0] = minX;\n    opt_extent[1] = minY;\n    opt_extent[2] = maxX;\n    opt_extent[3] = maxY;\n    return opt_extent;\n  } else {\n    return [minX, minY, maxX, maxY];\n  }\n}\n\n\n/**\n * Create a new empty extent or make the provided one empty.\n * @param {module:ol/extent~Extent=} opt_extent Extent.\n * @return {module:ol/extent~Extent} Extent.\n */\nexport function createOrUpdateEmpty(opt_extent) {\n  return createOrUpdate(\n    Infinity, Infinity, -Infinity, -Infinity, opt_extent);\n}\n\n\n/**\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n * @param {module:ol/extent~Extent=} opt_extent Extent.\n * @return {module:ol/extent~Extent} Extent.\n */\nexport function createOrUpdateFromCoordinate(coordinate, opt_extent) {\n  const x = coordinate[0];\n  const y = coordinate[1];\n  return createOrUpdate(x, y, x, y, opt_extent);\n}\n\n\n/**\n * @param {Array.<module:ol/coordinate~Coordinate>} coordinates Coordinates.\n * @param {module:ol/extent~Extent=} opt_extent Extent.\n * @return {module:ol/extent~Extent} Extent.\n */\nexport function createOrUpdateFromCoordinates(coordinates, opt_extent) {\n  const extent = createOrUpdateEmpty(opt_extent);\n  return extendCoordinates(extent, coordinates);\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {module:ol/extent~Extent=} opt_extent Extent.\n * @return {module:ol/extent~Extent} Extent.\n */\nexport function createOrUpdateFromFlatCoordinates(flatCoordinates, offset, end, stride, opt_extent) {\n  const extent = createOrUpdateEmpty(opt_extent);\n  return extendFlatCoordinates(extent, flatCoordinates, offset, end, stride);\n}\n\n/**\n * @param {Array.<Array.<module:ol/coordinate~Coordinate>>} rings Rings.\n * @param {module:ol/extent~Extent=} opt_extent Extent.\n * @return {module:ol/extent~Extent} Extent.\n */\nexport function createOrUpdateFromRings(rings, opt_extent) {\n  const extent = createOrUpdateEmpty(opt_extent);\n  return extendRings(extent, rings);\n}\n\n\n/**\n * Determine if two extents are equivalent.\n * @param {module:ol/extent~Extent} extent1 Extent 1.\n * @param {module:ol/extent~Extent} extent2 Extent 2.\n * @return {boolean} The two extents are equivalent.\n * @api\n */\nexport function equals(extent1, extent2) {\n  return extent1[0] == extent2[0] && extent1[2] == extent2[2] &&\n      extent1[1] == extent2[1] && extent1[3] == extent2[3];\n}\n\n\n/**\n * Modify an extent to include another extent.\n * @param {module:ol/extent~Extent} extent1 The extent to be modified.\n * @param {module:ol/extent~Extent} extent2 The extent that will be included in the first.\n * @return {module:ol/extent~Extent} A reference to the first (extended) extent.\n * @api\n */\nexport function extend(extent1, extent2) {\n  if (extent2[0] < extent1[0]) {\n    extent1[0] = extent2[0];\n  }\n  if (extent2[2] > extent1[2]) {\n    extent1[2] = extent2[2];\n  }\n  if (extent2[1] < extent1[1]) {\n    extent1[1] = extent2[1];\n  }\n  if (extent2[3] > extent1[3]) {\n    extent1[3] = extent2[3];\n  }\n  return extent1;\n}\n\n\n/**\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n */\nexport function extendCoordinate(extent, coordinate) {\n  if (coordinate[0] < extent[0]) {\n    extent[0] = coordinate[0];\n  }\n  if (coordinate[0] > extent[2]) {\n    extent[2] = coordinate[0];\n  }\n  if (coordinate[1] < extent[1]) {\n    extent[1] = coordinate[1];\n  }\n  if (coordinate[1] > extent[3]) {\n    extent[3] = coordinate[1];\n  }\n}\n\n\n/**\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {Array.<module:ol/coordinate~Coordinate>} coordinates Coordinates.\n * @return {module:ol/extent~Extent} Extent.\n */\nexport function extendCoordinates(extent, coordinates) {\n  for (let i = 0, ii = coordinates.length; i < ii; ++i) {\n    extendCoordinate(extent, coordinates[i]);\n  }\n  return extent;\n}\n\n\n/**\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {module:ol/extent~Extent} Extent.\n */\nexport function extendFlatCoordinates(extent, flatCoordinates, offset, end, stride) {\n  for (; offset < end; offset += stride) {\n    extendXY(extent, flatCoordinates[offset], flatCoordinates[offset + 1]);\n  }\n  return extent;\n}\n\n\n/**\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {Array.<Array.<module:ol/coordinate~Coordinate>>} rings Rings.\n * @return {module:ol/extent~Extent} Extent.\n */\nexport function extendRings(extent, rings) {\n  for (let i = 0, ii = rings.length; i < ii; ++i) {\n    extendCoordinates(extent, rings[i]);\n  }\n  return extent;\n}\n\n\n/**\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {number} x X.\n * @param {number} y Y.\n */\nexport function extendXY(extent, x, y) {\n  extent[0] = Math.min(extent[0], x);\n  extent[1] = Math.min(extent[1], y);\n  extent[2] = Math.max(extent[2], x);\n  extent[3] = Math.max(extent[3], y);\n}\n\n\n/**\n * This function calls `callback` for each corner of the extent. If the\n * callback returns a truthy value the function returns that value\n * immediately. Otherwise the function returns `false`.\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {function(this:T, module:ol/coordinate~Coordinate): S} callback Callback.\n * @param {T=} opt_this Value to use as `this` when executing `callback`.\n * @return {S|boolean} Value.\n * @template S, T\n */\nexport function forEachCorner(extent, callback, opt_this) {\n  let val;\n  val = callback.call(opt_this, getBottomLeft(extent));\n  if (val) {\n    return val;\n  }\n  val = callback.call(opt_this, getBottomRight(extent));\n  if (val) {\n    return val;\n  }\n  val = callback.call(opt_this, getTopRight(extent));\n  if (val) {\n    return val;\n  }\n  val = callback.call(opt_this, getTopLeft(extent));\n  if (val) {\n    return val;\n  }\n  return false;\n}\n\n\n/**\n * Get the size of an extent.\n * @param {module:ol/extent~Extent} extent Extent.\n * @return {number} Area.\n * @api\n */\nexport function getArea(extent) {\n  let area = 0;\n  if (!isEmpty(extent)) {\n    area = getWidth(extent) * getHeight(extent);\n  }\n  return area;\n}\n\n\n/**\n * Get the bottom left coordinate of an extent.\n * @param {module:ol/extent~Extent} extent Extent.\n * @return {module:ol/coordinate~Coordinate} Bottom left coordinate.\n * @api\n */\nexport function getBottomLeft(extent) {\n  return [extent[0], extent[1]];\n}\n\n\n/**\n * Get the bottom right coordinate of an extent.\n * @param {module:ol/extent~Extent} extent Extent.\n * @return {module:ol/coordinate~Coordinate} Bottom right coordinate.\n * @api\n */\nexport function getBottomRight(extent) {\n  return [extent[2], extent[1]];\n}\n\n\n/**\n * Get the center coordinate of an extent.\n * @param {module:ol/extent~Extent} extent Extent.\n * @return {module:ol/coordinate~Coordinate} Center.\n * @api\n */\nexport function getCenter(extent) {\n  return [(extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2];\n}\n\n\n/**\n * Get a corner coordinate of an extent.\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {module:ol/extent/Corner} corner Corner.\n * @return {module:ol/coordinate~Coordinate} Corner coordinate.\n */\nexport function getCorner(extent, corner) {\n  let coordinate;\n  if (corner === Corner.BOTTOM_LEFT) {\n    coordinate = getBottomLeft(extent);\n  } else if (corner === Corner.BOTTOM_RIGHT) {\n    coordinate = getBottomRight(extent);\n  } else if (corner === Corner.TOP_LEFT) {\n    coordinate = getTopLeft(extent);\n  } else if (corner === Corner.TOP_RIGHT) {\n    coordinate = getTopRight(extent);\n  } else {\n    assert(false, 13); // Invalid corner\n  }\n  return (\n    /** @type {!module:ol/coordinate~Coordinate} */ (coordinate)\n  );\n}\n\n\n/**\n * @param {module:ol/extent~Extent} extent1 Extent 1.\n * @param {module:ol/extent~Extent} extent2 Extent 2.\n * @return {number} Enlarged area.\n */\nexport function getEnlargedArea(extent1, extent2) {\n  const minX = Math.min(extent1[0], extent2[0]);\n  const minY = Math.min(extent1[1], extent2[1]);\n  const maxX = Math.max(extent1[2], extent2[2]);\n  const maxY = Math.max(extent1[3], extent2[3]);\n  return (maxX - minX) * (maxY - minY);\n}\n\n\n/**\n * @param {module:ol/coordinate~Coordinate} center Center.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @param {module:ol/size~Size} size Size.\n * @param {module:ol/extent~Extent=} opt_extent Destination extent.\n * @return {module:ol/extent~Extent} Extent.\n */\nexport function getForViewAndSize(center, resolution, rotation, size, opt_extent) {\n  const dx = resolution * size[0] / 2;\n  const dy = resolution * size[1] / 2;\n  const cosRotation = Math.cos(rotation);\n  const sinRotation = Math.sin(rotation);\n  const xCos = dx * cosRotation;\n  const xSin = dx * sinRotation;\n  const yCos = dy * cosRotation;\n  const ySin = dy * sinRotation;\n  const x = center[0];\n  const y = center[1];\n  const x0 = x - xCos + ySin;\n  const x1 = x - xCos - ySin;\n  const x2 = x + xCos - ySin;\n  const x3 = x + xCos + ySin;\n  const y0 = y - xSin - yCos;\n  const y1 = y - xSin + yCos;\n  const y2 = y + xSin + yCos;\n  const y3 = y + xSin - yCos;\n  return createOrUpdate(\n    Math.min(x0, x1, x2, x3), Math.min(y0, y1, y2, y3),\n    Math.max(x0, x1, x2, x3), Math.max(y0, y1, y2, y3),\n    opt_extent);\n}\n\n\n/**\n * Get the height of an extent.\n * @param {module:ol/extent~Extent} extent Extent.\n * @return {number} Height.\n * @api\n */\nexport function getHeight(extent) {\n  return extent[3] - extent[1];\n}\n\n\n/**\n * @param {module:ol/extent~Extent} extent1 Extent 1.\n * @param {module:ol/extent~Extent} extent2 Extent 2.\n * @return {number} Intersection area.\n */\nexport function getIntersectionArea(extent1, extent2) {\n  const intersection = getIntersection(extent1, extent2);\n  return getArea(intersection);\n}\n\n\n/**\n * Get the intersection of two extents.\n * @param {module:ol/extent~Extent} extent1 Extent 1.\n * @param {module:ol/extent~Extent} extent2 Extent 2.\n * @param {module:ol/extent~Extent=} opt_extent Optional extent to populate with intersection.\n * @return {module:ol/extent~Extent} Intersecting extent.\n * @api\n */\nexport function getIntersection(extent1, extent2, opt_extent) {\n  const intersection = opt_extent ? opt_extent : createEmpty();\n  if (intersects(extent1, extent2)) {\n    if (extent1[0] > extent2[0]) {\n      intersection[0] = extent1[0];\n    } else {\n      intersection[0] = extent2[0];\n    }\n    if (extent1[1] > extent2[1]) {\n      intersection[1] = extent1[1];\n    } else {\n      intersection[1] = extent2[1];\n    }\n    if (extent1[2] < extent2[2]) {\n      intersection[2] = extent1[2];\n    } else {\n      intersection[2] = extent2[2];\n    }\n    if (extent1[3] < extent2[3]) {\n      intersection[3] = extent1[3];\n    } else {\n      intersection[3] = extent2[3];\n    }\n  } else {\n    createOrUpdateEmpty(intersection);\n  }\n  return intersection;\n}\n\n\n/**\n * @param {module:ol/extent~Extent} extent Extent.\n * @return {number} Margin.\n */\nexport function getMargin(extent) {\n  return getWidth(extent) + getHeight(extent);\n}\n\n\n/**\n * Get the size (width, height) of an extent.\n * @param {module:ol/extent~Extent} extent The extent.\n * @return {module:ol/size~Size} The extent size.\n * @api\n */\nexport function getSize(extent) {\n  return [extent[2] - extent[0], extent[3] - extent[1]];\n}\n\n\n/**\n * Get the top left coordinate of an extent.\n * @param {module:ol/extent~Extent} extent Extent.\n * @return {module:ol/coordinate~Coordinate} Top left coordinate.\n * @api\n */\nexport function getTopLeft(extent) {\n  return [extent[0], extent[3]];\n}\n\n\n/**\n * Get the top right coordinate of an extent.\n * @param {module:ol/extent~Extent} extent Extent.\n * @return {module:ol/coordinate~Coordinate} Top right coordinate.\n * @api\n */\nexport function getTopRight(extent) {\n  return [extent[2], extent[3]];\n}\n\n\n/**\n * Get the width of an extent.\n * @param {module:ol/extent~Extent} extent Extent.\n * @return {number} Width.\n * @api\n */\nexport function getWidth(extent) {\n  return extent[2] - extent[0];\n}\n\n\n/**\n * Determine if one extent intersects another.\n * @param {module:ol/extent~Extent} extent1 Extent 1.\n * @param {module:ol/extent~Extent} extent2 Extent.\n * @return {boolean} The two extents intersect.\n * @api\n */\nexport function intersects(extent1, extent2) {\n  return extent1[0] <= extent2[2] &&\n      extent1[2] >= extent2[0] &&\n      extent1[1] <= extent2[3] &&\n      extent1[3] >= extent2[1];\n}\n\n\n/**\n * Determine if an extent is empty.\n * @param {module:ol/extent~Extent} extent Extent.\n * @return {boolean} Is empty.\n * @api\n */\nexport function isEmpty(extent) {\n  return extent[2] < extent[0] || extent[3] < extent[1];\n}\n\n\n/**\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {module:ol/extent~Extent=} opt_extent Extent.\n * @return {module:ol/extent~Extent} Extent.\n */\nexport function returnOrUpdate(extent, opt_extent) {\n  if (opt_extent) {\n    opt_extent[0] = extent[0];\n    opt_extent[1] = extent[1];\n    opt_extent[2] = extent[2];\n    opt_extent[3] = extent[3];\n    return opt_extent;\n  } else {\n    return extent;\n  }\n}\n\n\n/**\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {number} value Value.\n */\nexport function scaleFromCenter(extent, value) {\n  const deltaX = ((extent[2] - extent[0]) / 2) * (value - 1);\n  const deltaY = ((extent[3] - extent[1]) / 2) * (value - 1);\n  extent[0] -= deltaX;\n  extent[2] += deltaX;\n  extent[1] -= deltaY;\n  extent[3] += deltaY;\n}\n\n\n/**\n * Determine if the segment between two coordinates intersects (crosses,\n * touches, or is contained by) the provided extent.\n * @param {module:ol/extent~Extent} extent The extent.\n * @param {module:ol/coordinate~Coordinate} start Segment start coordinate.\n * @param {module:ol/coordinate~Coordinate} end Segment end coordinate.\n * @return {boolean} The segment intersects the extent.\n */\nexport function intersectsSegment(extent, start, end) {\n  let intersects = false;\n  const startRel = coordinateRelationship(extent, start);\n  const endRel = coordinateRelationship(extent, end);\n  if (startRel === Relationship.INTERSECTING ||\n      endRel === Relationship.INTERSECTING) {\n    intersects = true;\n  } else {\n    const minX = extent[0];\n    const minY = extent[1];\n    const maxX = extent[2];\n    const maxY = extent[3];\n    const startX = start[0];\n    const startY = start[1];\n    const endX = end[0];\n    const endY = end[1];\n    const slope = (endY - startY) / (endX - startX);\n    let x, y;\n    if (!!(endRel & Relationship.ABOVE) &&\n        !(startRel & Relationship.ABOVE)) {\n      // potentially intersects top\n      x = endX - ((endY - maxY) / slope);\n      intersects = x >= minX && x <= maxX;\n    }\n    if (!intersects && !!(endRel & Relationship.RIGHT) &&\n        !(startRel & Relationship.RIGHT)) {\n      // potentially intersects right\n      y = endY - ((endX - maxX) * slope);\n      intersects = y >= minY && y <= maxY;\n    }\n    if (!intersects && !!(endRel & Relationship.BELOW) &&\n        !(startRel & Relationship.BELOW)) {\n      // potentially intersects bottom\n      x = endX - ((endY - minY) / slope);\n      intersects = x >= minX && x <= maxX;\n    }\n    if (!intersects && !!(endRel & Relationship.LEFT) &&\n        !(startRel & Relationship.LEFT)) {\n      // potentially intersects left\n      y = endY - ((endX - minX) * slope);\n      intersects = y >= minY && y <= maxY;\n    }\n\n  }\n  return intersects;\n}\n\n\n/**\n * Apply a transform function to the extent.\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {module:ol/proj~TransformFunction} transformFn Transform function.\n * Called with `[minX, minY, maxX, maxY]` extent coordinates.\n * @param {module:ol/extent~Extent=} opt_extent Destination extent.\n * @return {module:ol/extent~Extent} Extent.\n * @api\n */\nexport function applyTransform(extent, transformFn, opt_extent) {\n  const coordinates = [\n    extent[0], extent[1],\n    extent[0], extent[3],\n    extent[2], extent[1],\n    extent[2], extent[3]\n  ];\n  transformFn(coordinates, coordinates, 2);\n  const xs = [coordinates[0], coordinates[2], coordinates[4], coordinates[6]];\n  const ys = [coordinates[1], coordinates[3], coordinates[5], coordinates[7]];\n  return _boundingExtentXYs(xs, ys, opt_extent);\n}\n","/**\n * @module ol/geom/flat/transform\n */\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {module:ol/transform~Transform} transform Transform.\n * @param {Array.<number>=} opt_dest Destination.\n * @return {Array.<number>} Transformed coordinates.\n */\nexport function transform2D(flatCoordinates, offset, end, stride, transform, opt_dest) {\n  const dest = opt_dest ? opt_dest : [];\n  let i = 0;\n  for (let j = offset; j < end; j += stride) {\n    const x = flatCoordinates[j];\n    const y = flatCoordinates[j + 1];\n    dest[i++] = transform[0] * x + transform[2] * y + transform[4];\n    dest[i++] = transform[1] * x + transform[3] * y + transform[5];\n  }\n  if (opt_dest && dest.length != i) {\n    dest.length = i;\n  }\n  return dest;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} angle Angle.\n * @param {Array.<number>} anchor Rotation anchor point.\n * @param {Array.<number>=} opt_dest Destination.\n * @return {Array.<number>} Transformed coordinates.\n */\nexport function rotate(flatCoordinates, offset, end, stride, angle, anchor, opt_dest) {\n  const dest = opt_dest ? opt_dest : [];\n  const cos = Math.cos(angle);\n  const sin = Math.sin(angle);\n  const anchorX = anchor[0];\n  const anchorY = anchor[1];\n  let i = 0;\n  for (let j = offset; j < end; j += stride) {\n    const deltaX = flatCoordinates[j] - anchorX;\n    const deltaY = flatCoordinates[j + 1] - anchorY;\n    dest[i++] = anchorX + deltaX * cos - deltaY * sin;\n    dest[i++] = anchorY + deltaX * sin + deltaY * cos;\n    for (let k = j + 2; k < j + stride; ++k) {\n      dest[i++] = flatCoordinates[k];\n    }\n  }\n  if (opt_dest && dest.length != i) {\n    dest.length = i;\n  }\n  return dest;\n}\n\n\n/**\n * Scale the coordinates.\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} sx Scale factor in the x-direction.\n * @param {number} sy Scale factor in the y-direction.\n * @param {Array.<number>} anchor Scale anchor point.\n * @param {Array.<number>=} opt_dest Destination.\n * @return {Array.<number>} Transformed coordinates.\n */\nexport function scale(flatCoordinates, offset, end, stride, sx, sy, anchor, opt_dest) {\n  const dest = opt_dest ? opt_dest : [];\n  const anchorX = anchor[0];\n  const anchorY = anchor[1];\n  let i = 0;\n  for (let j = offset; j < end; j += stride) {\n    const deltaX = flatCoordinates[j] - anchorX;\n    const deltaY = flatCoordinates[j + 1] - anchorY;\n    dest[i++] = anchorX + sx * deltaX;\n    dest[i++] = anchorY + sy * deltaY;\n    for (let k = j + 2; k < j + stride; ++k) {\n      dest[i++] = flatCoordinates[k];\n    }\n  }\n  if (opt_dest && dest.length != i) {\n    dest.length = i;\n  }\n  return dest;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} deltaX Delta X.\n * @param {number} deltaY Delta Y.\n * @param {Array.<number>=} opt_dest Destination.\n * @return {Array.<number>} Transformed coordinates.\n */\nexport function translate(flatCoordinates, offset, end, stride, deltaX, deltaY, opt_dest) {\n  const dest = opt_dest ? opt_dest : [];\n  let i = 0;\n  for (let j = offset; j < end; j += stride) {\n    dest[i++] = flatCoordinates[j] + deltaX;\n    dest[i++] = flatCoordinates[j + 1] + deltaY;\n    for (let k = j + 2; k < j + stride; ++k) {\n      dest[i++] = flatCoordinates[k];\n    }\n  }\n  if (opt_dest && dest.length != i) {\n    dest.length = i;\n  }\n  return dest;\n}\n","/**\n * @module ol/math\n */\nimport {assert} from './asserts.js';\n\n/**\n * Takes a number and clamps it to within the provided bounds.\n * @param {number} value The input number.\n * @param {number} min The minimum value to return.\n * @param {number} max The maximum value to return.\n * @return {number} The input number if it is within bounds, or the nearest\n *     number within the bounds.\n */\nexport function clamp(value, min, max) {\n  return Math.min(Math.max(value, min), max);\n}\n\n\n/**\n * Return the hyperbolic cosine of a given number. The method will use the\n * native `Math.cosh` function if it is available, otherwise the hyperbolic\n * cosine will be calculated via the reference implementation of the Mozilla\n * developer network.\n *\n * @param {number} x X.\n * @return {number} Hyperbolic cosine of x.\n */\nexport const cosh = (function() {\n  // Wrapped in a iife, to save the overhead of checking for the native\n  // implementation on every invocation.\n  let cosh;\n  if ('cosh' in Math) {\n    // The environment supports the native Math.cosh function, use it…\n    cosh = Math.cosh;\n  } else {\n    // … else, use the reference implementation of MDN:\n    cosh = function(x) {\n      const y = Math.exp(x);\n      return (y + 1 / y) / 2;\n    };\n  }\n  return cosh;\n}());\n\n\n/**\n * @param {number} x X.\n * @return {number} The smallest power of two greater than or equal to x.\n */\nexport function roundUpToPowerOfTwo(x) {\n  assert(0 < x, 29); // `x` must be greater than `0`\n  return Math.pow(2, Math.ceil(Math.log(x) / Math.LN2));\n}\n\n\n/**\n * Returns the square of the closest distance between the point (x, y) and the\n * line segment (x1, y1) to (x2, y2).\n * @param {number} x X.\n * @param {number} y Y.\n * @param {number} x1 X1.\n * @param {number} y1 Y1.\n * @param {number} x2 X2.\n * @param {number} y2 Y2.\n * @return {number} Squared distance.\n */\nexport function squaredSegmentDistance(x, y, x1, y1, x2, y2) {\n  const dx = x2 - x1;\n  const dy = y2 - y1;\n  if (dx !== 0 || dy !== 0) {\n    const t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);\n    if (t > 1) {\n      x1 = x2;\n      y1 = y2;\n    } else if (t > 0) {\n      x1 += dx * t;\n      y1 += dy * t;\n    }\n  }\n  return squaredDistance(x, y, x1, y1);\n}\n\n\n/**\n * Returns the square of the distance between the points (x1, y1) and (x2, y2).\n * @param {number} x1 X1.\n * @param {number} y1 Y1.\n * @param {number} x2 X2.\n * @param {number} y2 Y2.\n * @return {number} Squared distance.\n */\nexport function squaredDistance(x1, y1, x2, y2) {\n  const dx = x2 - x1;\n  const dy = y2 - y1;\n  return dx * dx + dy * dy;\n}\n\n\n/**\n * Solves system of linear equations using Gaussian elimination method.\n *\n * @param {Array.<Array.<number>>} mat Augmented matrix (n x n + 1 column)\n *                                     in row-major order.\n * @return {Array.<number>} The resulting vector.\n */\nexport function solveLinearSystem(mat) {\n  const n = mat.length;\n\n  for (let i = 0; i < n; i++) {\n    // Find max in the i-th column (ignoring i - 1 first rows)\n    let maxRow = i;\n    let maxEl = Math.abs(mat[i][i]);\n    for (let r = i + 1; r < n; r++) {\n      const absValue = Math.abs(mat[r][i]);\n      if (absValue > maxEl) {\n        maxEl = absValue;\n        maxRow = r;\n      }\n    }\n\n    if (maxEl === 0) {\n      return null; // matrix is singular\n    }\n\n    // Swap max row with i-th (current) row\n    const tmp = mat[maxRow];\n    mat[maxRow] = mat[i];\n    mat[i] = tmp;\n\n    // Subtract the i-th row to make all the remaining rows 0 in the i-th column\n    for (let j = i + 1; j < n; j++) {\n      const coef = -mat[j][i] / mat[i][i];\n      for (let k = i; k < n + 1; k++) {\n        if (i == k) {\n          mat[j][k] = 0;\n        } else {\n          mat[j][k] += coef * mat[i][k];\n        }\n      }\n    }\n  }\n\n  // Solve Ax=b for upper triangular matrix A (mat)\n  const x = new Array(n);\n  for (let l = n - 1; l >= 0; l--) {\n    x[l] = mat[l][n] / mat[l][l];\n    for (let m = l - 1; m >= 0; m--) {\n      mat[m][n] -= mat[m][l] * x[l];\n    }\n  }\n  return x;\n}\n\n\n/**\n * Converts radians to to degrees.\n *\n * @param {number} angleInRadians Angle in radians.\n * @return {number} Angle in degrees.\n */\nexport function toDegrees(angleInRadians) {\n  return angleInRadians * 180 / Math.PI;\n}\n\n\n/**\n * Converts degrees to radians.\n *\n * @param {number} angleInDegrees Angle in degrees.\n * @return {number} Angle in radians.\n */\nexport function toRadians(angleInDegrees) {\n  return angleInDegrees * Math.PI / 180;\n}\n\n/**\n * Returns the modulo of a / b, depending on the sign of b.\n *\n * @param {number} a Dividend.\n * @param {number} b Divisor.\n * @return {number} Modulo.\n */\nexport function modulo(a, b) {\n  const r = a % b;\n  return r * b < 0 ? r + b : r;\n}\n\n/**\n * Calculates the linearly interpolated value of x between a and b.\n *\n * @param {number} a Number\n * @param {number} b Number\n * @param {number} x Value to be interpolated.\n * @return {number} Interpolated value.\n */\nexport function lerp(a, b, x) {\n  return a + x * (b - a);\n}\n","/**\n * @module ol/geom/GeometryType\n */\n\n/**\n * The geometry type. One of `'Point'`, `'LineString'`, `'LinearRing'`,\n * `'Polygon'`, `'MultiPoint'`, `'MultiLineString'`, `'MultiPolygon'`,\n * `'GeometryCollection'`, `'Circle'`.\n * @enum {string}\n */\nexport default {\n  POINT: 'Point',\n  LINE_STRING: 'LineString',\n  LINEAR_RING: 'LinearRing',\n  POLYGON: 'Polygon',\n  MULTI_POINT: 'MultiPoint',\n  MULTI_LINE_STRING: 'MultiLineString',\n  MULTI_POLYGON: 'MultiPolygon',\n  GEOMETRY_COLLECTION: 'GeometryCollection',\n  CIRCLE: 'Circle'\n};\n","/**\n * @license\n * Latitude/longitude spherical geodesy formulae taken from\n * http://www.movable-type.co.uk/scripts/latlong.html\n * Licensed under CC-BY-3.0.\n */\n\n/**\n * @module ol/sphere\n */\nimport {toRadians, toDegrees} from './math.js';\nimport GeometryType from './geom/GeometryType.js';\n\n\n/**\n * Object literal with options for the {@link getLength} or {@link getArea}\n * functions.\n * @typedef {Object} SphereMetricOptions\n * @property {module:ol/proj~ProjectionLike} [projection='EPSG:3857']\n * Projection of the  geometry.  By default, the geometry is assumed to be in\n * Web Mercator.\n * @property {number} [radius=6371008.8] Sphere radius.  By default, the radius of the\n * earth is used (Clarke 1866 Authalic Sphere).\n */\n\n\n/**\n * The mean Earth radius (1/3 * (2a + b)) for the WGS84 ellipsoid.\n * https://en.wikipedia.org/wiki/Earth_radius#Mean_radius\n * @type {number}\n */\nexport const DEFAULT_RADIUS = 6371008.8;\n\n\n/**\n * Get the great circle distance (in meters) between two geographic coordinates.\n * @param {Array} c1 Starting coordinate.\n * @param {Array} c2 Ending coordinate.\n * @param {number=} opt_radius The sphere radius to use.  Defaults to the Earth's\n *     mean radius using the WGS84 ellipsoid.\n * @return {number} The great circle distance between the points (in meters).\n * @api\n */\nexport function getDistance(c1, c2, opt_radius) {\n  const radius = opt_radius || DEFAULT_RADIUS;\n  const lat1 = toRadians(c1[1]);\n  const lat2 = toRadians(c2[1]);\n  const deltaLatBy2 = (lat2 - lat1) / 2;\n  const deltaLonBy2 = toRadians(c2[0] - c1[0]) / 2;\n  const a = Math.sin(deltaLatBy2) * Math.sin(deltaLatBy2) +\n      Math.sin(deltaLonBy2) * Math.sin(deltaLonBy2) *\n      Math.cos(lat1) * Math.cos(lat2);\n  return 2 * radius * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n}\n\n\n/**\n * Get the cumulative great circle length of linestring coordinates (geographic).\n * @param {Array} coordinates Linestring coordinates.\n * @param {number} radius The sphere radius to use.\n * @return {number} The length (in meters).\n */\nfunction getLengthInternal(coordinates, radius) {\n  let length = 0;\n  for (let i = 0, ii = coordinates.length; i < ii - 1; ++i) {\n    length += getDistance(coordinates[i], coordinates[i + 1], radius);\n  }\n  return length;\n}\n\n\n/**\n * Get the spherical length of a geometry.  This length is the sum of the\n * great circle distances between coordinates.  For polygons, the length is\n * the sum of all rings.  For points, the length is zero.  For multi-part\n * geometries, the length is the sum of the length of each part.\n * @param {module:ol/geom/Geometry} geometry A geometry.\n * @param {module:ol/sphere~SphereMetricOptions=} opt_options Options for the\n * length calculation.  By default, geometries are assumed to be in 'EPSG:3857'.\n * You can change this by providing a `projection` option.\n * @return {number} The spherical length (in meters).\n * @api\n */\nexport function getLength(geometry, opt_options) {\n  const options = opt_options || {};\n  const radius = options.radius || DEFAULT_RADIUS;\n  const projection = options.projection || 'EPSG:3857';\n  const type = geometry.getType();\n  if (type !== GeometryType.GEOMETRY_COLLECTION) {\n    geometry = geometry.clone().transform(projection, 'EPSG:4326');\n  }\n  let length = 0;\n  let coordinates, coords, i, ii, j, jj;\n  switch (type) {\n    case GeometryType.POINT:\n    case GeometryType.MULTI_POINT: {\n      break;\n    }\n    case GeometryType.LINE_STRING:\n    case GeometryType.LINEAR_RING: {\n      coordinates = /** @type {module:ol/geom/SimpleGeometry} */ (geometry).getCoordinates();\n      length = getLengthInternal(coordinates, radius);\n      break;\n    }\n    case GeometryType.MULTI_LINE_STRING:\n    case GeometryType.POLYGON: {\n      coordinates = /** @type {module:ol/geom/SimpleGeometry} */ (geometry).getCoordinates();\n      for (i = 0, ii = coordinates.length; i < ii; ++i) {\n        length += getLengthInternal(coordinates[i], radius);\n      }\n      break;\n    }\n    case GeometryType.MULTI_POLYGON: {\n      coordinates = /** @type {module:ol/geom/SimpleGeometry} */ (geometry).getCoordinates();\n      for (i = 0, ii = coordinates.length; i < ii; ++i) {\n        coords = coordinates[i];\n        for (j = 0, jj = coords.length; j < jj; ++j) {\n          length += getLengthInternal(coords[j], radius);\n        }\n      }\n      break;\n    }\n    case GeometryType.GEOMETRY_COLLECTION: {\n      const geometries = /** @type {module:ol/geom/GeometryCollection} */ (geometry).getGeometries();\n      for (i = 0, ii = geometries.length; i < ii; ++i) {\n        length += getLength(geometries[i], opt_options);\n      }\n      break;\n    }\n    default: {\n      throw new Error('Unsupported geometry type: ' + type);\n    }\n  }\n  return length;\n}\n\n\n/**\n * Returns the spherical area for a list of coordinates.\n *\n * [Reference](https://trs-new.jpl.nasa.gov/handle/2014/40409)\n * Robert. G. Chamberlain and William H. Duquette, \"Some Algorithms for\n * Polygons on a Sphere\", JPL Publication 07-03, Jet Propulsion\n * Laboratory, Pasadena, CA, June 2007\n *\n * @param {Array.<module:ol/coordinate~Coordinate>} coordinates List of coordinates of a linear\n * ring. If the ring is oriented clockwise, the area will be positive,\n * otherwise it will be negative.\n * @param {number} radius The sphere radius.\n * @return {number} Area (in square meters).\n */\nfunction getAreaInternal(coordinates, radius) {\n  let area = 0;\n  const len = coordinates.length;\n  let x1 = coordinates[len - 1][0];\n  let y1 = coordinates[len - 1][1];\n  for (let i = 0; i < len; i++) {\n    const x2 = coordinates[i][0];\n    const y2 = coordinates[i][1];\n    area += toRadians(x2 - x1) *\n        (2 + Math.sin(toRadians(y1)) +\n        Math.sin(toRadians(y2)));\n    x1 = x2;\n    y1 = y2;\n  }\n  return area * radius * radius / 2.0;\n}\n\n\n/**\n * Get the spherical area of a geometry.  This is the area (in meters) assuming\n * that polygon edges are segments of great circles on a sphere.\n * @param {module:ol/geom/Geometry} geometry A geometry.\n * @param {module:ol/sphere~SphereMetricOptions=} opt_options Options for the area\n *     calculation.  By default, geometries are assumed to be in 'EPSG:3857'.\n *     You can change this by providing a `projection` option.\n * @return {number} The spherical area (in square meters).\n * @api\n */\nexport function getArea(geometry, opt_options) {\n  const options = opt_options || {};\n  const radius = options.radius || DEFAULT_RADIUS;\n  const projection = options.projection || 'EPSG:3857';\n  const type = geometry.getType();\n  if (type !== GeometryType.GEOMETRY_COLLECTION) {\n    geometry = geometry.clone().transform(projection, 'EPSG:4326');\n  }\n  let area = 0;\n  let coordinates, coords, i, ii, j, jj;\n  switch (type) {\n    case GeometryType.POINT:\n    case GeometryType.MULTI_POINT:\n    case GeometryType.LINE_STRING:\n    case GeometryType.MULTI_LINE_STRING:\n    case GeometryType.LINEAR_RING: {\n      break;\n    }\n    case GeometryType.POLYGON: {\n      coordinates = /** @type {module:ol/geom/Polygon} */ (geometry).getCoordinates();\n      area = Math.abs(getAreaInternal(coordinates[0], radius));\n      for (i = 1, ii = coordinates.length; i < ii; ++i) {\n        area -= Math.abs(getAreaInternal(coordinates[i], radius));\n      }\n      break;\n    }\n    case GeometryType.MULTI_POLYGON: {\n      coordinates = /** @type {module:ol/geom/SimpleGeometry} */ (geometry).getCoordinates();\n      for (i = 0, ii = coordinates.length; i < ii; ++i) {\n        coords = coordinates[i];\n        area += Math.abs(getAreaInternal(coords[0], radius));\n        for (j = 1, jj = coords.length; j < jj; ++j) {\n          area -= Math.abs(getAreaInternal(coords[j], radius));\n        }\n      }\n      break;\n    }\n    case GeometryType.GEOMETRY_COLLECTION: {\n      const geometries = /** @type {module:ol/geom/GeometryCollection} */ (geometry).getGeometries();\n      for (i = 0, ii = geometries.length; i < ii; ++i) {\n        area += getArea(geometries[i], opt_options);\n      }\n      break;\n    }\n    default: {\n      throw new Error('Unsupported geometry type: ' + type);\n    }\n  }\n  return area;\n}\n\n\n/**\n * Returns the coordinate at the given distance and bearing from `c1`.\n *\n * @param {module:ol/coordinate~Coordinate} c1 The origin point (`[lon, lat]` in degrees).\n * @param {number} distance The great-circle distance between the origin\n *     point and the target point.\n * @param {number} bearing The bearing (in radians).\n * @param {number=} opt_radius The sphere radius to use.  Defaults to the Earth's\n *     mean radius using the WGS84 ellipsoid.\n * @return {module:ol/coordinate~Coordinate} The target point.\n */\nexport function offset(c1, distance, bearing, opt_radius) {\n  const radius = opt_radius || DEFAULT_RADIUS;\n  const lat1 = toRadians(c1[1]);\n  const lon1 = toRadians(c1[0]);\n  const dByR = distance / radius;\n  const lat = Math.asin(\n    Math.sin(lat1) * Math.cos(dByR) +\n      Math.cos(lat1) * Math.sin(dByR) * Math.cos(bearing));\n  const lon = lon1 + Math.atan2(\n    Math.sin(bearing) * Math.sin(dByR) * Math.cos(lat1),\n    Math.cos(dByR) - Math.sin(lat1) * Math.sin(lat));\n  return [toDegrees(lon), toDegrees(lat)];\n}\n","/**\n * @module ol/proj/Units\n */\n\n/**\n * Projection units: `'degrees'`, `'ft'`, `'m'`, `'pixels'`, `'tile-pixels'` or\n * `'us-ft'`.\n * @enum {string}\n */\nconst Units = {\n  DEGREES: 'degrees',\n  FEET: 'ft',\n  METERS: 'm',\n  PIXELS: 'pixels',\n  TILE_PIXELS: 'tile-pixels',\n  USFEET: 'us-ft'\n};\n\n\n/**\n * Meters per unit lookup table.\n * @const\n * @type {Object.<module:ol/proj/Units, number>}\n * @api\n */\nexport const METERS_PER_UNIT = {};\n// use the radius of the Normal sphere\nMETERS_PER_UNIT[Units.DEGREES] = 2 * Math.PI * 6370997 / 360;\nMETERS_PER_UNIT[Units.FEET] = 0.3048;\nMETERS_PER_UNIT[Units.METERS] = 1;\nMETERS_PER_UNIT[Units.USFEET] = 1200 / 3937;\n\nexport default Units;\n","/**\n * @module ol/proj/Projection\n */\nimport {METERS_PER_UNIT} from '../proj/Units.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {string} code The SRS identifier code, e.g. `EPSG:4326`.\n * @property {module:ol/proj/Units|string} [units] Units. Required unless a\n * proj4 projection is defined for `code`.\n * @property {module:ol/extent~Extent} [extent] The validity extent for the SRS.\n * @property {string} [axisOrientation='enu'] The axis orientation as specified in Proj4.\n * @property {boolean} [global=false] Whether the projection is valid for the whole globe.\n * @property {number} [metersPerUnit] The meters per unit for the SRS.\n * If not provided, the `units` are used to get the meters per unit from the {@link module:ol/proj/Units~METERS_PER_UNIT}\n * lookup table.\n * @property {module:ol/extent~Extent} [worldExtent] The world extent for the SRS.\n * @property {function(number, module:ol/coordinate~Coordinate):number} [getPointResolution]\n * Function to determine resolution at a point. The function is called with a\n * `{number}` view resolution and an `{module:ol/coordinate~Coordinate}` as arguments, and returns\n * the `{number}` resolution at the passed coordinate. If this is `undefined`,\n * the default {@link module:ol/proj#getPointResolution} function will be used.\n */\n\n\n/**\n * @classdesc\n * Projection definition class. One of these is created for each projection\n * supported in the application and stored in the {@link module:ol/proj} namespace.\n * You can use these in applications, but this is not required, as API params\n * and options use {@link module:ol/proj~ProjectionLike} which means the simple string\n * code will suffice.\n *\n * You can use {@link module:ol/proj~get} to retrieve the object for a particular\n * projection.\n *\n * The library includes definitions for `EPSG:4326` and `EPSG:3857`, together\n * with the following aliases:\n * * `EPSG:4326`: CRS:84, urn:ogc:def:crs:EPSG:6.6:4326,\n *     urn:ogc:def:crs:OGC:1.3:CRS84, urn:ogc:def:crs:OGC:2:84,\n *     http://www.opengis.net/gml/srs/epsg.xml#4326,\n *     urn:x-ogc:def:crs:EPSG:4326\n * * `EPSG:3857`: EPSG:102100, EPSG:102113, EPSG:900913,\n *     urn:ogc:def:crs:EPSG:6.18:3:3857,\n *     http://www.opengis.net/gml/srs/epsg.xml#3857\n *\n * If you use [proj4js](https://github.com/proj4js/proj4js), aliases can\n * be added using `proj4.defs()`. After all required projection definitions are\n * added, call the {@link module:ol/proj/proj4~register} function.\n *\n * @api\n */\nclass Projection {\n\n  /**\n   * @param {module:ol/proj/Projection~Options} options Projection options.\n   */\n  constructor(options) {\n    /**\n     * @private\n     * @type {string}\n     */\n    this.code_ = options.code;\n\n    /**\n     * Units of projected coordinates. When set to `TILE_PIXELS`, a\n     * `this.extent_` and `this.worldExtent_` must be configured properly for each\n     * tile.\n     * @private\n     * @type {module:ol/proj/Units}\n     */\n    this.units_ = /** @type {module:ol/proj/Units} */ (options.units);\n\n    /**\n     * Validity extent of the projection in projected coordinates. For projections\n     * with `TILE_PIXELS` units, this is the extent of the tile in\n     * tile pixel space.\n     * @private\n     * @type {module:ol/extent~Extent}\n     */\n    this.extent_ = options.extent !== undefined ? options.extent : null;\n\n    /**\n     * Extent of the world in EPSG:4326. For projections with\n     * `TILE_PIXELS` units, this is the extent of the tile in\n     * projected coordinate space.\n     * @private\n     * @type {module:ol/extent~Extent}\n     */\n    this.worldExtent_ = options.worldExtent !== undefined ?\n      options.worldExtent : null;\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.axisOrientation_ = options.axisOrientation !== undefined ?\n      options.axisOrientation : 'enu';\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.global_ = options.global !== undefined ? options.global : false;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.canWrapX_ = !!(this.global_ && this.extent_);\n\n    /**\n     * @private\n     * @type {function(number, module:ol/coordinate~Coordinate):number|undefined}\n     */\n    this.getPointResolutionFunc_ = options.getPointResolution;\n\n    /**\n     * @private\n     * @type {module:ol/tilegrid/TileGrid}\n     */\n    this.defaultTileGrid_ = null;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.metersPerUnit_ = options.metersPerUnit;\n  }\n\n  /**\n   * @return {boolean} The projection is suitable for wrapping the x-axis\n   */\n  canWrapX() {\n    return this.canWrapX_;\n  }\n\n  /**\n   * Get the code for this projection, e.g. 'EPSG:4326'.\n   * @return {string} Code.\n   * @api\n   */\n  getCode() {\n    return this.code_;\n  }\n\n  /**\n   * Get the validity extent for this projection.\n   * @return {module:ol/extent~Extent} Extent.\n   * @api\n   */\n  getExtent() {\n    return this.extent_;\n  }\n\n  /**\n   * Get the units of this projection.\n   * @return {module:ol/proj/Units} Units.\n   * @api\n   */\n  getUnits() {\n    return this.units_;\n  }\n\n  /**\n   * Get the amount of meters per unit of this projection.  If the projection is\n   * not configured with `metersPerUnit` or a units identifier, the return is\n   * `undefined`.\n   * @return {number|undefined} Meters.\n   * @api\n   */\n  getMetersPerUnit() {\n    return this.metersPerUnit_ || METERS_PER_UNIT[this.units_];\n  }\n\n  /**\n   * Get the world extent for this projection.\n   * @return {module:ol/extent~Extent} Extent.\n   * @api\n   */\n  getWorldExtent() {\n    return this.worldExtent_;\n  }\n\n  /**\n   * Get the axis orientation of this projection.\n   * Example values are:\n   * enu - the default easting, northing, elevation.\n   * neu - northing, easting, up - useful for \"lat/long\" geographic coordinates,\n   *     or south orientated transverse mercator.\n   * wnu - westing, northing, up - some planetary coordinate systems have\n   *     \"west positive\" coordinate systems\n   * @return {string} Axis orientation.\n   * @api\n   */\n  getAxisOrientation() {\n    return this.axisOrientation_;\n  }\n\n  /**\n   * Is this projection a global projection which spans the whole world?\n   * @return {boolean} Whether the projection is global.\n   * @api\n   */\n  isGlobal() {\n    return this.global_;\n  }\n\n  /**\n   * Set if the projection is a global projection which spans the whole world\n   * @param {boolean} global Whether the projection is global.\n   * @api\n   */\n  setGlobal(global) {\n    this.global_ = global;\n    this.canWrapX_ = !!(global && this.extent_);\n  }\n\n  /**\n   * @return {module:ol/tilegrid/TileGrid} The default tile grid.\n   */\n  getDefaultTileGrid() {\n    return this.defaultTileGrid_;\n  }\n\n  /**\n   * @param {module:ol/tilegrid/TileGrid} tileGrid The default tile grid.\n   */\n  setDefaultTileGrid(tileGrid) {\n    this.defaultTileGrid_ = tileGrid;\n  }\n\n  /**\n   * Set the validity extent for this projection.\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @api\n   */\n  setExtent(extent) {\n    this.extent_ = extent;\n    this.canWrapX_ = !!(this.global_ && extent);\n  }\n\n  /**\n   * Set the world extent for this projection.\n   * @param {module:ol/extent~Extent} worldExtent World extent\n   *     [minlon, minlat, maxlon, maxlat].\n   * @api\n   */\n  setWorldExtent(worldExtent) {\n    this.worldExtent_ = worldExtent;\n  }\n\n  /**\n   * Set the getPointResolution function (see {@link module:ol/proj~getPointResolution}\n   * for this projection.\n   * @param {function(number, module:ol/coordinate~Coordinate):number} func Function\n   * @api\n   */\n  setGetPointResolution(func) {\n    this.getPointResolutionFunc_ = func;\n  }\n\n  /**\n   * Get the custom point resolution function for this projection (if set).\n   * @return {function(number, module:ol/coordinate~Coordinate):number|undefined} The custom point\n   * resolution function (if set).\n   */\n  getPointResolutionFunc() {\n    return this.getPointResolutionFunc_;\n  }\n}\n\nexport default Projection;\n","/**\n * @module ol/proj/epsg3857\n */\nimport {cosh} from '../math.js';\nimport Projection from '../proj/Projection.js';\nimport Units from '../proj/Units.js';\n\n\n/**\n * Radius of WGS84 sphere\n *\n * @const\n * @type {number}\n */\nexport const RADIUS = 6378137;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const HALF_SIZE = Math.PI * RADIUS;\n\n\n/**\n * @const\n * @type {module:ol/extent~Extent}\n */\nexport const EXTENT = [\n  -HALF_SIZE, -HALF_SIZE,\n  HALF_SIZE, HALF_SIZE\n];\n\n\n/**\n * @const\n * @type {module:ol/extent~Extent}\n */\nexport const WORLD_EXTENT = [-180, -85, 180, 85];\n\n\n/**\n * @classdesc\n * Projection object for web/spherical Mercator (EPSG:3857).\n */\nclass EPSG3857Projection extends Projection {\n\n  /**\n   * @param {string} code Code.\n   */\n  constructor(code) {\n    super({\n      code: code,\n      units: Units.METERS,\n      extent: EXTENT,\n      global: true,\n      worldExtent: WORLD_EXTENT,\n      getPointResolution: function(resolution, point) {\n        return resolution / cosh(point[1] / RADIUS);\n      }\n    });\n\n  }\n\n}\n\n\n/**\n * Projections equal to EPSG:3857.\n *\n * @const\n * @type {Array.<module:ol/proj/Projection>}\n */\nexport const PROJECTIONS = [\n  new EPSG3857Projection('EPSG:3857'),\n  new EPSG3857Projection('EPSG:102100'),\n  new EPSG3857Projection('EPSG:102113'),\n  new EPSG3857Projection('EPSG:900913'),\n  new EPSG3857Projection('urn:ogc:def:crs:EPSG:6.18:3:3857'),\n  new EPSG3857Projection('urn:ogc:def:crs:EPSG::3857'),\n  new EPSG3857Projection('http://www.opengis.net/gml/srs/epsg.xml#3857')\n];\n\n\n/**\n * Transformation from EPSG:4326 to EPSG:3857.\n *\n * @param {Array.<number>} input Input array of coordinate values.\n * @param {Array.<number>=} opt_output Output array of coordinate values.\n * @param {number=} opt_dimension Dimension (default is `2`).\n * @return {Array.<number>} Output array of coordinate values.\n */\nexport function fromEPSG4326(input, opt_output, opt_dimension) {\n  const length = input.length;\n  const dimension = opt_dimension > 1 ? opt_dimension : 2;\n  let output = opt_output;\n  if (output === undefined) {\n    if (dimension > 2) {\n      // preserve values beyond second dimension\n      output = input.slice();\n    } else {\n      output = new Array(length);\n    }\n  }\n  const halfSize = HALF_SIZE;\n  for (let i = 0; i < length; i += dimension) {\n    output[i] = halfSize * input[i] / 180;\n    let y = RADIUS *\n        Math.log(Math.tan(Math.PI * (input[i + 1] + 90) / 360));\n    if (y > halfSize) {\n      y = halfSize;\n    } else if (y < -halfSize) {\n      y = -halfSize;\n    }\n    output[i + 1] = y;\n  }\n  return output;\n}\n\n\n/**\n * Transformation from EPSG:3857 to EPSG:4326.\n *\n * @param {Array.<number>} input Input array of coordinate values.\n * @param {Array.<number>=} opt_output Output array of coordinate values.\n * @param {number=} opt_dimension Dimension (default is `2`).\n * @return {Array.<number>} Output array of coordinate values.\n */\nexport function toEPSG4326(input, opt_output, opt_dimension) {\n  const length = input.length;\n  const dimension = opt_dimension > 1 ? opt_dimension : 2;\n  let output = opt_output;\n  if (output === undefined) {\n    if (dimension > 2) {\n      // preserve values beyond second dimension\n      output = input.slice();\n    } else {\n      output = new Array(length);\n    }\n  }\n  for (let i = 0; i < length; i += dimension) {\n    output[i] = 180 * input[i] / HALF_SIZE;\n    output[i + 1] = 360 * Math.atan(\n      Math.exp(input[i + 1] / RADIUS)) / Math.PI - 90;\n  }\n  return output;\n}\n","/**\n * @module ol/proj/epsg4326\n */\nimport Projection from '../proj/Projection.js';\nimport Units from '../proj/Units.js';\n\n\n/**\n * Semi-major radius of the WGS84 ellipsoid.\n *\n * @const\n * @type {number}\n */\nexport const RADIUS = 6378137;\n\n\n/**\n * Extent of the EPSG:4326 projection which is the whole world.\n *\n * @const\n * @type {module:ol/extent~Extent}\n */\nexport const EXTENT = [-180, -90, 180, 90];\n\n\n/**\n * @const\n * @type {number}\n */\nexport const METERS_PER_UNIT = Math.PI * RADIUS / 180;\n\n\n/**\n * @classdesc\n * Projection object for WGS84 geographic coordinates (EPSG:4326).\n *\n * Note that OpenLayers does not strictly comply with the EPSG definition.\n * The EPSG registry defines 4326 as a CRS for Latitude,Longitude (y,x).\n * OpenLayers treats EPSG:4326 as a pseudo-projection, with x,y coordinates.\n */\nclass EPSG4326Projection extends Projection {\n\n  /**\n   * @param {string} code Code.\n   * @param {string=} opt_axisOrientation Axis orientation.\n   */\n  constructor(code, opt_axisOrientation) {\n    super({\n      code: code,\n      units: Units.DEGREES,\n      extent: EXTENT,\n      axisOrientation: opt_axisOrientation,\n      global: true,\n      metersPerUnit: METERS_PER_UNIT,\n      worldExtent: EXTENT\n    });\n\n  }\n\n}\n\n\n/**\n * Projections equal to EPSG:4326.\n *\n * @const\n * @type {Array.<module:ol/proj/Projection>}\n */\nexport const PROJECTIONS = [\n  new EPSG4326Projection('CRS:84'),\n  new EPSG4326Projection('EPSG:4326', 'neu'),\n  new EPSG4326Projection('urn:ogc:def:crs:EPSG::4326', 'neu'),\n  new EPSG4326Projection('urn:ogc:def:crs:EPSG:6.6:4326', 'neu'),\n  new EPSG4326Projection('urn:ogc:def:crs:OGC:1.3:CRS84'),\n  new EPSG4326Projection('urn:ogc:def:crs:OGC:2:84'),\n  new EPSG4326Projection('http://www.opengis.net/gml/srs/epsg.xml#4326', 'neu'),\n  new EPSG4326Projection('urn:x-ogc:def:crs:EPSG:4326', 'neu')\n];\n","/**\n * @module ol/proj/projections\n */\n\n\n/**\n * @type {Object.<string, module:ol/proj/Projection>}\n */\nlet cache = {};\n\n\n/**\n * Clear the projections cache.\n */\nexport function clear() {\n  cache = {};\n}\n\n\n/**\n * Get a cached projection by code.\n * @param {string} code The code for the projection.\n * @return {module:ol/proj/Projection} The projection (if cached).\n */\nexport function get(code) {\n  return cache[code] || null;\n}\n\n\n/**\n * Add a projection to the cache.\n * @param {string} code The projection code.\n * @param {module:ol/proj/Projection} projection The projection to cache.\n */\nexport function add(code, projection) {\n  cache[code] = projection;\n}\n","/**\n * @module ol/proj/transforms\n */\nimport {isEmpty} from '../obj.js';\n\n\n/**\n * @private\n * @type {!Object.<string, Object.<string, module:ol/proj~TransformFunction>>}\n */\nlet transforms = {};\n\n\n/**\n * Clear the transform cache.\n */\nexport function clear() {\n  transforms = {};\n}\n\n\n/**\n * Registers a conversion function to convert coordinates from the source\n * projection to the destination projection.\n *\n * @param {module:ol/proj/Projection} source Source.\n * @param {module:ol/proj/Projection} destination Destination.\n * @param {module:ol/proj~TransformFunction} transformFn Transform.\n */\nexport function add(source, destination, transformFn) {\n  const sourceCode = source.getCode();\n  const destinationCode = destination.getCode();\n  if (!(sourceCode in transforms)) {\n    transforms[sourceCode] = {};\n  }\n  transforms[sourceCode][destinationCode] = transformFn;\n}\n\n\n/**\n * Unregisters the conversion function to convert coordinates from the source\n * projection to the destination projection.  This method is used to clean up\n * cached transforms during testing.\n *\n * @param {module:ol/proj/Projection} source Source projection.\n * @param {module:ol/proj/Projection} destination Destination projection.\n * @return {module:ol/proj~TransformFunction} transformFn The unregistered transform.\n */\nexport function remove(source, destination) {\n  const sourceCode = source.getCode();\n  const destinationCode = destination.getCode();\n  const transform = transforms[sourceCode][destinationCode];\n  delete transforms[sourceCode][destinationCode];\n  if (isEmpty(transforms[sourceCode])) {\n    delete transforms[sourceCode];\n  }\n  return transform;\n}\n\n\n/**\n * Get a transform given a source code and a destination code.\n * @param {string} sourceCode The code for the source projection.\n * @param {string} destinationCode The code for the destination projection.\n * @return {module:ol/proj~TransformFunction|undefined} The transform function (if found).\n */\nexport function get(sourceCode, destinationCode) {\n  let transform;\n  if (sourceCode in transforms && destinationCode in transforms[sourceCode]) {\n    transform = transforms[sourceCode][destinationCode];\n  }\n  return transform;\n}\n","/**\n * @module ol/proj\n */\n\n/**\n * The ol/proj module stores:\n * * a list of {@link module:ol/proj/Projection}\n * objects, one for each projection supported by the application\n * * a list of transform functions needed to convert coordinates in one projection\n * into another.\n *\n * The static functions are the methods used to maintain these.\n * Each transform function can handle not only simple coordinate pairs, but also\n * large arrays of coordinates such as vector geometries.\n *\n * When loaded, the library adds projection objects for EPSG:4326 (WGS84\n * geographic coordinates) and EPSG:3857 (Web or Spherical Mercator, as used\n * for example by Bing Maps or OpenStreetMap), together with the relevant\n * transform functions.\n *\n * Additional transforms may be added by using the http://proj4js.org/\n * library (version 2.2 or later). You can use the full build supplied by\n * Proj4js, or create a custom build to support those projections you need; see\n * the Proj4js website for how to do this. You also need the Proj4js definitions\n * for the required projections. These definitions can be obtained from\n * https://epsg.io/, and are a JS function, so can be loaded in a script\n * tag (as in the examples) or pasted into your application.\n *\n * After all required projection definitions are added to proj4's registry (by\n * using `proj4.defs()`), simply call `register(proj4)` from the `ol/proj/proj4`\n * package. Existing transforms are not changed by this function. See\n * examples/wms-image-custom-proj for an example of this.\n *\n * Additional projection definitions can be registered with `proj4.defs()` any\n * time. Just make sure to call `register(proj4)` again; for example, with user-supplied data where you don't\n * know in advance what projections are needed, you can initially load minimal\n * support and then load whichever are requested.\n *\n * Note that Proj4js does not support projection extents. If you want to add\n * one for creating default tile grids, you can add it after the Projection\n * object has been created with `setExtent`, for example,\n * `get('EPSG:1234').setExtent(extent)`.\n *\n * In addition to Proj4js support, any transform functions can be added with\n * {@link module:ol/proj~addCoordinateTransforms}. To use this, you must first create\n * a {@link module:ol/proj/Projection} object for the new projection and add it with\n * {@link module:ol/proj~addProjection}. You can then add the forward and inverse\n * functions with {@link module:ol/proj~addCoordinateTransforms}. See\n * examples/wms-custom-proj for an example of this.\n *\n * Note that if no transforms are needed and you only need to define the\n * projection, just add a {@link module:ol/proj/Projection} with\n * {@link module:ol/proj~addProjection}. See examples/wms-no-proj for an example of\n * this.\n */\nimport {getDistance} from './sphere.js';\nimport {applyTransform} from './extent.js';\nimport {modulo} from './math.js';\nimport {toEPSG4326, fromEPSG4326, PROJECTIONS as EPSG3857_PROJECTIONS} from './proj/epsg3857.js';\nimport {PROJECTIONS as EPSG4326_PROJECTIONS} from './proj/epsg4326.js';\nimport Projection from './proj/Projection.js';\nimport Units, {METERS_PER_UNIT} from './proj/Units.js';\nimport * as projections from './proj/projections.js';\nimport {add as addTransformFunc, clear as clearTransformFuncs, get as getTransformFunc} from './proj/transforms.js';\n\n\n/**\n * A projection as {@link module:ol/proj/Projection}, SRS identifier\n * string or undefined.\n * @typedef {module:ol/proj/Projection|string|undefined} ProjectionLike\n * @api\n */\n\n\n/**\n * A transform function accepts an array of input coordinate values, an optional\n * output array, and an optional dimension (default should be 2).  The function\n * transforms the input coordinate values, populates the output array, and\n * returns the output array.\n *\n * @typedef {function(Array.<number>, Array.<number>=, number=): Array.<number>} TransformFunction\n * @api\n */\n\n\nexport {METERS_PER_UNIT};\n\n\n/**\n * @param {Array.<number>} input Input coordinate array.\n * @param {Array.<number>=} opt_output Output array of coordinate values.\n * @param {number=} opt_dimension Dimension.\n * @return {Array.<number>} Output coordinate array (new array, same coordinate\n *     values).\n */\nexport function cloneTransform(input, opt_output, opt_dimension) {\n  let output;\n  if (opt_output !== undefined) {\n    for (let i = 0, ii = input.length; i < ii; ++i) {\n      opt_output[i] = input[i];\n    }\n    output = opt_output;\n  } else {\n    output = input.slice();\n  }\n  return output;\n}\n\n\n/**\n * @param {Array.<number>} input Input coordinate array.\n * @param {Array.<number>=} opt_output Output array of coordinate values.\n * @param {number=} opt_dimension Dimension.\n * @return {Array.<number>} Input coordinate array (same array as input).\n */\nexport function identityTransform(input, opt_output, opt_dimension) {\n  if (opt_output !== undefined && input !== opt_output) {\n    for (let i = 0, ii = input.length; i < ii; ++i) {\n      opt_output[i] = input[i];\n    }\n    input = opt_output;\n  }\n  return input;\n}\n\n\n/**\n * Add a Projection object to the list of supported projections that can be\n * looked up by their code.\n *\n * @param {module:ol/proj/Projection} projection Projection instance.\n * @api\n */\nexport function addProjection(projection) {\n  projections.add(projection.getCode(), projection);\n  addTransformFunc(projection, projection, cloneTransform);\n}\n\n\n/**\n * @param {Array.<module:ol/proj/Projection>} projections Projections.\n */\nexport function addProjections(projections) {\n  projections.forEach(addProjection);\n}\n\n\n/**\n * Fetches a Projection object for the code specified.\n *\n * @param {module:ol/proj~ProjectionLike} projectionLike Either a code string which is\n *     a combination of authority and identifier such as \"EPSG:4326\", or an\n *     existing projection object, or undefined.\n * @return {module:ol/proj/Projection} Projection object, or null if not in list.\n * @api\n */\nexport function get(projectionLike) {\n  let projection = null;\n  if (projectionLike instanceof Projection) {\n    projection = projectionLike;\n  } else if (typeof projectionLike === 'string') {\n    const code = projectionLike;\n    projection = projections.get(code);\n  }\n  return projection;\n}\n\n\n/**\n * Get the resolution of the point in degrees or distance units.\n * For projections with degrees as the unit this will simply return the\n * provided resolution. For other projections the point resolution is\n * by default estimated by transforming the 'point' pixel to EPSG:4326,\n * measuring its width and height on the normal sphere,\n * and taking the average of the width and height.\n * A custom function can be provided for a specific projection, either\n * by setting the `getPointResolution` option in the\n * {@link module:ol/proj/Projection~Projection} constructor or by using\n * {@link module:ol/proj/Projection~Projection#setGetPointResolution} to change an existing\n * projection object.\n * @param {module:ol/proj~ProjectionLike} projection The projection.\n * @param {number} resolution Nominal resolution in projection units.\n * @param {module:ol/coordinate~Coordinate} point Point to find adjusted resolution at.\n * @param {module:ol/proj/Units=} opt_units Units to get the point resolution in.\n * Default is the projection's units.\n * @return {number} Point resolution.\n * @api\n */\nexport function getPointResolution(projection, resolution, point, opt_units) {\n  projection = get(projection);\n  let pointResolution;\n  const getter = projection.getPointResolutionFunc();\n  if (getter) {\n    pointResolution = getter(resolution, point);\n  } else {\n    const units = projection.getUnits();\n    if (units == Units.DEGREES && !opt_units || opt_units == Units.DEGREES) {\n      pointResolution = resolution;\n    } else {\n      // Estimate point resolution by transforming the center pixel to EPSG:4326,\n      // measuring its width and height on the normal sphere, and taking the\n      // average of the width and height.\n      const toEPSG4326 = getTransformFromProjections(projection, get('EPSG:4326'));\n      let vertices = [\n        point[0] - resolution / 2, point[1],\n        point[0] + resolution / 2, point[1],\n        point[0], point[1] - resolution / 2,\n        point[0], point[1] + resolution / 2\n      ];\n      vertices = toEPSG4326(vertices, vertices, 2);\n      const width = getDistance(vertices.slice(0, 2), vertices.slice(2, 4));\n      const height = getDistance(vertices.slice(4, 6), vertices.slice(6, 8));\n      pointResolution = (width + height) / 2;\n      const metersPerUnit = opt_units ?\n        METERS_PER_UNIT[opt_units] :\n        projection.getMetersPerUnit();\n      if (metersPerUnit !== undefined) {\n        pointResolution /= metersPerUnit;\n      }\n    }\n  }\n  return pointResolution;\n}\n\n\n/**\n * Registers transformation functions that don't alter coordinates. Those allow\n * to transform between projections with equal meaning.\n *\n * @param {Array.<module:ol/proj/Projection>} projections Projections.\n * @api\n */\nexport function addEquivalentProjections(projections) {\n  addProjections(projections);\n  projections.forEach(function(source) {\n    projections.forEach(function(destination) {\n      if (source !== destination) {\n        addTransformFunc(source, destination, cloneTransform);\n      }\n    });\n  });\n}\n\n\n/**\n * Registers transformation functions to convert coordinates in any projection\n * in projection1 to any projection in projection2.\n *\n * @param {Array.<module:ol/proj/Projection>} projections1 Projections with equal\n *     meaning.\n * @param {Array.<module:ol/proj/Projection>} projections2 Projections with equal\n *     meaning.\n * @param {module:ol/proj~TransformFunction} forwardTransform Transformation from any\n *   projection in projection1 to any projection in projection2.\n * @param {module:ol/proj~TransformFunction} inverseTransform Transform from any projection\n *   in projection2 to any projection in projection1..\n */\nexport function addEquivalentTransforms(projections1, projections2, forwardTransform, inverseTransform) {\n  projections1.forEach(function(projection1) {\n    projections2.forEach(function(projection2) {\n      addTransformFunc(projection1, projection2, forwardTransform);\n      addTransformFunc(projection2, projection1, inverseTransform);\n    });\n  });\n}\n\n\n/**\n * Clear all cached projections and transforms.\n */\nexport function clearAllProjections() {\n  projections.clear();\n  clearTransformFuncs();\n}\n\n\n/**\n * @param {module:ol/proj/Projection|string|undefined} projection Projection.\n * @param {string} defaultCode Default code.\n * @return {module:ol/proj/Projection} Projection.\n */\nexport function createProjection(projection, defaultCode) {\n  if (!projection) {\n    return get(defaultCode);\n  } else if (typeof projection === 'string') {\n    return get(projection);\n  } else {\n    return (\n      /** @type {module:ol/proj/Projection} */ (projection)\n    );\n  }\n}\n\n\n/**\n * Creates a {@link module:ol/proj~TransformFunction} from a simple 2D coordinate transform\n * function.\n * @param {function(module:ol/coordinate~Coordinate): module:ol/coordinate~Coordinate} coordTransform Coordinate\n *     transform.\n * @return {module:ol/proj~TransformFunction} Transform function.\n */\nexport function createTransformFromCoordinateTransform(coordTransform) {\n  return (\n    /**\n     * @param {Array.<number>} input Input.\n     * @param {Array.<number>=} opt_output Output.\n     * @param {number=} opt_dimension Dimension.\n     * @return {Array.<number>} Output.\n     */\n    function(input, opt_output, opt_dimension) {\n      const length = input.length;\n      const dimension = opt_dimension !== undefined ? opt_dimension : 2;\n      const output = opt_output !== undefined ? opt_output : new Array(length);\n      for (let i = 0; i < length; i += dimension) {\n        const point = coordTransform([input[i], input[i + 1]]);\n        output[i] = point[0];\n        output[i + 1] = point[1];\n        for (let j = dimension - 1; j >= 2; --j) {\n          output[i + j] = input[i + j];\n        }\n      }\n      return output;\n    });\n}\n\n\n/**\n * Registers coordinate transform functions to convert coordinates between the\n * source projection and the destination projection.\n * The forward and inverse functions convert coordinate pairs; this function\n * converts these into the functions used internally which also handle\n * extents and coordinate arrays.\n *\n * @param {module:ol/proj~ProjectionLike} source Source projection.\n * @param {module:ol/proj~ProjectionLike} destination Destination projection.\n * @param {function(module:ol/coordinate~Coordinate): module:ol/coordinate~Coordinate} forward The forward transform\n *     function (that is, from the source projection to the destination\n *     projection) that takes a {@link module:ol/coordinate~Coordinate} as argument and returns\n *     the transformed {@link module:ol/coordinate~Coordinate}.\n * @param {function(module:ol/coordinate~Coordinate): module:ol/coordinate~Coordinate} inverse The inverse transform\n *     function (that is, from the destination projection to the source\n *     projection) that takes a {@link module:ol/coordinate~Coordinate} as argument and returns\n *     the transformed {@link module:ol/coordinate~Coordinate}.\n * @api\n */\nexport function addCoordinateTransforms(source, destination, forward, inverse) {\n  const sourceProj = get(source);\n  const destProj = get(destination);\n  addTransformFunc(sourceProj, destProj, createTransformFromCoordinateTransform(forward));\n  addTransformFunc(destProj, sourceProj, createTransformFromCoordinateTransform(inverse));\n}\n\n\n/**\n * Transforms a coordinate from longitude/latitude to a different projection.\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate as longitude and latitude, i.e.\n *     an array with longitude as 1st and latitude as 2nd element.\n * @param {module:ol/proj~ProjectionLike=} opt_projection Target projection. The\n *     default is Web Mercator, i.e. 'EPSG:3857'.\n * @return {module:ol/coordinate~Coordinate} Coordinate projected to the target projection.\n * @api\n */\nexport function fromLonLat(coordinate, opt_projection) {\n  return transform(coordinate, 'EPSG:4326',\n    opt_projection !== undefined ? opt_projection : 'EPSG:3857');\n}\n\n\n/**\n * Transforms a coordinate to longitude/latitude.\n * @param {module:ol/coordinate~Coordinate} coordinate Projected coordinate.\n * @param {module:ol/proj~ProjectionLike=} opt_projection Projection of the coordinate.\n *     The default is Web Mercator, i.e. 'EPSG:3857'.\n * @return {module:ol/coordinate~Coordinate} Coordinate as longitude and latitude, i.e. an array\n *     with longitude as 1st and latitude as 2nd element.\n * @api\n */\nexport function toLonLat(coordinate, opt_projection) {\n  const lonLat = transform(coordinate,\n    opt_projection !== undefined ? opt_projection : 'EPSG:3857', 'EPSG:4326');\n  const lon = lonLat[0];\n  if (lon < -180 || lon > 180) {\n    lonLat[0] = modulo(lon + 180, 360) - 180;\n  }\n  return lonLat;\n}\n\n\n/**\n * Checks if two projections are the same, that is every coordinate in one\n * projection does represent the same geographic point as the same coordinate in\n * the other projection.\n *\n * @param {module:ol/proj/Projection} projection1 Projection 1.\n * @param {module:ol/proj/Projection} projection2 Projection 2.\n * @return {boolean} Equivalent.\n * @api\n */\nexport function equivalent(projection1, projection2) {\n  if (projection1 === projection2) {\n    return true;\n  }\n  const equalUnits = projection1.getUnits() === projection2.getUnits();\n  if (projection1.getCode() === projection2.getCode()) {\n    return equalUnits;\n  } else {\n    const transformFunc = getTransformFromProjections(projection1, projection2);\n    return transformFunc === cloneTransform && equalUnits;\n  }\n}\n\n\n/**\n * Searches in the list of transform functions for the function for converting\n * coordinates from the source projection to the destination projection.\n *\n * @param {module:ol/proj/Projection} sourceProjection Source Projection object.\n * @param {module:ol/proj/Projection} destinationProjection Destination Projection\n *     object.\n * @return {module:ol/proj~TransformFunction} Transform function.\n */\nexport function getTransformFromProjections(sourceProjection, destinationProjection) {\n  const sourceCode = sourceProjection.getCode();\n  const destinationCode = destinationProjection.getCode();\n  let transformFunc = getTransformFunc(sourceCode, destinationCode);\n  if (!transformFunc) {\n    transformFunc = identityTransform;\n  }\n  return transformFunc;\n}\n\n\n/**\n * Given the projection-like objects, searches for a transformation\n * function to convert a coordinates array from the source projection to the\n * destination projection.\n *\n * @param {module:ol/proj~ProjectionLike} source Source.\n * @param {module:ol/proj~ProjectionLike} destination Destination.\n * @return {module:ol/proj~TransformFunction} Transform function.\n * @api\n */\nexport function getTransform(source, destination) {\n  const sourceProjection = get(source);\n  const destinationProjection = get(destination);\n  return getTransformFromProjections(sourceProjection, destinationProjection);\n}\n\n\n/**\n * Transforms a coordinate from source projection to destination projection.\n * This returns a new coordinate (and does not modify the original).\n *\n * See {@link module:ol/proj~transformExtent} for extent transformation.\n * See the transform method of {@link module:ol/geom/Geometry~Geometry} and its\n * subclasses for geometry transforms.\n *\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n * @param {module:ol/proj~ProjectionLike} source Source projection-like.\n * @param {module:ol/proj~ProjectionLike} destination Destination projection-like.\n * @return {module:ol/coordinate~Coordinate} Coordinate.\n * @api\n */\nexport function transform(coordinate, source, destination) {\n  const transformFunc = getTransform(source, destination);\n  return transformFunc(coordinate, undefined, coordinate.length);\n}\n\n\n/**\n * Transforms an extent from source projection to destination projection.  This\n * returns a new extent (and does not modify the original).\n *\n * @param {module:ol/extent~Extent} extent The extent to transform.\n * @param {module:ol/proj~ProjectionLike} source Source projection-like.\n * @param {module:ol/proj~ProjectionLike} destination Destination projection-like.\n * @return {module:ol/extent~Extent} The transformed extent.\n * @api\n */\nexport function transformExtent(extent, source, destination) {\n  const transformFunc = getTransform(source, destination);\n  return applyTransform(extent, transformFunc);\n}\n\n\n/**\n * Transforms the given point to the destination projection.\n *\n * @param {module:ol/coordinate~Coordinate} point Point.\n * @param {module:ol/proj/Projection} sourceProjection Source projection.\n * @param {module:ol/proj/Projection} destinationProjection Destination projection.\n * @return {module:ol/coordinate~Coordinate} Point.\n */\nexport function transformWithProjections(point, sourceProjection, destinationProjection) {\n  const transformFunc = getTransformFromProjections(sourceProjection, destinationProjection);\n  return transformFunc(point);\n}\n\n/**\n * Add transforms to and from EPSG:4326 and EPSG:3857.  This function is called\n * by when this module is executed and should only need to be called again after\n * `clearAllProjections()` is called (e.g. in tests).\n */\nexport function addCommon() {\n  // Add transformations that don't alter coordinates to convert within set of\n  // projections with equal meaning.\n  addEquivalentProjections(EPSG3857_PROJECTIONS);\n  addEquivalentProjections(EPSG4326_PROJECTIONS);\n  // Add transformations to convert EPSG:4326 like coordinates to EPSG:3857 like\n  // coordinates and back.\n  addEquivalentTransforms(EPSG4326_PROJECTIONS, EPSG3857_PROJECTIONS, fromEPSG4326, toEPSG4326);\n}\n\naddCommon();\n","/**\n * @module ol/transform\n */\nimport {assert} from './asserts.js';\n\n\n/**\n * An array representing an affine 2d transformation for use with\n * {@link module:ol/transform} functions. The array has 6 elements.\n * @typedef {!Array.<number>} Transform\n */\n\n\n/**\n * Collection of affine 2d transformation functions. The functions work on an\n * array of 6 elements. The element order is compatible with the [SVGMatrix\n * interface](https://developer.mozilla.org/en-US/docs/Web/API/SVGMatrix) and is\n * a subset (elements a to f) of a 3×3 matrix:\n * ```\n * [ a c e ]\n * [ b d f ]\n * [ 0 0 1 ]\n * ```\n */\n\n\n/**\n * @private\n * @type {module:ol/transform~Transform}\n */\nconst tmp_ = new Array(6);\n\n\n/**\n * Create an identity transform.\n * @return {!module:ol/transform~Transform} Identity transform.\n */\nexport function create() {\n  return [1, 0, 0, 1, 0, 0];\n}\n\n\n/**\n * Resets the given transform to an identity transform.\n * @param {!module:ol/transform~Transform} transform Transform.\n * @return {!module:ol/transform~Transform} Transform.\n */\nexport function reset(transform) {\n  return set(transform, 1, 0, 0, 1, 0, 0);\n}\n\n\n/**\n * Multiply the underlying matrices of two transforms and return the result in\n * the first transform.\n * @param {!module:ol/transform~Transform} transform1 Transform parameters of matrix 1.\n * @param {!module:ol/transform~Transform} transform2 Transform parameters of matrix 2.\n * @return {!module:ol/transform~Transform} transform1 multiplied with transform2.\n */\nexport function multiply(transform1, transform2) {\n  const a1 = transform1[0];\n  const b1 = transform1[1];\n  const c1 = transform1[2];\n  const d1 = transform1[3];\n  const e1 = transform1[4];\n  const f1 = transform1[5];\n  const a2 = transform2[0];\n  const b2 = transform2[1];\n  const c2 = transform2[2];\n  const d2 = transform2[3];\n  const e2 = transform2[4];\n  const f2 = transform2[5];\n\n  transform1[0] = a1 * a2 + c1 * b2;\n  transform1[1] = b1 * a2 + d1 * b2;\n  transform1[2] = a1 * c2 + c1 * d2;\n  transform1[3] = b1 * c2 + d1 * d2;\n  transform1[4] = a1 * e2 + c1 * f2 + e1;\n  transform1[5] = b1 * e2 + d1 * f2 + f1;\n\n  return transform1;\n}\n\n/**\n * Set the transform components a-f on a given transform.\n * @param {!module:ol/transform~Transform} transform Transform.\n * @param {number} a The a component of the transform.\n * @param {number} b The b component of the transform.\n * @param {number} c The c component of the transform.\n * @param {number} d The d component of the transform.\n * @param {number} e The e component of the transform.\n * @param {number} f The f component of the transform.\n * @return {!module:ol/transform~Transform} Matrix with transform applied.\n */\nexport function set(transform, a, b, c, d, e, f) {\n  transform[0] = a;\n  transform[1] = b;\n  transform[2] = c;\n  transform[3] = d;\n  transform[4] = e;\n  transform[5] = f;\n  return transform;\n}\n\n\n/**\n * Set transform on one matrix from another matrix.\n * @param {!module:ol/transform~Transform} transform1 Matrix to set transform to.\n * @param {!module:ol/transform~Transform} transform2 Matrix to set transform from.\n * @return {!module:ol/transform~Transform} transform1 with transform from transform2 applied.\n */\nexport function setFromArray(transform1, transform2) {\n  transform1[0] = transform2[0];\n  transform1[1] = transform2[1];\n  transform1[2] = transform2[2];\n  transform1[3] = transform2[3];\n  transform1[4] = transform2[4];\n  transform1[5] = transform2[5];\n  return transform1;\n}\n\n\n/**\n * Transforms the given coordinate with the given transform returning the\n * resulting, transformed coordinate. The coordinate will be modified in-place.\n *\n * @param {module:ol/transform~Transform} transform The transformation.\n * @param {module:ol/coordinate~Coordinate|module:ol/pixel~Pixel} coordinate The coordinate to transform.\n * @return {module:ol/coordinate~Coordinate|module:ol/pixel~Pixel} return coordinate so that operations can be\n *     chained together.\n */\nexport function apply(transform, coordinate) {\n  const x = coordinate[0];\n  const y = coordinate[1];\n  coordinate[0] = transform[0] * x + transform[2] * y + transform[4];\n  coordinate[1] = transform[1] * x + transform[3] * y + transform[5];\n  return coordinate;\n}\n\n\n/**\n * Applies rotation to the given transform.\n * @param {!module:ol/transform~Transform} transform Transform.\n * @param {number} angle Angle in radians.\n * @return {!module:ol/transform~Transform} The rotated transform.\n */\nexport function rotate(transform, angle) {\n  const cos = Math.cos(angle);\n  const sin = Math.sin(angle);\n  return multiply(transform, set(tmp_, cos, sin, -sin, cos, 0, 0));\n}\n\n\n/**\n * Applies scale to a given transform.\n * @param {!module:ol/transform~Transform} transform Transform.\n * @param {number} x Scale factor x.\n * @param {number} y Scale factor y.\n * @return {!module:ol/transform~Transform} The scaled transform.\n */\nexport function scale(transform, x, y) {\n  return multiply(transform, set(tmp_, x, 0, 0, y, 0, 0));\n}\n\n\n/**\n * Applies translation to the given transform.\n * @param {!module:ol/transform~Transform} transform Transform.\n * @param {number} dx Translation x.\n * @param {number} dy Translation y.\n * @return {!module:ol/transform~Transform} The translated transform.\n */\nexport function translate(transform, dx, dy) {\n  return multiply(transform, set(tmp_, 1, 0, 0, 1, dx, dy));\n}\n\n\n/**\n * Creates a composite transform given an initial translation, scale, rotation, and\n * final translation (in that order only, not commutative).\n * @param {!module:ol/transform~Transform} transform The transform (will be modified in place).\n * @param {number} dx1 Initial translation x.\n * @param {number} dy1 Initial translation y.\n * @param {number} sx Scale factor x.\n * @param {number} sy Scale factor y.\n * @param {number} angle Rotation (in counter-clockwise radians).\n * @param {number} dx2 Final translation x.\n * @param {number} dy2 Final translation y.\n * @return {!module:ol/transform~Transform} The composite transform.\n */\nexport function compose(transform, dx1, dy1, sx, sy, angle, dx2, dy2) {\n  const sin = Math.sin(angle);\n  const cos = Math.cos(angle);\n  transform[0] = sx * cos;\n  transform[1] = sy * sin;\n  transform[2] = -sx * sin;\n  transform[3] = sy * cos;\n  transform[4] = dx2 * sx * cos - dy2 * sx * sin + dx1;\n  transform[5] = dx2 * sy * sin + dy2 * sy * cos + dy1;\n  return transform;\n}\n\n\n/**\n * Invert the given transform.\n * @param {!module:ol/transform~Transform} transform Transform.\n * @return {!module:ol/transform~Transform} Inverse of the transform.\n */\nexport function invert(transform) {\n  const det = determinant(transform);\n  assert(det !== 0, 32); // Transformation matrix cannot be inverted\n\n  const a = transform[0];\n  const b = transform[1];\n  const c = transform[2];\n  const d = transform[3];\n  const e = transform[4];\n  const f = transform[5];\n\n  transform[0] = d / det;\n  transform[1] = -b / det;\n  transform[2] = -c / det;\n  transform[3] = a / det;\n  transform[4] = (c * f - d * e) / det;\n  transform[5] = -(a * f - b * e) / det;\n\n  return transform;\n}\n\n\n/**\n * Returns the determinant of the given matrix.\n * @param {!module:ol/transform~Transform} mat Matrix.\n * @return {number} Determinant.\n */\nexport function determinant(mat) {\n  return mat[0] * mat[3] - mat[1] * mat[2];\n}\n","/**\n * @module ol/geom/Geometry\n */\nimport BaseObject from '../Object.js';\nimport {createEmpty, getHeight, returnOrUpdate} from '../extent.js';\nimport {FALSE} from '../functions.js';\nimport {transform2D} from '../geom/flat/transform.js';\nimport {get as getProjection, getTransform} from '../proj.js';\nimport Units from '../proj/Units.js';\nimport {create as createTransform, compose as composeTransform} from '../transform.js';\n\n\n/**\n * @type {module:ol/transform~Transform}\n */\nconst tmpTransform = createTransform();\n\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Base class for vector geometries.\n *\n * To get notified of changes to the geometry, register a listener for the\n * generic `change` event on your geometry instance.\n *\n * @abstract\n * @api\n */\nclass Geometry extends BaseObject {\n  constructor() {\n\n    super();\n\n    /**\n     * @private\n     * @type {module:ol/extent~Extent}\n     */\n    this.extent_ = createEmpty();\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.extentRevision_ = -1;\n\n    /**\n     * @protected\n     * @type {Object.<string, module:ol/geom/Geometry>}\n     */\n    this.simplifiedGeometryCache = {};\n\n    /**\n     * @protected\n     * @type {number}\n     */\n    this.simplifiedGeometryMaxMinSquaredTolerance = 0;\n\n    /**\n     * @protected\n     * @type {number}\n     */\n    this.simplifiedGeometryRevision = 0;\n\n  }\n\n  /**\n   * Make a complete copy of the geometry.\n   * @abstract\n   * @return {!module:ol/geom/Geometry} Clone.\n   */\n  clone() {}\n\n  /**\n   * @abstract\n   * @param {number} x X.\n   * @param {number} y Y.\n   * @param {module:ol/coordinate~Coordinate} closestPoint Closest point.\n   * @param {number} minSquaredDistance Minimum squared distance.\n   * @return {number} Minimum squared distance.\n   */\n  closestPointXY(x, y, closestPoint, minSquaredDistance) {}\n\n  /**\n   * Return the closest point of the geometry to the passed point as\n   * {@link module:ol/coordinate~Coordinate coordinate}.\n   * @param {module:ol/coordinate~Coordinate} point Point.\n   * @param {module:ol/coordinate~Coordinate=} opt_closestPoint Closest point.\n   * @return {module:ol/coordinate~Coordinate} Closest point.\n   * @api\n   */\n  getClosestPoint(point, opt_closestPoint) {\n    const closestPoint = opt_closestPoint ? opt_closestPoint : [NaN, NaN];\n    this.closestPointXY(point[0], point[1], closestPoint, Infinity);\n    return closestPoint;\n  }\n\n  /**\n   * Returns true if this geometry includes the specified coordinate. If the\n   * coordinate is on the boundary of the geometry, returns false.\n   * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n   * @return {boolean} Contains coordinate.\n   * @api\n   */\n  intersectsCoordinate(coordinate) {\n    return this.containsXY(coordinate[0], coordinate[1]);\n  }\n\n  /**\n   * @abstract\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @protected\n   * @return {module:ol/extent~Extent} extent Extent.\n   */\n  computeExtent(extent) {}\n\n  /**\n   * Get the extent of the geometry.\n   * @param {module:ol/extent~Extent=} opt_extent Extent.\n   * @return {module:ol/extent~Extent} extent Extent.\n   * @api\n   */\n  getExtent(opt_extent) {\n    if (this.extentRevision_ != this.getRevision()) {\n      this.extent_ = this.computeExtent(this.extent_);\n      this.extentRevision_ = this.getRevision();\n    }\n    return returnOrUpdate(this.extent_, opt_extent);\n  }\n\n  /**\n   * Rotate the geometry around a given coordinate. This modifies the geometry\n   * coordinates in place.\n   * @abstract\n   * @param {number} angle Rotation angle in radians.\n   * @param {module:ol/coordinate~Coordinate} anchor The rotation center.\n   * @api\n   */\n  rotate(angle, anchor) {}\n\n  /**\n   * Scale the geometry (with an optional origin).  This modifies the geometry\n   * coordinates in place.\n   * @abstract\n   * @param {number} sx The scaling factor in the x-direction.\n   * @param {number=} opt_sy The scaling factor in the y-direction (defaults to\n   *     sx).\n   * @param {module:ol/coordinate~Coordinate=} opt_anchor The scale origin (defaults to the center\n   *     of the geometry extent).\n   * @api\n   */\n  scale(sx, opt_sy, opt_anchor) {}\n\n  /**\n   * Translate the geometry. This modifies the geometry coordinates in place.\n   * @abstract\n   * @param {number} deltaX Delta X.\n   * @param {number} deltaY Delta Y.\n   * @api\n   */\n  translate(deltaX, deltaY) {}\n\n  /**\n   * Create a simplified version of this geometry.  For linestrings, this uses\n   * the the {@link\n   * https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm\n   * Douglas Peucker} algorithm.  For polygons, a quantization-based\n   * simplification is used to preserve topology.\n   * @function\n   * @param {number} tolerance The tolerance distance for simplification.\n   * @return {module:ol/geom/Geometry} A new, simplified version of the original\n   *     geometry.\n   * @api\n   */\n  simplify(tolerance) {\n    return this.getSimplifiedGeometry(tolerance * tolerance);\n  }\n\n  /**\n   * Create a simplified version of this geometry using the Douglas Peucker\n   * algorithm.\n   * See https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm.\n   * @abstract\n   * @param {number} squaredTolerance Squared tolerance.\n   * @return {module:ol/geom/Geometry} Simplified geometry.\n   */\n  getSimplifiedGeometry(squaredTolerance) {}\n\n  /**\n   * Get the type of this geometry.\n   * @abstract\n   * @return {module:ol/geom/GeometryType} Geometry type.\n   */\n  getType() {}\n\n  /**\n   * Apply a transform function to each coordinate of the geometry.\n   * The geometry is modified in place.\n   * If you do not want the geometry modified in place, first `clone()` it and\n   * then use this function on the clone.\n   * @abstract\n   * @param {module:ol/proj~TransformFunction} transformFn Transform.\n   */\n  applyTransform(transformFn) {}\n\n  /**\n   * Test if the geometry and the passed extent intersect.\n   * @abstract\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @return {boolean} `true` if the geometry and the extent intersect.\n   */\n  intersectsExtent(extent) {}\n\n  /**\n   * Translate the geometry.  This modifies the geometry coordinates in place.  If\n   * instead you want a new geometry, first `clone()` this geometry.\n   * @abstract\n   * @param {number} deltaX Delta X.\n   * @param {number} deltaY Delta Y.\n   */\n  translate(deltaX, deltaY) {}\n\n  /**\n   * Transform each coordinate of the geometry from one coordinate reference\n   * system to another. The geometry is modified in place.\n   * For example, a line will be transformed to a line and a circle to a circle.\n   * If you do not want the geometry modified in place, first `clone()` it and\n   * then use this function on the clone.\n   *\n   * @param {module:ol/proj~ProjectionLike} source The current projection.  Can be a\n   *     string identifier or a {@link module:ol/proj/Projection~Projection} object.\n   * @param {module:ol/proj~ProjectionLike} destination The desired projection.  Can be a\n   *     string identifier or a {@link module:ol/proj/Projection~Projection} object.\n   * @return {module:ol/geom/Geometry} This geometry.  Note that original geometry is\n   *     modified in place.\n   * @api\n   */\n  transform(source, destination) {\n    source = getProjection(source);\n    const transformFn = source.getUnits() == Units.TILE_PIXELS ?\n      function(inCoordinates, outCoordinates, stride) {\n        const pixelExtent = source.getExtent();\n        const projectedExtent = source.getWorldExtent();\n        const scale = getHeight(projectedExtent) / getHeight(pixelExtent);\n        composeTransform(tmpTransform,\n          projectedExtent[0], projectedExtent[3],\n          scale, -scale, 0,\n          0, 0);\n        transform2D(inCoordinates, 0, inCoordinates.length, stride,\n          tmpTransform, outCoordinates);\n        return getTransform(source, destination)(inCoordinates, outCoordinates, stride);\n      } :\n      getTransform(source, destination);\n    this.applyTransform(transformFn);\n    return this;\n  }\n}\n\n\n/**\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\nGeometry.prototype.containsXY = FALSE;\n\n\nexport default Geometry;\n","/**\n * @module ol/color\n */\nimport {assert} from './asserts.js';\nimport {clamp} from './math.js';\n\n\n/**\n * A color represented as a short array [red, green, blue, alpha].\n * red, green, and blue should be integers in the range 0..255 inclusive.\n * alpha should be a float in the range 0..1 inclusive. If no alpha value is\n * given then `1` will be used.\n * @typedef {Array.<number>} Color\n * @api\n */\n\n\n/**\n * This RegExp matches # followed by 3, 4, 6, or 8 hex digits.\n * @const\n * @type {RegExp}\n * @private\n */\nconst HEX_COLOR_RE_ = /^#([a-f0-9]{3}|[a-f0-9]{4}(?:[a-f0-9]{2}){0,2})$/i;\n\n\n/**\n * Regular expression for matching potential named color style strings.\n * @const\n * @type {RegExp}\n * @private\n */\nconst NAMED_COLOR_RE_ = /^([a-z]*)$/i;\n\n\n/**\n * Return the color as an rgba string.\n * @param {module:ol/color~Color|string} color Color.\n * @return {string} Rgba string.\n * @api\n */\nexport function asString(color) {\n  if (typeof color === 'string') {\n    return color;\n  } else {\n    return toString(color);\n  }\n}\n\n/**\n * Return named color as an rgba string.\n * @param {string} color Named color.\n * @return {string} Rgb string.\n */\nfunction fromNamed(color) {\n  const el = document.createElement('div');\n  el.style.color = color;\n  if (el.style.color !== '') {\n    document.body.appendChild(el);\n    const rgb = getComputedStyle(el).color;\n    document.body.removeChild(el);\n    return rgb;\n  } else {\n    return '';\n  }\n}\n\n\n/**\n * @param {string} s String.\n * @return {module:ol/color~Color} Color.\n */\nexport const fromString = (\n  function() {\n\n    // We maintain a small cache of parsed strings.  To provide cheap LRU-like\n    // semantics, whenever the cache grows too large we simply delete an\n    // arbitrary 25% of the entries.\n\n    /**\n     * @const\n     * @type {number}\n     */\n    const MAX_CACHE_SIZE = 1024;\n\n    /**\n     * @type {Object.<string, module:ol/color~Color>}\n     */\n    const cache = {};\n\n    /**\n     * @type {number}\n     */\n    let cacheSize = 0;\n\n    return (\n      /**\n       * @param {string} s String.\n       * @return {module:ol/color~Color} Color.\n       */\n      function(s) {\n        let color;\n        if (cache.hasOwnProperty(s)) {\n          color = cache[s];\n        } else {\n          if (cacheSize >= MAX_CACHE_SIZE) {\n            let i = 0;\n            for (const key in cache) {\n              if ((i++ & 3) === 0) {\n                delete cache[key];\n                --cacheSize;\n              }\n            }\n          }\n          color = fromStringInternal_(s);\n          cache[s] = color;\n          ++cacheSize;\n        }\n        return color;\n      }\n    );\n\n  })();\n\n/**\n * Return the color as an array. This function maintains a cache of calculated\n * arrays which means the result should not be modified.\n * @param {module:ol/color~Color|string} color Color.\n * @return {module:ol/color~Color} Color.\n * @api\n */\nexport function asArray(color) {\n  if (Array.isArray(color)) {\n    return color;\n  } else {\n    return fromString(/** @type {string} */ (color));\n  }\n}\n\n/**\n * @param {string} s String.\n * @private\n * @return {module:ol/color~Color} Color.\n */\nfunction fromStringInternal_(s) {\n  let r, g, b, a, color;\n\n  if (NAMED_COLOR_RE_.exec(s)) {\n    s = fromNamed(s);\n  }\n\n  if (HEX_COLOR_RE_.exec(s)) { // hex\n    const n = s.length - 1; // number of hex digits\n    let d; // number of digits per channel\n    if (n <= 4) {\n      d = 1;\n    } else {\n      d = 2;\n    }\n    const hasAlpha = n === 4 || n === 8;\n    r = parseInt(s.substr(1 + 0 * d, d), 16);\n    g = parseInt(s.substr(1 + 1 * d, d), 16);\n    b = parseInt(s.substr(1 + 2 * d, d), 16);\n    if (hasAlpha) {\n      a = parseInt(s.substr(1 + 3 * d, d), 16);\n    } else {\n      a = 255;\n    }\n    if (d == 1) {\n      r = (r << 4) + r;\n      g = (g << 4) + g;\n      b = (b << 4) + b;\n      if (hasAlpha) {\n        a = (a << 4) + a;\n      }\n    }\n    color = [r, g, b, a / 255];\n  } else if (s.indexOf('rgba(') == 0) { // rgba()\n    color = s.slice(5, -1).split(',').map(Number);\n    normalize(color);\n  } else if (s.indexOf('rgb(') == 0) { // rgb()\n    color = s.slice(4, -1).split(',').map(Number);\n    color.push(1);\n    normalize(color);\n  } else {\n    assert(false, 14); // Invalid color\n  }\n  return (\n    /** @type {module:ol/color~Color} */ (color)\n  );\n}\n\n\n/**\n * TODO this function is only used in the test, we probably shouldn't export it\n * @param {module:ol/color~Color} color Color.\n * @return {module:ol/color~Color} Clamped color.\n */\nexport function normalize(color) {\n  color[0] = clamp((color[0] + 0.5) | 0, 0, 255);\n  color[1] = clamp((color[1] + 0.5) | 0, 0, 255);\n  color[2] = clamp((color[2] + 0.5) | 0, 0, 255);\n  color[3] = clamp(color[3], 0, 1);\n  return color;\n}\n\n\n/**\n * @param {module:ol/color~Color} color Color.\n * @return {string} String.\n */\nexport function toString(color) {\n  let r = color[0];\n  if (r != (r | 0)) {\n    r = (r + 0.5) | 0;\n  }\n  let g = color[1];\n  if (g != (g | 0)) {\n    g = (g + 0.5) | 0;\n  }\n  let b = color[2];\n  if (b != (b | 0)) {\n    b = (b + 0.5) | 0;\n  }\n  const a = color[3] === undefined ? 1 : color[3];\n  return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';\n}\n","/**\n * @module ol/colorlike\n */\nimport {toString} from './color.js';\n\n\n/**\n * A type accepted by CanvasRenderingContext2D.fillStyle\n * or CanvasRenderingContext2D.strokeStyle.\n * Represents a color, pattern, or gradient. The origin for patterns and\n * gradients as fill style is an increment of 512 css pixels from map coordinate\n * `[0, 0]`. For seamless repeat patterns, width and height of the pattern image\n * must be a factor of two (2, 4, 8, ..., 512).\n *\n * @typedef {string|CanvasPattern|CanvasGradient} ColorLike\n * @api\n */\n\n\n/**\n * @param {module:ol/color~Color|module:ol/colorlike~ColorLike} color Color.\n * @return {module:ol/colorlike~ColorLike} The color as an {@link ol/colorlike~ColorLike}.\n * @api\n */\nexport function asColorLike(color) {\n  if (isColorLike(color)) {\n    return /** @type {string|CanvasPattern|CanvasGradient} */ (color);\n  } else {\n    return toString(/** @type {module:ol/color~Color} */ (color));\n  }\n}\n\n\n/**\n * @param {?} color The value that is potentially an {@link ol/colorlike~ColorLike}.\n * @return {boolean} The color is an {@link ol/colorlike~ColorLike}.\n */\nexport function isColorLike(color) {\n  return (\n    typeof color === 'string' ||\n    color instanceof CanvasPattern ||\n    color instanceof CanvasGradient\n  );\n}\n","/**\n * @module ol/dom\n */\n\n\n/**\n * Create an html canvas element and returns its 2d context.\n * @param {number=} opt_width Canvas width.\n * @param {number=} opt_height Canvas height.\n * @return {CanvasRenderingContext2D} The context.\n */\nexport function createCanvasContext2D(opt_width, opt_height) {\n  const canvas = /** @type {HTMLCanvasElement} */ (document.createElement('CANVAS'));\n  if (opt_width) {\n    canvas.width = opt_width;\n  }\n  if (opt_height) {\n    canvas.height = opt_height;\n  }\n  return /** @type {CanvasRenderingContext2D} */ (canvas.getContext('2d'));\n}\n\n\n/**\n * Get the current computed width for the given element including margin,\n * padding and border.\n * Equivalent to jQuery's `$(el).outerWidth(true)`.\n * @param {!HTMLElement} element Element.\n * @return {number} The width.\n */\nexport function outerWidth(element) {\n  let width = element.offsetWidth;\n  const style = getComputedStyle(element);\n  width += parseInt(style.marginLeft, 10) + parseInt(style.marginRight, 10);\n\n  return width;\n}\n\n\n/**\n * Get the current computed height for the given element including margin,\n * padding and border.\n * Equivalent to jQuery's `$(el).outerHeight(true)`.\n * @param {!HTMLElement} element Element.\n * @return {number} The height.\n */\nexport function outerHeight(element) {\n  let height = element.offsetHeight;\n  const style = getComputedStyle(element);\n  height += parseInt(style.marginTop, 10) + parseInt(style.marginBottom, 10);\n\n  return height;\n}\n\n/**\n * @param {Node} newNode Node to replace old node\n * @param {Node} oldNode The node to be replaced\n */\nexport function replaceNode(newNode, oldNode) {\n  const parent = oldNode.parentNode;\n  if (parent) {\n    parent.replaceChild(newNode, oldNode);\n  }\n}\n\n/**\n * @param {Node} node The node to remove.\n * @returns {Node} The node that was removed or null.\n */\nexport function removeNode(node) {\n  return node && node.parentNode ? node.parentNode.removeChild(node) : null;\n}\n\n/**\n * @param {Node} node The node to remove the children from.\n */\nexport function removeChildren(node) {\n  while (node.lastChild) {\n    node.removeChild(node.lastChild);\n  }\n}\n","/**\n * @module ol/webgl\n */\n\n\n/**\n * Constants taken from goog.webgl\n */\n\n\n/**\n * @const\n * @type {number}\n */\nexport const ONE = 1;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const SRC_ALPHA = 0x0302;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const COLOR_ATTACHMENT0 = 0x8CE0;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const COLOR_BUFFER_BIT = 0x00004000;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const TRIANGLES = 0x0004;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const TRIANGLE_STRIP = 0x0005;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const ONE_MINUS_SRC_ALPHA = 0x0303;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const ARRAY_BUFFER = 0x8892;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const ELEMENT_ARRAY_BUFFER = 0x8893;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const STREAM_DRAW = 0x88E0;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const STATIC_DRAW = 0x88E4;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const DYNAMIC_DRAW = 0x88E8;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const CULL_FACE = 0x0B44;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const BLEND = 0x0BE2;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const STENCIL_TEST = 0x0B90;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const DEPTH_TEST = 0x0B71;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const SCISSOR_TEST = 0x0C11;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const UNSIGNED_BYTE = 0x1401;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const UNSIGNED_SHORT = 0x1403;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const UNSIGNED_INT = 0x1405;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const FLOAT = 0x1406;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const RGBA = 0x1908;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const FRAGMENT_SHADER = 0x8B30;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const VERTEX_SHADER = 0x8B31;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const LINK_STATUS = 0x8B82;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const LINEAR = 0x2601;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const TEXTURE_MAG_FILTER = 0x2800;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const TEXTURE_MIN_FILTER = 0x2801;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const TEXTURE_WRAP_S = 0x2802;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const TEXTURE_WRAP_T = 0x2803;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const TEXTURE_2D = 0x0DE1;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const TEXTURE0 = 0x84C0;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const CLAMP_TO_EDGE = 0x812F;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const COMPILE_STATUS = 0x8B81;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const FRAMEBUFFER = 0x8D40;\n\n\n/** end of goog.webgl constants\n */\n\n\n/**\n * @const\n * @type {Array.<string>}\n */\nconst CONTEXT_IDS = [\n  'experimental-webgl',\n  'webgl',\n  'webkit-3d',\n  'moz-webgl'\n];\n\n\n/**\n * @param {HTMLCanvasElement} canvas Canvas.\n * @param {Object=} opt_attributes Attributes.\n * @return {WebGLRenderingContext} WebGL rendering context.\n */\nexport function getContext(canvas, opt_attributes) {\n  const ii = CONTEXT_IDS.length;\n  for (let i = 0; i < ii; ++i) {\n    try {\n      const context = canvas.getContext(CONTEXT_IDS[i], opt_attributes);\n      if (context) {\n        return /** @type {!WebGLRenderingContext} */ (context);\n      }\n    } catch (e) {\n      // pass\n    }\n  }\n  return null;\n}\n\n\n/**\n * Include debuggable shader sources.  Default is `true`. This should be set to\n * `false` for production builds.\n * @type {boolean}\n */\nexport const DEBUG = true;\n\n\n/**\n * The maximum supported WebGL texture size in pixels. If WebGL is not\n * supported, the value is set to `undefined`.\n * @type {number|undefined}\n */\nlet MAX_TEXTURE_SIZE; // value is set below\n\n\n/**\n * List of supported WebGL extensions.\n * @type {Array.<string>}\n */\nlet EXTENSIONS; // value is set below\n\n\n/**\n * True if both OpenLayers and browser support WebGL.\n * @type {boolean}\n * @api\n */\nlet HAS = false;\n\n//TODO Remove side effects\nif (typeof window !== 'undefined' && 'WebGLRenderingContext' in window) {\n  try {\n    const canvas = /** @type {HTMLCanvasElement} */ (document.createElement('CANVAS'));\n    const gl = getContext(canvas, {failIfMajorPerformanceCaveat: true});\n    if (gl) {\n      HAS = true;\n      MAX_TEXTURE_SIZE = /** @type {number} */ (gl.getParameter(gl.MAX_TEXTURE_SIZE));\n      EXTENSIONS = gl.getSupportedExtensions();\n    }\n  } catch (e) {\n    // pass\n  }\n}\n\nexport {HAS, MAX_TEXTURE_SIZE, EXTENSIONS};\n","/**\n * @module ol/has\n */\n\nconst ua = typeof navigator !== 'undefined' ?\n  navigator.userAgent.toLowerCase() : '';\n\n/**\n * User agent string says we are dealing with Firefox as browser.\n * @type {boolean}\n */\nexport const FIREFOX = ua.indexOf('firefox') !== -1;\n\n/**\n * User agent string says we are dealing with Safari as browser.\n * @type {boolean}\n */\nexport const SAFARI = ua.indexOf('safari') !== -1 && ua.indexOf('chrom') == -1;\n\n/**\n * User agent string says we are dealing with a WebKit engine.\n * @type {boolean}\n */\nexport const WEBKIT = ua.indexOf('webkit') !== -1 && ua.indexOf('edge') == -1;\n\n/**\n * User agent string says we are dealing with a Mac as platform.\n * @type {boolean}\n */\nexport const MAC = ua.indexOf('macintosh') !== -1;\n\n\n/**\n * The ratio between physical pixels and device-independent pixels\n * (dips) on the device (`window.devicePixelRatio`).\n * @const\n * @type {number}\n * @api\n */\nexport const DEVICE_PIXEL_RATIO = window.devicePixelRatio || 1;\n\n\n/**\n * True if the browser's Canvas implementation implements {get,set}LineDash.\n * @type {boolean}\n */\nexport const CANVAS_LINE_DASH = function() {\n  let has = false;\n  try {\n    has = !!document.createElement('CANVAS').getContext('2d').setLineDash;\n  } catch (e) {\n    // pass\n  }\n  return has;\n}();\n\n\n/**\n * Is HTML5 geolocation supported in the current browser?\n * @const\n * @type {boolean}\n * @api\n */\nexport const GEOLOCATION = 'geolocation' in navigator;\n\n\n/**\n * True if browser supports touch events.\n * @const\n * @type {boolean}\n * @api\n */\nexport const TOUCH = 'ontouchstart' in window;\n\n\n/**\n * True if browser supports pointer events.\n * @const\n * @type {boolean}\n */\nexport const POINTER = 'PointerEvent' in window;\n\n\n/**\n * True if browser supports ms pointer events (IE 10).\n * @const\n * @type {boolean}\n */\nexport const MSPOINTER = !!(navigator.msPointerEnabled);\n\n\nexport {HAS as WEBGL} from './webgl.js';\n","/**\n * @module ol/css\n */\n\n\n/**\n * The CSS class for hidden feature.\n *\n * @const\n * @type {string}\n */\nexport const CLASS_HIDDEN = 'ol-hidden';\n\n\n/**\n * The CSS class that we'll give the DOM elements to have them selectable.\n *\n * @const\n * @type {string}\n */\nexport const CLASS_SELECTABLE = 'ol-selectable';\n\n\n/**\n * The CSS class that we'll give the DOM elements to have them unselectable.\n *\n * @const\n * @type {string}\n */\nexport const CLASS_UNSELECTABLE = 'ol-unselectable';\n\n\n/**\n * The CSS class for unsupported feature.\n *\n * @const\n * @type {string}\n */\nexport const CLASS_UNSUPPORTED = 'ol-unsupported';\n\n\n/**\n * The CSS class for controls.\n *\n * @const\n * @type {string}\n */\nexport const CLASS_CONTROL = 'ol-control';\n\n\n/**\n * The CSS class that we'll give the DOM elements that are collapsed, i.e.\n * to those elements which usually can be expanded.\n *\n * @const\n * @type {string}\n */\nexport const CLASS_COLLAPSED = 'ol-collapsed';\n\n\n/**\n * Get the list of font families from a font spec.  Note that this doesn't work\n * for font families that have commas in them.\n * @param {string} The CSS font property.\n * @return {Object.<string>} The font families (or null if the input spec is invalid).\n */\nexport const getFontFamilies = (function() {\n  let style;\n  const cache = {};\n  return function(font) {\n    if (!style) {\n      style = document.createElement('div').style;\n    }\n    if (!(font in cache)) {\n      style.font = font;\n      const family = style.fontFamily;\n      style.font = '';\n      if (!family) {\n        return null;\n      }\n      cache[font] = family.split(/,\\s?/);\n    }\n    return cache[font];\n  };\n})();\n","/**\n * @module ol/ImageState\n */\n\n/**\n * @enum {number}\n */\nexport default {\n  IDLE: 0,\n  LOADING: 1,\n  LOADED: 2,\n  ERROR: 3\n};\n","/**\n * @module ol/structs/LRUCache\n */\n\nimport {assert} from '../asserts.js';\nimport EventTarget from '../events/EventTarget.js';\nimport EventType from '../events/EventType.js';\n\n\n/**\n * @typedef {Object} Entry\n * @property {string} key_\n * @property {Object} newer\n * @property {Object} older\n * @property {*} value_\n */\n\n\n/**\n * @classdesc\n * Implements a Least-Recently-Used cache where the keys do not conflict with\n * Object's properties (e.g. 'hasOwnProperty' is not allowed as a key). Expiring\n * items from the cache is the responsibility of the user.\n *\n * @fires module:ol/events/Event~Event\n * @template T\n */\nclass LRUCache extends EventTarget {\n\n  /**\n   * @param {number=} opt_highWaterMark High water mark.\n   */\n  constructor(opt_highWaterMark) {\n\n    super();\n\n    /**\n     * @type {number}\n     */\n    this.highWaterMark = opt_highWaterMark !== undefined ? opt_highWaterMark : 2048;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.count_ = 0;\n\n    /**\n     * @private\n     * @type {!Object.<string, module:ol/structs/LRUCache~Entry>}\n     */\n    this.entries_ = {};\n\n    /**\n     * @private\n     * @type {?module:ol/structs/LRUCache~Entry}\n     */\n    this.oldest_ = null;\n\n    /**\n     * @private\n     * @type {?module:ol/structs/LRUCache~Entry}\n     */\n    this.newest_ = null;\n\n  }\n\n\n  /**\n   * @return {boolean} Can expire cache.\n   */\n  canExpireCache() {\n    return this.getCount() > this.highWaterMark;\n  }\n\n\n  /**\n   * FIXME empty description for jsdoc\n   */\n  clear() {\n    this.count_ = 0;\n    this.entries_ = {};\n    this.oldest_ = null;\n    this.newest_ = null;\n    this.dispatchEvent(EventType.CLEAR);\n  }\n\n\n  /**\n   * @param {string} key Key.\n   * @return {boolean} Contains key.\n   */\n  containsKey(key) {\n    return this.entries_.hasOwnProperty(key);\n  }\n\n\n  /**\n   * @param {function(this: S, T, string, module:ol/structs/LRUCache): ?} f The function\n   *     to call for every entry from the oldest to the newer. This function takes\n   *     3 arguments (the entry value, the entry key and the LRUCache object).\n   *     The return value is ignored.\n   * @param {S=} opt_this The object to use as `this` in `f`.\n   * @template S\n   */\n  forEach(f, opt_this) {\n    let entry = this.oldest_;\n    while (entry) {\n      f.call(opt_this, entry.value_, entry.key_, this);\n      entry = entry.newer;\n    }\n  }\n\n\n  /**\n   * @param {string} key Key.\n   * @return {T} Value.\n   */\n  get(key) {\n    const entry = this.entries_[key];\n    assert(entry !== undefined,\n      15); // Tried to get a value for a key that does not exist in the cache\n    if (entry === this.newest_) {\n      return entry.value_;\n    } else if (entry === this.oldest_) {\n      this.oldest_ = /** @type {module:ol/structs/LRUCache~Entry} */ (this.oldest_.newer);\n      this.oldest_.older = null;\n    } else {\n      entry.newer.older = entry.older;\n      entry.older.newer = entry.newer;\n    }\n    entry.newer = null;\n    entry.older = this.newest_;\n    this.newest_.newer = entry;\n    this.newest_ = entry;\n    return entry.value_;\n  }\n\n\n  /**\n   * Remove an entry from the cache.\n   * @param {string} key The entry key.\n   * @return {T} The removed entry.\n   */\n  remove(key) {\n    const entry = this.entries_[key];\n    assert(entry !== undefined, 15); // Tried to get a value for a key that does not exist in the cache\n    if (entry === this.newest_) {\n      this.newest_ = /** @type {module:ol/structs/LRUCache~Entry} */ (entry.older);\n      if (this.newest_) {\n        this.newest_.newer = null;\n      }\n    } else if (entry === this.oldest_) {\n      this.oldest_ = /** @type {module:ol/structs/LRUCache~Entry} */ (entry.newer);\n      if (this.oldest_) {\n        this.oldest_.older = null;\n      }\n    } else {\n      entry.newer.older = entry.older;\n      entry.older.newer = entry.newer;\n    }\n    delete this.entries_[key];\n    --this.count_;\n    return entry.value_;\n  }\n\n\n  /**\n   * @return {number} Count.\n   */\n  getCount() {\n    return this.count_;\n  }\n\n\n  /**\n   * @return {Array.<string>} Keys.\n   */\n  getKeys() {\n    const keys = new Array(this.count_);\n    let i = 0;\n    let entry;\n    for (entry = this.newest_; entry; entry = entry.older) {\n      keys[i++] = entry.key_;\n    }\n    return keys;\n  }\n\n\n  /**\n   * @return {Array.<T>} Values.\n   */\n  getValues() {\n    const values = new Array(this.count_);\n    let i = 0;\n    let entry;\n    for (entry = this.newest_; entry; entry = entry.older) {\n      values[i++] = entry.value_;\n    }\n    return values;\n  }\n\n\n  /**\n   * @return {T} Last value.\n   */\n  peekLast() {\n    return this.oldest_.value_;\n  }\n\n\n  /**\n   * @return {string} Last key.\n   */\n  peekLastKey() {\n    return this.oldest_.key_;\n  }\n\n\n  /**\n   * Get the key of the newest item in the cache.  Throws if the cache is empty.\n   * @return {string} The newest key.\n   */\n  peekFirstKey() {\n    return this.newest_.key_;\n  }\n\n\n  /**\n   * @return {T} value Value.\n   */\n  pop() {\n    const entry = this.oldest_;\n    delete this.entries_[entry.key_];\n    if (entry.newer) {\n      entry.newer.older = null;\n    }\n    this.oldest_ = /** @type {module:ol/structs/LRUCache~Entry} */ (entry.newer);\n    if (!this.oldest_) {\n      this.newest_ = null;\n    }\n    --this.count_;\n    return entry.value_;\n  }\n\n\n  /**\n   * @param {string} key Key.\n   * @param {T} value Value.\n   */\n  replace(key, value) {\n    this.get(key); // update `newest_`\n    this.entries_[key].value_ = value;\n  }\n\n\n  /**\n   * @param {string} key Key.\n   * @param {T} value Value.\n   */\n  set(key, value) {\n    assert(!(key in this.entries_),\n      16); // Tried to set a value for a key that is used already\n    const entry = /** @type {module:ol/structs/LRUCache~Entry} */ ({\n      key_: key,\n      newer: null,\n      older: this.newest_,\n      value_: value\n    });\n    if (!this.newest_) {\n      this.oldest_ = entry;\n    } else {\n      this.newest_.newer = entry;\n    }\n    this.newest_ = entry;\n    this.entries_[key] = entry;\n    ++this.count_;\n  }\n\n\n  /**\n   * Set a maximum number of entries for the cache.\n   * @param {number} size Cache size.\n   * @api\n   */\n  setSize(size) {\n    this.highWaterMark = size;\n  }\n\n\n  /**\n   * Prune the cache.\n   */\n  prune() {\n    while (this.canExpireCache()) {\n      this.pop();\n    }\n  }\n\n}\n\nexport default LRUCache;\n","/**\n * @module ol/render/canvas\n */\nimport {getFontFamilies} from '../css.js';\nimport {createCanvasContext2D} from '../dom.js';\nimport {clear} from '../obj.js';\nimport LRUCache from '../structs/LRUCache.js';\nimport {create as createTransform} from '../transform.js';\n\n\n/**\n * @typedef {Object} FillState\n * @property {module:ol/colorlike~ColorLike} fillStyle\n */\n\n\n/**\n * @typedef {Object} FillStrokeState\n * @property {module:ol/colorlike~ColorLike} [currentFillStyle]\n * @property {module:ol/colorlike~ColorLike} [currentStrokeStyle]\n * @property {string} [currentLineCap]\n * @property {Array.<number>} currentLineDash\n * @property {number} [currentLineDashOffset]\n * @property {string} [currentLineJoin]\n * @property {number} [currentLineWidth]\n * @property {number} [currentMiterLimit]\n * @property {number} [lastStroke]\n * @property {module:ol/colorlike~ColorLike} [fillStyle]\n * @property {module:ol/colorlike~ColorLike} [strokeStyle]\n * @property {string} [lineCap]\n * @property {Array.<number>} lineDash\n * @property {number} [lineDashOffset]\n * @property {string} [lineJoin]\n * @property {number} [lineWidth]\n * @property {number} [miterLimit]\n */\n\n\n/**\n * @typedef {Object} StrokeState\n * @property {string} lineCap\n * @property {Array.<number>} lineDash\n * @property {number} lineDashOffset\n * @property {string} lineJoin\n * @property {number} lineWidth\n * @property {number} miterLimit\n * @property {module:ol/colorlike~ColorLike} strokeStyle\n */\n\n\n/**\n * @typedef {Object} TextState\n * @property {string} font\n * @property {string} [textAlign]\n * @property {string} textBaseline\n */\n\n\n/**\n * Container for decluttered replay instructions that need to be rendered or\n * omitted together, i.e. when styles render both an image and text, or for the\n * characters that form text along lines. The basic elements of this array are\n * `[minX, minY, maxX, maxY, count]`, where the first four entries are the\n * rendered extent of the group in pixel space. `count` is the number of styles\n * in the group, i.e. 2 when an image and a text are grouped, or 1 otherwise.\n * In addition to these four elements, declutter instruction arrays (i.e. the\n * arguments to {@link module:ol/render/canvas~drawImage} are appended to the array.\n * @typedef {Array.<*>} DeclutterGroup\n */\n\n\n/**\n * @const\n * @type {string}\n */\nexport const defaultFont = '10px sans-serif';\n\n\n/**\n * @const\n * @type {module:ol/color~Color}\n */\nexport const defaultFillStyle = [0, 0, 0, 1];\n\n\n/**\n * @const\n * @type {string}\n */\nexport const defaultLineCap = 'round';\n\n\n/**\n * @const\n * @type {Array.<number>}\n */\nexport const defaultLineDash = [];\n\n\n/**\n * @const\n * @type {number}\n */\nexport const defaultLineDashOffset = 0;\n\n\n/**\n * @const\n * @type {string}\n */\nexport const defaultLineJoin = 'round';\n\n\n/**\n * @const\n * @type {number}\n */\nexport const defaultMiterLimit = 10;\n\n\n/**\n * @const\n * @type {module:ol/color~Color}\n */\nexport const defaultStrokeStyle = [0, 0, 0, 1];\n\n\n/**\n * @const\n * @type {string}\n */\nexport const defaultTextAlign = 'center';\n\n\n/**\n * @const\n * @type {string}\n */\nexport const defaultTextBaseline = 'middle';\n\n\n/**\n * @const\n * @type {Array.<number>}\n */\nexport const defaultPadding = [0, 0, 0, 0];\n\n\n/**\n * @const\n * @type {number}\n */\nexport const defaultLineWidth = 1;\n\n\n/**\n * The label cache for text rendering. To change the default cache size of 2048\n * entries, use {@link module:ol/structs/LRUCache#setSize}.\n * @type {module:ol/structs/LRUCache.<HTMLCanvasElement>}\n * @api\n */\nexport const labelCache = new LRUCache();\n\n\n/**\n * @type {!Object.<string, number>}\n */\nexport const checkedFonts = {};\n\n\n/**\n * @type {CanvasRenderingContext2D}\n */\nlet measureContext = null;\n\n\n/**\n * @type {!Object.<string, number>}\n */\nexport const textHeights = {};\n\n\n/**\n * Clears the label cache when a font becomes available.\n * @param {string} fontSpec CSS font spec.\n */\nexport const checkFont = (function() {\n  const retries = 60;\n  const checked = checkedFonts;\n  const size = '32px ';\n  const referenceFonts = ['monospace', 'serif'];\n  const len = referenceFonts.length;\n  const text = 'wmytzilWMYTZIL@#/&?$%10\\uF013';\n  let interval, referenceWidth;\n\n  function isAvailable(font) {\n    const context = getMeasureContext();\n    let available = true;\n    for (let i = 0; i < len; ++i) {\n      const referenceFont = referenceFonts[i];\n      context.font = size + referenceFont;\n      referenceWidth = context.measureText(text).width;\n      if (font != referenceFont) {\n        context.font = size + font + ',' + referenceFont;\n        const width = context.measureText(text).width;\n        // If width and referenceWidth are the same, then the fallback was used\n        // instead of the font we wanted, so the font is not available.\n        available = available && width != referenceWidth;\n      }\n    }\n    return available;\n  }\n\n  function check() {\n    let done = true;\n    for (const font in checked) {\n      if (checked[font] < retries) {\n        if (isAvailable(font)) {\n          checked[font] = retries;\n          clear(textHeights);\n          // Make sure that loaded fonts are picked up by Safari\n          measureContext = null;\n          labelCache.clear();\n        } else {\n          ++checked[font];\n          done = false;\n        }\n      }\n    }\n    if (done) {\n      clearInterval(interval);\n      interval = undefined;\n    }\n  }\n\n  return function(fontSpec) {\n    const fontFamilies = getFontFamilies(fontSpec);\n    if (!fontFamilies) {\n      return;\n    }\n    for (let i = 0, ii = fontFamilies.length; i < ii; ++i) {\n      const fontFamily = fontFamilies[i];\n      if (!(fontFamily in checked)) {\n        checked[fontFamily] = retries;\n        if (!isAvailable(fontFamily)) {\n          checked[fontFamily] = 0;\n          if (interval === undefined) {\n            interval = setInterval(check, 32);\n          }\n        }\n      }\n    }\n  };\n})();\n\n\n/**\n * @return {CanvasRenderingContext2D} Measure context.\n */\nfunction getMeasureContext() {\n  if (!measureContext) {\n    measureContext = createCanvasContext2D(1, 1);\n  }\n  return measureContext;\n}\n\n\n/**\n * @param {string} font Font to use for measuring.\n * @return {module:ol/size~Size} Measurement.\n */\nexport const measureTextHeight = (function() {\n  let span;\n  const heights = textHeights;\n  return function(font) {\n    let height = heights[font];\n    if (height == undefined) {\n      if (!span) {\n        span = document.createElement('span');\n        span.textContent = 'M';\n        span.style.margin = span.style.padding = '0 !important';\n        span.style.position = 'absolute !important';\n        span.style.left = '-99999px !important';\n      }\n      span.style.font = font;\n      document.body.appendChild(span);\n      height = heights[font] = span.offsetHeight;\n      document.body.removeChild(span);\n    }\n    return height;\n  };\n})();\n\n\n/**\n * @param {string} font Font.\n * @param {string} text Text.\n * @return {number} Width.\n */\nexport function measureTextWidth(font, text) {\n  const measureContext = getMeasureContext();\n  if (font != measureContext.font) {\n    measureContext.font = font;\n  }\n  return measureContext.measureText(text).width;\n}\n\n\n/**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} rotation Rotation.\n * @param {number} offsetX X offset.\n * @param {number} offsetY Y offset.\n */\nexport function rotateAtOffset(context, rotation, offsetX, offsetY) {\n  if (rotation !== 0) {\n    context.translate(offsetX, offsetY);\n    context.rotate(rotation);\n    context.translate(-offsetX, -offsetY);\n  }\n}\n\n\nexport const resetTransform = createTransform();\n\n\n/**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {module:ol/transform~Transform|null} transform Transform.\n * @param {number} opacity Opacity.\n * @param {HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} image Image.\n * @param {number} originX Origin X.\n * @param {number} originY Origin Y.\n * @param {number} w Width.\n * @param {number} h Height.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {number} scale Scale.\n */\nexport function drawImage(context,\n  transform, opacity, image, originX, originY, w, h, x, y, scale) {\n  let alpha;\n  if (opacity != 1) {\n    alpha = context.globalAlpha;\n    context.globalAlpha = alpha * opacity;\n  }\n  if (transform) {\n    context.setTransform.apply(context, transform);\n  }\n\n  context.drawImage(image, originX, originY, w, h, x, y, w * scale, h * scale);\n\n  if (alpha) {\n    context.globalAlpha = alpha;\n  }\n  if (transform) {\n    context.setTransform.apply(context, resetTransform);\n  }\n}\n","/**\n * @module ol/style/Image\n */\n\n\n/**\n * @typedef {Object} Options\n * @property {number} opacity\n * @property {boolean} rotateWithView\n * @property {number} rotation\n * @property {number} scale\n * @property {boolean} snapToPixel\n */\n\n\n/**\n * @classdesc\n * A base class used for creating subclasses and not instantiated in\n * apps. Base class for {@link module:ol/style/Icon~Icon}, {@link module:ol/style/Circle~CircleStyle} and\n * {@link module:ol/style/RegularShape~RegularShape}.\n * @api\n */\nclass ImageStyle {\n  /**\n   * @param {module:ol/style/Image~Options} options Options.\n   */\n  constructor(options) {\n\n    /**\n    * @private\n    * @type {number}\n    */\n    this.opacity_ = options.opacity;\n\n    /**\n    * @private\n    * @type {boolean}\n    */\n    this.rotateWithView_ = options.rotateWithView;\n\n    /**\n    * @private\n    * @type {number}\n    */\n    this.rotation_ = options.rotation;\n\n    /**\n    * @private\n    * @type {number}\n    */\n    this.scale_ = options.scale;\n\n    /**\n    * @private\n    * @type {boolean}\n    */\n    this.snapToPixel_ = options.snapToPixel;\n\n  }\n\n  /**\n  * Get the symbolizer opacity.\n  * @return {number} Opacity.\n  * @api\n  */\n  getOpacity() {\n    return this.opacity_;\n  }\n\n  /**\n  * Determine whether the symbolizer rotates with the map.\n  * @return {boolean} Rotate with map.\n  * @api\n  */\n  getRotateWithView() {\n    return this.rotateWithView_;\n  }\n\n  /**\n  * Get the symoblizer rotation.\n  * @return {number} Rotation.\n  * @api\n  */\n  getRotation() {\n    return this.rotation_;\n  }\n\n  /**\n  * Get the symbolizer scale.\n  * @return {number} Scale.\n  * @api\n  */\n  getScale() {\n    return this.scale_;\n  }\n\n  /**\n  * Determine whether the symbolizer should be snapped to a pixel.\n  * @return {boolean} The symbolizer should snap to a pixel.\n  * @api\n  */\n  getSnapToPixel() {\n    return this.snapToPixel_;\n  }\n\n  /**\n  * Get the anchor point in pixels. The anchor determines the center point for the\n  * symbolizer.\n  * @abstract\n  * @return {Array.<number>} Anchor.\n  */\n  getAnchor() {}\n\n  /**\n  * Get the image element for the symbolizer.\n  * @abstract\n  * @param {number} pixelRatio Pixel ratio.\n  * @return {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} Image element.\n  */\n  getImage(pixelRatio) {}\n\n  /**\n  * @abstract\n  * @param {number} pixelRatio Pixel ratio.\n  * @return {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} Image element.\n  */\n  getHitDetectionImage(pixelRatio) {}\n\n  /**\n  * @abstract\n  * @return {module:ol/ImageState} Image state.\n  */\n  getImageState() {}\n\n  /**\n  * @abstract\n  * @return {module:ol/size~Size} Image size.\n  */\n  getImageSize() {}\n\n  /**\n  * @abstract\n  * @return {module:ol/size~Size} Size of the hit-detection image.\n  */\n  getHitDetectionImageSize() {}\n\n  /**\n  * Get the origin of the symbolizer.\n  * @abstract\n  * @return {Array.<number>} Origin.\n  */\n  getOrigin() {}\n\n  /**\n  * Get the size of the symbolizer (in pixels).\n  * @abstract\n  * @return {module:ol/size~Size} Size.\n  */\n  getSize() {}\n\n  /**\n  * Set the opacity.\n  *\n  * @param {number} opacity Opacity.\n  * @api\n  */\n  setOpacity(opacity) {\n    this.opacity_ = opacity;\n  }\n\n  /**\n  * Set whether to rotate the style with the view.\n  *\n  * @param {boolean} rotateWithView Rotate with map.\n  * @api\n  */\n  setRotateWithView(rotateWithView) {\n    this.rotateWithView_ = rotateWithView;\n  }\n\n  /**\n  * Set the rotation.\n  *\n  * @param {number} rotation Rotation.\n  * @api\n  */\n  setRotation(rotation) {\n    this.rotation_ = rotation;\n  }\n\n  /**\n  * Set the scale.\n  *\n  * @param {number} scale Scale.\n  * @api\n  */\n  setScale(scale) {\n    this.scale_ = scale;\n  }\n\n  /**\n  * Set whether to snap the image to the closest pixel.\n  *\n  * @param {boolean} snapToPixel Snap to pixel?\n  * @api\n  */\n  setSnapToPixel(snapToPixel) {\n    this.snapToPixel_ = snapToPixel;\n  }\n\n  /**\n  * @abstract\n  * @param {function(this: T, module:ol/events/Event)} listener Listener function.\n  * @param {T} thisArg Value to use as `this` when executing `listener`.\n  * @return {module:ol/events~EventsKey|undefined} Listener key.\n  * @template T\n  */\n  listenImageChange(listener, thisArg) {}\n\n  /**\n  * Load not yet loaded URI.\n  * @abstract\n  */\n  load() {}\n\n  /**\n  * @abstract\n  * @param {function(this: T, module:ol/events/Event)} listener Listener function.\n  * @param {T} thisArg Value to use as `this` when executing `listener`.\n  * @template T\n  */\n  unlistenImageChange(listener, thisArg) {}\n}\n\nexport default ImageStyle;\n","/**\n * @module ol/style/RegularShape\n */\n\nimport {asColorLike} from '../colorlike.js';\nimport {createCanvasContext2D} from '../dom.js';\nimport {CANVAS_LINE_DASH} from '../has.js';\nimport ImageState from '../ImageState.js';\nimport {defaultStrokeStyle, defaultFillStyle, defaultLineCap, defaultLineWidth, defaultLineJoin, defaultMiterLimit} from '../render/canvas.js';\nimport ImageStyle from '../style/Image.js';\n\n\n/**\n * Specify radius for regular polygons, or radius1 and radius2 for stars.\n * @typedef {Object} Options\n * @property {module:ol/style/Fill} [fill] Fill style.\n * @property {number} points Number of points for stars and regular polygons. In case of a polygon, the number of points\n * is the number of sides.\n * @property {number} [radius] Radius of a regular polygon.\n * @property {number} [radius1] Outer radius of a star.\n * @property {number} [radius2] Inner radius of a star.\n * @property {number} [angle=0] Shape's angle in radians. A value of 0 will have one of the shape's point facing up.\n * @property {boolean} [snapToPixel=true] If `true` integral numbers of pixels are used as the X and Y pixel coordinate\n * when drawing the shape in the output canvas. If `false` fractional numbers may be used. Using `true` allows for\n * \"sharp\" rendering (no blur), while using `false` allows for \"accurate\" rendering. Note that accuracy is important if\n * the shape's position is animated. Without it, the shape may jitter noticeably.\n * @property {module:ol/style/Stroke} [stroke] Stroke style.\n * @property {number} [rotation=0] Rotation in radians (positive rotation clockwise).\n * @property {boolean} [rotateWithView=false] Whether to rotate the shape with the view.\n * @property {module:ol/style/AtlasManager} [atlasManager] The atlas manager to use for this symbol. When\n * using WebGL it is recommended to use an atlas manager to avoid texture switching. If an atlas manager is given, the\n * symbol is added to an atlas. By default no atlas manager is used.\n */\n\n\n/**\n * @typedef {Object} RenderOptions\n * @property {module:ol/colorlike~ColorLike} [strokeStyle]\n * @property {number} strokeWidth\n * @property {number} size\n * @property {string} lineCap\n * @property {Array.<number>} lineDash\n * @property {number} lineDashOffset\n * @property {string} lineJoin\n * @property {number} miterLimit\n */\n\n\n/**\n * @classdesc\n * Set regular shape style for vector features. The resulting shape will be\n * a regular polygon when `radius` is provided, or a star when `radius1` and\n * `radius2` are provided.\n * @api\n */\nclass RegularShape extends ImageStyle {\n  /**\n   * @param {module:ol/style/RegularShape~Options} options Options.\n   */\n  constructor(options) {\n    /**\n     * @type {boolean}\n     */\n    const snapToPixel = options.snapToPixel !== undefined ?\n      options.snapToPixel : true;\n\n    /**\n     * @type {boolean}\n     */\n    const rotateWithView = options.rotateWithView !== undefined ?\n      options.rotateWithView : false;\n\n    super({\n      opacity: 1,\n      rotateWithView: rotateWithView,\n      rotation: options.rotation !== undefined ? options.rotation : 0,\n      scale: 1,\n      snapToPixel: snapToPixel\n    });\n\n    /**\n     * @private\n     * @type {Array.<string>}\n     */\n    this.checksums_ = null;\n\n    /**\n     * @private\n     * @type {HTMLCanvasElement}\n     */\n    this.canvas_ = null;\n\n    /**\n     * @private\n     * @type {HTMLCanvasElement}\n     */\n    this.hitDetectionCanvas_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/style/Fill}\n     */\n    this.fill_ = options.fill !== undefined ? options.fill : null;\n\n    /**\n     * @private\n     * @type {Array.<number>}\n     */\n    this.origin_ = [0, 0];\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.points_ = options.points;\n\n    /**\n     * @protected\n     * @type {number}\n     */\n    this.radius_ = /** @type {number} */ (options.radius !== undefined ?\n      options.radius : options.radius1);\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.radius2_ = options.radius2;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.angle_ = options.angle !== undefined ? options.angle : 0;\n\n    /**\n     * @private\n     * @type {module:ol/style/Stroke}\n     */\n    this.stroke_ = options.stroke !== undefined ? options.stroke : null;\n\n    /**\n     * @private\n     * @type {Array.<number>}\n     */\n    this.anchor_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/size~Size}\n     */\n    this.size_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/size~Size}\n     */\n    this.imageSize_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/size~Size}\n     */\n    this.hitDetectionImageSize_ = null;\n\n    /**\n     * @protected\n     * @type {module:ol/style/AtlasManager|undefined}\n     */\n    this.atlasManager_ = options.atlasManager;\n\n    this.render_(this.atlasManager_);\n\n  }\n\n  /**\n   * Clones the style. If an atlasmanager was provided to the original style it will be used in the cloned style, too.\n   * @return {module:ol/style/RegularShape} The cloned style.\n   * @api\n   */\n  clone() {\n    const style = new RegularShape({\n      fill: this.getFill() ? this.getFill().clone() : undefined,\n      points: this.getPoints(),\n      radius: this.getRadius(),\n      radius2: this.getRadius2(),\n      angle: this.getAngle(),\n      snapToPixel: this.getSnapToPixel(),\n      stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n      rotation: this.getRotation(),\n      rotateWithView: this.getRotateWithView(),\n      atlasManager: this.atlasManager_\n    });\n    style.setOpacity(this.getOpacity());\n    style.setScale(this.getScale());\n    return style;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  getAnchor() {\n    return this.anchor_;\n  }\n\n  /**\n   * Get the angle used in generating the shape.\n   * @return {number} Shape's rotation in radians.\n   * @api\n   */\n  getAngle() {\n    return this.angle_;\n  }\n\n  /**\n   * Get the fill style for the shape.\n   * @return {module:ol/style/Fill} Fill style.\n   * @api\n   */\n  getFill() {\n    return this.fill_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getHitDetectionImage(pixelRatio) {\n    return this.hitDetectionCanvas_;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  getImage(pixelRatio) {\n    return this.canvas_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getImageSize() {\n    return this.imageSize_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getHitDetectionImageSize() {\n    return this.hitDetectionImageSize_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getImageState() {\n    return ImageState.LOADED;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  getOrigin() {\n    return this.origin_;\n  }\n\n  /**\n   * Get the number of points for generating the shape.\n   * @return {number} Number of points for stars and regular polygons.\n   * @api\n   */\n  getPoints() {\n    return this.points_;\n  }\n\n  /**\n   * Get the (primary) radius for the shape.\n   * @return {number} Radius.\n   * @api\n   */\n  getRadius() {\n    return this.radius_;\n  }\n\n  /**\n   * Get the secondary radius for the shape.\n   * @return {number|undefined} Radius2.\n   * @api\n   */\n  getRadius2() {\n    return this.radius2_;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  getSize() {\n    return this.size_;\n  }\n\n  /**\n   * Get the stroke style for the shape.\n   * @return {module:ol/style/Stroke} Stroke style.\n   * @api\n   */\n  getStroke() {\n    return this.stroke_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  listenImageChange(listener, thisArg) {}\n\n  /**\n   * @inheritDoc\n   */\n  load() {}\n\n  /**\n   * @inheritDoc\n   */\n  unlistenImageChange(listener, thisArg) {}\n\n  /**\n   * @protected\n   * @param {module:ol/style/AtlasManager|undefined} atlasManager An atlas manager.\n   */\n  render_(atlasManager) {\n    let imageSize;\n    let lineCap = '';\n    let lineJoin = '';\n    let miterLimit = 0;\n    let lineDash = null;\n    let lineDashOffset = 0;\n    let strokeStyle;\n    let strokeWidth = 0;\n\n    if (this.stroke_) {\n      strokeStyle = this.stroke_.getColor();\n      if (strokeStyle === null) {\n        strokeStyle = defaultStrokeStyle;\n      }\n      strokeStyle = asColorLike(strokeStyle);\n      strokeWidth = this.stroke_.getWidth();\n      if (strokeWidth === undefined) {\n        strokeWidth = defaultLineWidth;\n      }\n      lineDash = this.stroke_.getLineDash();\n      lineDashOffset = this.stroke_.getLineDashOffset();\n      if (!CANVAS_LINE_DASH) {\n        lineDash = null;\n        lineDashOffset = 0;\n      }\n      lineJoin = this.stroke_.getLineJoin();\n      if (lineJoin === undefined) {\n        lineJoin = defaultLineJoin;\n      }\n      lineCap = this.stroke_.getLineCap();\n      if (lineCap === undefined) {\n        lineCap = defaultLineCap;\n      }\n      miterLimit = this.stroke_.getMiterLimit();\n      if (miterLimit === undefined) {\n        miterLimit = defaultMiterLimit;\n      }\n    }\n\n    let size = 2 * (this.radius_ + strokeWidth) + 1;\n\n    /** @type {module:ol/style/RegularShape~RenderOptions} */\n    const renderOptions = {\n      strokeStyle: strokeStyle,\n      strokeWidth: strokeWidth,\n      size: size,\n      lineCap: lineCap,\n      lineDash: lineDash,\n      lineDashOffset: lineDashOffset,\n      lineJoin: lineJoin,\n      miterLimit: miterLimit\n    };\n\n    if (atlasManager === undefined) {\n      // no atlas manager is used, create a new canvas\n      const context = createCanvasContext2D(size, size);\n      this.canvas_ = context.canvas;\n\n      // canvas.width and height are rounded to the closest integer\n      size = this.canvas_.width;\n      imageSize = size;\n\n      this.draw_(renderOptions, context, 0, 0);\n\n      this.createHitDetectionCanvas_(renderOptions);\n    } else {\n      // an atlas manager is used, add the symbol to an atlas\n      size = Math.round(size);\n\n      const hasCustomHitDetectionImage = !this.fill_;\n      let renderHitDetectionCallback;\n      if (hasCustomHitDetectionImage) {\n        // render the hit-detection image into a separate atlas image\n        renderHitDetectionCallback =\n            this.drawHitDetectionCanvas_.bind(this, renderOptions);\n      }\n\n      const id = this.getChecksum();\n      const info = atlasManager.add(\n        id, size, size, this.draw_.bind(this, renderOptions),\n        renderHitDetectionCallback);\n\n      this.canvas_ = info.image;\n      this.origin_ = [info.offsetX, info.offsetY];\n      imageSize = info.image.width;\n\n      if (hasCustomHitDetectionImage) {\n        this.hitDetectionCanvas_ = info.hitImage;\n        this.hitDetectionImageSize_ =\n            [info.hitImage.width, info.hitImage.height];\n      } else {\n        this.hitDetectionCanvas_ = this.canvas_;\n        this.hitDetectionImageSize_ = [imageSize, imageSize];\n      }\n    }\n\n    this.anchor_ = [size / 2, size / 2];\n    this.size_ = [size, size];\n    this.imageSize_ = [imageSize, imageSize];\n  }\n\n  /**\n   * @private\n   * @param {module:ol/style/RegularShape~RenderOptions} renderOptions Render options.\n   * @param {CanvasRenderingContext2D} context The rendering context.\n   * @param {number} x The origin for the symbol (x).\n   * @param {number} y The origin for the symbol (y).\n   */\n  draw_(renderOptions, context, x, y) {\n    let i, angle0, radiusC;\n    // reset transform\n    context.setTransform(1, 0, 0, 1, 0, 0);\n\n    // then move to (x, y)\n    context.translate(x, y);\n\n    context.beginPath();\n\n    let points = this.points_;\n    if (points === Infinity) {\n      context.arc(\n        renderOptions.size / 2, renderOptions.size / 2,\n        this.radius_, 0, 2 * Math.PI, true);\n    } else {\n      const radius2 = (this.radius2_ !== undefined) ? this.radius2_\n        : this.radius_;\n      if (radius2 !== this.radius_) {\n        points = 2 * points;\n      }\n      for (i = 0; i <= points; i++) {\n        angle0 = i * 2 * Math.PI / points - Math.PI / 2 + this.angle_;\n        radiusC = i % 2 === 0 ? this.radius_ : radius2;\n        context.lineTo(renderOptions.size / 2 + radiusC * Math.cos(angle0),\n          renderOptions.size / 2 + radiusC * Math.sin(angle0));\n      }\n    }\n\n\n    if (this.fill_) {\n      let color = this.fill_.getColor();\n      if (color === null) {\n        color = defaultFillStyle;\n      }\n      context.fillStyle = asColorLike(color);\n      context.fill();\n    }\n    if (this.stroke_) {\n      context.strokeStyle = renderOptions.strokeStyle;\n      context.lineWidth = renderOptions.strokeWidth;\n      if (renderOptions.lineDash) {\n        context.setLineDash(renderOptions.lineDash);\n        context.lineDashOffset = renderOptions.lineDashOffset;\n      }\n      context.lineCap = renderOptions.lineCap;\n      context.lineJoin = renderOptions.lineJoin;\n      context.miterLimit = renderOptions.miterLimit;\n      context.stroke();\n    }\n    context.closePath();\n  }\n\n  /**\n   * @private\n   * @param {module:ol/style/RegularShape~RenderOptions} renderOptions Render options.\n   */\n  createHitDetectionCanvas_(renderOptions) {\n    this.hitDetectionImageSize_ = [renderOptions.size, renderOptions.size];\n    if (this.fill_) {\n      this.hitDetectionCanvas_ = this.canvas_;\n      return;\n    }\n\n    // if no fill style is set, create an extra hit-detection image with a\n    // default fill style\n    const context = createCanvasContext2D(renderOptions.size, renderOptions.size);\n    this.hitDetectionCanvas_ = context.canvas;\n\n    this.drawHitDetectionCanvas_(renderOptions, context, 0, 0);\n  }\n\n  /**\n   * @private\n   * @param {module:ol/style/RegularShape~RenderOptions} renderOptions Render options.\n   * @param {CanvasRenderingContext2D} context The context.\n   * @param {number} x The origin for the symbol (x).\n   * @param {number} y The origin for the symbol (y).\n   */\n  drawHitDetectionCanvas_(renderOptions, context, x, y) {\n    // reset transform\n    context.setTransform(1, 0, 0, 1, 0, 0);\n\n    // then move to (x, y)\n    context.translate(x, y);\n\n    context.beginPath();\n\n    let points = this.points_;\n    if (points === Infinity) {\n      context.arc(\n        renderOptions.size / 2, renderOptions.size / 2,\n        this.radius_, 0, 2 * Math.PI, true);\n    } else {\n      const radius2 = (this.radius2_ !== undefined) ? this.radius2_\n        : this.radius_;\n      if (radius2 !== this.radius_) {\n        points = 2 * points;\n      }\n      let i, radiusC, angle0;\n      for (i = 0; i <= points; i++) {\n        angle0 = i * 2 * Math.PI / points - Math.PI / 2 + this.angle_;\n        radiusC = i % 2 === 0 ? this.radius_ : radius2;\n        context.lineTo(renderOptions.size / 2 + radiusC * Math.cos(angle0),\n          renderOptions.size / 2 + radiusC * Math.sin(angle0));\n      }\n    }\n\n    context.fillStyle = defaultFillStyle;\n    context.fill();\n    if (this.stroke_) {\n      context.strokeStyle = renderOptions.strokeStyle;\n      context.lineWidth = renderOptions.strokeWidth;\n      if (renderOptions.lineDash) {\n        context.setLineDash(renderOptions.lineDash);\n        context.lineDashOffset = renderOptions.lineDashOffset;\n      }\n      context.stroke();\n    }\n    context.closePath();\n  }\n\n  /**\n   * @return {string} The checksum.\n   */\n  getChecksum() {\n    const strokeChecksum = this.stroke_ ?\n      this.stroke_.getChecksum() : '-';\n    const fillChecksum = this.fill_ ?\n      this.fill_.getChecksum() : '-';\n\n    const recalculate = !this.checksums_ ||\n        (strokeChecksum != this.checksums_[1] ||\n        fillChecksum != this.checksums_[2] ||\n        this.radius_ != this.checksums_[3] ||\n        this.radius2_ != this.checksums_[4] ||\n        this.angle_ != this.checksums_[5] ||\n        this.points_ != this.checksums_[6]);\n\n    if (recalculate) {\n      const checksum = 'r' + strokeChecksum + fillChecksum +\n          (this.radius_ !== undefined ? this.radius_.toString() : '-') +\n          (this.radius2_ !== undefined ? this.radius2_.toString() : '-') +\n          (this.angle_ !== undefined ? this.angle_.toString() : '-') +\n          (this.points_ !== undefined ? this.points_.toString() : '-');\n      this.checksums_ = [checksum, strokeChecksum, fillChecksum,\n        this.radius_, this.radius2_, this.angle_, this.points_];\n    }\n\n    return this.checksums_[0];\n  }\n}\n\n\nexport default RegularShape;\n","/**\n * @module ol/style/Circle\n */\n\nimport RegularShape from '../style/RegularShape.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/style/Fill} [fill] Fill style.\n * @property {number} radius Circle radius.\n * @property {boolean} [snapToPixel=true] If `true` integral numbers of pixels are used as the X and Y pixel coordinate\n * when drawing the circle in the output canvas. If `false` fractional numbers may be used. Using `true` allows for\n * \"sharp\" rendering (no blur), while using `false` allows for \"accurate\" rendering. Note that accuracy is important if\n * the circle's position is animated. Without it, the circle may jitter noticeably.\n * @property {module:ol/style/Stroke} [stroke] Stroke style.\n * @property {module:ol/style/AtlasManager} [atlasManager] The atlas manager to use for this circle.\n * When using WebGL it is recommended to use an atlas manager to avoid texture switching. If an atlas manager is given,\n * the circle is added to an atlas. By default no atlas manager is used.\n */\n\n\n/**\n * @classdesc\n * Set circle style for vector features.\n * @api\n */\nclass CircleStyle extends RegularShape {\n  /**\n   * @param {module:ol/style/Circle~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options || {};\n\n    super({\n      points: Infinity,\n      fill: options.fill,\n      radius: options.radius,\n      snapToPixel: options.snapToPixel,\n      stroke: options.stroke,\n      atlasManager: options.atlasManager\n    });\n\n  }\n\n  /**\n  * Clones the style.  If an atlasmanager was provided to the original style it will be used in the cloned style, too.\n  * @return {module:ol/style/Circle} The cloned style.\n  * @override\n  * @api\n  */\n  clone() {\n    const style = new CircleStyle({\n      fill: this.getFill() ? this.getFill().clone() : undefined,\n      stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n      radius: this.getRadius(),\n      snapToPixel: this.getSnapToPixel(),\n      atlasManager: this.atlasManager_\n    });\n    style.setOpacity(this.getOpacity());\n    style.setScale(this.getScale());\n    return style;\n  }\n\n  /**\n  * Set the circle radius.\n  *\n  * @param {number} radius Circle radius.\n  * @api\n  */\n  setRadius(radius) {\n    this.radius_ = radius;\n    this.render_(this.atlasManager_);\n  }\n}\n\n\nexport default CircleStyle;\n","/**\n * @module ol/style/Fill\n */\nimport {getUid} from '../util.js';\nimport {asString} from '../color.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/color~Color|module:ol/colorlike~ColorLike} [color] A color, gradient or pattern.\n * See {@link module:ol/color~Color} and {@link module:ol/colorlike~ColorLike} for possible formats.\n * Default null; if null, the Canvas/renderer default black will be used.\n */\n\n\n/**\n * @classdesc\n * Set fill style for vector features.\n * @api\n */\nclass Fill {\n  /**\n   * @param {module:ol/style/Fill~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options || {};\n\n    /**\n     * @private\n     * @type {module:ol/color~Color|module:ol/colorlike~ColorLike}\n     */\n    this.color_ = options.color !== undefined ? options.color : null;\n\n    /**\n     * @private\n     * @type {string|undefined}\n     */\n    this.checksum_ = undefined;\n  }\n\n  /**\n   * Clones the style. The color is not cloned if it is an {@link module:ol/colorlike~ColorLike}.\n   * @return {module:ol/style/Fill} The cloned style.\n   * @api\n   */\n  clone() {\n    const color = this.getColor();\n    return new Fill({\n      color: (color && color.slice) ? color.slice() : color || undefined\n    });\n  }\n\n  /**\n   * Get the fill color.\n   * @return {module:ol/color~Color|module:ol/colorlike~ColorLike} Color.\n   * @api\n   */\n  getColor() {\n    return this.color_;\n  }\n\n  /**\n   * Set the color.\n   *\n   * @param {module:ol/color~Color|module:ol/colorlike~ColorLike} color Color.\n   * @api\n   */\n  setColor(color) {\n    this.color_ = color;\n    this.checksum_ = undefined;\n  }\n\n  /**\n   * @return {string} The checksum.\n   */\n  getChecksum() {\n    if (this.checksum_ === undefined) {\n      if (\n        this.color_ instanceof CanvasPattern ||\n          this.color_ instanceof CanvasGradient\n      ) {\n        this.checksum_ = getUid(this.color_).toString();\n      } else {\n        this.checksum_ = 'f' + (this.color_ ? asString(this.color_) : '-');\n      }\n    }\n\n    return this.checksum_;\n  }\n}\n\nexport default Fill;\n","/**\n * @module ol/style/Stroke\n */\nimport {getUid} from '../util.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/color~Color|module:ol/colorlike~ColorLike} [color] A color, gradient or pattern.\n * See {@link module:ol/color~Color} and {@link module:ol/colorlike~ColorLike} for possible formats.\n * Default null; if null, the Canvas/renderer default black will be used.\n * @property {string} [lineCap='round'] Line cap style: `butt`, `round`, or `square`.\n * @property {string} [lineJoin='round'] Line join style: `bevel`, `round`, or `miter`.\n * @property {Array.<number>} [lineDash] Line dash pattern. Default is `undefined` (no dash).\n * Please note that Internet Explorer 10 and lower do not support the `setLineDash` method on\n * the `CanvasRenderingContext2D` and therefore this option will have no visual effect in these browsers.\n * @property {number} [lineDashOffset=0] Line dash offset.\n * @property {number} [miterLimit=10] Miter limit.\n * @property {number} [width] Width.\n */\n\n\n/**\n * @classdesc\n * Set stroke style for vector features.\n * Note that the defaults given are the Canvas defaults, which will be used if\n * option is not defined. The `get` functions return whatever was entered in\n * the options; they will not return the default.\n * @api\n */\nclass Stroke {\n  /**\n   * @param {module:ol/style/Stroke~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options || {};\n\n    /**\n     * @private\n     * @type {module:ol/color~Color|module:ol/colorlike~ColorLike}\n     */\n    this.color_ = options.color !== undefined ? options.color : null;\n\n    /**\n     * @private\n     * @type {string|undefined}\n     */\n    this.lineCap_ = options.lineCap;\n\n    /**\n     * @private\n     * @type {Array.<number>}\n     */\n    this.lineDash_ = options.lineDash !== undefined ? options.lineDash : null;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.lineDashOffset_ = options.lineDashOffset;\n\n    /**\n     * @private\n     * @type {string|undefined}\n     */\n    this.lineJoin_ = options.lineJoin;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.miterLimit_ = options.miterLimit;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.width_ = options.width;\n\n    /**\n     * @private\n     * @type {string|undefined}\n     */\n    this.checksum_ = undefined;\n  }\n\n  /**\n   * Clones the style.\n   * @return {module:ol/style/Stroke} The cloned style.\n   * @api\n   */\n  clone() {\n    const color = this.getColor();\n    return new Stroke({\n      color: (color && color.slice) ? color.slice() : color || undefined,\n      lineCap: this.getLineCap(),\n      lineDash: this.getLineDash() ? this.getLineDash().slice() : undefined,\n      lineDashOffset: this.getLineDashOffset(),\n      lineJoin: this.getLineJoin(),\n      miterLimit: this.getMiterLimit(),\n      width: this.getWidth()\n    });\n  }\n\n  /**\n   * Get the stroke color.\n   * @return {module:ol/color~Color|module:ol/colorlike~ColorLike} Color.\n   * @api\n   */\n  getColor() {\n    return this.color_;\n  }\n\n  /**\n   * Get the line cap type for the stroke.\n   * @return {string|undefined} Line cap.\n   * @api\n   */\n  getLineCap() {\n    return this.lineCap_;\n  }\n\n  /**\n   * Get the line dash style for the stroke.\n   * @return {Array.<number>} Line dash.\n   * @api\n   */\n  getLineDash() {\n    return this.lineDash_;\n  }\n\n  /**\n   * Get the line dash offset for the stroke.\n   * @return {number|undefined} Line dash offset.\n   * @api\n   */\n  getLineDashOffset() {\n    return this.lineDashOffset_;\n  }\n\n  /**\n   * Get the line join type for the stroke.\n   * @return {string|undefined} Line join.\n   * @api\n   */\n  getLineJoin() {\n    return this.lineJoin_;\n  }\n\n  /**\n   * Get the miter limit for the stroke.\n   * @return {number|undefined} Miter limit.\n   * @api\n   */\n  getMiterLimit() {\n    return this.miterLimit_;\n  }\n\n  /**\n   * Get the stroke width.\n   * @return {number|undefined} Width.\n   * @api\n   */\n  getWidth() {\n    return this.width_;\n  }\n\n  /**\n   * Set the color.\n   *\n   * @param {module:ol/color~Color|module:ol/colorlike~ColorLike} color Color.\n   * @api\n   */\n  setColor(color) {\n    this.color_ = color;\n    this.checksum_ = undefined;\n  }\n\n  /**\n   * Set the line cap.\n   *\n   * @param {string|undefined} lineCap Line cap.\n   * @api\n   */\n  setLineCap(lineCap) {\n    this.lineCap_ = lineCap;\n    this.checksum_ = undefined;\n  }\n\n  /**\n   * Set the line dash.\n   *\n   * Please note that Internet Explorer 10 and lower [do not support][mdn] the\n   * `setLineDash` method on the `CanvasRenderingContext2D` and therefore this\n   * property will have no visual effect in these browsers.\n   *\n   * [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash#Browser_compatibility\n   *\n   * @param {Array.<number>} lineDash Line dash.\n   * @api\n   */\n  setLineDash(lineDash) {\n    this.lineDash_ = lineDash;\n    this.checksum_ = undefined;\n  }\n\n  /**\n   * Set the line dash offset.\n   *\n   * @param {number|undefined} lineDashOffset Line dash offset.\n   * @api\n   */\n  setLineDashOffset(lineDashOffset) {\n    this.lineDashOffset_ = lineDashOffset;\n    this.checksum_ = undefined;\n  }\n\n  /**\n   * Set the line join.\n   *\n   * @param {string|undefined} lineJoin Line join.\n   * @api\n   */\n  setLineJoin(lineJoin) {\n    this.lineJoin_ = lineJoin;\n    this.checksum_ = undefined;\n  }\n\n  /**\n   * Set the miter limit.\n   *\n   * @param {number|undefined} miterLimit Miter limit.\n   * @api\n   */\n  setMiterLimit(miterLimit) {\n    this.miterLimit_ = miterLimit;\n    this.checksum_ = undefined;\n  }\n\n  /**\n   * Set the width.\n   *\n   * @param {number|undefined} width Width.\n   * @api\n   */\n  setWidth(width) {\n    this.width_ = width;\n    this.checksum_ = undefined;\n  }\n\n  /**\n   * @return {string} The checksum.\n   */\n  getChecksum() {\n    if (this.checksum_ === undefined) {\n      this.checksum_ = 's';\n      if (this.color_) {\n        if (typeof this.color_ === 'string') {\n          this.checksum_ += this.color_;\n        } else {\n          this.checksum_ += getUid(this.color_).toString();\n        }\n      } else {\n        this.checksum_ += '-';\n      }\n      this.checksum_ += ',' +\n          (this.lineCap_ !== undefined ?\n            this.lineCap_.toString() : '-') + ',' +\n          (this.lineDash_ ?\n            this.lineDash_.toString() : '-') + ',' +\n          (this.lineDashOffset_ !== undefined ?\n            this.lineDashOffset_ : '-') + ',' +\n          (this.lineJoin_ !== undefined ?\n            this.lineJoin_ : '-') + ',' +\n          (this.miterLimit_ !== undefined ?\n            this.miterLimit_.toString() : '-') + ',' +\n          (this.width_ !== undefined ?\n            this.width_.toString() : '-');\n    }\n\n    return this.checksum_;\n  }\n}\n\nexport default Stroke;\n","/**\n * @module ol/style/Style\n */\n\n/**\n * Feature styles.\n *\n * If no style is defined, the following default style is used:\n * ```js\n *  import {Fill, Stroke, Circle, Style} from 'ol/style';\n *\n *  var fill = new Fill({\n *    color: 'rgba(255,255,255,0.4)'\n *  });\n *  var stroke = new Stroke({\n *    color: '#3399CC',\n *    width: 1.25\n *  });\n *  var styles = [\n *    new Style({\n *      image: new Circle({\n *        fill: fill,\n *        stroke: stroke,\n *        radius: 5\n *      }),\n *      fill: fill,\n *      stroke: stroke\n *    })\n *  ];\n * ```\n *\n * A separate editing style has the following defaults:\n * ```js\n *  import {Fill, Stroke, Circle, Style} from 'ol/style';\n *  import GeometryType from 'ol/geom/GeometryType';\n *\n *  var white = [255, 255, 255, 1];\n *  var blue = [0, 153, 255, 1];\n *  var width = 3;\n *  styles[GeometryType.POLYGON] = [\n *    new Style({\n *      fill: new Fill({\n *        color: [255, 255, 255, 0.5]\n *      })\n *    })\n *  ];\n *  styles[GeometryType.MULTI_POLYGON] =\n *      styles[GeometryType.POLYGON];\n *  styles[GeometryType.LINE_STRING] = [\n *    new Style({\n *      stroke: new Stroke({\n *        color: white,\n *        width: width + 2\n *      })\n *    }),\n *    new Style({\n *      stroke: new Stroke({\n *        color: blue,\n *        width: width\n *      })\n *    })\n *  ];\n *  styles[GeometryType.MULTI_LINE_STRING] =\n *      styles[GeometryType.LINE_STRING];\n *  styles[GeometryType.POINT] = [\n *    new Style({\n *      image: new Circle({\n *        radius: width * 2,\n *        fill: new Fill({\n *          color: blue\n *        }),\n *        stroke: new Stroke({\n *          color: white,\n *          width: width / 2\n *        })\n *      }),\n *      zIndex: Infinity\n *    })\n *  ];\n *  styles[GeometryType.MULTI_POINT] =\n *      styles[GeometryType.POINT];\n *  styles[GeometryType.GEOMETRY_COLLECTION] =\n *      styles[GeometryType.POLYGON].concat(\n *          styles[GeometryType.LINE_STRING],\n *          styles[GeometryType.POINT]\n *      );\n * ```\n */\nimport {assert} from '../asserts.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport CircleStyle from '../style/Circle.js';\nimport Fill from '../style/Fill.js';\nimport Stroke from '../style/Stroke.js';\n\n\n/**\n * A function that takes an {@link module:ol/Feature} and a `{number}`\n * representing the view's resolution. The function should return a\n * {@link module:ol/style/Style} or an array of them. This way e.g. a\n * vector layer can be styled.\n *\n * @typedef {function((module:ol/Feature|module:ol/render/Feature), number):\n *     (module:ol/style/Style|Array.<module:ol/style/Style>)} StyleFunction\n */\n\n\n/**\n * A function that takes an {@link module:ol/Feature} as argument and returns an\n * {@link module:ol/geom/Geometry} that will be rendered and styled for the feature.\n *\n * @typedef {function((module:ol/Feature|module:ol/render/Feature)):\n *     (module:ol/geom/Geometry|module:ol/render/Feature|undefined)} GeometryFunction\n */\n\n\n/**\n * Custom renderer function. Takes two arguments:\n *\n * 1. The pixel coordinates of the geometry in GeoJSON notation.\n * 2. The {@link module:ol/render~State} of the layer renderer.\n *\n * @typedef {function((module:ol/coordinate~Coordinate|Array<module:ol/coordinate~Coordinate>|Array.<Array.<module:ol/coordinate~Coordinate>>),module:ol/render~State)}\n * RenderFunction\n */\n\n\n/**\n * @typedef {Object} Options\n * @property {string|module:ol/geom/Geometry|module:ol/style/Style~GeometryFunction} [geometry] Feature property or geometry\n * or function returning a geometry to render for this style.\n * @property {module:ol/style/Fill} [fill] Fill style.\n * @property {module:ol/style/Image} [image] Image style.\n * @property {module:ol/style/Style~RenderFunction} [renderer] Custom renderer. When configured, `fill`, `stroke` and `image` will be\n * ignored, and the provided function will be called with each render frame for each geometry.\n * @property {module:ol/style/Stroke} [stroke] Stroke style.\n * @property {module:ol/style/Text} [text] Text style.\n * @property {number} [zIndex] Z index.\n */\n\n\n/**\n * @classdesc\n * Container for vector feature rendering styles. Any changes made to the style\n * or its children through `set*()` methods will not take effect until the\n * feature or layer that uses the style is re-rendered.\n * @api\n */\nclass Style {\n  /**\n   * @param {module:ol/style/Style~Options=} opt_options Style options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options || {};\n\n    /**\n     * @private\n     * @type {string|module:ol/geom/Geometry|module:ol/style/Style~GeometryFunction}\n     */\n    this.geometry_ = null;\n\n    /**\n     * @private\n     * @type {!module:ol/style/Style~GeometryFunction}\n     */\n    this.geometryFunction_ = defaultGeometryFunction;\n\n    if (options.geometry !== undefined) {\n      this.setGeometry(options.geometry);\n    }\n\n    /**\n     * @private\n     * @type {module:ol/style/Fill}\n     */\n    this.fill_ = options.fill !== undefined ? options.fill : null;\n\n    /**\n       * @private\n       * @type {module:ol/style/Image}\n       */\n    this.image_ = options.image !== undefined ? options.image : null;\n\n    /**\n     * @private\n     * @type {module:ol/style/Style~RenderFunction|null}\n     */\n    this.renderer_ = options.renderer !== undefined ? options.renderer : null;\n\n    /**\n     * @private\n     * @type {module:ol/style/Stroke}\n     */\n    this.stroke_ = options.stroke !== undefined ? options.stroke : null;\n\n    /**\n     * @private\n     * @type {module:ol/style/Text}\n     */\n    this.text_ = options.text !== undefined ? options.text : null;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.zIndex_ = options.zIndex;\n\n  }\n\n  /**\n   * Clones the style.\n   * @return {module:ol/style/Style} The cloned style.\n   * @api\n   */\n  clone() {\n    let geometry = this.getGeometry();\n    if (geometry && geometry.clone) {\n      geometry = geometry.clone();\n    }\n    return new Style({\n      geometry: geometry,\n      fill: this.getFill() ? this.getFill().clone() : undefined,\n      image: this.getImage() ? this.getImage().clone() : undefined,\n      stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n      text: this.getText() ? this.getText().clone() : undefined,\n      zIndex: this.getZIndex()\n    });\n  }\n\n  /**\n   * Get the custom renderer function that was configured with\n   * {@link #setRenderer} or the `renderer` constructor option.\n   * @return {module:ol/style/Style~RenderFunction|null} Custom renderer function.\n   * @api\n   */\n  getRenderer() {\n    return this.renderer_;\n  }\n\n  /**\n   * Sets a custom renderer function for this style. When set, `fill`, `stroke`\n   * and `image` options of the style will be ignored.\n   * @param {module:ol/style/Style~RenderFunction|null} renderer Custom renderer function.\n   * @api\n   */\n  setRenderer(renderer) {\n    this.renderer_ = renderer;\n  }\n\n  /**\n   * Get the geometry to be rendered.\n   * @return {string|module:ol/geom/Geometry|module:ol/style/Style~GeometryFunction}\n   * Feature property or geometry or function that returns the geometry that will\n   * be rendered with this style.\n   * @api\n   */\n  getGeometry() {\n    return this.geometry_;\n  }\n\n  /**\n   * Get the function used to generate a geometry for rendering.\n   * @return {!module:ol/style/Style~GeometryFunction} Function that is called with a feature\n   * and returns the geometry to render instead of the feature's geometry.\n   * @api\n   */\n  getGeometryFunction() {\n    return this.geometryFunction_;\n  }\n\n  /**\n   * Get the fill style.\n   * @return {module:ol/style/Fill} Fill style.\n   * @api\n   */\n  getFill() {\n    return this.fill_;\n  }\n\n  /**\n   * Set the fill style.\n   * @param {module:ol/style/Fill} fill Fill style.\n   * @api\n   */\n  setFill(fill) {\n    this.fill_ = fill;\n  }\n\n  /**\n   * Get the image style.\n   * @return {module:ol/style/Image} Image style.\n   * @api\n   */\n  getImage() {\n    return this.image_;\n  }\n\n  /**\n   * Set the image style.\n   * @param {module:ol/style/Image} image Image style.\n   * @api\n   */\n  setImage(image) {\n    this.image_ = image;\n  }\n\n  /**\n   * Get the stroke style.\n   * @return {module:ol/style/Stroke} Stroke style.\n   * @api\n   */\n  getStroke() {\n    return this.stroke_;\n  }\n\n  /**\n   * Set the stroke style.\n   * @param {module:ol/style/Stroke} stroke Stroke style.\n   * @api\n   */\n  setStroke(stroke) {\n    this.stroke_ = stroke;\n  }\n\n  /**\n   * Get the text style.\n   * @return {module:ol/style/Text} Text style.\n   * @api\n   */\n  getText() {\n    return this.text_;\n  }\n\n  /**\n   * Set the text style.\n   * @param {module:ol/style/Text} text Text style.\n   * @api\n   */\n  setText(text) {\n    this.text_ = text;\n  }\n\n  /**\n   * Get the z-index for the style.\n   * @return {number|undefined} ZIndex.\n   * @api\n   */\n  getZIndex() {\n    return this.zIndex_;\n  }\n\n  /**\n   * Set a geometry that is rendered instead of the feature's geometry.\n   *\n   * @param {string|module:ol/geom/Geometry|module:ol/style/Style~GeometryFunction} geometry\n   *     Feature property or geometry or function returning a geometry to render\n   *     for this style.\n   * @api\n   */\n  setGeometry(geometry) {\n    if (typeof geometry === 'function') {\n      this.geometryFunction_ = geometry;\n    } else if (typeof geometry === 'string') {\n      this.geometryFunction_ = function(feature) {\n        return (\n          /** @type {module:ol/geom/Geometry} */ (feature.get(geometry))\n        );\n      };\n    } else if (!geometry) {\n      this.geometryFunction_ = defaultGeometryFunction;\n    } else if (geometry !== undefined) {\n      this.geometryFunction_ = function() {\n        return (\n          /** @type {module:ol/geom/Geometry} */ (geometry)\n        );\n      };\n    }\n    this.geometry_ = geometry;\n  }\n\n  /**\n   * Set the z-index.\n   *\n   * @param {number|undefined} zIndex ZIndex.\n   * @api\n   */\n  setZIndex(zIndex) {\n    this.zIndex_ = zIndex;\n  }\n}\n\n\n/**\n * Convert the provided object into a style function.  Functions passed through\n * unchanged.  Arrays of module:ol/style/Style or single style objects wrapped in a\n * new style function.\n * @param {module:ol/style/Style~StyleFunction|Array.<module:ol/style/Style>|module:ol/style/Style} obj\n *     A style function, a single style, or an array of styles.\n * @return {module:ol/style/Style~StyleFunction} A style function.\n */\nexport function toFunction(obj) {\n  let styleFunction;\n\n  if (typeof obj === 'function') {\n    styleFunction = obj;\n  } else {\n    /**\n     * @type {Array.<module:ol/style/Style>}\n     */\n    let styles;\n    if (Array.isArray(obj)) {\n      styles = obj;\n    } else {\n      assert(obj instanceof Style,\n        41); // Expected an `module:ol/style/Style~Style` or an array of `module:ol/style/Style~Style`\n      styles = [obj];\n    }\n    styleFunction = function() {\n      return styles;\n    };\n  }\n  return styleFunction;\n}\n\n\n/**\n * @type {Array.<module:ol/style/Style>}\n */\nlet defaultStyles = null;\n\n\n/**\n * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n * @param {number} resolution Resolution.\n * @return {Array.<module:ol/style/Style>} Style.\n */\nexport function createDefaultStyle(feature, resolution) {\n  // We don't use an immediately-invoked function\n  // and a closure so we don't get an error at script evaluation time in\n  // browsers that do not support Canvas. (module:ol/style/Circle~CircleStyle does\n  // canvas.getContext('2d') at construction time, which will cause an.error\n  // in such browsers.)\n  if (!defaultStyles) {\n    const fill = new Fill({\n      color: 'rgba(255,255,255,0.4)'\n    });\n    const stroke = new Stroke({\n      color: '#3399CC',\n      width: 1.25\n    });\n    defaultStyles = [\n      new Style({\n        image: new CircleStyle({\n          fill: fill,\n          stroke: stroke,\n          radius: 5\n        }),\n        fill: fill,\n        stroke: stroke\n      })\n    ];\n  }\n  return defaultStyles;\n}\n\n\n/**\n * Default styles for editing features.\n * @return {Object.<module:ol/geom/GeometryType, Array.<module:ol/style/Style>>} Styles\n */\nexport function createEditingStyle() {\n  /** @type {Object.<module:ol/geom/GeometryType, Array.<module:ol/style/Style>>} */\n  const styles = {};\n  const white = [255, 255, 255, 1];\n  const blue = [0, 153, 255, 1];\n  const width = 3;\n  styles[GeometryType.POLYGON] = [\n    new Style({\n      fill: new Fill({\n        color: [255, 255, 255, 0.5]\n      })\n    })\n  ];\n  styles[GeometryType.MULTI_POLYGON] =\n      styles[GeometryType.POLYGON];\n\n  styles[GeometryType.LINE_STRING] = [\n    new Style({\n      stroke: new Stroke({\n        color: white,\n        width: width + 2\n      })\n    }),\n    new Style({\n      stroke: new Stroke({\n        color: blue,\n        width: width\n      })\n    })\n  ];\n  styles[GeometryType.MULTI_LINE_STRING] =\n      styles[GeometryType.LINE_STRING];\n\n  styles[GeometryType.CIRCLE] =\n      styles[GeometryType.POLYGON].concat(\n        styles[GeometryType.LINE_STRING]\n      );\n\n\n  styles[GeometryType.POINT] = [\n    new Style({\n      image: new CircleStyle({\n        radius: width * 2,\n        fill: new Fill({\n          color: blue\n        }),\n        stroke: new Stroke({\n          color: white,\n          width: width / 2\n        })\n      }),\n      zIndex: Infinity\n    })\n  ];\n  styles[GeometryType.MULTI_POINT] =\n      styles[GeometryType.POINT];\n\n  styles[GeometryType.GEOMETRY_COLLECTION] =\n      styles[GeometryType.POLYGON].concat(\n        styles[GeometryType.LINE_STRING],\n        styles[GeometryType.POINT]\n      );\n\n  return styles;\n}\n\n\n/**\n * Function that is called with a feature and returns its default geometry.\n * @param {module:ol/Feature|module:ol/render/Feature} feature Feature to get the geometry for.\n * @return {module:ol/geom/Geometry|module:ol/render/Feature|undefined} Geometry to render.\n */\nfunction defaultGeometryFunction(feature) {\n  return feature.getGeometry();\n}\n\nexport default Style;\n","/**\n * @module ol/Feature\n */\nimport {assert} from './asserts.js';\nimport {listen, unlisten, unlistenByKey} from './events.js';\nimport EventType from './events/EventType.js';\nimport BaseObject, {getChangeEventType} from './Object.js';\nimport Geometry from './geom/Geometry.js';\nimport Style from './style/Style.js';\n\n/**\n * @classdesc\n * A vector object for geographic features with a geometry and other\n * attribute properties, similar to the features in vector file formats like\n * GeoJSON.\n *\n * Features can be styled individually with `setStyle`; otherwise they use the\n * style of their vector layer.\n *\n * Note that attribute properties are set as {@link module:ol/Object} properties on\n * the feature object, so they are observable, and have get/set accessors.\n *\n * Typically, a feature has a single geometry property. You can set the\n * geometry using the `setGeometry` method and get it with `getGeometry`.\n * It is possible to store more than one geometry on a feature using attribute\n * properties. By default, the geometry used for rendering is identified by\n * the property name `geometry`. If you want to use another geometry property\n * for rendering, use the `setGeometryName` method to change the attribute\n * property associated with the geometry for the feature.  For example:\n *\n * ```js\n *\n * import Feature from 'ol/Feature';\n * import Polygon from 'ol/geom/Polygon';\n * import Point from 'ol/geom/Point';\n *\n * var feature = new Feature({\n *   geometry: new Polygon(polyCoords),\n *   labelPoint: new Point(labelCoords),\n *   name: 'My Polygon'\n * });\n *\n * // get the polygon geometry\n * var poly = feature.getGeometry();\n *\n * // Render the feature as a point using the coordinates from labelPoint\n * feature.setGeometryName('labelPoint');\n *\n * // get the point geometry\n * var point = feature.getGeometry();\n * ```\n *\n * @api\n */\nclass Feature extends BaseObject {\n  /**\n   * @param {module:ol/geom/Geometry|Object.<string, *>=} opt_geometryOrProperties\n   *     You may pass a Geometry object directly, or an object literal containing\n   *     properties. If you pass an object literal, you may include a Geometry\n   *     associated with a `geometry` key.\n   */\n  constructor(opt_geometryOrProperties) {\n\n    super();\n\n    /**\n     * @private\n     * @type {number|string|undefined}\n     */\n    this.id_ = undefined;\n\n    /**\n     * @type {string}\n     * @private\n     */\n    this.geometryName_ = 'geometry';\n\n    /**\n     * User provided style.\n     * @private\n     * @type {module:ol/style/Style|Array.<module:ol/style/Style>|module:ol/style/Style~StyleFunction}\n     */\n    this.style_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/style/Style~StyleFunction|undefined}\n     */\n    this.styleFunction_ = undefined;\n\n    /**\n     * @private\n     * @type {?module:ol/events~EventsKey}\n     */\n    this.geometryChangeKey_ = null;\n\n    listen(\n      this, getChangeEventType(this.geometryName_),\n      this.handleGeometryChanged_, this);\n\n    if (opt_geometryOrProperties !== undefined) {\n      if (opt_geometryOrProperties instanceof Geometry ||\n          !opt_geometryOrProperties) {\n        const geometry = opt_geometryOrProperties;\n        this.setGeometry(geometry);\n      } else {\n        /** @type {Object.<string, *>} */\n        const properties = opt_geometryOrProperties;\n        this.setProperties(properties);\n      }\n    }\n  }\n\n  /**\n   * Clone this feature. If the original feature has a geometry it\n   * is also cloned. The feature id is not set in the clone.\n   * @return {module:ol/Feature} The clone.\n   * @api\n   */\n  clone() {\n    const clone = new Feature(this.getProperties());\n    clone.setGeometryName(this.getGeometryName());\n    const geometry = this.getGeometry();\n    if (geometry) {\n      clone.setGeometry(geometry.clone());\n    }\n    const style = this.getStyle();\n    if (style) {\n      clone.setStyle(style);\n    }\n    return clone;\n  }\n\n  /**\n   * Get the feature's default geometry.  A feature may have any number of named\n   * geometries.  The \"default\" geometry (the one that is rendered by default) is\n   * set when calling {@link module:ol/Feature~Feature#setGeometry}.\n   * @return {module:ol/geom/Geometry|undefined} The default geometry for the feature.\n   * @api\n   * @observable\n   */\n  getGeometry() {\n    return (\n      /** @type {module:ol/geom/Geometry|undefined} */ (this.get(this.geometryName_))\n    );\n  }\n\n  /**\n   * Get the feature identifier.  This is a stable identifier for the feature and\n   * is either set when reading data from a remote source or set explicitly by\n   * calling {@link module:ol/Feature~Feature#setId}.\n   * @return {number|string|undefined} Id.\n   * @api\n   */\n  getId() {\n    return this.id_;\n  }\n\n  /**\n   * Get the name of the feature's default geometry.  By default, the default\n   * geometry is named `geometry`.\n   * @return {string} Get the property name associated with the default geometry\n   *     for this feature.\n   * @api\n   */\n  getGeometryName() {\n    return this.geometryName_;\n  }\n\n  /**\n   * Get the feature's style. Will return what was provided to the\n   * {@link module:ol/Feature~Feature#setStyle} method.\n   * @return {module:ol/style/Style|Array.<module:ol/style/Style>|module:ol/style/Style~StyleFunction} The feature style.\n   * @api\n   */\n  getStyle() {\n    return this.style_;\n  }\n\n  /**\n   * Get the feature's style function.\n   * @return {module:ol/style/Style~StyleFunction|undefined} Return a function\n   * representing the current style of this feature.\n   * @api\n   */\n  getStyleFunction() {\n    return this.styleFunction_;\n  }\n\n  /**\n   * @private\n   */\n  handleGeometryChange_() {\n    this.changed();\n  }\n\n  /**\n   * @private\n   */\n  handleGeometryChanged_() {\n    if (this.geometryChangeKey_) {\n      unlistenByKey(this.geometryChangeKey_);\n      this.geometryChangeKey_ = null;\n    }\n    const geometry = this.getGeometry();\n    if (geometry) {\n      this.geometryChangeKey_ = listen(geometry,\n        EventType.CHANGE, this.handleGeometryChange_, this);\n    }\n    this.changed();\n  }\n\n  /**\n   * Set the default geometry for the feature.  This will update the property\n   * with the name returned by {@link module:ol/Feature~Feature#getGeometryName}.\n   * @param {module:ol/geom/Geometry|undefined} geometry The new geometry.\n   * @api\n   * @observable\n   */\n  setGeometry(geometry) {\n    this.set(this.geometryName_, geometry);\n  }\n\n  /**\n   * Set the style for the feature.  This can be a single style object, an array\n   * of styles, or a function that takes a resolution and returns an array of\n   * styles. If it is `null` the feature has no style (a `null` style).\n   * @param {module:ol/style/Style|Array.<module:ol/style/Style>|module:ol/style/Style~StyleFunction} style Style for this feature.\n   * @api\n   * @fires module:ol/events/Event~Event#event:change\n   */\n  setStyle(style) {\n    this.style_ = style;\n    this.styleFunction_ = !style ? undefined : createStyleFunction(style);\n    this.changed();\n  }\n\n  /**\n   * Set the feature id.  The feature id is considered stable and may be used when\n   * requesting features or comparing identifiers returned from a remote source.\n   * The feature id can be used with the\n   * {@link module:ol/source/Vector~VectorSource#getFeatureById} method.\n   * @param {number|string|undefined} id The feature id.\n   * @api\n   * @fires module:ol/events/Event~Event#event:change\n   */\n  setId(id) {\n    this.id_ = id;\n    this.changed();\n  }\n\n  /**\n   * Set the property name to be used when getting the feature's default geometry.\n   * When calling {@link module:ol/Feature~Feature#getGeometry}, the value of the property with\n   * this name will be returned.\n   * @param {string} name The property name of the default geometry.\n   * @api\n   */\n  setGeometryName(name) {\n    unlisten(\n      this, getChangeEventType(this.geometryName_),\n      this.handleGeometryChanged_, this);\n    this.geometryName_ = name;\n    listen(\n      this, getChangeEventType(this.geometryName_),\n      this.handleGeometryChanged_, this);\n    this.handleGeometryChanged_();\n  }\n}\n\n\n/**\n * Convert the provided object into a feature style function.  Functions passed\n * through unchanged.  Arrays of module:ol/style/Style or single style objects wrapped\n * in a new feature style function.\n * @param {module:ol/style/Style~StyleFunction|!Array.<module:ol/style/Style>|!module:ol/style/Style} obj\n *     A feature style function, a single style, or an array of styles.\n * @return {module:ol/style/Style~StyleFunction} A style function.\n */\nexport function createStyleFunction(obj) {\n  if (typeof obj === 'function') {\n    return obj;\n  } else {\n    /**\n     * @type {Array.<module:ol/style/Style>}\n     */\n    let styles;\n    if (Array.isArray(obj)) {\n      styles = obj;\n    } else {\n      assert(obj instanceof Style,\n        41); // Expected an `module:ol/style/Style~Style` or an array of `module:ol/style/Style~Style`\n      styles = [obj];\n    }\n    return function() {\n      return styles;\n    };\n  }\n}\nexport default Feature;\n","/**\n * @module ol/GeolocationProperty\n */\n\n/**\n * @enum {string}\n */\nexport default {\n  ACCURACY: 'accuracy',\n  ACCURACY_GEOMETRY: 'accuracyGeometry',\n  ALTITUDE: 'altitude',\n  ALTITUDE_ACCURACY: 'altitudeAccuracy',\n  HEADING: 'heading',\n  POSITION: 'position',\n  PROJECTION: 'projection',\n  SPEED: 'speed',\n  TRACKING: 'tracking',\n  TRACKING_OPTIONS: 'trackingOptions'\n};\n","/**\n * @module ol/array\n */\n\n\n/**\n * Performs a binary search on the provided sorted list and returns the index of the item if found. If it can't be found it'll return -1.\n * https://github.com/darkskyapp/binary-search\n *\n * @param {Array.<*>} haystack Items to search through.\n * @param {*} needle The item to look for.\n * @param {Function=} opt_comparator Comparator function.\n * @return {number} The index of the item if found, -1 if not.\n */\nexport function binarySearch(haystack, needle, opt_comparator) {\n  let mid, cmp;\n  const comparator = opt_comparator || numberSafeCompareFunction;\n  let low = 0;\n  let high = haystack.length;\n  let found = false;\n\n  while (low < high) {\n    /* Note that \"(low + high) >>> 1\" may overflow, and results in a typecast\n     * to double (which gives the wrong results). */\n    mid = low + (high - low >> 1);\n    cmp = +comparator(haystack[mid], needle);\n\n    if (cmp < 0.0) { /* Too low. */\n      low = mid + 1;\n\n    } else { /* Key found or too high */\n      high = mid;\n      found = !cmp;\n    }\n  }\n\n  /* Key not found. */\n  return found ? low : ~low;\n}\n\n\n/**\n * Compare function for array sort that is safe for numbers.\n * @param {*} a The first object to be compared.\n * @param {*} b The second object to be compared.\n * @return {number} A negative number, zero, or a positive number as the first\n *     argument is less than, equal to, or greater than the second.\n */\nexport function numberSafeCompareFunction(a, b) {\n  return a > b ? 1 : a < b ? -1 : 0;\n}\n\n\n/**\n * Whether the array contains the given object.\n * @param {Array.<*>} arr The array to test for the presence of the element.\n * @param {*} obj The object for which to test.\n * @return {boolean} The object is in the array.\n */\nexport function includes(arr, obj) {\n  return arr.indexOf(obj) >= 0;\n}\n\n\n/**\n * @param {Array.<number>} arr Array.\n * @param {number} target Target.\n * @param {number} direction 0 means return the nearest, > 0\n *    means return the largest nearest, < 0 means return the\n *    smallest nearest.\n * @return {number} Index.\n */\nexport function linearFindNearest(arr, target, direction) {\n  const n = arr.length;\n  if (arr[0] <= target) {\n    return 0;\n  } else if (target <= arr[n - 1]) {\n    return n - 1;\n  } else {\n    let i;\n    if (direction > 0) {\n      for (i = 1; i < n; ++i) {\n        if (arr[i] < target) {\n          return i - 1;\n        }\n      }\n    } else if (direction < 0) {\n      for (i = 1; i < n; ++i) {\n        if (arr[i] <= target) {\n          return i;\n        }\n      }\n    } else {\n      for (i = 1; i < n; ++i) {\n        if (arr[i] == target) {\n          return i;\n        } else if (arr[i] < target) {\n          if (arr[i - 1] - target < target - arr[i]) {\n            return i - 1;\n          } else {\n            return i;\n          }\n        }\n      }\n    }\n    return n - 1;\n  }\n}\n\n\n/**\n * @param {Array.<*>} arr Array.\n * @param {number} begin Begin index.\n * @param {number} end End index.\n */\nexport function reverseSubArray(arr, begin, end) {\n  while (begin < end) {\n    const tmp = arr[begin];\n    arr[begin] = arr[end];\n    arr[end] = tmp;\n    ++begin;\n    --end;\n  }\n}\n\n\n/**\n * @param {Array.<VALUE>} arr The array to modify.\n * @param {!Array.<VALUE>|VALUE} data The elements or arrays of elements to add to arr.\n * @template VALUE\n */\nexport function extend(arr, data) {\n  const extension = Array.isArray(data) ? data : [data];\n  const length = extension.length;\n  for (let i = 0; i < length; i++) {\n    arr[arr.length] = extension[i];\n  }\n}\n\n\n/**\n * @param {Array.<VALUE>} arr The array to modify.\n * @param {VALUE} obj The element to remove.\n * @template VALUE\n * @return {boolean} If the element was removed.\n */\nexport function remove(arr, obj) {\n  const i = arr.indexOf(obj);\n  const found = i > -1;\n  if (found) {\n    arr.splice(i, 1);\n  }\n  return found;\n}\n\n\n/**\n * @param {Array.<VALUE>} arr The array to search in.\n * @param {function(VALUE, number, ?) : boolean} func The function to compare.\n * @template VALUE\n * @return {VALUE|null} The element found or null.\n */\nexport function find(arr, func) {\n  const length = arr.length >>> 0;\n  let value;\n\n  for (let i = 0; i < length; i++) {\n    value = arr[i];\n    if (func(value, i, arr)) {\n      return value;\n    }\n  }\n  return null;\n}\n\n\n/**\n * @param {Array|Uint8ClampedArray} arr1 The first array to compare.\n * @param {Array|Uint8ClampedArray} arr2 The second array to compare.\n * @return {boolean} Whether the two arrays are equal.\n */\nexport function equals(arr1, arr2) {\n  const len1 = arr1.length;\n  if (len1 !== arr2.length) {\n    return false;\n  }\n  for (let i = 0; i < len1; i++) {\n    if (arr1[i] !== arr2[i]) {\n      return false;\n    }\n  }\n  return true;\n}\n\n\n/**\n * @param {Array.<*>} arr The array to sort (modifies original).\n * @param {Function} compareFnc Comparison function.\n */\nexport function stableSort(arr, compareFnc) {\n  const length = arr.length;\n  const tmp = Array(arr.length);\n  let i;\n  for (i = 0; i < length; i++) {\n    tmp[i] = {index: i, value: arr[i]};\n  }\n  tmp.sort(function(a, b) {\n    return compareFnc(a.value, b.value) || a.index - b.index;\n  });\n  for (i = 0; i < arr.length; i++) {\n    arr[i] = tmp[i].value;\n  }\n}\n\n\n/**\n * @param {Array.<*>} arr The array to search in.\n * @param {Function} func Comparison function.\n * @return {number} Return index.\n */\nexport function findIndex(arr, func) {\n  let index;\n  const found = !arr.every(function(el, idx) {\n    index = idx;\n    return !func(el, idx, arr);\n  });\n  return found ? index : -1;\n}\n\n\n/**\n * @param {Array.<*>} arr The array to test.\n * @param {Function=} opt_func Comparison function.\n * @param {boolean=} opt_strict Strictly sorted (default false).\n * @return {boolean} Return index.\n */\nexport function isSorted(arr, opt_func, opt_strict) {\n  const compare = opt_func || numberSafeCompareFunction;\n  return arr.every(function(currentVal, index) {\n    if (index === 0) {\n      return true;\n    }\n    const res = compare(arr[index - 1], currentVal);\n    return !(res > 0 || opt_strict && res === 0);\n  });\n}\n","/**\n * @module ol/geom/GeometryLayout\n */\n\n/**\n * The coordinate layout for geometries, indicating whether a 3rd or 4th z ('Z')\n * or measure ('M') coordinate is available. Supported values are `'XY'`,\n * `'XYZ'`, `'XYM'`, `'XYZM'`.\n * @enum {string}\n */\nexport default {\n  XY: 'XY',\n  XYZ: 'XYZ',\n  XYM: 'XYM',\n  XYZM: 'XYZM'\n};\n","/**\n * @module ol/geom/SimpleGeometry\n */\nimport {FALSE} from '../functions.js';\nimport {createOrUpdateFromFlatCoordinates, getCenter} from '../extent.js';\nimport Geometry from '../geom/Geometry.js';\nimport GeometryLayout from '../geom/GeometryLayout.js';\nimport {rotate, scale, translate, transform2D} from '../geom/flat/transform.js';\nimport {clear} from '../obj.js';\n\n/**\n * @classdesc\n * Abstract base class; only used for creating subclasses; do not instantiate\n * in apps, as cannot be rendered.\n *\n * @abstract\n * @api\n */\nclass SimpleGeometry extends Geometry {\n  constructor() {\n\n    super();\n\n    /**\n     * @protected\n     * @type {module:ol/geom/GeometryLayout}\n     */\n    this.layout = GeometryLayout.XY;\n\n    /**\n     * @protected\n     * @type {number}\n     */\n    this.stride = 2;\n\n    /**\n     * @protected\n     * @type {Array.<number>}\n     */\n    this.flatCoordinates = null;\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  computeExtent(extent) {\n    return createOrUpdateFromFlatCoordinates(this.flatCoordinates,\n      0, this.flatCoordinates.length, this.stride, extent);\n  }\n\n  /**\n   * @abstract\n   * @return {Array} Coordinates.\n   */\n  getCoordinates() {}\n\n  /**\n   * Return the first coordinate of the geometry.\n   * @return {module:ol/coordinate~Coordinate} First coordinate.\n   * @api\n   */\n  getFirstCoordinate() {\n    return this.flatCoordinates.slice(0, this.stride);\n  }\n\n  /**\n   * @return {Array.<number>} Flat coordinates.\n   */\n  getFlatCoordinates() {\n    return this.flatCoordinates;\n  }\n\n  /**\n   * Return the last coordinate of the geometry.\n   * @return {module:ol/coordinate~Coordinate} Last point.\n   * @api\n   */\n  getLastCoordinate() {\n    return this.flatCoordinates.slice(this.flatCoordinates.length - this.stride);\n  }\n\n  /**\n   * Return the {@link module:ol/geom/GeometryLayout~GeometryLayout layout} of the geometry.\n   * @return {module:ol/geom/GeometryLayout} Layout.\n   * @api\n   */\n  getLayout() {\n    return this.layout;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getSimplifiedGeometry(squaredTolerance) {\n    if (this.simplifiedGeometryRevision != this.getRevision()) {\n      clear(this.simplifiedGeometryCache);\n      this.simplifiedGeometryMaxMinSquaredTolerance = 0;\n      this.simplifiedGeometryRevision = this.getRevision();\n    }\n    // If squaredTolerance is negative or if we know that simplification will not\n    // have any effect then just return this.\n    if (squaredTolerance < 0 ||\n        (this.simplifiedGeometryMaxMinSquaredTolerance !== 0 &&\n         squaredTolerance <= this.simplifiedGeometryMaxMinSquaredTolerance)) {\n      return this;\n    }\n    const key = squaredTolerance.toString();\n    if (this.simplifiedGeometryCache.hasOwnProperty(key)) {\n      return this.simplifiedGeometryCache[key];\n    } else {\n      const simplifiedGeometry =\n          this.getSimplifiedGeometryInternal(squaredTolerance);\n      const simplifiedFlatCoordinates = simplifiedGeometry.getFlatCoordinates();\n      if (simplifiedFlatCoordinates.length < this.flatCoordinates.length) {\n        this.simplifiedGeometryCache[key] = simplifiedGeometry;\n        return simplifiedGeometry;\n      } else {\n        // Simplification did not actually remove any coordinates.  We now know\n        // that any calls to getSimplifiedGeometry with a squaredTolerance less\n        // than or equal to the current squaredTolerance will also not have any\n        // effect.  This allows us to short circuit simplification (saving CPU\n        // cycles) and prevents the cache of simplified geometries from filling\n        // up with useless identical copies of this geometry (saving memory).\n        this.simplifiedGeometryMaxMinSquaredTolerance = squaredTolerance;\n        return this;\n      }\n    }\n  }\n\n  /**\n   * @param {number} squaredTolerance Squared tolerance.\n   * @return {module:ol/geom/SimpleGeometry} Simplified geometry.\n   * @protected\n   */\n  getSimplifiedGeometryInternal(squaredTolerance) {\n    return this;\n  }\n\n  /**\n   * @return {number} Stride.\n   */\n  getStride() {\n    return this.stride;\n  }\n\n  /**\n   * @param {module:ol/geom/GeometryLayout} layout Layout.\n   * @param {Array.<number>} flatCoordinates Flat coordinates.\n    */\n  setFlatCoordinates(layout, flatCoordinates) {\n    this.stride = getStrideForLayout(layout);\n    this.layout = layout;\n    this.flatCoordinates = flatCoordinates;\n  }\n\n  /**\n   * @abstract\n   * @param {!Array} coordinates Coordinates.\n   * @param {module:ol/geom/GeometryLayout=} opt_layout Layout.\n   */\n  setCoordinates(coordinates, opt_layout) {}\n\n  /**\n   * @param {module:ol/geom/GeometryLayout|undefined} layout Layout.\n   * @param {Array} coordinates Coordinates.\n   * @param {number} nesting Nesting.\n   * @protected\n   */\n  setLayout(layout, coordinates, nesting) {\n    /** @type {number} */\n    let stride;\n    if (layout) {\n      stride = getStrideForLayout(layout);\n    } else {\n      for (let i = 0; i < nesting; ++i) {\n        if (coordinates.length === 0) {\n          this.layout = GeometryLayout.XY;\n          this.stride = 2;\n          return;\n        } else {\n          coordinates = /** @type {Array} */ (coordinates[0]);\n        }\n      }\n      stride = coordinates.length;\n      layout = getLayoutForStride(stride);\n    }\n    this.layout = layout;\n    this.stride = stride;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  applyTransform(transformFn) {\n    if (this.flatCoordinates) {\n      transformFn(this.flatCoordinates, this.flatCoordinates, this.stride);\n      this.changed();\n    }\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  rotate(angle, anchor) {\n    const flatCoordinates = this.getFlatCoordinates();\n    if (flatCoordinates) {\n      const stride = this.getStride();\n      rotate(\n        flatCoordinates, 0, flatCoordinates.length,\n        stride, angle, anchor, flatCoordinates);\n      this.changed();\n    }\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  scale(sx, opt_sy, opt_anchor) {\n    let sy = opt_sy;\n    if (sy === undefined) {\n      sy = sx;\n    }\n    let anchor = opt_anchor;\n    if (!anchor) {\n      anchor = getCenter(this.getExtent());\n    }\n    const flatCoordinates = this.getFlatCoordinates();\n    if (flatCoordinates) {\n      const stride = this.getStride();\n      scale(\n        flatCoordinates, 0, flatCoordinates.length,\n        stride, sx, sy, anchor, flatCoordinates);\n      this.changed();\n    }\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  translate(deltaX, deltaY) {\n    const flatCoordinates = this.getFlatCoordinates();\n    if (flatCoordinates) {\n      const stride = this.getStride();\n      translate(\n        flatCoordinates, 0, flatCoordinates.length, stride,\n        deltaX, deltaY, flatCoordinates);\n      this.changed();\n    }\n  }\n}\n\n\n/**\n * @param {number} stride Stride.\n * @return {module:ol/geom/GeometryLayout} layout Layout.\n */\nfunction getLayoutForStride(stride) {\n  let layout;\n  if (stride == 2) {\n    layout = GeometryLayout.XY;\n  } else if (stride == 3) {\n    layout = GeometryLayout.XYZ;\n  } else if (stride == 4) {\n    layout = GeometryLayout.XYZM;\n  }\n  return (\n    /** @type {module:ol/geom/GeometryLayout} */ (layout)\n  );\n}\n\n\n/**\n * @param {module:ol/geom/GeometryLayout} layout Layout.\n * @return {number} Stride.\n */\nexport function getStrideForLayout(layout) {\n  let stride;\n  if (layout == GeometryLayout.XY) {\n    stride = 2;\n  } else if (layout == GeometryLayout.XYZ || layout == GeometryLayout.XYM) {\n    stride = 3;\n  } else if (layout == GeometryLayout.XYZM) {\n    stride = 4;\n  }\n  return /** @type {number} */ (stride);\n}\n\n\n/**\n * @inheritDoc\n */\nSimpleGeometry.prototype.containsXY = FALSE;\n\n\n/**\n * @param {module:ol/geom/SimpleGeometry} simpleGeometry Simple geometry.\n * @param {module:ol/transform~Transform} transform Transform.\n * @param {Array.<number>=} opt_dest Destination.\n * @return {Array.<number>} Transformed flat coordinates.\n */\nexport function transformGeom2D(simpleGeometry, transform, opt_dest) {\n  const flatCoordinates = simpleGeometry.getFlatCoordinates();\n  if (!flatCoordinates) {\n    return null;\n  } else {\n    const stride = simpleGeometry.getStride();\n    return transform2D(\n      flatCoordinates, 0, flatCoordinates.length, stride,\n      transform, opt_dest);\n  }\n}\n\nexport default SimpleGeometry;\n","/**\n * @module ol/geom/flat/area\n */\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {number} Area.\n */\nexport function linearRing(flatCoordinates, offset, end, stride) {\n  let twiceArea = 0;\n  let x1 = flatCoordinates[end - stride];\n  let y1 = flatCoordinates[end - stride + 1];\n  for (; offset < end; offset += stride) {\n    const x2 = flatCoordinates[offset];\n    const y2 = flatCoordinates[offset + 1];\n    twiceArea += y1 * x2 - x1 * y2;\n    x1 = x2;\n    y1 = y2;\n  }\n  return twiceArea / 2;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<number>} ends Ends.\n * @param {number} stride Stride.\n * @return {number} Area.\n */\nexport function linearRings(flatCoordinates, offset, ends, stride) {\n  let area = 0;\n  for (let i = 0, ii = ends.length; i < ii; ++i) {\n    const end = ends[i];\n    area += linearRing(flatCoordinates, offset, end, stride);\n    offset = end;\n  }\n  return area;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<Array.<number>>} endss Endss.\n * @param {number} stride Stride.\n * @return {number} Area.\n */\nexport function linearRingss(flatCoordinates, offset, endss, stride) {\n  let area = 0;\n  for (let i = 0, ii = endss.length; i < ii; ++i) {\n    const ends = endss[i];\n    area += linearRings(flatCoordinates, offset, ends, stride);\n    offset = ends[ends.length - 1];\n  }\n  return area;\n}\n","/**\n * @module ol/geom/flat/closest\n */\nimport {lerp, squaredDistance as squaredDx} from '../../math.js';\n\n\n/**\n * Returns the point on the 2D line segment flatCoordinates[offset1] to\n * flatCoordinates[offset2] that is closest to the point (x, y).  Extra\n * dimensions are linearly interpolated.\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset1 Offset 1.\n * @param {number} offset2 Offset 2.\n * @param {number} stride Stride.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {Array.<number>} closestPoint Closest point.\n */\nfunction assignClosest(flatCoordinates, offset1, offset2, stride, x, y, closestPoint) {\n  const x1 = flatCoordinates[offset1];\n  const y1 = flatCoordinates[offset1 + 1];\n  const dx = flatCoordinates[offset2] - x1;\n  const dy = flatCoordinates[offset2 + 1] - y1;\n  let offset;\n  if (dx === 0 && dy === 0) {\n    offset = offset1;\n  } else {\n    const t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);\n    if (t > 1) {\n      offset = offset2;\n    } else if (t > 0) {\n      for (let i = 0; i < stride; ++i) {\n        closestPoint[i] = lerp(flatCoordinates[offset1 + i],\n          flatCoordinates[offset2 + i], t);\n      }\n      closestPoint.length = stride;\n      return;\n    } else {\n      offset = offset1;\n    }\n  }\n  for (let i = 0; i < stride; ++i) {\n    closestPoint[i] = flatCoordinates[offset + i];\n  }\n  closestPoint.length = stride;\n}\n\n\n/**\n * Return the squared of the largest distance between any pair of consecutive\n * coordinates.\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} max Max squared delta.\n * @return {number} Max squared delta.\n */\nexport function maxSquaredDelta(flatCoordinates, offset, end, stride, max) {\n  let x1 = flatCoordinates[offset];\n  let y1 = flatCoordinates[offset + 1];\n  for (offset += stride; offset < end; offset += stride) {\n    const x2 = flatCoordinates[offset];\n    const y2 = flatCoordinates[offset + 1];\n    const squaredDelta = squaredDx(x1, y1, x2, y2);\n    if (squaredDelta > max) {\n      max = squaredDelta;\n    }\n    x1 = x2;\n    y1 = y2;\n  }\n  return max;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} max Max squared delta.\n * @return {number} Max squared delta.\n */\nexport function arrayMaxSquaredDelta(flatCoordinates, offset, ends, stride, max) {\n  for (let i = 0, ii = ends.length; i < ii; ++i) {\n    const end = ends[i];\n    max = maxSquaredDelta(\n      flatCoordinates, offset, end, stride, max);\n    offset = end;\n  }\n  return max;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<Array.<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} max Max squared delta.\n * @return {number} Max squared delta.\n */\nexport function multiArrayMaxSquaredDelta(flatCoordinates, offset, endss, stride, max) {\n  for (let i = 0, ii = endss.length; i < ii; ++i) {\n    const ends = endss[i];\n    max = arrayMaxSquaredDelta(\n      flatCoordinates, offset, ends, stride, max);\n    offset = ends[ends.length - 1];\n  }\n  return max;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} maxDelta Max delta.\n * @param {boolean} isRing Is ring.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {Array.<number>} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @param {Array.<number>=} opt_tmpPoint Temporary point object.\n * @return {number} Minimum squared distance.\n */\nexport function assignClosestPoint(flatCoordinates, offset, end,\n  stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance,\n  opt_tmpPoint) {\n  if (offset == end) {\n    return minSquaredDistance;\n  }\n  let i, squaredDistance;\n  if (maxDelta === 0) {\n    // All points are identical, so just test the first point.\n    squaredDistance = squaredDx(\n      x, y, flatCoordinates[offset], flatCoordinates[offset + 1]);\n    if (squaredDistance < minSquaredDistance) {\n      for (i = 0; i < stride; ++i) {\n        closestPoint[i] = flatCoordinates[offset + i];\n      }\n      closestPoint.length = stride;\n      return squaredDistance;\n    } else {\n      return minSquaredDistance;\n    }\n  }\n  const tmpPoint = opt_tmpPoint ? opt_tmpPoint : [NaN, NaN];\n  let index = offset + stride;\n  while (index < end) {\n    assignClosest(\n      flatCoordinates, index - stride, index, stride, x, y, tmpPoint);\n    squaredDistance = squaredDx(x, y, tmpPoint[0], tmpPoint[1]);\n    if (squaredDistance < minSquaredDistance) {\n      minSquaredDistance = squaredDistance;\n      for (i = 0; i < stride; ++i) {\n        closestPoint[i] = tmpPoint[i];\n      }\n      closestPoint.length = stride;\n      index += stride;\n    } else {\n      // Skip ahead multiple points, because we know that all the skipped\n      // points cannot be any closer than the closest point we have found so\n      // far.  We know this because we know how close the current point is, how\n      // close the closest point we have found so far is, and the maximum\n      // distance between consecutive points.  For example, if we're currently\n      // at distance 10, the best we've found so far is 3, and that the maximum\n      // distance between consecutive points is 2, then we'll need to skip at\n      // least (10 - 3) / 2 == 3 (rounded down) points to have any chance of\n      // finding a closer point.  We use Math.max(..., 1) to ensure that we\n      // always advance at least one point, to avoid an infinite loop.\n      index += stride * Math.max(\n        ((Math.sqrt(squaredDistance) -\n            Math.sqrt(minSquaredDistance)) / maxDelta) | 0, 1);\n    }\n  }\n  if (isRing) {\n    // Check the closing segment.\n    assignClosest(\n      flatCoordinates, end - stride, offset, stride, x, y, tmpPoint);\n    squaredDistance = squaredDx(x, y, tmpPoint[0], tmpPoint[1]);\n    if (squaredDistance < minSquaredDistance) {\n      minSquaredDistance = squaredDistance;\n      for (i = 0; i < stride; ++i) {\n        closestPoint[i] = tmpPoint[i];\n      }\n      closestPoint.length = stride;\n    }\n  }\n  return minSquaredDistance;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} maxDelta Max delta.\n * @param {boolean} isRing Is ring.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {Array.<number>} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @param {Array.<number>=} opt_tmpPoint Temporary point object.\n * @return {number} Minimum squared distance.\n */\nexport function assignClosestArrayPoint(flatCoordinates, offset, ends,\n  stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance,\n  opt_tmpPoint) {\n  const tmpPoint = opt_tmpPoint ? opt_tmpPoint : [NaN, NaN];\n  for (let i = 0, ii = ends.length; i < ii; ++i) {\n    const end = ends[i];\n    minSquaredDistance = assignClosestPoint(\n      flatCoordinates, offset, end, stride,\n      maxDelta, isRing, x, y, closestPoint, minSquaredDistance, tmpPoint);\n    offset = end;\n  }\n  return minSquaredDistance;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<Array.<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} maxDelta Max delta.\n * @param {boolean} isRing Is ring.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {Array.<number>} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @param {Array.<number>=} opt_tmpPoint Temporary point object.\n * @return {number} Minimum squared distance.\n */\nexport function assignClosestMultiArrayPoint(flatCoordinates, offset,\n  endss, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance,\n  opt_tmpPoint) {\n  const tmpPoint = opt_tmpPoint ? opt_tmpPoint : [NaN, NaN];\n  for (let i = 0, ii = endss.length; i < ii; ++i) {\n    const ends = endss[i];\n    minSquaredDistance = assignClosestArrayPoint(\n      flatCoordinates, offset, ends, stride,\n      maxDelta, isRing, x, y, closestPoint, minSquaredDistance, tmpPoint);\n    offset = ends[ends.length - 1];\n  }\n  return minSquaredDistance;\n}\n","/**\n * @module ol/geom/flat/deflate\n */\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n * @param {number} stride Stride.\n * @return {number} offset Offset.\n */\nexport function deflateCoordinate(flatCoordinates, offset, coordinate, stride) {\n  for (let i = 0, ii = coordinate.length; i < ii; ++i) {\n    flatCoordinates[offset++] = coordinate[i];\n  }\n  return offset;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<module:ol/coordinate~Coordinate>} coordinates Coordinates.\n * @param {number} stride Stride.\n * @return {number} offset Offset.\n */\nexport function deflateCoordinates(flatCoordinates, offset, coordinates, stride) {\n  for (let i = 0, ii = coordinates.length; i < ii; ++i) {\n    const coordinate = coordinates[i];\n    for (let j = 0; j < stride; ++j) {\n      flatCoordinates[offset++] = coordinate[j];\n    }\n  }\n  return offset;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<Array.<module:ol/coordinate~Coordinate>>} coordinatess Coordinatess.\n * @param {number} stride Stride.\n * @param {Array.<number>=} opt_ends Ends.\n * @return {Array.<number>} Ends.\n */\nexport function deflateCoordinatesArray(flatCoordinates, offset, coordinatess, stride, opt_ends) {\n  const ends = opt_ends ? opt_ends : [];\n  let i = 0;\n  for (let j = 0, jj = coordinatess.length; j < jj; ++j) {\n    const end = deflateCoordinates(\n      flatCoordinates, offset, coordinatess[j], stride);\n    ends[i++] = end;\n    offset = end;\n  }\n  ends.length = i;\n  return ends;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<Array.<Array.<module:ol/coordinate~Coordinate>>>} coordinatesss Coordinatesss.\n * @param {number} stride Stride.\n * @param {Array.<Array.<number>>=} opt_endss Endss.\n * @return {Array.<Array.<number>>} Endss.\n */\nexport function deflateMultiCoordinatesArray(flatCoordinates, offset, coordinatesss, stride, opt_endss) {\n  const endss = opt_endss ? opt_endss : [];\n  let i = 0;\n  for (let j = 0, jj = coordinatesss.length; j < jj; ++j) {\n    const ends = deflateCoordinatesArray(\n      flatCoordinates, offset, coordinatesss[j], stride, endss[i]);\n    endss[i++] = ends;\n    offset = ends[ends.length - 1];\n  }\n  endss.length = i;\n  return endss;\n}\n","/**\n * @module ol/geom/flat/inflate\n */\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {Array.<module:ol/coordinate~Coordinate>=} opt_coordinates Coordinates.\n * @return {Array.<module:ol/coordinate~Coordinate>} Coordinates.\n */\nexport function inflateCoordinates(flatCoordinates, offset, end, stride, opt_coordinates) {\n  const coordinates = opt_coordinates !== undefined ? opt_coordinates : [];\n  let i = 0;\n  for (let j = offset; j < end; j += stride) {\n    coordinates[i++] = flatCoordinates.slice(j, j + stride);\n  }\n  coordinates.length = i;\n  return coordinates;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {Array.<Array.<module:ol/coordinate~Coordinate>>=} opt_coordinatess Coordinatess.\n * @return {Array.<Array.<module:ol/coordinate~Coordinate>>} Coordinatess.\n */\nexport function inflateCoordinatesArray(flatCoordinates, offset, ends, stride, opt_coordinatess) {\n  const coordinatess = opt_coordinatess !== undefined ? opt_coordinatess : [];\n  let i = 0;\n  for (let j = 0, jj = ends.length; j < jj; ++j) {\n    const end = ends[j];\n    coordinatess[i++] = inflateCoordinates(\n      flatCoordinates, offset, end, stride, coordinatess[i]);\n    offset = end;\n  }\n  coordinatess.length = i;\n  return coordinatess;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<Array.<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {Array.<Array.<Array.<module:ol/coordinate~Coordinate>>>=} opt_coordinatesss\n *     Coordinatesss.\n * @return {Array.<Array.<Array.<module:ol/coordinate~Coordinate>>>} Coordinatesss.\n */\nexport function inflateMultiCoordinatesArray(flatCoordinates, offset, endss, stride, opt_coordinatesss) {\n  const coordinatesss = opt_coordinatesss !== undefined ? opt_coordinatesss : [];\n  let i = 0;\n  for (let j = 0, jj = endss.length; j < jj; ++j) {\n    const ends = endss[j];\n    coordinatesss[i++] = inflateCoordinatesArray(\n      flatCoordinates, offset, ends, stride, coordinatesss[i]);\n    offset = ends[ends.length - 1];\n  }\n  coordinatesss.length = i;\n  return coordinatesss;\n}\n","/**\n * @module ol/geom/flat/simplify\n */\n// Based on simplify-js https://github.com/mourner/simplify-js\n// Copyright (c) 2012, Vladimir Agafonkin\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are met:\n//\n//    1. Redistributions of source code must retain the above copyright notice,\n//       this list of conditions and the following disclaimer.\n//\n//    2. Redistributions in binary form must reproduce the above copyright\n//       notice, this list of conditions and the following disclaimer in the\n//       documentation and/or other materials provided with the distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\n// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n// POSSIBILITY OF SUCH DAMAGE.\n\nimport {squaredSegmentDistance, squaredDistance} from '../../math.js';\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {boolean} highQuality Highest quality.\n * @param {Array.<number>=} opt_simplifiedFlatCoordinates Simplified flat\n *     coordinates.\n * @return {Array.<number>} Simplified line string.\n */\nexport function simplifyLineString(flatCoordinates, offset, end,\n  stride, squaredTolerance, highQuality, opt_simplifiedFlatCoordinates) {\n  const simplifiedFlatCoordinates = opt_simplifiedFlatCoordinates !== undefined ?\n    opt_simplifiedFlatCoordinates : [];\n  if (!highQuality) {\n    end = radialDistance(flatCoordinates, offset, end,\n      stride, squaredTolerance,\n      simplifiedFlatCoordinates, 0);\n    flatCoordinates = simplifiedFlatCoordinates;\n    offset = 0;\n    stride = 2;\n  }\n  simplifiedFlatCoordinates.length = douglasPeucker(\n    flatCoordinates, offset, end, stride, squaredTolerance,\n    simplifiedFlatCoordinates, 0);\n  return simplifiedFlatCoordinates;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {Array.<number>} simplifiedFlatCoordinates Simplified flat\n *     coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @return {number} Simplified offset.\n */\nexport function douglasPeucker(flatCoordinates, offset, end,\n  stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset) {\n  const n = (end - offset) / stride;\n  if (n < 3) {\n    for (; offset < end; offset += stride) {\n      simplifiedFlatCoordinates[simplifiedOffset++] =\n          flatCoordinates[offset];\n      simplifiedFlatCoordinates[simplifiedOffset++] =\n          flatCoordinates[offset + 1];\n    }\n    return simplifiedOffset;\n  }\n  /** @type {Array.<number>} */\n  const markers = new Array(n);\n  markers[0] = 1;\n  markers[n - 1] = 1;\n  /** @type {Array.<number>} */\n  const stack = [offset, end - stride];\n  let index = 0;\n  while (stack.length > 0) {\n    const last = stack.pop();\n    const first = stack.pop();\n    let maxSquaredDistance = 0;\n    const x1 = flatCoordinates[first];\n    const y1 = flatCoordinates[first + 1];\n    const x2 = flatCoordinates[last];\n    const y2 = flatCoordinates[last + 1];\n    for (let i = first + stride; i < last; i += stride) {\n      const x = flatCoordinates[i];\n      const y = flatCoordinates[i + 1];\n      const squaredDistance = squaredSegmentDistance(\n        x, y, x1, y1, x2, y2);\n      if (squaredDistance > maxSquaredDistance) {\n        index = i;\n        maxSquaredDistance = squaredDistance;\n      }\n    }\n    if (maxSquaredDistance > squaredTolerance) {\n      markers[(index - offset) / stride] = 1;\n      if (first + stride < index) {\n        stack.push(first, index);\n      }\n      if (index + stride < last) {\n        stack.push(index, last);\n      }\n    }\n  }\n  for (let i = 0; i < n; ++i) {\n    if (markers[i]) {\n      simplifiedFlatCoordinates[simplifiedOffset++] =\n          flatCoordinates[offset + i * stride];\n      simplifiedFlatCoordinates[simplifiedOffset++] =\n          flatCoordinates[offset + i * stride + 1];\n    }\n  }\n  return simplifiedOffset;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {Array.<number>} simplifiedFlatCoordinates Simplified flat\n *     coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @param {Array.<number>} simplifiedEnds Simplified ends.\n * @return {number} Simplified offset.\n */\nexport function douglasPeuckerArray(flatCoordinates, offset,\n  ends, stride, squaredTolerance, simplifiedFlatCoordinates,\n  simplifiedOffset, simplifiedEnds) {\n  for (let i = 0, ii = ends.length; i < ii; ++i) {\n    const end = ends[i];\n    simplifiedOffset = douglasPeucker(\n      flatCoordinates, offset, end, stride, squaredTolerance,\n      simplifiedFlatCoordinates, simplifiedOffset);\n    simplifiedEnds.push(simplifiedOffset);\n    offset = end;\n  }\n  return simplifiedOffset;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<Array.<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {Array.<number>} simplifiedFlatCoordinates Simplified flat\n *     coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @param {Array.<Array.<number>>} simplifiedEndss Simplified endss.\n * @return {number} Simplified offset.\n */\nexport function douglasPeuckerMultiArray(\n  flatCoordinates, offset, endss, stride, squaredTolerance,\n  simplifiedFlatCoordinates, simplifiedOffset, simplifiedEndss) {\n  for (let i = 0, ii = endss.length; i < ii; ++i) {\n    const ends = endss[i];\n    const simplifiedEnds = [];\n    simplifiedOffset = douglasPeuckerArray(\n      flatCoordinates, offset, ends, stride, squaredTolerance,\n      simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds);\n    simplifiedEndss.push(simplifiedEnds);\n    offset = ends[ends.length - 1];\n  }\n  return simplifiedOffset;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {Array.<number>} simplifiedFlatCoordinates Simplified flat\n *     coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @return {number} Simplified offset.\n */\nexport function radialDistance(flatCoordinates, offset, end,\n  stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset) {\n  if (end <= offset + stride) {\n    // zero or one point, no simplification possible, so copy and return\n    for (; offset < end; offset += stride) {\n      simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset];\n      simplifiedFlatCoordinates[simplifiedOffset++] =\n          flatCoordinates[offset + 1];\n    }\n    return simplifiedOffset;\n  }\n  let x1 = flatCoordinates[offset];\n  let y1 = flatCoordinates[offset + 1];\n  // copy first point\n  simplifiedFlatCoordinates[simplifiedOffset++] = x1;\n  simplifiedFlatCoordinates[simplifiedOffset++] = y1;\n  let x2 = x1;\n  let y2 = y1;\n  for (offset += stride; offset < end; offset += stride) {\n    x2 = flatCoordinates[offset];\n    y2 = flatCoordinates[offset + 1];\n    if (squaredDistance(x1, y1, x2, y2) > squaredTolerance) {\n      // copy point at offset\n      simplifiedFlatCoordinates[simplifiedOffset++] = x2;\n      simplifiedFlatCoordinates[simplifiedOffset++] = y2;\n      x1 = x2;\n      y1 = y2;\n    }\n  }\n  if (x2 != x1 || y2 != y1) {\n    // copy last point\n    simplifiedFlatCoordinates[simplifiedOffset++] = x2;\n    simplifiedFlatCoordinates[simplifiedOffset++] = y2;\n  }\n  return simplifiedOffset;\n}\n\n\n/**\n * @param {number} value Value.\n * @param {number} tolerance Tolerance.\n * @return {number} Rounded value.\n */\nexport function snap(value, tolerance) {\n  return tolerance * Math.round(value / tolerance);\n}\n\n\n/**\n * Simplifies a line string using an algorithm designed by Tim Schaub.\n * Coordinates are snapped to the nearest value in a virtual grid and\n * consecutive duplicate coordinates are discarded.  This effectively preserves\n * topology as the simplification of any subsection of a line string is\n * independent of the rest of the line string.  This means that, for examples,\n * the common edge between two polygons will be simplified to the same line\n * string independently in both polygons.  This implementation uses a single\n * pass over the coordinates and eliminates intermediate collinear points.\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} tolerance Tolerance.\n * @param {Array.<number>} simplifiedFlatCoordinates Simplified flat\n *     coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @return {number} Simplified offset.\n */\nexport function quantize(flatCoordinates, offset, end, stride,\n  tolerance, simplifiedFlatCoordinates, simplifiedOffset) {\n  // do nothing if the line is empty\n  if (offset == end) {\n    return simplifiedOffset;\n  }\n  // snap the first coordinate (P1)\n  let x1 = snap(flatCoordinates[offset], tolerance);\n  let y1 = snap(flatCoordinates[offset + 1], tolerance);\n  offset += stride;\n  // add the first coordinate to the output\n  simplifiedFlatCoordinates[simplifiedOffset++] = x1;\n  simplifiedFlatCoordinates[simplifiedOffset++] = y1;\n  // find the next coordinate that does not snap to the same value as the first\n  // coordinate (P2)\n  let x2, y2;\n  do {\n    x2 = snap(flatCoordinates[offset], tolerance);\n    y2 = snap(flatCoordinates[offset + 1], tolerance);\n    offset += stride;\n    if (offset == end) {\n      // all coordinates snap to the same value, the line collapses to a point\n      // push the last snapped value anyway to ensure that the output contains\n      // at least two points\n      // FIXME should we really return at least two points anyway?\n      simplifiedFlatCoordinates[simplifiedOffset++] = x2;\n      simplifiedFlatCoordinates[simplifiedOffset++] = y2;\n      return simplifiedOffset;\n    }\n  } while (x2 == x1 && y2 == y1);\n  while (offset < end) {\n    // snap the next coordinate (P3)\n    const x3 = snap(flatCoordinates[offset], tolerance);\n    const y3 = snap(flatCoordinates[offset + 1], tolerance);\n    offset += stride;\n    // skip P3 if it is equal to P2\n    if (x3 == x2 && y3 == y2) {\n      continue;\n    }\n    // calculate the delta between P1 and P2\n    const dx1 = x2 - x1;\n    const dy1 = y2 - y1;\n    // calculate the delta between P3 and P1\n    const dx2 = x3 - x1;\n    const dy2 = y3 - y1;\n    // if P1, P2, and P3 are colinear and P3 is further from P1 than P2 is from\n    // P1 in the same direction then P2 is on the straight line between P1 and\n    // P3\n    if ((dx1 * dy2 == dy1 * dx2) &&\n        ((dx1 < 0 && dx2 < dx1) || dx1 == dx2 || (dx1 > 0 && dx2 > dx1)) &&\n        ((dy1 < 0 && dy2 < dy1) || dy1 == dy2 || (dy1 > 0 && dy2 > dy1))) {\n      // discard P2 and set P2 = P3\n      x2 = x3;\n      y2 = y3;\n      continue;\n    }\n    // either P1, P2, and P3 are not colinear, or they are colinear but P3 is\n    // between P3 and P1 or on the opposite half of the line to P2.  add P2,\n    // and continue with P1 = P2 and P2 = P3\n    simplifiedFlatCoordinates[simplifiedOffset++] = x2;\n    simplifiedFlatCoordinates[simplifiedOffset++] = y2;\n    x1 = x2;\n    y1 = y2;\n    x2 = x3;\n    y2 = y3;\n  }\n  // add the last point (P2)\n  simplifiedFlatCoordinates[simplifiedOffset++] = x2;\n  simplifiedFlatCoordinates[simplifiedOffset++] = y2;\n  return simplifiedOffset;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} tolerance Tolerance.\n * @param {Array.<number>} simplifiedFlatCoordinates Simplified flat\n *     coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @param {Array.<number>} simplifiedEnds Simplified ends.\n * @return {number} Simplified offset.\n */\nexport function quantizeArray(\n  flatCoordinates, offset, ends, stride,\n  tolerance,\n  simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds) {\n  for (let i = 0, ii = ends.length; i < ii; ++i) {\n    const end = ends[i];\n    simplifiedOffset = quantize(\n      flatCoordinates, offset, end, stride,\n      tolerance,\n      simplifiedFlatCoordinates, simplifiedOffset);\n    simplifiedEnds.push(simplifiedOffset);\n    offset = end;\n  }\n  return simplifiedOffset;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<Array.<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} tolerance Tolerance.\n * @param {Array.<number>} simplifiedFlatCoordinates Simplified flat\n *     coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @param {Array.<Array.<number>>} simplifiedEndss Simplified endss.\n * @return {number} Simplified offset.\n */\nexport function quantizeMultiArray(\n  flatCoordinates, offset, endss, stride,\n  tolerance,\n  simplifiedFlatCoordinates, simplifiedOffset, simplifiedEndss) {\n  for (let i = 0, ii = endss.length; i < ii; ++i) {\n    const ends = endss[i];\n    const simplifiedEnds = [];\n    simplifiedOffset = quantizeArray(\n      flatCoordinates, offset, ends, stride,\n      tolerance,\n      simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds);\n    simplifiedEndss.push(simplifiedEnds);\n    offset = ends[ends.length - 1];\n  }\n  return simplifiedOffset;\n}\n","/**\n * @module ol/geom/LinearRing\n */\nimport {closestSquaredDistanceXY} from '../extent.js';\nimport GeometryLayout from '../geom/GeometryLayout.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport SimpleGeometry from '../geom/SimpleGeometry.js';\nimport {linearRing as linearRingArea} from '../geom/flat/area.js';\nimport {assignClosestPoint, maxSquaredDelta} from '../geom/flat/closest.js';\nimport {deflateCoordinates} from '../geom/flat/deflate.js';\nimport {inflateCoordinates} from '../geom/flat/inflate.js';\nimport {douglasPeucker} from '../geom/flat/simplify.js';\n\n/**\n * @classdesc\n * Linear ring geometry. Only used as part of polygon; cannot be rendered\n * on its own.\n *\n * @api\n */\nclass LinearRing extends SimpleGeometry {\n\n  /**\n   * @param {Array.<module:ol/coordinate~Coordinate>|Array.<number>} coordinates Coordinates.\n   *     For internal use, flat coordinates in combination with `opt_layout` are also accepted.\n   * @param {module:ol/geom/GeometryLayout=} opt_layout Layout.\n   */\n  constructor(coordinates, opt_layout) {\n\n    super();\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.maxDelta_ = -1;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.maxDeltaRevision_ = -1;\n\n    if (opt_layout !== undefined && !Array.isArray(coordinates[0])) {\n      this.setFlatCoordinates(opt_layout, coordinates);\n    } else {\n      this.setCoordinates(coordinates, opt_layout);\n    }\n\n  }\n\n  /**\n   * Make a complete copy of the geometry.\n   * @return {!module:ol/geom/LinearRing} Clone.\n   * @override\n   * @api\n   */\n  clone() {\n    return new LinearRing(this.flatCoordinates.slice(), this.layout);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  closestPointXY(x, y, closestPoint, minSquaredDistance) {\n    if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n      return minSquaredDistance;\n    }\n    if (this.maxDeltaRevision_ != this.getRevision()) {\n      this.maxDelta_ = Math.sqrt(maxSquaredDelta(\n        this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, 0));\n      this.maxDeltaRevision_ = this.getRevision();\n    }\n    return assignClosestPoint(\n      this.flatCoordinates, 0, this.flatCoordinates.length, this.stride,\n      this.maxDelta_, true, x, y, closestPoint, minSquaredDistance);\n  }\n\n  /**\n   * Return the area of the linear ring on projected plane.\n   * @return {number} Area (on projected plane).\n   * @api\n   */\n  getArea() {\n    return linearRingArea(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);\n  }\n\n  /**\n   * Return the coordinates of the linear ring.\n   * @return {Array.<module:ol/coordinate~Coordinate>} Coordinates.\n   * @override\n   * @api\n   */\n  getCoordinates() {\n    return inflateCoordinates(\n      this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getSimplifiedGeometryInternal(squaredTolerance) {\n    const simplifiedFlatCoordinates = [];\n    simplifiedFlatCoordinates.length = douglasPeucker(\n      this.flatCoordinates, 0, this.flatCoordinates.length, this.stride,\n      squaredTolerance, simplifiedFlatCoordinates, 0);\n    return new LinearRing(simplifiedFlatCoordinates, GeometryLayout.XY);\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  getType() {\n    return GeometryType.LINEAR_RING;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  intersectsExtent(extent) {}\n\n  /**\n   * Set the coordinates of the linear ring.\n   * @param {!Array.<module:ol/coordinate~Coordinate>} coordinates Coordinates.\n   * @param {module:ol/geom/GeometryLayout=} opt_layout Layout.\n   * @override\n   * @api\n   */\n  setCoordinates(coordinates, opt_layout) {\n    this.setLayout(opt_layout, coordinates, 1);\n    if (!this.flatCoordinates) {\n      this.flatCoordinates = [];\n    }\n    this.flatCoordinates.length = deflateCoordinates(\n      this.flatCoordinates, 0, coordinates, this.stride);\n    this.changed();\n  }\n}\n\n\nexport default LinearRing;\n","/**\n * @module ol/geom/Point\n */\nimport {createOrUpdateFromCoordinate, containsXY} from '../extent.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport SimpleGeometry from '../geom/SimpleGeometry.js';\nimport {deflateCoordinate} from '../geom/flat/deflate.js';\nimport {squaredDistance as squaredDx} from '../math.js';\n\n/**\n * @classdesc\n * Point geometry.\n *\n * @api\n */\nclass Point extends SimpleGeometry {\n\n  /**\n   * @param {module:ol/coordinate~Coordinate} coordinates Coordinates.\n   * @param {module:ol/geom/GeometryLayout=} opt_layout Layout.\n   */\n  constructor(coordinates, opt_layout) {\n    super();\n    this.setCoordinates(coordinates, opt_layout);\n  }\n\n  /**\n   * Make a complete copy of the geometry.\n   * @return {!module:ol/geom/Point} Clone.\n   * @override\n   * @api\n   */\n  clone() {\n    const point = new Point(this.flatCoordinates.slice(), this.layout);\n    return point;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  closestPointXY(x, y, closestPoint, minSquaredDistance) {\n    const flatCoordinates = this.flatCoordinates;\n    const squaredDistance = squaredDx(x, y, flatCoordinates[0], flatCoordinates[1]);\n    if (squaredDistance < minSquaredDistance) {\n      const stride = this.stride;\n      for (let i = 0; i < stride; ++i) {\n        closestPoint[i] = flatCoordinates[i];\n      }\n      closestPoint.length = stride;\n      return squaredDistance;\n    } else {\n      return minSquaredDistance;\n    }\n  }\n\n  /**\n   * Return the coordinate of the point.\n   * @return {module:ol/coordinate~Coordinate} Coordinates.\n   * @override\n   * @api\n   */\n  getCoordinates() {\n    return !this.flatCoordinates ? [] : this.flatCoordinates.slice();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  computeExtent(extent) {\n    return createOrUpdateFromCoordinate(this.flatCoordinates, extent);\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  getType() {\n    return GeometryType.POINT;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  intersectsExtent(extent) {\n    return containsXY(extent, this.flatCoordinates[0], this.flatCoordinates[1]);\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  setCoordinates(coordinates, opt_layout) {\n    this.setLayout(opt_layout, coordinates, 0);\n    if (!this.flatCoordinates) {\n      this.flatCoordinates = [];\n    }\n    this.flatCoordinates.length = deflateCoordinate(\n      this.flatCoordinates, 0, coordinates, this.stride);\n    this.changed();\n  }\n}\n\n\nexport default Point;\n","/**\n * @module ol/geom/flat/contains\n */\nimport {forEachCorner} from '../../extent.js';\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {module:ol/extent~Extent} extent Extent.\n * @return {boolean} Contains extent.\n */\nexport function linearRingContainsExtent(flatCoordinates, offset, end, stride, extent) {\n  const outside = forEachCorner(extent,\n    /**\n     * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n     * @return {boolean} Contains (x, y).\n     */\n    function(coordinate) {\n      return !linearRingContainsXY(flatCoordinates, offset, end, stride, coordinate[0], coordinate[1]);\n    });\n  return !outside;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\nexport function linearRingContainsXY(flatCoordinates, offset, end, stride, x, y) {\n  // http://geomalgorithms.com/a03-_inclusion.html\n  // Copyright 2000 softSurfer, 2012 Dan Sunday\n  // This code may be freely used and modified for any purpose\n  // providing that this copyright notice is included with it.\n  // SoftSurfer makes no warranty for this code, and cannot be held\n  // liable for any real or imagined damage resulting from its use.\n  // Users of this code must verify correctness for their application.\n  let wn = 0;\n  let x1 = flatCoordinates[end - stride];\n  let y1 = flatCoordinates[end - stride + 1];\n  for (; offset < end; offset += stride) {\n    const x2 = flatCoordinates[offset];\n    const y2 = flatCoordinates[offset + 1];\n    if (y1 <= y) {\n      if (y2 > y && ((x2 - x1) * (y - y1)) - ((x - x1) * (y2 - y1)) > 0) {\n        wn++;\n      }\n    } else if (y2 <= y && ((x2 - x1) * (y - y1)) - ((x - x1) * (y2 - y1)) < 0) {\n      wn--;\n    }\n    x1 = x2;\n    y1 = y2;\n  }\n  return wn !== 0;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\nexport function linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y) {\n  if (ends.length === 0) {\n    return false;\n  }\n  if (!linearRingContainsXY(flatCoordinates, offset, ends[0], stride, x, y)) {\n    return false;\n  }\n  for (let i = 1, ii = ends.length; i < ii; ++i) {\n    if (linearRingContainsXY(flatCoordinates, ends[i - 1], ends[i], stride, x, y)) {\n      return false;\n    }\n  }\n  return true;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<Array.<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\nexport function linearRingssContainsXY(flatCoordinates, offset, endss, stride, x, y) {\n  if (endss.length === 0) {\n    return false;\n  }\n  for (let i = 0, ii = endss.length; i < ii; ++i) {\n    const ends = endss[i];\n    if (linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y)) {\n      return true;\n    }\n    offset = ends[ends.length - 1];\n  }\n  return false;\n}\n","/**\n * @module ol/geom/flat/interiorpoint\n */\nimport {numberSafeCompareFunction} from '../../array.js';\nimport {linearRingsContainsXY} from '../flat/contains.js';\n\n\n/**\n * Calculates a point that is likely to lie in the interior of the linear rings.\n * Inspired by JTS's com.vividsolutions.jts.geom.Geometry#getInteriorPoint.\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {Array.<number>} flatCenters Flat centers.\n * @param {number} flatCentersOffset Flat center offset.\n * @param {Array.<number>=} opt_dest Destination.\n * @return {Array.<number>} Destination point as XYM coordinate, where M is the\n * length of the horizontal intersection that the point belongs to.\n */\nexport function getInteriorPointOfArray(flatCoordinates, offset,\n  ends, stride, flatCenters, flatCentersOffset, opt_dest) {\n  let i, ii, x, x1, x2, y1, y2;\n  const y = flatCenters[flatCentersOffset + 1];\n  /** @type {Array.<number>} */\n  const intersections = [];\n  // Calculate intersections with the horizontal line\n  for (let r = 0, rr = ends.length; r < rr; ++r) {\n    const end = ends[r];\n    x1 = flatCoordinates[end - stride];\n    y1 = flatCoordinates[end - stride + 1];\n    for (i = offset; i < end; i += stride) {\n      x2 = flatCoordinates[i];\n      y2 = flatCoordinates[i + 1];\n      if ((y <= y1 && y2 <= y) || (y1 <= y && y <= y2)) {\n        x = (y - y1) / (y2 - y1) * (x2 - x1) + x1;\n        intersections.push(x);\n      }\n      x1 = x2;\n      y1 = y2;\n    }\n  }\n  // Find the longest segment of the horizontal line that has its center point\n  // inside the linear ring.\n  let pointX = NaN;\n  let maxSegmentLength = -Infinity;\n  intersections.sort(numberSafeCompareFunction);\n  x1 = intersections[0];\n  for (i = 1, ii = intersections.length; i < ii; ++i) {\n    x2 = intersections[i];\n    const segmentLength = Math.abs(x2 - x1);\n    if (segmentLength > maxSegmentLength) {\n      x = (x1 + x2) / 2;\n      if (linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y)) {\n        pointX = x;\n        maxSegmentLength = segmentLength;\n      }\n    }\n    x1 = x2;\n  }\n  if (isNaN(pointX)) {\n    // There is no horizontal line that has its center point inside the linear\n    // ring.  Use the center of the the linear ring's extent.\n    pointX = flatCenters[flatCentersOffset];\n  }\n  if (opt_dest) {\n    opt_dest.push(pointX, y, maxSegmentLength);\n    return opt_dest;\n  } else {\n    return [pointX, y, maxSegmentLength];\n  }\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<Array.<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {Array.<number>} flatCenters Flat centers.\n * @return {Array.<number>} Interior points as XYM coordinates, where M is the\n * length of the horizontal intersection that the point belongs to.\n */\nexport function getInteriorPointsOfMultiArray(flatCoordinates, offset, endss, stride, flatCenters) {\n  let interiorPoints = [];\n  for (let i = 0, ii = endss.length; i < ii; ++i) {\n    const ends = endss[i];\n    interiorPoints = getInteriorPointOfArray(flatCoordinates,\n      offset, ends, stride, flatCenters, 2 * i, interiorPoints);\n    offset = ends[ends.length - 1];\n  }\n  return interiorPoints;\n}\n","/**\n * @module ol/geom/flat/segments\n */\n\n\n/**\n * This function calls `callback` for each segment of the flat coordinates\n * array. If the callback returns a truthy value the function returns that\n * value immediately. Otherwise the function returns `false`.\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {function(this: S, module:ol/coordinate~Coordinate, module:ol/coordinate~Coordinate): T} callback Function\n *     called for each segment.\n * @param {S=} opt_this The object to be used as the value of 'this'\n *     within callback.\n * @return {T|boolean} Value.\n * @template T,S\n */\nexport function forEach(flatCoordinates, offset, end, stride, callback, opt_this) {\n  const point1 = [flatCoordinates[offset], flatCoordinates[offset + 1]];\n  const point2 = [];\n  let ret;\n  for (; (offset + stride) < end; offset += stride) {\n    point2[0] = flatCoordinates[offset + stride];\n    point2[1] = flatCoordinates[offset + stride + 1];\n    ret = callback.call(opt_this, point1, point2);\n    if (ret) {\n      return ret;\n    }\n    point1[0] = point2[0];\n    point1[1] = point2[1];\n  }\n  return false;\n}\n","/**\n * @module ol/geom/flat/intersectsextent\n */\nimport {containsExtent, createEmpty, extendFlatCoordinates, intersects, intersectsSegment} from '../../extent.js';\nimport {linearRingContainsXY, linearRingContainsExtent} from '../flat/contains.js';\nimport {forEach as forEachSegment} from '../flat/segments.js';\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {module:ol/extent~Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\nexport function intersectsLineString(flatCoordinates, offset, end, stride, extent) {\n  const coordinatesExtent = extendFlatCoordinates(\n    createEmpty(), flatCoordinates, offset, end, stride);\n  if (!intersects(extent, coordinatesExtent)) {\n    return false;\n  }\n  if (containsExtent(extent, coordinatesExtent)) {\n    return true;\n  }\n  if (coordinatesExtent[0] >= extent[0] &&\n      coordinatesExtent[2] <= extent[2]) {\n    return true;\n  }\n  if (coordinatesExtent[1] >= extent[1] &&\n      coordinatesExtent[3] <= extent[3]) {\n    return true;\n  }\n  return forEachSegment(flatCoordinates, offset, end, stride,\n    /**\n     * @param {module:ol/coordinate~Coordinate} point1 Start point.\n     * @param {module:ol/coordinate~Coordinate} point2 End point.\n     * @return {boolean} `true` if the segment and the extent intersect,\n     *     `false` otherwise.\n     */\n    function(point1, point2) {\n      return intersectsSegment(extent, point1, point2);\n    });\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {module:ol/extent~Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\nexport function intersectsLineStringArray(flatCoordinates, offset, ends, stride, extent) {\n  for (let i = 0, ii = ends.length; i < ii; ++i) {\n    if (intersectsLineString(\n      flatCoordinates, offset, ends[i], stride, extent)) {\n      return true;\n    }\n    offset = ends[i];\n  }\n  return false;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {module:ol/extent~Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\nexport function intersectsLinearRing(flatCoordinates, offset, end, stride, extent) {\n  if (intersectsLineString(\n    flatCoordinates, offset, end, stride, extent)) {\n    return true;\n  }\n  if (linearRingContainsXY(flatCoordinates, offset, end, stride, extent[0], extent[1])) {\n    return true;\n  }\n  if (linearRingContainsXY(flatCoordinates, offset, end, stride, extent[0], extent[3])) {\n    return true;\n  }\n  if (linearRingContainsXY(flatCoordinates, offset, end, stride, extent[2], extent[1])) {\n    return true;\n  }\n  if (linearRingContainsXY(flatCoordinates, offset, end, stride, extent[2], extent[3])) {\n    return true;\n  }\n  return false;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {module:ol/extent~Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\nexport function intersectsLinearRingArray(flatCoordinates, offset, ends, stride, extent) {\n  if (!intersectsLinearRing(\n    flatCoordinates, offset, ends[0], stride, extent)) {\n    return false;\n  }\n  if (ends.length === 1) {\n    return true;\n  }\n  for (let i = 1, ii = ends.length; i < ii; ++i) {\n    if (linearRingContainsExtent(flatCoordinates, ends[i - 1], ends[i], stride, extent)) {\n      return false;\n    }\n  }\n  return true;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<Array.<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {module:ol/extent~Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\nexport function intersectsLinearRingMultiArray(flatCoordinates, offset, endss, stride, extent) {\n  for (let i = 0, ii = endss.length; i < ii; ++i) {\n    const ends = endss[i];\n    if (intersectsLinearRingArray(\n      flatCoordinates, offset, ends, stride, extent)) {\n      return true;\n    }\n    offset = ends[ends.length - 1];\n  }\n  return false;\n}\n","/**\n * @module ol/geom/flat/reverse\n */\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n */\nexport function coordinates(flatCoordinates, offset, end, stride) {\n  while (offset < end - stride) {\n    for (let i = 0; i < stride; ++i) {\n      const tmp = flatCoordinates[offset + i];\n      flatCoordinates[offset + i] = flatCoordinates[end - stride + i];\n      flatCoordinates[end - stride + i] = tmp;\n    }\n    offset += stride;\n    end -= stride;\n  }\n}\n","/**\n * @module ol/geom/flat/orient\n */\nimport {coordinates as reverseCoordinates} from '../flat/reverse.js';\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {boolean} Is clockwise.\n */\nexport function linearRingIsClockwise(flatCoordinates, offset, end, stride) {\n  // http://tinyurl.com/clockwise-method\n  // https://github.com/OSGeo/gdal/blob/trunk/gdal/ogr/ogrlinearring.cpp\n  let edge = 0;\n  let x1 = flatCoordinates[end - stride];\n  let y1 = flatCoordinates[end - stride + 1];\n  for (; offset < end; offset += stride) {\n    const x2 = flatCoordinates[offset];\n    const y2 = flatCoordinates[offset + 1];\n    edge += (x2 - x1) * (y2 + y1);\n    x1 = x2;\n    y1 = y2;\n  }\n  return edge > 0;\n}\n\n\n/**\n * Determines if linear rings are oriented.  By default, left-hand orientation\n * is tested (first ring must be clockwise, remaining rings counter-clockwise).\n * To test for right-hand orientation, use the `opt_right` argument.\n *\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<number>} ends Array of end indexes.\n * @param {number} stride Stride.\n * @param {boolean=} opt_right Test for right-hand orientation\n *     (counter-clockwise exterior ring and clockwise interior rings).\n * @return {boolean} Rings are correctly oriented.\n */\nexport function linearRingIsOriented(flatCoordinates, offset, ends, stride, opt_right) {\n  const right = opt_right !== undefined ? opt_right : false;\n  for (let i = 0, ii = ends.length; i < ii; ++i) {\n    const end = ends[i];\n    const isClockwise = linearRingIsClockwise(\n      flatCoordinates, offset, end, stride);\n    if (i === 0) {\n      if ((right && isClockwise) || (!right && !isClockwise)) {\n        return false;\n      }\n    } else {\n      if ((right && !isClockwise) || (!right && isClockwise)) {\n        return false;\n      }\n    }\n    offset = end;\n  }\n  return true;\n}\n\n\n/**\n * Determines if linear rings are oriented.  By default, left-hand orientation\n * is tested (first ring must be clockwise, remaining rings counter-clockwise).\n * To test for right-hand orientation, use the `opt_right` argument.\n *\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<Array.<number>>} endss Array of array of end indexes.\n * @param {number} stride Stride.\n * @param {boolean=} opt_right Test for right-hand orientation\n *     (counter-clockwise exterior ring and clockwise interior rings).\n * @return {boolean} Rings are correctly oriented.\n */\nexport function linearRingsAreOriented(flatCoordinates, offset, endss, stride, opt_right) {\n  for (let i = 0, ii = endss.length; i < ii; ++i) {\n    if (!linearRingIsOriented(\n      flatCoordinates, offset, endss[i], stride, opt_right)) {\n      return false;\n    }\n  }\n  return true;\n}\n\n\n/**\n * Orient coordinates in a flat array of linear rings.  By default, rings\n * are oriented following the left-hand rule (clockwise for exterior and\n * counter-clockwise for interior rings).  To orient according to the\n * right-hand rule, use the `opt_right` argument.\n *\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {boolean=} opt_right Follow the right-hand rule for orientation.\n * @return {number} End.\n */\nexport function orientLinearRings(flatCoordinates, offset, ends, stride, opt_right) {\n  const right = opt_right !== undefined ? opt_right : false;\n  for (let i = 0, ii = ends.length; i < ii; ++i) {\n    const end = ends[i];\n    const isClockwise = linearRingIsClockwise(\n      flatCoordinates, offset, end, stride);\n    const reverse = i === 0 ?\n      (right && isClockwise) || (!right && !isClockwise) :\n      (right && !isClockwise) || (!right && isClockwise);\n    if (reverse) {\n      reverseCoordinates(flatCoordinates, offset, end, stride);\n    }\n    offset = end;\n  }\n  return offset;\n}\n\n\n/**\n * Orient coordinates in a flat array of linear rings.  By default, rings\n * are oriented following the left-hand rule (clockwise for exterior and\n * counter-clockwise for interior rings).  To orient according to the\n * right-hand rule, use the `opt_right` argument.\n *\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<Array.<number>>} endss Array of array of end indexes.\n * @param {number} stride Stride.\n * @param {boolean=} opt_right Follow the right-hand rule for orientation.\n * @return {number} End.\n */\nexport function orientLinearRingsArray(flatCoordinates, offset, endss, stride, opt_right) {\n  for (let i = 0, ii = endss.length; i < ii; ++i) {\n    offset = orientLinearRings(\n      flatCoordinates, offset, endss[i], stride, opt_right);\n  }\n  return offset;\n}\n","/**\n * @module ol/geom/Polygon\n */\nimport {extend} from '../array.js';\nimport {closestSquaredDistanceXY, getCenter} from '../extent.js';\nimport GeometryLayout from '../geom/GeometryLayout.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport LinearRing from '../geom/LinearRing.js';\nimport Point from '../geom/Point.js';\nimport SimpleGeometry from '../geom/SimpleGeometry.js';\nimport {offset as sphereOffset} from '../sphere.js';\nimport {linearRings as linearRingsArea} from '../geom/flat/area.js';\nimport {assignClosestArrayPoint, arrayMaxSquaredDelta} from '../geom/flat/closest.js';\nimport {linearRingsContainsXY} from '../geom/flat/contains.js';\nimport {deflateCoordinatesArray} from '../geom/flat/deflate.js';\nimport {inflateCoordinatesArray} from '../geom/flat/inflate.js';\nimport {getInteriorPointOfArray} from '../geom/flat/interiorpoint.js';\nimport {intersectsLinearRingArray} from '../geom/flat/intersectsextent.js';\nimport {linearRingIsOriented, orientLinearRings} from '../geom/flat/orient.js';\nimport {quantizeArray} from '../geom/flat/simplify.js';\nimport {modulo} from '../math.js';\n\n/**\n * @classdesc\n * Polygon geometry.\n *\n * @api\n */\nclass Polygon extends SimpleGeometry {\n\n  /**\n   * @param {!Array.<Array.<module:ol/coordinate~Coordinate>>|!Array.<number>} coordinates\n   *     Array of linear rings that define the polygon. The first linear ring of the\n   *     array defines the outer-boundary or surface of the polygon. Each subsequent\n   *     linear ring defines a hole in the surface of the polygon. A linear ring is\n   *     an array of vertices' coordinates where the first coordinate and the last are\n   *     equivalent. (For internal use, flat coordinates in combination with\n   *     `opt_layout` and `opt_ends` are also accepted.)\n   * @param {module:ol/geom/GeometryLayout=} opt_layout Layout.\n   * @param {Array.<number>=} opt_ends Ends (for internal use with flat coordinates).\n   */\n  constructor(coordinates, opt_layout, opt_ends) {\n\n    super();\n\n    /**\n     * @type {Array.<number>}\n     * @private\n     */\n    this.ends_ = [];\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.flatInteriorPointRevision_ = -1;\n\n    /**\n     * @private\n     * @type {module:ol/coordinate~Coordinate}\n     */\n    this.flatInteriorPoint_ = null;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.maxDelta_ = -1;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.maxDeltaRevision_ = -1;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.orientedRevision_ = -1;\n\n    /**\n     * @private\n     * @type {Array.<number>}\n     */\n    this.orientedFlatCoordinates_ = null;\n\n    if (opt_layout !== undefined && opt_ends) {\n      this.setFlatCoordinates(opt_layout, coordinates);\n      this.ends_ = opt_ends;\n    } else {\n      this.setCoordinates(coordinates, opt_layout);\n    }\n\n  }\n\n  /**\n   * Append the passed linear ring to this polygon.\n   * @param {module:ol/geom/LinearRing} linearRing Linear ring.\n   * @api\n   */\n  appendLinearRing(linearRing) {\n    if (!this.flatCoordinates) {\n      this.flatCoordinates = linearRing.getFlatCoordinates().slice();\n    } else {\n      extend(this.flatCoordinates, linearRing.getFlatCoordinates());\n    }\n    this.ends_.push(this.flatCoordinates.length);\n    this.changed();\n  }\n\n  /**\n   * Make a complete copy of the geometry.\n   * @return {!module:ol/geom/Polygon} Clone.\n   * @override\n   * @api\n   */\n  clone() {\n    return new Polygon(this.flatCoordinates.slice(), this.layout, this.ends_.slice());\n  }\n\n  /**\n   * @inheritDoc\n   */\n  closestPointXY(x, y, closestPoint, minSquaredDistance) {\n    if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n      return minSquaredDistance;\n    }\n    if (this.maxDeltaRevision_ != this.getRevision()) {\n      this.maxDelta_ = Math.sqrt(arrayMaxSquaredDelta(\n        this.flatCoordinates, 0, this.ends_, this.stride, 0));\n      this.maxDeltaRevision_ = this.getRevision();\n    }\n    return assignClosestArrayPoint(\n      this.flatCoordinates, 0, this.ends_, this.stride,\n      this.maxDelta_, true, x, y, closestPoint, minSquaredDistance);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  containsXY(x, y) {\n    return linearRingsContainsXY(this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride, x, y);\n  }\n\n  /**\n   * Return the area of the polygon on projected plane.\n   * @return {number} Area (on projected plane).\n   * @api\n   */\n  getArea() {\n    return linearRingsArea(this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride);\n  }\n\n  /**\n   * Get the coordinate array for this geometry.  This array has the structure\n   * of a GeoJSON coordinate array for polygons.\n   *\n   * @param {boolean=} opt_right Orient coordinates according to the right-hand\n   *     rule (counter-clockwise for exterior and clockwise for interior rings).\n   *     If `false`, coordinates will be oriented according to the left-hand rule\n   *     (clockwise for exterior and counter-clockwise for interior rings).\n   *     By default, coordinate orientation will depend on how the geometry was\n   *     constructed.\n   * @return {Array.<Array.<module:ol/coordinate~Coordinate>>} Coordinates.\n   * @override\n   * @api\n   */\n  getCoordinates(opt_right) {\n    let flatCoordinates;\n    if (opt_right !== undefined) {\n      flatCoordinates = this.getOrientedFlatCoordinates().slice();\n      orientLinearRings(\n        flatCoordinates, 0, this.ends_, this.stride, opt_right);\n    } else {\n      flatCoordinates = this.flatCoordinates;\n    }\n\n    return inflateCoordinatesArray(\n      flatCoordinates, 0, this.ends_, this.stride);\n  }\n\n  /**\n   * @return {Array.<number>} Ends.\n   */\n  getEnds() {\n    return this.ends_;\n  }\n\n  /**\n   * @return {Array.<number>} Interior point.\n   */\n  getFlatInteriorPoint() {\n    if (this.flatInteriorPointRevision_ != this.getRevision()) {\n      const flatCenter = getCenter(this.getExtent());\n      this.flatInteriorPoint_ = getInteriorPointOfArray(\n        this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride,\n        flatCenter, 0);\n      this.flatInteriorPointRevision_ = this.getRevision();\n    }\n    return this.flatInteriorPoint_;\n  }\n\n  /**\n   * Return an interior point of the polygon.\n   * @return {module:ol/geom/Point} Interior point as XYM coordinate, where M is the\n   * length of the horizontal intersection that the point belongs to.\n   * @api\n   */\n  getInteriorPoint() {\n    return new Point(this.getFlatInteriorPoint(), GeometryLayout.XYM);\n  }\n\n  /**\n   * Return the number of rings of the polygon,  this includes the exterior\n   * ring and any interior rings.\n   *\n   * @return {number} Number of rings.\n   * @api\n   */\n  getLinearRingCount() {\n    return this.ends_.length;\n  }\n\n  /**\n   * Return the Nth linear ring of the polygon geometry. Return `null` if the\n   * given index is out of range.\n   * The exterior linear ring is available at index `0` and the interior rings\n   * at index `1` and beyond.\n   *\n   * @param {number} index Index.\n   * @return {module:ol/geom/LinearRing} Linear ring.\n   * @api\n   */\n  getLinearRing(index) {\n    if (index < 0 || this.ends_.length <= index) {\n      return null;\n    }\n    return new LinearRing(this.flatCoordinates.slice(\n      index === 0 ? 0 : this.ends_[index - 1], this.ends_[index]), this.layout);\n  }\n\n  /**\n   * Return the linear rings of the polygon.\n   * @return {Array.<module:ol/geom/LinearRing>} Linear rings.\n   * @api\n   */\n  getLinearRings() {\n    const layout = this.layout;\n    const flatCoordinates = this.flatCoordinates;\n    const ends = this.ends_;\n    const linearRings = [];\n    let offset = 0;\n    for (let i = 0, ii = ends.length; i < ii; ++i) {\n      const end = ends[i];\n      const linearRing = new LinearRing(flatCoordinates.slice(offset, end), layout);\n      linearRings.push(linearRing);\n      offset = end;\n    }\n    return linearRings;\n  }\n\n  /**\n   * @return {Array.<number>} Oriented flat coordinates.\n   */\n  getOrientedFlatCoordinates() {\n    if (this.orientedRevision_ != this.getRevision()) {\n      const flatCoordinates = this.flatCoordinates;\n      if (linearRingIsOriented(\n        flatCoordinates, 0, this.ends_, this.stride)) {\n        this.orientedFlatCoordinates_ = flatCoordinates;\n      } else {\n        this.orientedFlatCoordinates_ = flatCoordinates.slice();\n        this.orientedFlatCoordinates_.length =\n            orientLinearRings(\n              this.orientedFlatCoordinates_, 0, this.ends_, this.stride);\n      }\n      this.orientedRevision_ = this.getRevision();\n    }\n    return this.orientedFlatCoordinates_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getSimplifiedGeometryInternal(squaredTolerance) {\n    const simplifiedFlatCoordinates = [];\n    const simplifiedEnds = [];\n    simplifiedFlatCoordinates.length = quantizeArray(\n      this.flatCoordinates, 0, this.ends_, this.stride,\n      Math.sqrt(squaredTolerance),\n      simplifiedFlatCoordinates, 0, simplifiedEnds);\n    return new Polygon(simplifiedFlatCoordinates, GeometryLayout.XY, simplifiedEnds);\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  getType() {\n    return GeometryType.POLYGON;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  intersectsExtent(extent) {\n    return intersectsLinearRingArray(\n      this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride, extent);\n  }\n\n  /**\n   * Set the coordinates of the polygon.\n   * @param {!Array.<Array.<module:ol/coordinate~Coordinate>>} coordinates Coordinates.\n   * @param {module:ol/geom/GeometryLayout=} opt_layout Layout.\n   * @override\n   * @api\n   */\n  setCoordinates(coordinates, opt_layout) {\n    this.setLayout(opt_layout, coordinates, 2);\n    if (!this.flatCoordinates) {\n      this.flatCoordinates = [];\n    }\n    const ends = deflateCoordinatesArray(\n      this.flatCoordinates, 0, coordinates, this.stride, this.ends_);\n    this.flatCoordinates.length = ends.length === 0 ? 0 : ends[ends.length - 1];\n    this.changed();\n  }\n}\n\n\nexport default Polygon;\n\n\n/**\n * Create an approximation of a circle on the surface of a sphere.\n * @param {module:ol/coordinate~Coordinate} center Center (`[lon, lat]` in degrees).\n * @param {number} radius The great-circle distance from the center to\n *     the polygon vertices.\n * @param {number=} opt_n Optional number of vertices for the resulting\n *     polygon. Default is `32`.\n * @param {number=} opt_sphereRadius Optional radius for the sphere (defaults to\n *     the Earth's mean radius using the WGS84 ellipsoid).\n * @return {module:ol/geom/Polygon} The \"circular\" polygon.\n * @api\n */\nexport function circular(center, radius, opt_n, opt_sphereRadius) {\n  const n = opt_n ? opt_n : 32;\n  /** @type {Array.<number>} */\n  const flatCoordinates = [];\n  for (let i = 0; i < n; ++i) {\n    extend(flatCoordinates, sphereOffset(center, radius, 2 * Math.PI * i / n, opt_sphereRadius));\n  }\n  flatCoordinates.push(flatCoordinates[0], flatCoordinates[1]);\n  return new Polygon(flatCoordinates, GeometryLayout.XY, [flatCoordinates.length]);\n}\n\n\n/**\n * Create a polygon from an extent. The layout used is `XY`.\n * @param {module:ol/extent~Extent} extent The extent.\n * @return {module:ol/geom/Polygon} The polygon.\n * @api\n */\nexport function fromExtent(extent) {\n  const minX = extent[0];\n  const minY = extent[1];\n  const maxX = extent[2];\n  const maxY = extent[3];\n  const flatCoordinates =\n      [minX, minY, minX, maxY, maxX, maxY, maxX, minY, minX, minY];\n  return new Polygon(flatCoordinates, GeometryLayout.XY, [flatCoordinates.length]);\n}\n\n\n/**\n * Create a regular polygon from a circle.\n * @param {module:ol/geom/Circle} circle Circle geometry.\n * @param {number=} opt_sides Number of sides of the polygon. Default is 32.\n * @param {number=} opt_angle Start angle for the first vertex of the polygon in\n *     radians. Default is 0.\n * @return {module:ol/geom/Polygon} Polygon geometry.\n * @api\n */\nexport function fromCircle(circle, opt_sides, opt_angle) {\n  const sides = opt_sides ? opt_sides : 32;\n  const stride = circle.getStride();\n  const layout = circle.getLayout();\n  const center = circle.getCenter();\n  const arrayLength = stride * (sides + 1);\n  const flatCoordinates = new Array(arrayLength);\n  for (let i = 0; i < arrayLength; i += stride) {\n    flatCoordinates[i] = 0;\n    flatCoordinates[i + 1] = 0;\n    for (let j = 2; j < stride; j++) {\n      flatCoordinates[i + j] = center[j];\n    }\n  }\n  const ends = [flatCoordinates.length];\n  const polygon = new Polygon(flatCoordinates, layout, ends);\n  makeRegular(polygon, center, circle.getRadius(), opt_angle);\n  return polygon;\n}\n\n\n/**\n * Modify the coordinates of a polygon to make it a regular polygon.\n * @param {module:ol/geom/Polygon} polygon Polygon geometry.\n * @param {module:ol/coordinate~Coordinate} center Center of the regular polygon.\n * @param {number} radius Radius of the regular polygon.\n * @param {number=} opt_angle Start angle for the first vertex of the polygon in\n *     radians. Default is 0.\n */\nexport function makeRegular(polygon, center, radius, opt_angle) {\n  const flatCoordinates = polygon.getFlatCoordinates();\n  const stride = polygon.getStride();\n  const sides = flatCoordinates.length / stride - 1;\n  const startAngle = opt_angle ? opt_angle : 0;\n  for (let i = 0; i <= sides; ++i) {\n    const offset = i * stride;\n    const angle = startAngle + (modulo(i, sides) * 2 * Math.PI / sides);\n    flatCoordinates[offset] = center[0] + (radius * Math.cos(angle));\n    flatCoordinates[offset + 1] = center[1] + (radius * Math.sin(angle));\n  }\n  polygon.changed();\n}\n","/**\n * @module ol/Geolocation\n */\nimport GeolocationProperty from './GeolocationProperty.js';\nimport BaseObject, {getChangeEventType} from './Object.js';\nimport {listen} from './events.js';\nimport EventType from './events/EventType.js';\nimport {circular as circularPolygon} from './geom/Polygon.js';\nimport {GEOLOCATION} from './has.js';\nimport {toRadians} from './math.js';\nimport {get as getProjection, getTransformFromProjections, identityTransform} from './proj.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {boolean} [tracking=false] Start Tracking right after\n * instantiation.\n * @property {PositionOptions} [trackingOptions] Tracking options.\n * See http://www.w3.org/TR/geolocation-API/#position_options_interface.\n * @property {module:ol/proj~ProjectionLike} [projection] The projection the position\n * is reported in.\n */\n\n\n/**\n * @classdesc\n * Helper class for providing HTML5 Geolocation capabilities.\n * The [Geolocation API](http://www.w3.org/TR/geolocation-API/)\n * is used to locate a user's position.\n *\n * To get notified of position changes, register a listener for the generic\n * `change` event on your instance of {@link module:ol/Geolocation~Geolocation}.\n *\n * Example:\n *\n *     var geolocation = new Geolocation({\n *       // take the projection to use from the map's view\n *       projection: view.getProjection()\n *     });\n *     // listen to changes in position\n *     geolocation.on('change', function(evt) {\n *       window.console.log(geolocation.getPosition());\n *     });\n *\n * @fires error\n * @api\n */\nclass Geolocation extends BaseObject {\n\n  /**\n   * @param {module:ol/Geolocation~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    super();\n\n    const options = opt_options || {};\n\n    /**\n     * The unprojected (EPSG:4326) device position.\n     * @private\n     * @type {module:ol/coordinate~Coordinate}\n     */\n    this.position_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/proj~TransformFunction}\n     */\n    this.transform_ = identityTransform;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.watchId_ = undefined;\n\n    listen(\n      this, getChangeEventType(GeolocationProperty.PROJECTION),\n      this.handleProjectionChanged_, this);\n    listen(\n      this, getChangeEventType(GeolocationProperty.TRACKING),\n      this.handleTrackingChanged_, this);\n\n    if (options.projection !== undefined) {\n      this.setProjection(options.projection);\n    }\n    if (options.trackingOptions !== undefined) {\n      this.setTrackingOptions(options.trackingOptions);\n    }\n\n    this.setTracking(options.tracking !== undefined ? options.tracking : false);\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  disposeInternal() {\n    this.setTracking(false);\n    super.disposeInternal();\n  }\n\n  /**\n   * @private\n   */\n  handleProjectionChanged_() {\n    const projection = this.getProjection();\n    if (projection) {\n      this.transform_ = getTransformFromProjections(\n        getProjection('EPSG:4326'), projection);\n      if (this.position_) {\n        this.set(GeolocationProperty.POSITION, this.transform_(this.position_));\n      }\n    }\n  }\n\n  /**\n   * @private\n   */\n  handleTrackingChanged_() {\n    if (GEOLOCATION) {\n      const tracking = this.getTracking();\n      if (tracking && this.watchId_ === undefined) {\n        this.watchId_ = navigator.geolocation.watchPosition(\n          this.positionChange_.bind(this),\n          this.positionError_.bind(this),\n          this.getTrackingOptions());\n      } else if (!tracking && this.watchId_ !== undefined) {\n        navigator.geolocation.clearWatch(this.watchId_);\n        this.watchId_ = undefined;\n      }\n    }\n  }\n\n  /**\n   * @private\n   * @param {Position} position position event.\n   */\n  positionChange_(position) {\n    const coords = position.coords;\n    this.set(GeolocationProperty.ACCURACY, coords.accuracy);\n    this.set(GeolocationProperty.ALTITUDE,\n      coords.altitude === null ? undefined : coords.altitude);\n    this.set(GeolocationProperty.ALTITUDE_ACCURACY,\n      coords.altitudeAccuracy === null ?\n        undefined : coords.altitudeAccuracy);\n    this.set(GeolocationProperty.HEADING, coords.heading === null ?\n      undefined : toRadians(coords.heading));\n    if (!this.position_) {\n      this.position_ = [coords.longitude, coords.latitude];\n    } else {\n      this.position_[0] = coords.longitude;\n      this.position_[1] = coords.latitude;\n    }\n    const projectedPosition = this.transform_(this.position_);\n    this.set(GeolocationProperty.POSITION, projectedPosition);\n    this.set(GeolocationProperty.SPEED,\n      coords.speed === null ? undefined : coords.speed);\n    const geometry = circularPolygon(this.position_, coords.accuracy);\n    geometry.applyTransform(this.transform_);\n    this.set(GeolocationProperty.ACCURACY_GEOMETRY, geometry);\n    this.changed();\n  }\n\n  /**\n   * Triggered when the Geolocation returns an error.\n   * @event error\n   * @api\n   */\n\n  /**\n   * @private\n   * @param {PositionError} error error object.\n   */\n  positionError_(error) {\n    error.type = EventType.ERROR;\n    this.setTracking(false);\n    this.dispatchEvent(/** @type {{type: string, target: undefined}} */ (error));\n  }\n\n  /**\n   * Get the accuracy of the position in meters.\n   * @return {number|undefined} The accuracy of the position measurement in\n   *     meters.\n   * @observable\n   * @api\n   */\n  getAccuracy() {\n    return /** @type {number|undefined} */ (this.get(GeolocationProperty.ACCURACY));\n  }\n\n  /**\n   * Get a geometry of the position accuracy.\n   * @return {?module:ol/geom/Polygon} A geometry of the position accuracy.\n   * @observable\n   * @api\n   */\n  getAccuracyGeometry() {\n    return (\n      /** @type {?module:ol/geom/Polygon} */ (this.get(GeolocationProperty.ACCURACY_GEOMETRY) || null)\n    );\n  }\n\n  /**\n   * Get the altitude associated with the position.\n   * @return {number|undefined} The altitude of the position in meters above mean\n   *     sea level.\n   * @observable\n   * @api\n   */\n  getAltitude() {\n    return /** @type {number|undefined} */ (this.get(GeolocationProperty.ALTITUDE));\n  }\n\n  /**\n   * Get the altitude accuracy of the position.\n   * @return {number|undefined} The accuracy of the altitude measurement in\n   *     meters.\n   * @observable\n   * @api\n   */\n  getAltitudeAccuracy() {\n    return /** @type {number|undefined} */ (this.get(GeolocationProperty.ALTITUDE_ACCURACY));\n  }\n\n  /**\n   * Get the heading as radians clockwise from North.\n   * Note: depending on the browser, the heading is only defined if the `enableHighAccuracy`\n   * is set to `true` in the tracking options.\n   * @return {number|undefined} The heading of the device in radians from north.\n   * @observable\n   * @api\n   */\n  getHeading() {\n    return /** @type {number|undefined} */ (this.get(GeolocationProperty.HEADING));\n  }\n\n  /**\n   * Get the position of the device.\n   * @return {module:ol/coordinate~Coordinate|undefined} The current position of the device reported\n   *     in the current projection.\n   * @observable\n   * @api\n   */\n  getPosition() {\n    return (\n      /** @type {module:ol/coordinate~Coordinate|undefined} */ (this.get(GeolocationProperty.POSITION))\n    );\n  }\n\n  /**\n   * Get the projection associated with the position.\n   * @return {module:ol/proj/Projection|undefined} The projection the position is\n   *     reported in.\n   * @observable\n   * @api\n   */\n  getProjection() {\n    return (\n      /** @type {module:ol/proj/Projection|undefined} */ (this.get(GeolocationProperty.PROJECTION))\n    );\n  }\n\n  /**\n   * Get the speed in meters per second.\n   * @return {number|undefined} The instantaneous speed of the device in meters\n   *     per second.\n   * @observable\n   * @api\n   */\n  getSpeed() {\n    return /** @type {number|undefined} */ (this.get(GeolocationProperty.SPEED));\n  }\n\n  /**\n   * Determine if the device location is being tracked.\n   * @return {boolean} The device location is being tracked.\n   * @observable\n   * @api\n   */\n  getTracking() {\n    return /** @type {boolean} */ (this.get(GeolocationProperty.TRACKING));\n  }\n\n  /**\n   * Get the tracking options.\n   * See http://www.w3.org/TR/geolocation-API/#position-options.\n   * @return {PositionOptions|undefined} PositionOptions as defined by\n   *     the [HTML5 Geolocation spec\n   *     ](http://www.w3.org/TR/geolocation-API/#position_options_interface).\n   * @observable\n   * @api\n   */\n  getTrackingOptions() {\n    return /** @type {PositionOptions|undefined} */ (this.get(GeolocationProperty.TRACKING_OPTIONS));\n  }\n\n  /**\n   * Set the projection to use for transforming the coordinates.\n   * @param {module:ol/proj~ProjectionLike} projection The projection the position is\n   *     reported in.\n   * @observable\n   * @api\n   */\n  setProjection(projection) {\n    this.set(GeolocationProperty.PROJECTION, getProjection(projection));\n  }\n\n  /**\n   * Enable or disable tracking.\n   * @param {boolean} tracking Enable tracking.\n   * @observable\n   * @api\n   */\n  setTracking(tracking) {\n    this.set(GeolocationProperty.TRACKING, tracking);\n  }\n\n  /**\n   * Set the tracking options.\n   * See http://www.w3.org/TR/geolocation-API/#position-options.\n   * @param {PositionOptions} options PositionOptions as defined by the\n   *     [HTML5 Geolocation spec\n   *     ](http://www.w3.org/TR/geolocation-API/#position_options_interface).\n   * @observable\n   * @api\n   */\n  setTrackingOptions(options) {\n    this.set(GeolocationProperty.TRACKING_OPTIONS, options);\n  }\n}\n\n\nexport default Geolocation;\n","/**\n * @module ol/string\n */\n\n/**\n * @param {number} number Number to be formatted\n * @param {number} width The desired width\n * @param {number=} opt_precision Precision of the output string (i.e. number of decimal places)\n * @returns {string} Formatted string\n */\nexport function padNumber(number, width, opt_precision) {\n  const numberString = opt_precision !== undefined ? number.toFixed(opt_precision) : '' + number;\n  let decimal = numberString.indexOf('.');\n  decimal = decimal === -1 ? numberString.length : decimal;\n  return decimal > width ? numberString : new Array(1 + width - decimal).join('0') + numberString;\n}\n\n\n/**\n * Adapted from https://github.com/omichelsen/compare-versions/blob/master/index.js\n * @param {string|number} v1 First version\n * @param {string|number} v2 Second version\n * @returns {number} Value\n */\nexport function compareVersions(v1, v2) {\n  const s1 = ('' + v1).split('.');\n  const s2 = ('' + v2).split('.');\n\n  for (let i = 0; i < Math.max(s1.length, s2.length); i++) {\n    const n1 = parseInt(s1[i] || '0', 10);\n    const n2 = parseInt(s2[i] || '0', 10);\n\n    if (n1 > n2) {\n      return 1;\n    }\n    if (n2 > n1) {\n      return -1;\n    }\n  }\n\n  return 0;\n}\n","/**\n * @module ol/coordinate\n */\nimport {modulo} from './math.js';\nimport {padNumber} from './string.js';\n\n\n/**\n * An array of numbers representing an xy coordinate. Example: `[16, 48]`.\n * @typedef {Array.<number>} Coordinate\n * @api\n */\n\n\n/**\n * A function that takes a {@link module:ol/coordinate~Coordinate} and\n * transforms it into a `{string}`.\n *\n * @typedef {function((module:ol/coordinate~Coordinate|undefined)): string} CoordinateFormat\n * @api\n */\n\n\n/**\n * Add `delta` to `coordinate`. `coordinate` is modified in place and returned\n * by the function.\n *\n * Example:\n *\n *     import {add} from 'ol/coordinate';\n *\n *     var coord = [7.85, 47.983333];\n *     add(coord, [-2, 4]);\n *     // coord is now [5.85, 51.983333]\n *\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n * @param {module:ol/coordinate~Coordinate} delta Delta.\n * @return {module:ol/coordinate~Coordinate} The input coordinate adjusted by\n * the given delta.\n * @api\n */\nexport function add(coordinate, delta) {\n  coordinate[0] += delta[0];\n  coordinate[1] += delta[1];\n  return coordinate;\n}\n\n\n/**\n * Calculates the point closest to the passed coordinate on the passed circle.\n *\n * @param {module:ol/coordinate~Coordinate} coordinate The coordinate.\n * @param {module:ol/geom/Circle} circle The circle.\n * @return {module:ol/coordinate~Coordinate} Closest point on the circumference.\n */\nexport function closestOnCircle(coordinate, circle) {\n  const r = circle.getRadius();\n  const center = circle.getCenter();\n  const x0 = center[0];\n  const y0 = center[1];\n  const x1 = coordinate[0];\n  const y1 = coordinate[1];\n\n  let dx = x1 - x0;\n  const dy = y1 - y0;\n  if (dx === 0 && dy === 0) {\n    dx = 1;\n  }\n  const d = Math.sqrt(dx * dx + dy * dy);\n\n  const x = x0 + r * dx / d;\n  const y = y0 + r * dy / d;\n\n  return [x, y];\n}\n\n\n/**\n * Calculates the point closest to the passed coordinate on the passed segment.\n * This is the foot of the perpendicular of the coordinate to the segment when\n * the foot is on the segment, or the closest segment coordinate when the foot\n * is outside the segment.\n *\n * @param {module:ol/coordinate~Coordinate} coordinate The coordinate.\n * @param {Array.<module:ol/coordinate~Coordinate>} segment The two coordinates\n * of the segment.\n * @return {module:ol/coordinate~Coordinate} The foot of the perpendicular of\n * the coordinate to the segment.\n */\nexport function closestOnSegment(coordinate, segment) {\n  const x0 = coordinate[0];\n  const y0 = coordinate[1];\n  const start = segment[0];\n  const end = segment[1];\n  const x1 = start[0];\n  const y1 = start[1];\n  const x2 = end[0];\n  const y2 = end[1];\n  const dx = x2 - x1;\n  const dy = y2 - y1;\n  const along = (dx === 0 && dy === 0) ? 0 :\n    ((dx * (x0 - x1)) + (dy * (y0 - y1))) / ((dx * dx + dy * dy) || 0);\n  let x, y;\n  if (along <= 0) {\n    x = x1;\n    y = y1;\n  } else if (along >= 1) {\n    x = x2;\n    y = y2;\n  } else {\n    x = x1 + along * dx;\n    y = y1 + along * dy;\n  }\n  return [x, y];\n}\n\n\n/**\n * Returns a {@link module:ol/coordinate~CoordinateFormat} function that can be\n * used to format\n * a {module:ol/coordinate~Coordinate} to a string.\n *\n * Example without specifying the fractional digits:\n *\n *     import {createStringXY} from 'ol/coordinate';\n *\n *     var coord = [7.85, 47.983333];\n *     var stringifyFunc = createStringXY();\n *     var out = stringifyFunc(coord);\n *     // out is now '8, 48'\n *\n * Example with explicitly specifying 2 fractional digits:\n *\n *     import {createStringXY} from 'ol/coordinate';\n *\n *     var coord = [7.85, 47.983333];\n *     var stringifyFunc = createStringXY(2);\n *     var out = stringifyFunc(coord);\n *     // out is now '7.85, 47.98'\n *\n * @param {number=} opt_fractionDigits The number of digits to include\n *    after the decimal point. Default is `0`.\n * @return {module:ol/coordinate~CoordinateFormat} Coordinate format.\n * @api\n */\nexport function createStringXY(opt_fractionDigits) {\n  return (\n    /**\n     * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n     * @return {string} String XY.\n     */\n    function(coordinate) {\n      return toStringXY(coordinate, opt_fractionDigits);\n    }\n  );\n}\n\n\n/**\n * @param {string} hemispheres Hemispheres.\n * @param {number} degrees Degrees.\n * @param {number=} opt_fractionDigits The number of digits to include\n *    after the decimal point. Default is `0`.\n * @return {string} String.\n */\nexport function degreesToStringHDMS(hemispheres, degrees, opt_fractionDigits) {\n  const normalizedDegrees = modulo(degrees + 180, 360) - 180;\n  const x = Math.abs(3600 * normalizedDegrees);\n  const dflPrecision = opt_fractionDigits || 0;\n  const precision = Math.pow(10, dflPrecision);\n\n  let deg = Math.floor(x / 3600);\n  let min = Math.floor((x - deg * 3600) / 60);\n  let sec = x - (deg * 3600) - (min * 60);\n  sec = Math.ceil(sec * precision) / precision;\n\n  if (sec >= 60) {\n    sec = 0;\n    min += 1;\n  }\n\n  if (min >= 60) {\n    min = 0;\n    deg += 1;\n  }\n\n  return deg + '\\u00b0 ' + padNumber(min, 2) + '\\u2032 ' +\n    padNumber(sec, 2, dflPrecision) + '\\u2033' +\n    (normalizedDegrees == 0 ? '' : ' ' + hemispheres.charAt(normalizedDegrees < 0 ? 1 : 0));\n}\n\n\n/**\n * Transforms the given {@link module:ol/coordinate~Coordinate} to a string\n * using the given string template. The strings `{x}` and `{y}` in the template\n * will be replaced with the first and second coordinate values respectively.\n *\n * Example without specifying the fractional digits:\n *\n *     import {format} from 'ol/coordinate';\n *\n *     var coord = [7.85, 47.983333];\n *     var template = 'Coordinate is ({x}|{y}).';\n *     var out = format(coord, template);\n *     // out is now 'Coordinate is (8|48).'\n *\n * Example explicitly specifying the fractional digits:\n *\n *     import {format} from 'ol/coordinate';\n *\n *     var coord = [7.85, 47.983333];\n *     var template = 'Coordinate is ({x}|{y}).';\n *     var out = format(coord, template, 2);\n *     // out is now 'Coordinate is (7.85|47.98).'\n *\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n * @param {string} template A template string with `{x}` and `{y}` placeholders\n *     that will be replaced by first and second coordinate values.\n * @param {number=} opt_fractionDigits The number of digits to include\n *    after the decimal point. Default is `0`.\n * @return {string} Formatted coordinate.\n * @api\n */\nexport function format(coordinate, template, opt_fractionDigits) {\n  if (coordinate) {\n    return template\n      .replace('{x}', coordinate[0].toFixed(opt_fractionDigits))\n      .replace('{y}', coordinate[1].toFixed(opt_fractionDigits));\n  } else {\n    return '';\n  }\n}\n\n\n/**\n * @param {module:ol/coordinate~Coordinate} coordinate1 First coordinate.\n * @param {module:ol/coordinate~Coordinate} coordinate2 Second coordinate.\n * @return {boolean} The two coordinates are equal.\n */\nexport function equals(coordinate1, coordinate2) {\n  let equals = true;\n  for (let i = coordinate1.length - 1; i >= 0; --i) {\n    if (coordinate1[i] != coordinate2[i]) {\n      equals = false;\n      break;\n    }\n  }\n  return equals;\n}\n\n\n/**\n * Rotate `coordinate` by `angle`. `coordinate` is modified in place and\n * returned by the function.\n *\n * Example:\n *\n *     import {rotate} from 'ol/coordinate';\n *\n *     var coord = [7.85, 47.983333];\n *     var rotateRadians = Math.PI / 2; // 90 degrees\n *     rotate(coord, rotateRadians);\n *     // coord is now [-47.983333, 7.85]\n *\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n * @param {number} angle Angle in radian.\n * @return {module:ol/coordinate~Coordinate} Coordinate.\n * @api\n */\nexport function rotate(coordinate, angle) {\n  const cosAngle = Math.cos(angle);\n  const sinAngle = Math.sin(angle);\n  const x = coordinate[0] * cosAngle - coordinate[1] * sinAngle;\n  const y = coordinate[1] * cosAngle + coordinate[0] * sinAngle;\n  coordinate[0] = x;\n  coordinate[1] = y;\n  return coordinate;\n}\n\n\n/**\n * Scale `coordinate` by `scale`. `coordinate` is modified in place and returned\n * by the function.\n *\n * Example:\n *\n *     import {scale as scaleCoordinate} from 'ol/coordinate';\n *\n *     var coord = [7.85, 47.983333];\n *     var scale = 1.2;\n *     scaleCoordinate(coord, scale);\n *     // coord is now [9.42, 57.5799996]\n *\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n * @param {number} scale Scale factor.\n * @return {module:ol/coordinate~Coordinate} Coordinate.\n */\nexport function scale(coordinate, scale) {\n  coordinate[0] *= scale;\n  coordinate[1] *= scale;\n  return coordinate;\n}\n\n\n/**\n * @param {module:ol/coordinate~Coordinate} coord1 First coordinate.\n * @param {module:ol/coordinate~Coordinate} coord2 Second coordinate.\n * @return {number} Squared distance between coord1 and coord2.\n */\nexport function squaredDistance(coord1, coord2) {\n  const dx = coord1[0] - coord2[0];\n  const dy = coord1[1] - coord2[1];\n  return dx * dx + dy * dy;\n}\n\n\n/**\n * @param {module:ol/coordinate~Coordinate} coord1 First coordinate.\n * @param {module:ol/coordinate~Coordinate} coord2 Second coordinate.\n * @return {number} Distance between coord1 and coord2.\n */\nexport function distance(coord1, coord2) {\n  return Math.sqrt(squaredDistance(coord1, coord2));\n}\n\n\n/**\n * Calculate the squared distance from a coordinate to a line segment.\n *\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate of the point.\n * @param {Array.<module:ol/coordinate~Coordinate>} segment Line segment (2\n * coordinates).\n * @return {number} Squared distance from the point to the line segment.\n */\nexport function squaredDistanceToSegment(coordinate, segment) {\n  return squaredDistance(coordinate,\n    closestOnSegment(coordinate, segment));\n}\n\n\n/**\n * Format a geographic coordinate with the hemisphere, degrees, minutes, and\n * seconds.\n *\n * Example without specifying fractional digits:\n *\n *     import {toStringHDMS} from 'ol/coordinate';\n *\n *     var coord = [7.85, 47.983333];\n *     var out = toStringHDMS(coord);\n *     // out is now '47° 58′ 60″ N 7° 50′ 60″ E'\n *\n * Example explicitly specifying 1 fractional digit:\n *\n *     import {toStringHDMS} from 'ol/coordinate';\n *\n *     var coord = [7.85, 47.983333];\n *     var out = toStringHDMS(coord, 1);\n *     // out is now '47° 58′ 60.0″ N 7° 50′ 60.0″ E'\n *\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n * @param {number=} opt_fractionDigits The number of digits to include\n *    after the decimal point. Default is `0`.\n * @return {string} Hemisphere, degrees, minutes and seconds.\n * @api\n */\nexport function toStringHDMS(coordinate, opt_fractionDigits) {\n  if (coordinate) {\n    return degreesToStringHDMS('NS', coordinate[1], opt_fractionDigits) + ' ' +\n        degreesToStringHDMS('EW', coordinate[0], opt_fractionDigits);\n  } else {\n    return '';\n  }\n}\n\n\n/**\n * Format a coordinate as a comma delimited string.\n *\n * Example without specifying fractional digits:\n *\n *     import {toStringXY} from 'ol/coordinate';\n *\n *     var coord = [7.85, 47.983333];\n *     var out = toStringXY(coord);\n *     // out is now '8, 48'\n *\n * Example explicitly specifying 1 fractional digit:\n *\n *     import {toStringXY} from 'ol/coordinate';\n *\n *     var coord = [7.85, 47.983333];\n *     var out = toStringXY(coord, 1);\n *     // out is now '7.8, 48.0'\n *\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n * @param {number=} opt_fractionDigits The number of digits to include\n *    after the decimal point. Default is `0`.\n * @return {string} XY.\n * @api\n */\nexport function toStringXY(coordinate, opt_fractionDigits) {\n  return format(coordinate, '{x}, {y}', opt_fractionDigits);\n}\n","/**\n * @module ol/geom/flat/interpolate\n */\nimport {binarySearch} from '../../array.js';\nimport {lerp} from '../../math.js';\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} fraction Fraction.\n * @param {Array.<number>=} opt_dest Destination.\n * @return {Array.<number>} Destination.\n */\nexport function interpolatePoint(flatCoordinates, offset, end, stride, fraction, opt_dest) {\n  let pointX = NaN;\n  let pointY = NaN;\n  const n = (end - offset) / stride;\n  if (n === 1) {\n    pointX = flatCoordinates[offset];\n    pointY = flatCoordinates[offset + 1];\n  } else if (n == 2) {\n    pointX = (1 - fraction) * flatCoordinates[offset] +\n        fraction * flatCoordinates[offset + stride];\n    pointY = (1 - fraction) * flatCoordinates[offset + 1] +\n        fraction * flatCoordinates[offset + stride + 1];\n  } else if (n !== 0) {\n    let x1 = flatCoordinates[offset];\n    let y1 = flatCoordinates[offset + 1];\n    let length = 0;\n    const cumulativeLengths = [0];\n    for (let i = offset + stride; i < end; i += stride) {\n      const x2 = flatCoordinates[i];\n      const y2 = flatCoordinates[i + 1];\n      length += Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));\n      cumulativeLengths.push(length);\n      x1 = x2;\n      y1 = y2;\n    }\n    const target = fraction * length;\n    const index = binarySearch(cumulativeLengths, target);\n    if (index < 0) {\n      const t = (target - cumulativeLengths[-index - 2]) /\n          (cumulativeLengths[-index - 1] - cumulativeLengths[-index - 2]);\n      const o = offset + (-index - 2) * stride;\n      pointX = lerp(\n        flatCoordinates[o], flatCoordinates[o + stride], t);\n      pointY = lerp(\n        flatCoordinates[o + 1], flatCoordinates[o + stride + 1], t);\n    } else {\n      pointX = flatCoordinates[offset + index * stride];\n      pointY = flatCoordinates[offset + index * stride + 1];\n    }\n  }\n  if (opt_dest) {\n    opt_dest[0] = pointX;\n    opt_dest[1] = pointY;\n    return opt_dest;\n  } else {\n    return [pointX, pointY];\n  }\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} m M.\n * @param {boolean} extrapolate Extrapolate.\n * @return {module:ol/coordinate~Coordinate} Coordinate.\n */\nexport function lineStringCoordinateAtM(flatCoordinates, offset, end, stride, m, extrapolate) {\n  if (end == offset) {\n    return null;\n  }\n  let coordinate;\n  if (m < flatCoordinates[offset + stride - 1]) {\n    if (extrapolate) {\n      coordinate = flatCoordinates.slice(offset, offset + stride);\n      coordinate[stride - 1] = m;\n      return coordinate;\n    } else {\n      return null;\n    }\n  } else if (flatCoordinates[end - 1] < m) {\n    if (extrapolate) {\n      coordinate = flatCoordinates.slice(end - stride, end);\n      coordinate[stride - 1] = m;\n      return coordinate;\n    } else {\n      return null;\n    }\n  }\n  // FIXME use O(1) search\n  if (m == flatCoordinates[offset + stride - 1]) {\n    return flatCoordinates.slice(offset, offset + stride);\n  }\n  let lo = offset / stride;\n  let hi = end / stride;\n  while (lo < hi) {\n    const mid = (lo + hi) >> 1;\n    if (m < flatCoordinates[(mid + 1) * stride - 1]) {\n      hi = mid;\n    } else {\n      lo = mid + 1;\n    }\n  }\n  const m0 = flatCoordinates[lo * stride - 1];\n  if (m == m0) {\n    return flatCoordinates.slice((lo - 1) * stride, (lo - 1) * stride + stride);\n  }\n  const m1 = flatCoordinates[(lo + 1) * stride - 1];\n  const t = (m - m0) / (m1 - m0);\n  coordinate = [];\n  for (let i = 0; i < stride - 1; ++i) {\n    coordinate.push(lerp(flatCoordinates[(lo - 1) * stride + i],\n      flatCoordinates[lo * stride + i], t));\n  }\n  coordinate.push(m);\n  return coordinate;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} m M.\n * @param {boolean} extrapolate Extrapolate.\n * @param {boolean} interpolate Interpolate.\n * @return {module:ol/coordinate~Coordinate} Coordinate.\n */\nexport function lineStringsCoordinateAtM(\n  flatCoordinates, offset, ends, stride, m, extrapolate, interpolate) {\n  if (interpolate) {\n    return lineStringCoordinateAtM(\n      flatCoordinates, offset, ends[ends.length - 1], stride, m, extrapolate);\n  }\n  let coordinate;\n  if (m < flatCoordinates[stride - 1]) {\n    if (extrapolate) {\n      coordinate = flatCoordinates.slice(0, stride);\n      coordinate[stride - 1] = m;\n      return coordinate;\n    } else {\n      return null;\n    }\n  }\n  if (flatCoordinates[flatCoordinates.length - 1] < m) {\n    if (extrapolate) {\n      coordinate = flatCoordinates.slice(flatCoordinates.length - stride);\n      coordinate[stride - 1] = m;\n      return coordinate;\n    } else {\n      return null;\n    }\n  }\n  for (let i = 0, ii = ends.length; i < ii; ++i) {\n    const end = ends[i];\n    if (offset == end) {\n      continue;\n    }\n    if (m < flatCoordinates[offset + stride - 1]) {\n      return null;\n    } else if (m <= flatCoordinates[end - 1]) {\n      return lineStringCoordinateAtM(\n        flatCoordinates, offset, end, stride, m, false);\n    }\n    offset = end;\n  }\n  return null;\n}\n","/**\n * @module ol/geom/flat/length\n */\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {number} Length.\n */\nexport function lineStringLength(flatCoordinates, offset, end, stride) {\n  let x1 = flatCoordinates[offset];\n  let y1 = flatCoordinates[offset + 1];\n  let length = 0;\n  for (let i = offset + stride; i < end; i += stride) {\n    const x2 = flatCoordinates[i];\n    const y2 = flatCoordinates[i + 1];\n    length += Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));\n    x1 = x2;\n    y1 = y2;\n  }\n  return length;\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {number} Perimeter.\n */\nexport function linearRingLength(flatCoordinates, offset, end, stride) {\n  let perimeter = lineStringLength(flatCoordinates, offset, end, stride);\n  const dx = flatCoordinates[end - stride] - flatCoordinates[offset];\n  const dy = flatCoordinates[end - stride + 1] - flatCoordinates[offset + 1];\n  perimeter += Math.sqrt(dx * dx + dy * dy);\n  return perimeter;\n}\n","/**\n * @module ol/geom/LineString\n */\nimport {extend} from '../array.js';\nimport {closestSquaredDistanceXY} from '../extent.js';\nimport GeometryLayout from '../geom/GeometryLayout.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport SimpleGeometry from '../geom/SimpleGeometry.js';\nimport {assignClosestPoint, maxSquaredDelta} from '../geom/flat/closest.js';\nimport {deflateCoordinates} from '../geom/flat/deflate.js';\nimport {inflateCoordinates} from '../geom/flat/inflate.js';\nimport {interpolatePoint, lineStringCoordinateAtM} from '../geom/flat/interpolate.js';\nimport {intersectsLineString} from '../geom/flat/intersectsextent.js';\nimport {lineStringLength} from '../geom/flat/length.js';\nimport {forEach as forEachSegment} from '../geom/flat/segments.js';\nimport {douglasPeucker} from '../geom/flat/simplify.js';\n\n/**\n * @classdesc\n * Linestring geometry.\n *\n * @api\n */\nclass LineString extends SimpleGeometry {\n\n  /**\n   * @param {Array.<module:ol/coordinate~Coordinate>|Array.<number>} coordinates Coordinates.\n   *     For internal use, flat coordinates in combination with `opt_layout` are also accepted.\n   * @param {module:ol/geom/GeometryLayout=} opt_layout Layout.\n   */\n  constructor(coordinates, opt_layout) {\n\n    super();\n\n    /**\n     * @private\n     * @type {module:ol/coordinate~Coordinate}\n     */\n    this.flatMidpoint_ = null;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.flatMidpointRevision_ = -1;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.maxDelta_ = -1;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.maxDeltaRevision_ = -1;\n\n    if (opt_layout !== undefined && !Array.isArray(coordinates[0])) {\n      this.setFlatCoordinates(opt_layout, coordinates);\n    } else {\n      this.setCoordinates(coordinates, opt_layout);\n    }\n\n  }\n\n  /**\n   * Append the passed coordinate to the coordinates of the linestring.\n   * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n   * @api\n   */\n  appendCoordinate(coordinate) {\n    if (!this.flatCoordinates) {\n      this.flatCoordinates = coordinate.slice();\n    } else {\n      extend(this.flatCoordinates, coordinate);\n    }\n    this.changed();\n  }\n\n  /**\n   * Make a complete copy of the geometry.\n   * @return {!module:ol/geom/LineString} Clone.\n   * @override\n   * @api\n   */\n  clone() {\n    return new LineString(this.flatCoordinates.slice(), this.layout);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  closestPointXY(x, y, closestPoint, minSquaredDistance) {\n    if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n      return minSquaredDistance;\n    }\n    if (this.maxDeltaRevision_ != this.getRevision()) {\n      this.maxDelta_ = Math.sqrt(maxSquaredDelta(\n        this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, 0));\n      this.maxDeltaRevision_ = this.getRevision();\n    }\n    return assignClosestPoint(\n      this.flatCoordinates, 0, this.flatCoordinates.length, this.stride,\n      this.maxDelta_, false, x, y, closestPoint, minSquaredDistance);\n  }\n\n  /**\n   * Iterate over each segment, calling the provided callback.\n   * If the callback returns a truthy value the function returns that\n   * value immediately. Otherwise the function returns `false`.\n   *\n   * @param {function(this: S, module:ol/coordinate~Coordinate, module:ol/coordinate~Coordinate): T} callback Function\n   *     called for each segment.\n   * @return {T|boolean} Value.\n   * @template T,S\n   * @api\n   */\n  forEachSegment(callback) {\n    return forEachSegment(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, callback);\n  }\n\n  /**\n   * Returns the coordinate at `m` using linear interpolation, or `null` if no\n   * such coordinate exists.\n   *\n   * `opt_extrapolate` controls extrapolation beyond the range of Ms in the\n   * MultiLineString. If `opt_extrapolate` is `true` then Ms less than the first\n   * M will return the first coordinate and Ms greater than the last M will\n   * return the last coordinate.\n   *\n   * @param {number} m M.\n   * @param {boolean=} opt_extrapolate Extrapolate. Default is `false`.\n   * @return {module:ol/coordinate~Coordinate} Coordinate.\n   * @api\n   */\n  getCoordinateAtM(m, opt_extrapolate) {\n    if (this.layout != GeometryLayout.XYM &&\n        this.layout != GeometryLayout.XYZM) {\n      return null;\n    }\n    const extrapolate = opt_extrapolate !== undefined ? opt_extrapolate : false;\n    return lineStringCoordinateAtM(this.flatCoordinates, 0,\n      this.flatCoordinates.length, this.stride, m, extrapolate);\n  }\n\n  /**\n   * Return the coordinates of the linestring.\n   * @return {Array.<module:ol/coordinate~Coordinate>} Coordinates.\n   * @override\n   * @api\n   */\n  getCoordinates() {\n    return inflateCoordinates(\n      this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);\n  }\n\n  /**\n   * Return the coordinate at the provided fraction along the linestring.\n   * The `fraction` is a number between 0 and 1, where 0 is the start of the\n   * linestring and 1 is the end.\n   * @param {number} fraction Fraction.\n   * @param {module:ol/coordinate~Coordinate=} opt_dest Optional coordinate whose values will\n   *     be modified. If not provided, a new coordinate will be returned.\n   * @return {module:ol/coordinate~Coordinate} Coordinate of the interpolated point.\n   * @api\n   */\n  getCoordinateAt(fraction, opt_dest) {\n    return interpolatePoint(\n      this.flatCoordinates, 0, this.flatCoordinates.length, this.stride,\n      fraction, opt_dest);\n  }\n\n  /**\n   * Return the length of the linestring on projected plane.\n   * @return {number} Length (on projected plane).\n   * @api\n   */\n  getLength() {\n    return lineStringLength(\n      this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);\n  }\n\n  /**\n   * @return {Array.<number>} Flat midpoint.\n   */\n  getFlatMidpoint() {\n    if (this.flatMidpointRevision_ != this.getRevision()) {\n      this.flatMidpoint_ = this.getCoordinateAt(0.5, this.flatMidpoint_);\n      this.flatMidpointRevision_ = this.getRevision();\n    }\n    return this.flatMidpoint_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getSimplifiedGeometryInternal(squaredTolerance) {\n    const simplifiedFlatCoordinates = [];\n    simplifiedFlatCoordinates.length = douglasPeucker(\n      this.flatCoordinates, 0, this.flatCoordinates.length, this.stride,\n      squaredTolerance, simplifiedFlatCoordinates, 0);\n    return new LineString(simplifiedFlatCoordinates, GeometryLayout.XY);\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  getType() {\n    return GeometryType.LINE_STRING;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  intersectsExtent(extent) {\n    return intersectsLineString(\n      this.flatCoordinates, 0, this.flatCoordinates.length, this.stride,\n      extent);\n  }\n\n  /**\n   * Set the coordinates of the linestring.\n   * @param {!Array.<module:ol/coordinate~Coordinate>} coordinates Coordinates.\n   * @param {module:ol/geom/GeometryLayout=} opt_layout Layout.\n   * @override\n   * @api\n   */\n  setCoordinates(coordinates, opt_layout) {\n    this.setLayout(opt_layout, coordinates, 1);\n    if (!this.flatCoordinates) {\n      this.flatCoordinates = [];\n    }\n    this.flatCoordinates.length = deflateCoordinates(\n      this.flatCoordinates, 0, coordinates, this.stride);\n    this.changed();\n  }\n}\n\n\nexport default LineString;\n","/**\n * @module ol/geom/flat/geodesic\n */\nimport {squaredSegmentDistance, toRadians, toDegrees} from '../../math.js';\nimport {get as getProjection, getTransform} from '../../proj.js';\n\n\n/**\n * @param {function(number): module:ol/coordinate~Coordinate} interpolate Interpolate function.\n * @param {module:ol/proj~TransformFunction} transform Transform from longitude/latitude to\n *     projected coordinates.\n * @param {number} squaredTolerance Squared tolerance.\n * @return {Array.<number>} Flat coordinates.\n */\nfunction line(interpolate, transform, squaredTolerance) {\n  // FIXME reduce garbage generation\n  // FIXME optimize stack operations\n\n  /** @type {Array.<number>} */\n  const flatCoordinates = [];\n\n  let geoA = interpolate(0);\n  let geoB = interpolate(1);\n\n  let a = transform(geoA);\n  let b = transform(geoB);\n\n  /** @type {Array.<module:ol/coordinate~Coordinate>} */\n  const geoStack = [geoB, geoA];\n  /** @type {Array.<module:ol/coordinate~Coordinate>} */\n  const stack = [b, a];\n  /** @type {Array.<number>} */\n  const fractionStack = [1, 0];\n\n  /** @type {!Object.<string, boolean>} */\n  const fractions = {};\n\n  let maxIterations = 1e5;\n  let geoM, m, fracA, fracB, fracM, key;\n\n  while (--maxIterations > 0 && fractionStack.length > 0) {\n    // Pop the a coordinate off the stack\n    fracA = fractionStack.pop();\n    geoA = geoStack.pop();\n    a = stack.pop();\n    // Add the a coordinate if it has not been added yet\n    key = fracA.toString();\n    if (!(key in fractions)) {\n      flatCoordinates.push(a[0], a[1]);\n      fractions[key] = true;\n    }\n    // Pop the b coordinate off the stack\n    fracB = fractionStack.pop();\n    geoB = geoStack.pop();\n    b = stack.pop();\n    // Find the m point between the a and b coordinates\n    fracM = (fracA + fracB) / 2;\n    geoM = interpolate(fracM);\n    m = transform(geoM);\n    if (squaredSegmentDistance(m[0], m[1], a[0], a[1],\n      b[0], b[1]) < squaredTolerance) {\n      // If the m point is sufficiently close to the straight line, then we\n      // discard it.  Just use the b coordinate and move on to the next line\n      // segment.\n      flatCoordinates.push(b[0], b[1]);\n      key = fracB.toString();\n      fractions[key] = true;\n    } else {\n      // Otherwise, we need to subdivide the current line segment.  Split it\n      // into two and push the two line segments onto the stack.\n      fractionStack.push(fracB, fracM, fracM, fracA);\n      stack.push(b, m, m, a);\n      geoStack.push(geoB, geoM, geoM, geoA);\n    }\n  }\n\n  return flatCoordinates;\n}\n\n\n/**\n * Generate a great-circle arcs between two lat/lon points.\n * @param {number} lon1 Longitude 1 in degrees.\n * @param {number} lat1 Latitude 1 in degrees.\n * @param {number} lon2 Longitude 2 in degrees.\n * @param {number} lat2 Latitude 2 in degrees.\n * @param {module:ol/proj/Projection} projection Projection.\n * @param {number} squaredTolerance Squared tolerance.\n * @return {Array.<number>} Flat coordinates.\n */\nexport function greatCircleArc(lon1, lat1, lon2, lat2, projection, squaredTolerance) {\n  const geoProjection = getProjection('EPSG:4326');\n\n  const cosLat1 = Math.cos(toRadians(lat1));\n  const sinLat1 = Math.sin(toRadians(lat1));\n  const cosLat2 = Math.cos(toRadians(lat2));\n  const sinLat2 = Math.sin(toRadians(lat2));\n  const cosDeltaLon = Math.cos(toRadians(lon2 - lon1));\n  const sinDeltaLon = Math.sin(toRadians(lon2 - lon1));\n  const d = sinLat1 * sinLat2 + cosLat1 * cosLat2 * cosDeltaLon;\n\n  return line(\n    /**\n     * @param {number} frac Fraction.\n     * @return {module:ol/coordinate~Coordinate} Coordinate.\n     */\n    function(frac) {\n      if (1 <= d) {\n        return [lon2, lat2];\n      }\n      const D = frac * Math.acos(d);\n      const cosD = Math.cos(D);\n      const sinD = Math.sin(D);\n      const y = sinDeltaLon * cosLat2;\n      const x = cosLat1 * sinLat2 - sinLat1 * cosLat2 * cosDeltaLon;\n      const theta = Math.atan2(y, x);\n      const lat = Math.asin(sinLat1 * cosD + cosLat1 * sinD * Math.cos(theta));\n      const lon = toRadians(lon1) +\n            Math.atan2(Math.sin(theta) * sinD * cosLat1,\n              cosD - sinLat1 * Math.sin(lat));\n      return [toDegrees(lon), toDegrees(lat)];\n    }, getTransform(geoProjection, projection), squaredTolerance);\n}\n\n\n/**\n * Generate a meridian (line at constant longitude).\n * @param {number} lon Longitude.\n * @param {number} lat1 Latitude 1.\n * @param {number} lat2 Latitude 2.\n * @param {module:ol/proj/Projection} projection Projection.\n * @param {number} squaredTolerance Squared tolerance.\n * @return {Array.<number>} Flat coordinates.\n */\nexport function meridian(lon, lat1, lat2, projection, squaredTolerance) {\n  const epsg4326Projection = getProjection('EPSG:4326');\n  return line(\n    /**\n     * @param {number} frac Fraction.\n     * @return {module:ol/coordinate~Coordinate} Coordinate.\n     */\n    function(frac) {\n      return [lon, lat1 + ((lat2 - lat1) * frac)];\n    },\n    getTransform(epsg4326Projection, projection), squaredTolerance);\n}\n\n\n/**\n * Generate a parallel (line at constant latitude).\n * @param {number} lat Latitude.\n * @param {number} lon1 Longitude 1.\n * @param {number} lon2 Longitude 2.\n * @param {module:ol/proj/Projection} projection Projection.\n * @param {number} squaredTolerance Squared tolerance.\n * @return {Array.<number>} Flat coordinates.\n */\nexport function parallel(lat, lon1, lon2, projection, squaredTolerance) {\n  const epsg4326Projection = getProjection('EPSG:4326');\n  return line(\n    /**\n     * @param {number} frac Fraction.\n     * @return {module:ol/coordinate~Coordinate} Coordinate.\n     */\n    function(frac) {\n      return [lon1 + ((lon2 - lon1) * frac), lat];\n    },\n    getTransform(epsg4326Projection, projection), squaredTolerance);\n}\n","/**\n * @module ol/render/EventType\n */\n\n/**\n * @enum {string}\n */\nexport default {\n  /**\n   * @event module:ol/render/Event~RenderEvent#postcompose\n   * @api\n   */\n  POSTCOMPOSE: 'postcompose',\n  /**\n   * @event module:ol/render/Event~RenderEvent#precompose\n   * @api\n   */\n  PRECOMPOSE: 'precompose',\n  /**\n   * @event module:ol/render/Event~RenderEvent#render\n   * @api\n   */\n  RENDER: 'render'\n};\n","/**\n * @module ol/style/TextPlacement\n */\n\n/**\n * Text placement. One of `'point'`, `'line'`. Default is `'point'`. Note that\n * `'line'` requires the underlying geometry to be a {@link module:ol/geom/LineString~LineString},\n * {@link module:ol/geom/Polygon~Polygon}, {@link module:ol/geom/MultiLineString~MultiLineString} or\n * {@link module:ol/geom/MultiPolygon~MultiPolygon}.\n * @enum {string}\n */\nexport default {\n  POINT: 'point',\n  LINE: 'line'\n};\n","/**\n * @module ol/style/Text\n */\nimport Fill from '../style/Fill.js';\nimport TextPlacement from '../style/TextPlacement.js';\n\n\n/**\n * The default fill color to use if no fill was set at construction time; a\n * blackish `#333`.\n *\n * @const {string}\n */\nconst DEFAULT_FILL_COLOR = '#333';\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [font] Font style as CSS 'font' value, see:\n * https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/font. Default is '10px sans-serif'\n * @property {number} [maxAngle] When `placement` is set to `'line'`, allow a maximum angle between adjacent characters.\n * The expected value is in radians, and the default is 45° (`Math.PI / 4`).\n * @property {number} [offsetX=0] Horizontal text offset in pixels. A positive will shift the text right.\n * @property {number} [offsetY=0] Vertical text offset in pixels. A positive will shift the text down.\n * @property {boolean} [overflow=false] For polygon labels or when `placement` is set to `'line'`, allow text to exceed\n * the width of the polygon at the label position or the length of the path that it follows.\n * @property {module:ol/style/TextPlacement|string} [placement] Text placement.\n * @property {number} [scale] Scale.\n * @property {boolean} [rotateWithView=false] Whether to rotate the text with the view.\n * @property {number} [rotation=0] Rotation in radians (positive rotation clockwise).\n * @property {string} [text] Text content.\n * @property {string} [textAlign] Text alignment. Possible values: 'left', 'right', 'center', 'end' or 'start'.\n * Default is 'center' for `placement: 'point'`. For `placement: 'line'`, the default is to let the renderer choose a\n * placement where `maxAngle` is not exceeded.\n * @property {string} [textBaseline='middle'] Text base line. Possible values: 'bottom', 'top', 'middle', 'alphabetic',\n * 'hanging', 'ideographic'.\n * @property {module:ol/style/Fill} [fill] Fill style. If none is provided, we'll use a dark fill-style (#333).\n * @property {module:ol/style/Stroke} [stroke] Stroke style.\n * @property {module:ol/style/Fill} [backgroundFill] Fill style for the text background when `placement` is\n * `'point'`. Default is no fill.\n * @property {module:ol/style/Stroke} [backgroundStroke] Stroke style for the text background  when `placement`\n * is `'point'`. Default is no stroke.\n * @property {Array.<number>} [padding=[0, 0, 0, 0]] Padding in pixels around the text for decluttering and background. The order of\n * values in the array is `[top, right, bottom, left]`.\n */\n\n\n/**\n * @classdesc\n * Set text style for vector features.\n * @api\n */\nclass Text {\n  /**\n   * @param {module:ol/style/Text~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options || {};\n\n    /**\n    * @private\n    * @type {string|undefined}\n    */\n    this.font_ = options.font;\n\n    /**\n    * @private\n    * @type {number|undefined}\n    */\n    this.rotation_ = options.rotation;\n\n    /**\n    * @private\n    * @type {boolean|undefined}\n    */\n    this.rotateWithView_ = options.rotateWithView;\n\n    /**\n    * @private\n    * @type {number|undefined}\n    */\n    this.scale_ = options.scale;\n\n    /**\n    * @private\n    * @type {string|undefined}\n    */\n    this.text_ = options.text;\n\n    /**\n    * @private\n    * @type {string|undefined}\n    */\n    this.textAlign_ = options.textAlign;\n\n    /**\n    * @private\n    * @type {string|undefined}\n    */\n    this.textBaseline_ = options.textBaseline;\n\n    /**\n    * @private\n    * @type {module:ol/style/Fill}\n    */\n    this.fill_ = options.fill !== undefined ? options.fill :\n      new Fill({color: DEFAULT_FILL_COLOR});\n\n    /**\n    * @private\n    * @type {number}\n    */\n    this.maxAngle_ = options.maxAngle !== undefined ? options.maxAngle : Math.PI / 4;\n\n    /**\n    * @private\n    * @type {module:ol/style/TextPlacement|string}\n    */\n    this.placement_ = options.placement !== undefined ? options.placement : TextPlacement.POINT;\n\n    /**\n    * @private\n    * @type {boolean}\n    */\n    this.overflow_ = !!options.overflow;\n\n    /**\n    * @private\n    * @type {module:ol/style/Stroke}\n    */\n    this.stroke_ = options.stroke !== undefined ? options.stroke : null;\n\n    /**\n    * @private\n    * @type {number}\n    */\n    this.offsetX_ = options.offsetX !== undefined ? options.offsetX : 0;\n\n    /**\n    * @private\n    * @type {number}\n    */\n    this.offsetY_ = options.offsetY !== undefined ? options.offsetY : 0;\n\n    /**\n    * @private\n    * @type {module:ol/style/Fill}\n    */\n    this.backgroundFill_ = options.backgroundFill ? options.backgroundFill : null;\n\n    /**\n    * @private\n    * @type {module:ol/style/Stroke}\n    */\n    this.backgroundStroke_ = options.backgroundStroke ? options.backgroundStroke : null;\n\n    /**\n    * @private\n    * @type {Array.<number>}\n    */\n    this.padding_ = options.padding === undefined ? null : options.padding;\n  }\n\n  /**\n  * Clones the style.\n  * @return {module:ol/style/Text} The cloned style.\n  * @api\n  */\n  clone() {\n    return new Text({\n      font: this.getFont(),\n      placement: this.getPlacement(),\n      maxAngle: this.getMaxAngle(),\n      overflow: this.getOverflow(),\n      rotation: this.getRotation(),\n      rotateWithView: this.getRotateWithView(),\n      scale: this.getScale(),\n      text: this.getText(),\n      textAlign: this.getTextAlign(),\n      textBaseline: this.getTextBaseline(),\n      fill: this.getFill() ? this.getFill().clone() : undefined,\n      stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n      offsetX: this.getOffsetX(),\n      offsetY: this.getOffsetY(),\n      backgroundFill: this.getBackgroundFill() ? this.getBackgroundFill().clone() : undefined,\n      backgroundStroke: this.getBackgroundStroke() ? this.getBackgroundStroke().clone() : undefined\n    });\n  }\n\n  /**\n  * Get the `overflow` configuration.\n  * @return {boolean} Let text overflow the length of the path they follow.\n  * @api\n  */\n  getOverflow() {\n    return this.overflow_;\n  }\n\n  /**\n  * Get the font name.\n  * @return {string|undefined} Font.\n  * @api\n  */\n  getFont() {\n    return this.font_;\n  }\n\n  /**\n  * Get the maximum angle between adjacent characters.\n  * @return {number} Angle in radians.\n  * @api\n  */\n  getMaxAngle() {\n    return this.maxAngle_;\n  }\n\n  /**\n  * Get the label placement.\n  * @return {module:ol/style/TextPlacement|string} Text placement.\n  * @api\n  */\n  getPlacement() {\n    return this.placement_;\n  }\n\n  /**\n  * Get the x-offset for the text.\n  * @return {number} Horizontal text offset.\n  * @api\n  */\n  getOffsetX() {\n    return this.offsetX_;\n  }\n\n  /**\n  * Get the y-offset for the text.\n  * @return {number} Vertical text offset.\n  * @api\n  */\n  getOffsetY() {\n    return this.offsetY_;\n  }\n\n  /**\n  * Get the fill style for the text.\n  * @return {module:ol/style/Fill} Fill style.\n  * @api\n  */\n  getFill() {\n    return this.fill_;\n  }\n\n  /**\n  * Determine whether the text rotates with the map.\n  * @return {boolean|undefined} Rotate with map.\n  * @api\n  */\n  getRotateWithView() {\n    return this.rotateWithView_;\n  }\n\n  /**\n  * Get the text rotation.\n  * @return {number|undefined} Rotation.\n  * @api\n  */\n  getRotation() {\n    return this.rotation_;\n  }\n\n  /**\n  * Get the text scale.\n  * @return {number|undefined} Scale.\n  * @api\n  */\n  getScale() {\n    return this.scale_;\n  }\n\n  /**\n  * Get the stroke style for the text.\n  * @return {module:ol/style/Stroke} Stroke style.\n  * @api\n  */\n  getStroke() {\n    return this.stroke_;\n  }\n\n  /**\n  * Get the text to be rendered.\n  * @return {string|undefined} Text.\n  * @api\n  */\n  getText() {\n    return this.text_;\n  }\n\n  /**\n  * Get the text alignment.\n  * @return {string|undefined} Text align.\n  * @api\n  */\n  getTextAlign() {\n    return this.textAlign_;\n  }\n\n  /**\n  * Get the text baseline.\n  * @return {string|undefined} Text baseline.\n  * @api\n  */\n  getTextBaseline() {\n    return this.textBaseline_;\n  }\n\n  /**\n  * Get the background fill style for the text.\n  * @return {module:ol/style/Fill} Fill style.\n  * @api\n  */\n  getBackgroundFill() {\n    return this.backgroundFill_;\n  }\n\n  /**\n  * Get the background stroke style for the text.\n  * @return {module:ol/style/Stroke} Stroke style.\n  * @api\n  */\n  getBackgroundStroke() {\n    return this.backgroundStroke_;\n  }\n\n  /**\n  * Get the padding for the text.\n  * @return {Array.<number>} Padding.\n  * @api\n  */\n  getPadding() {\n    return this.padding_;\n  }\n\n  /**\n  * Set the `overflow` property.\n  *\n  * @param {boolean} overflow Let text overflow the path that it follows.\n  * @api\n  */\n  setOverflow(overflow) {\n    this.overflow_ = overflow;\n  }\n\n  /**\n  * Set the font.\n  *\n  * @param {string|undefined} font Font.\n  * @api\n  */\n  setFont(font) {\n    this.font_ = font;\n  }\n\n  /**\n  * Set the maximum angle between adjacent characters.\n  *\n  * @param {number} maxAngle Angle in radians.\n  * @api\n  */\n  setMaxAngle(maxAngle) {\n    this.maxAngle_ = maxAngle;\n  }\n\n  /**\n  * Set the x offset.\n  *\n  * @param {number} offsetX Horizontal text offset.\n  * @api\n  */\n  setOffsetX(offsetX) {\n    this.offsetX_ = offsetX;\n  }\n\n  /**\n  * Set the y offset.\n  *\n  * @param {number} offsetY Vertical text offset.\n  * @api\n  */\n  setOffsetY(offsetY) {\n    this.offsetY_ = offsetY;\n  }\n\n  /**\n  * Set the text placement.\n  *\n  * @param {module:ol/style/TextPlacement|string} placement Placement.\n  * @api\n  */\n  setPlacement(placement) {\n    this.placement_ = placement;\n  }\n\n  /**\n  * Set the fill.\n  *\n  * @param {module:ol/style/Fill} fill Fill style.\n  * @api\n  */\n  setFill(fill) {\n    this.fill_ = fill;\n  }\n\n  /**\n  * Set the rotation.\n  *\n  * @param {number|undefined} rotation Rotation.\n  * @api\n  */\n  setRotation(rotation) {\n    this.rotation_ = rotation;\n  }\n\n  /**\n  * Set the scale.\n  *\n  * @param {number|undefined} scale Scale.\n  * @api\n  */\n  setScale(scale) {\n    this.scale_ = scale;\n  }\n\n  /**\n  * Set the stroke.\n  *\n  * @param {module:ol/style/Stroke} stroke Stroke style.\n  * @api\n  */\n  setStroke(stroke) {\n    this.stroke_ = stroke;\n  }\n\n  /**\n  * Set the text.\n  *\n  * @param {string|undefined} text Text.\n  * @api\n  */\n  setText(text) {\n    this.text_ = text;\n  }\n\n  /**\n  * Set the text alignment.\n  *\n  * @param {string|undefined} textAlign Text align.\n  * @api\n  */\n  setTextAlign(textAlign) {\n    this.textAlign_ = textAlign;\n  }\n\n  /**\n  * Set the text baseline.\n  *\n  * @param {string|undefined} textBaseline Text baseline.\n  * @api\n  */\n  setTextBaseline(textBaseline) {\n    this.textBaseline_ = textBaseline;\n  }\n\n  /**\n  * Set the background fill.\n  *\n  * @param {module:ol/style/Fill} fill Fill style.\n  * @api\n  */\n  setBackgroundFill(fill) {\n    this.backgroundFill_ = fill;\n  }\n\n  /**\n  * Set the background stroke.\n  *\n  * @param {module:ol/style/Stroke} stroke Stroke style.\n  * @api\n  */\n  setBackgroundStroke(stroke) {\n    this.backgroundStroke_ = stroke;\n  }\n\n  /**\n  * Set the padding (`[top, right, bottom, left]`).\n  *\n  * @param {!Array.<number>} padding Padding.\n  * @api\n  */\n  setPadding(padding) {\n    this.padding_ = padding;\n  }\n}\n\nexport default Text;\n","/**\n * @module ol/Graticule\n */\nimport {degreesToStringHDMS} from './coordinate.js';\nimport {listen, unlistenByKey} from './events.js';\nimport {intersects, getCenter} from './extent.js';\nimport GeometryLayout from './geom/GeometryLayout.js';\nimport LineString from './geom/LineString.js';\nimport Point from './geom/Point.js';\nimport {meridian, parallel} from './geom/flat/geodesic.js';\nimport {clamp} from './math.js';\nimport {get as getProjection, equivalent as equivalentProjection, getTransform, transformExtent} from './proj.js';\nimport RenderEventType from './render/EventType.js';\nimport Fill from './style/Fill.js';\nimport Stroke from './style/Stroke.js';\nimport Text from './style/Text.js';\n\n\n/**\n * @type {module:ol/style/Stroke}\n * @private\n * @const\n */\nconst DEFAULT_STROKE_STYLE = new Stroke({\n  color: 'rgba(0,0,0,0.2)'\n});\n\n/**\n * TODO can be configurable\n * @type {Array.<number>}\n * @private\n */\nconst INTERVALS = [\n  90, 45, 30, 20, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05, 0.01, 0.005, 0.002, 0.001\n];\n\n/**\n * @typedef {Object} GraticuleLabelDataType\n * @property {module:ol/geom/Point} geom\n * @property {string} text\n */\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/PluggableMap} [map] Reference to an\n * {@link module:ol/Map~Map} object.\n * @property {number} [maxLines=100] The maximum number of meridians and\n * parallels from the center of the map. The default value of 100 means that at\n * most 200 meridians and 200 parallels will be displayed. The default value is\n * appropriate for conformal projections like Spherical Mercator. If you\n * increase the value, more lines will be drawn and the drawing performance will\n * decrease.\n * @property {module:ol/style/Stroke} [strokeStyle='rgba(0,0,0,0.2)'] The\n * stroke style to use for drawing the graticule. If not provided, a not fully\n * opaque black will be used.\n * @property {number} [targetSize=100] The target size of the graticule cells,\n * in pixels.\n * @property {boolean} [showLabels=false] Render a label with the respective\n * latitude/longitude for each graticule line.\n * @property {function(number):string} [lonLabelFormatter] Label formatter for\n * longitudes. This function is called with the longitude as argument, and\n * should return a formatted string representing the longitude. By default,\n * labels are formatted as degrees, minutes, seconds and hemisphere.\n * @property {function(number):string} [latLabelFormatter] Label formatter for\n * latitudes. This function is called with the latitude as argument, and\n * should return a formatted string representing the latitude. By default,\n * labels are formatted as degrees, minutes, seconds and hemisphere.\n * @property {number} [lonLabelPosition=0] Longitude label position in fractions\n * (0..1) of view extent. 0 means at the bottom of the viewport, 1 means at the\n * top.\n * @property {number} [latLabelPosition=1] Latitude label position in fractions\n * (0..1) of view extent. 0 means at the left of the viewport, 1 means at the\n * right.\n * @property {module:ol/style/Text} [lonLabelStyle] Longitude label text\n * style. If not provided, the following style will be used:\n * ```js\n * new Text({\n *   font: '12px Calibri,sans-serif',\n *   textBaseline: 'bottom',\n *   fill: new Fill({\n *     color: 'rgba(0,0,0,1)'\n *   }),\n *   stroke: new Stroke({\n *     color: 'rgba(255,255,255,1)',\n *     width: 3\n *   })\n * });\n * ```\n * Note that the default's `textBaseline` configuration will not work well for\n * `lonLabelPosition` configurations that position labels close to the top of\n * the viewport.\n * @property {module:ol/style/Text} [latLabelStyle] Latitude label text style.\n * If not provided, the following style will be used:\n * ```js\n * new Text({\n *   font: '12px Calibri,sans-serif',\n *   textAlign: 'end',\n *   fill: new Fill({\n *     color: 'rgba(0,0,0,1)'\n *   }),\n *   stroke: Stroke({\n *     color: 'rgba(255,255,255,1)',\n *     width: 3\n *   })\n * });\n * ```\n * Note that the default's `textAlign` configuration will not work well for\n * `latLabelPosition` configurations that position labels close to the left of\n * the viewport.\n */\n\n\n/**\n * Render a grid for a coordinate system on a map.\n * @api\n */\nclass Graticule {\n\n  /**\n   * @param {module:ol/Graticule~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n    const options = opt_options || {};\n\n    /**\n     * @type {module:ol/PluggableMap}\n     * @private\n     */\n    this.map_ = null;\n\n    /**\n     * @type {?module:ol/events~EventsKey}\n     * @private\n     */\n    this.postcomposeListenerKey_ = null;\n\n    /**\n     * @type {module:ol/proj/Projection}\n     */\n    this.projection_ = null;\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.maxLat_ = Infinity;\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.maxLon_ = Infinity;\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.minLat_ = -Infinity;\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.minLon_ = -Infinity;\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.maxLatP_ = Infinity;\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.maxLonP_ = Infinity;\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.minLatP_ = -Infinity;\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.minLonP_ = -Infinity;\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.targetSize_ = options.targetSize !== undefined ? options.targetSize : 100;\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.maxLines_ = options.maxLines !== undefined ? options.maxLines : 100;\n\n    /**\n     * @type {Array.<module:ol/geom/LineString>}\n     * @private\n     */\n    this.meridians_ = [];\n\n    /**\n     * @type {Array.<module:ol/geom/LineString>}\n     * @private\n     */\n    this.parallels_ = [];\n\n    /**\n     * @type {module:ol/style/Stroke}\n     * @private\n     */\n    this.strokeStyle_ = options.strokeStyle !== undefined ? options.strokeStyle : DEFAULT_STROKE_STYLE;\n\n    /**\n     * @type {module:ol/proj~TransformFunction|undefined}\n     * @private\n     */\n    this.fromLonLatTransform_ = undefined;\n\n    /**\n     * @type {module:ol/proj~TransformFunction|undefined}\n     * @private\n     */\n    this.toLonLatTransform_ = undefined;\n\n    /**\n     * @type {module:ol/coordinate~Coordinate}\n     * @private\n     */\n    this.projectionCenterLonLat_ = null;\n\n    /**\n     * @type {Array.<module:ol/Graticule~GraticuleLabelDataType>}\n     * @private\n     */\n    this.meridiansLabels_ = null;\n\n    /**\n     * @type {Array.<module:ol/Graticule~GraticuleLabelDataType>}\n     * @private\n     */\n    this.parallelsLabels_ = null;\n\n    if (options.showLabels == true) {\n\n      /**\n       * @type {null|function(number):string}\n       * @private\n       */\n      this.lonLabelFormatter_ = options.lonLabelFormatter == undefined ?\n        degreesToStringHDMS.bind(this, 'EW') : options.lonLabelFormatter;\n\n      /**\n       * @type {function(number):string}\n       * @private\n       */\n      this.latLabelFormatter_ = options.latLabelFormatter == undefined ?\n        degreesToStringHDMS.bind(this, 'NS') : options.latLabelFormatter;\n\n      /**\n       * Longitude label position in fractions (0..1) of view extent. 0 means\n       * bottom, 1 means top.\n       * @type {number}\n       * @private\n       */\n      this.lonLabelPosition_ = options.lonLabelPosition == undefined ? 0 :\n        options.lonLabelPosition;\n\n      /**\n       * Latitude Label position in fractions (0..1) of view extent. 0 means left, 1\n       * means right.\n       * @type {number}\n       * @private\n       */\n      this.latLabelPosition_ = options.latLabelPosition == undefined ? 1 :\n        options.latLabelPosition;\n\n      /**\n       * @type {module:ol/style/Text}\n       * @private\n       */\n      this.lonLabelStyle_ = options.lonLabelStyle !== undefined ? options.lonLabelStyle :\n        new Text({\n          font: '12px Calibri,sans-serif',\n          textBaseline: 'bottom',\n          fill: new Fill({\n            color: 'rgba(0,0,0,1)'\n          }),\n          stroke: new Stroke({\n            color: 'rgba(255,255,255,1)',\n            width: 3\n          })\n        });\n\n      /**\n       * @type {module:ol/style/Text}\n       * @private\n       */\n      this.latLabelStyle_ = options.latLabelStyle !== undefined ? options.latLabelStyle :\n        new Text({\n          font: '12px Calibri,sans-serif',\n          textAlign: 'end',\n          fill: new Fill({\n            color: 'rgba(0,0,0,1)'\n          }),\n          stroke: new Stroke({\n            color: 'rgba(255,255,255,1)',\n            width: 3\n          })\n        });\n\n      this.meridiansLabels_ = [];\n      this.parallelsLabels_ = [];\n    }\n\n    this.setMap(options.map !== undefined ? options.map : null);\n  }\n\n  /**\n   * @param {number} lon Longitude.\n   * @param {number} minLat Minimal latitude.\n   * @param {number} maxLat Maximal latitude.\n   * @param {number} squaredTolerance Squared tolerance.\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {number} index Index.\n   * @return {number} Index.\n   * @private\n   */\n  addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, index) {\n    const lineString = this.getMeridian_(lon, minLat, maxLat, squaredTolerance, index);\n    if (intersects(lineString.getExtent(), extent)) {\n      if (this.meridiansLabels_) {\n        const textPoint = this.getMeridianPoint_(lineString, extent, index);\n        this.meridiansLabels_[index] = {\n          geom: textPoint,\n          text: this.lonLabelFormatter_(lon)\n        };\n      }\n      this.meridians_[index++] = lineString;\n    }\n    return index;\n  }\n\n  /**\n   * @param {module:ol/geom/LineString} lineString Meridian\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {number} index Index.\n   * @return {module:ol/geom/Point} Meridian point.\n   * @private\n   */\n  getMeridianPoint_(lineString, extent, index) {\n    const flatCoordinates = lineString.getFlatCoordinates();\n    const clampedBottom = Math.max(extent[1], flatCoordinates[1]);\n    const clampedTop = Math.min(extent[3], flatCoordinates[flatCoordinates.length - 1]);\n    const lat = clamp(\n      extent[1] + Math.abs(extent[1] - extent[3]) * this.lonLabelPosition_,\n      clampedBottom, clampedTop);\n    const coordinate = [flatCoordinates[0], lat];\n    let point;\n    if (index in this.meridiansLabels_) {\n      point = this.meridiansLabels_[index];\n      point.setCoordinates(coordinate);\n    } else {\n      point = new Point(coordinate);\n    }\n    return point;\n  }\n\n  /**\n   * @param {number} lat Latitude.\n   * @param {number} minLon Minimal longitude.\n   * @param {number} maxLon Maximal longitude.\n   * @param {number} squaredTolerance Squared tolerance.\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {number} index Index.\n   * @return {number} Index.\n   * @private\n   */\n  addParallel_(lat, minLon, maxLon, squaredTolerance, extent, index) {\n    const lineString = this.getParallel_(lat, minLon, maxLon, squaredTolerance, index);\n    if (intersects(lineString.getExtent(), extent)) {\n      if (this.parallelsLabels_) {\n        const textPoint = this.getParallelPoint_(lineString, extent, index);\n        this.parallelsLabels_[index] = {\n          geom: textPoint,\n          text: this.latLabelFormatter_(lat)\n        };\n      }\n      this.parallels_[index++] = lineString;\n    }\n    return index;\n  }\n\n  /**\n   * @param {module:ol/geom/LineString} lineString Parallels.\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {number} index Index.\n   * @return {module:ol/geom/Point} Parallel point.\n   * @private\n   */\n  getParallelPoint_(lineString, extent, index) {\n    const flatCoordinates = lineString.getFlatCoordinates();\n    const clampedLeft = Math.max(extent[0], flatCoordinates[0]);\n    const clampedRight = Math.min(extent[2], flatCoordinates[flatCoordinates.length - 2]);\n    const lon = clamp(\n      extent[0] + Math.abs(extent[0] - extent[2]) * this.latLabelPosition_,\n      clampedLeft, clampedRight);\n    const coordinate = [lon, flatCoordinates[1]];\n    let point;\n    if (index in this.parallelsLabels_) {\n      point = this.parallelsLabels_[index];\n      point.setCoordinates(coordinate);\n    } else {\n      point = new Point(coordinate);\n    }\n    return point;\n  }\n\n  /**\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {module:ol/coordinate~Coordinate} center Center.\n   * @param {number} resolution Resolution.\n   * @param {number} squaredTolerance Squared tolerance.\n   * @private\n   */\n  createGraticule_(extent, center, resolution, squaredTolerance) {\n\n    const interval = this.getInterval_(resolution);\n    if (interval == -1) {\n      this.meridians_.length = this.parallels_.length = 0;\n      if (this.meridiansLabels_) {\n        this.meridiansLabels_.length = 0;\n      }\n      if (this.parallelsLabels_) {\n        this.parallelsLabels_.length = 0;\n      }\n      return;\n    }\n\n    const centerLonLat = this.toLonLatTransform_(center);\n    let centerLon = centerLonLat[0];\n    let centerLat = centerLonLat[1];\n    const maxLines = this.maxLines_;\n    let cnt, idx, lat, lon;\n\n    let validExtent = [\n      Math.max(extent[0], this.minLonP_),\n      Math.max(extent[1], this.minLatP_),\n      Math.min(extent[2], this.maxLonP_),\n      Math.min(extent[3], this.maxLatP_)\n    ];\n\n    validExtent = transformExtent(validExtent, this.projection_, 'EPSG:4326');\n    const maxLat = validExtent[3];\n    const maxLon = validExtent[2];\n    const minLat = validExtent[1];\n    const minLon = validExtent[0];\n\n    // Create meridians\n\n    centerLon = Math.floor(centerLon / interval) * interval;\n    lon = clamp(centerLon, this.minLon_, this.maxLon_);\n\n    idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, 0);\n\n    cnt = 0;\n    while (lon != this.minLon_ && cnt++ < maxLines) {\n      lon = Math.max(lon - interval, this.minLon_);\n      idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, idx);\n    }\n\n    lon = clamp(centerLon, this.minLon_, this.maxLon_);\n\n    cnt = 0;\n    while (lon != this.maxLon_ && cnt++ < maxLines) {\n      lon = Math.min(lon + interval, this.maxLon_);\n      idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, idx);\n    }\n\n    this.meridians_.length = idx;\n    if (this.meridiansLabels_) {\n      this.meridiansLabels_.length = idx;\n    }\n\n    // Create parallels\n\n    centerLat = Math.floor(centerLat / interval) * interval;\n    lat = clamp(centerLat, this.minLat_, this.maxLat_);\n\n    idx = this.addParallel_(lat, minLon, maxLon, squaredTolerance, extent, 0);\n\n    cnt = 0;\n    while (lat != this.minLat_ && cnt++ < maxLines) {\n      lat = Math.max(lat - interval, this.minLat_);\n      idx = this.addParallel_(lat, minLon, maxLon, squaredTolerance, extent, idx);\n    }\n\n    lat = clamp(centerLat, this.minLat_, this.maxLat_);\n\n    cnt = 0;\n    while (lat != this.maxLat_ && cnt++ < maxLines) {\n      lat = Math.min(lat + interval, this.maxLat_);\n      idx = this.addParallel_(lat, minLon, maxLon, squaredTolerance, extent, idx);\n    }\n\n    this.parallels_.length = idx;\n    if (this.parallelsLabels_) {\n      this.parallelsLabels_.length = idx;\n    }\n\n  }\n\n  /**\n   * @param {number} resolution Resolution.\n   * @return {number} The interval in degrees.\n   * @private\n   */\n  getInterval_(resolution) {\n    const centerLon = this.projectionCenterLonLat_[0];\n    const centerLat = this.projectionCenterLonLat_[1];\n    let interval = -1;\n    const target = Math.pow(this.targetSize_ * resolution, 2);\n    /** @type {Array.<number>} **/\n    const p1 = [];\n    /** @type {Array.<number>} **/\n    const p2 = [];\n    for (let i = 0, ii = INTERVALS.length; i < ii; ++i) {\n      const delta = INTERVALS[i] / 2;\n      p1[0] = centerLon - delta;\n      p1[1] = centerLat - delta;\n      p2[0] = centerLon + delta;\n      p2[1] = centerLat + delta;\n      this.fromLonLatTransform_(p1, p1);\n      this.fromLonLatTransform_(p2, p2);\n      const dist = Math.pow(p2[0] - p1[0], 2) + Math.pow(p2[1] - p1[1], 2);\n      if (dist <= target) {\n        break;\n      }\n      interval = INTERVALS[i];\n    }\n    return interval;\n  }\n\n  /**\n   * Get the map associated with this graticule.\n   * @return {module:ol/PluggableMap} The map.\n   * @api\n   */\n  getMap() {\n    return this.map_;\n  }\n\n  /**\n   * @param {number} lon Longitude.\n   * @param {number} minLat Minimal latitude.\n   * @param {number} maxLat Maximal latitude.\n   * @param {number} squaredTolerance Squared tolerance.\n   * @return {module:ol/geom/LineString} The meridian line string.\n   * @param {number} index Index.\n   * @private\n   */\n  getMeridian_(lon, minLat, maxLat, squaredTolerance, index) {\n    const flatCoordinates = meridian(lon, minLat, maxLat, this.projection_, squaredTolerance);\n    let lineString = this.meridians_[index];\n    if (!lineString) {\n      lineString = this.meridians_[index] = new LineString(flatCoordinates, GeometryLayout.XY);\n    } else {\n      lineString.setFlatCoordinates(GeometryLayout.XY, flatCoordinates);\n      lineString.changed();\n    }\n    return lineString;\n  }\n\n  /**\n   * Get the list of meridians.  Meridians are lines of equal longitude.\n   * @return {Array.<module:ol/geom/LineString>} The meridians.\n   * @api\n   */\n  getMeridians() {\n    return this.meridians_;\n  }\n\n  /**\n   * @param {number} lat Latitude.\n   * @param {number} minLon Minimal longitude.\n   * @param {number} maxLon Maximal longitude.\n   * @param {number} squaredTolerance Squared tolerance.\n   * @return {module:ol/geom/LineString} The parallel line string.\n   * @param {number} index Index.\n   * @private\n   */\n  getParallel_(lat, minLon, maxLon, squaredTolerance, index) {\n    const flatCoordinates = parallel(lat, minLon, maxLon, this.projection_, squaredTolerance);\n    let lineString = this.parallels_[index];\n    if (!lineString) {\n      lineString = new LineString(flatCoordinates, GeometryLayout.XY);\n    } else {\n      lineString.setFlatCoordinates(GeometryLayout.XY, flatCoordinates);\n      lineString.changed();\n    }\n    return lineString;\n  }\n\n  /**\n   * Get the list of parallels.  Parallels are lines of equal latitude.\n   * @return {Array.<module:ol/geom/LineString>} The parallels.\n   * @api\n   */\n  getParallels() {\n    return this.parallels_;\n  }\n\n  /**\n   * @param {module:ol/render/Event} e Event.\n   * @private\n   */\n  handlePostCompose_(e) {\n    const vectorContext = e.vectorContext;\n    const frameState = e.frameState;\n    const extent = frameState.extent;\n    const viewState = frameState.viewState;\n    const center = viewState.center;\n    const projection = viewState.projection;\n    const resolution = viewState.resolution;\n    const pixelRatio = frameState.pixelRatio;\n    const squaredTolerance =\n        resolution * resolution / (4 * pixelRatio * pixelRatio);\n\n    const updateProjectionInfo = !this.projection_ ||\n        !equivalentProjection(this.projection_, projection);\n\n    if (updateProjectionInfo) {\n      this.updateProjectionInfo_(projection);\n    }\n\n    this.createGraticule_(extent, center, resolution, squaredTolerance);\n\n    // Draw the lines\n    vectorContext.setFillStrokeStyle(null, this.strokeStyle_);\n    let i, l, line;\n    for (i = 0, l = this.meridians_.length; i < l; ++i) {\n      line = this.meridians_[i];\n      vectorContext.drawGeometry(line);\n    }\n    for (i = 0, l = this.parallels_.length; i < l; ++i) {\n      line = this.parallels_[i];\n      vectorContext.drawGeometry(line);\n    }\n    let labelData;\n    if (this.meridiansLabels_) {\n      for (i = 0, l = this.meridiansLabels_.length; i < l; ++i) {\n        labelData = this.meridiansLabels_[i];\n        this.lonLabelStyle_.setText(labelData.text);\n        vectorContext.setTextStyle(this.lonLabelStyle_);\n        vectorContext.drawGeometry(labelData.geom);\n      }\n    }\n    if (this.parallelsLabels_) {\n      for (i = 0, l = this.parallelsLabels_.length; i < l; ++i) {\n        labelData = this.parallelsLabels_[i];\n        this.latLabelStyle_.setText(labelData.text);\n        vectorContext.setTextStyle(this.latLabelStyle_);\n        vectorContext.drawGeometry(labelData.geom);\n      }\n    }\n  }\n\n  /**\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @private\n   */\n  updateProjectionInfo_(projection) {\n    const epsg4326Projection = getProjection('EPSG:4326');\n\n    const worldExtent = projection.getWorldExtent();\n    const worldExtentP = transformExtent(worldExtent, epsg4326Projection, projection);\n\n    this.maxLat_ = worldExtent[3];\n    this.maxLon_ = worldExtent[2];\n    this.minLat_ = worldExtent[1];\n    this.minLon_ = worldExtent[0];\n\n    this.maxLatP_ = worldExtentP[3];\n    this.maxLonP_ = worldExtentP[2];\n    this.minLatP_ = worldExtentP[1];\n    this.minLonP_ = worldExtentP[0];\n\n    this.fromLonLatTransform_ = getTransform(epsg4326Projection, projection);\n\n    this.toLonLatTransform_ = getTransform(projection, epsg4326Projection);\n\n    this.projectionCenterLonLat_ = this.toLonLatTransform_(getCenter(projection.getExtent()));\n\n    this.projection_ = projection;\n  }\n\n  /**\n   * Set the map for this graticule.  The graticule will be rendered on the\n   * provided map.\n   * @param {module:ol/PluggableMap} map Map.\n   * @api\n   */\n  setMap(map) {\n    if (this.map_) {\n      unlistenByKey(this.postcomposeListenerKey_);\n      this.postcomposeListenerKey_ = null;\n      this.map_.render();\n    }\n    if (map) {\n      this.postcomposeListenerKey_ = listen(map, RenderEventType.POSTCOMPOSE, this.handlePostCompose_, this);\n      map.render();\n    }\n    this.map_ = map;\n  }\n}\n\nexport default Graticule;\n","/**\n * @module ol/ImageBase\n */\nimport EventTarget from './events/EventTarget.js';\nimport EventType from './events/EventType.js';\n\n/**\n * @abstract\n */\nclass ImageBase extends EventTarget {\n\n  /**\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {number|undefined} resolution Resolution.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {module:ol/ImageState} state State.\n   */\n  constructor(extent, resolution, pixelRatio, state) {\n\n    super();\n\n    /**\n     * @protected\n     * @type {module:ol/extent~Extent}\n     */\n    this.extent = extent;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.pixelRatio_ = pixelRatio;\n\n    /**\n     * @protected\n     * @type {number|undefined}\n     */\n    this.resolution = resolution;\n\n    /**\n     * @protected\n     * @type {module:ol/ImageState}\n     */\n    this.state = state;\n\n  }\n\n  /**\n   * @protected\n   */\n  changed() {\n    this.dispatchEvent(EventType.CHANGE);\n  }\n\n  /**\n   * @return {module:ol/extent~Extent} Extent.\n   */\n  getExtent() {\n    return this.extent;\n  }\n\n  /**\n   * @abstract\n   * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.\n   */\n  getImage() {}\n\n  /**\n   * @return {number} PixelRatio.\n   */\n  getPixelRatio() {\n    return this.pixelRatio_;\n  }\n\n  /**\n   * @return {number} Resolution.\n   */\n  getResolution() {\n    return /** @type {number} */ (this.resolution);\n  }\n\n  /**\n   * @return {module:ol/ImageState} State.\n   */\n  getState() {\n    return this.state;\n  }\n\n  /**\n   * Load not yet loaded URI.\n   * @abstract\n   */\n  load() {}\n}\n\n\nexport default ImageBase;\n","/**\n * @module ol/Image\n */\nimport ImageBase from './ImageBase.js';\nimport ImageState from './ImageState.js';\nimport {listenOnce, unlistenByKey} from './events.js';\nimport EventType from './events/EventType.js';\nimport {getHeight} from './extent.js';\n\n\n/**\n * A function that takes an {@link module:ol/Image~Image} for the image and a\n * `{string}` for the src as arguments. It is supposed to make it so the\n * underlying image {@link module:ol/Image~Image#getImage} is assigned the\n * content specified by the src. If not specified, the default is\n *\n *     function(image, src) {\n *       image.getImage().src = src;\n *     }\n *\n * Providing a custom `imageLoadFunction` can be useful to load images with\n * post requests or - in general - through XHR requests, where the src of the\n * image element would be set to a data URI when the content is loaded.\n *\n * @typedef {function(module:ol/Image, string)} LoadFunction\n * @api\n */\n\n\nclass ImageWrapper extends ImageBase {\n\n  /**\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {number|undefined} resolution Resolution.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {string} src Image source URI.\n   * @param {?string} crossOrigin Cross origin.\n   * @param {module:ol/Image~LoadFunction} imageLoadFunction Image load function.\n   */\n  constructor(extent, resolution, pixelRatio, src, crossOrigin, imageLoadFunction) {\n\n    super(extent, resolution, pixelRatio, ImageState.IDLE);\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.src_ = src;\n\n    /**\n     * @private\n     * @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement}\n     */\n    this.image_ = new Image();\n    if (crossOrigin !== null) {\n      this.image_.crossOrigin = crossOrigin;\n    }\n\n    /**\n     * @private\n     * @type {Array.<module:ol/events~EventsKey>}\n     */\n    this.imageListenerKeys_ = null;\n\n    /**\n     * @protected\n     * @type {module:ol/ImageState}\n     */\n    this.state = ImageState.IDLE;\n\n    /**\n     * @private\n     * @type {module:ol/Image~LoadFunction}\n     */\n    this.imageLoadFunction_ = imageLoadFunction;\n\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  getImage() {\n    return this.image_;\n  }\n\n  /**\n   * Tracks loading or read errors.\n   *\n   * @private\n   */\n  handleImageError_() {\n    this.state = ImageState.ERROR;\n    this.unlistenImage_();\n    this.changed();\n  }\n\n  /**\n   * Tracks successful image load.\n   *\n   * @private\n   */\n  handleImageLoad_() {\n    if (this.resolution === undefined) {\n      this.resolution = getHeight(this.extent) / this.image_.height;\n    }\n    this.state = ImageState.LOADED;\n    this.unlistenImage_();\n    this.changed();\n  }\n\n  /**\n   * Load the image or retry if loading previously failed.\n   * Loading is taken care of by the tile queue, and calling this method is\n   * only needed for preloading or for reloading in case of an error.\n   * @override\n   * @api\n   */\n  load() {\n    if (this.state == ImageState.IDLE || this.state == ImageState.ERROR) {\n      this.state = ImageState.LOADING;\n      this.changed();\n      this.imageListenerKeys_ = [\n        listenOnce(this.image_, EventType.ERROR,\n          this.handleImageError_, this),\n        listenOnce(this.image_, EventType.LOAD,\n          this.handleImageLoad_, this)\n      ];\n      this.imageLoadFunction_(this, this.src_);\n    }\n  }\n\n  /**\n   * @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image.\n   */\n  setImage(image) {\n    this.image_ = image;\n  }\n\n  /**\n   * Discards event handlers which listen for load completion or errors.\n   *\n   * @private\n   */\n  unlistenImage_() {\n    this.imageListenerKeys_.forEach(unlistenByKey);\n    this.imageListenerKeys_ = null;\n  }\n}\n\n\nexport default ImageWrapper;\n","/**\n * @module ol/TileState\n */\n\n/**\n * @enum {number}\n */\nexport default {\n  IDLE: 0,\n  LOADING: 1,\n  LOADED: 2,\n  ERROR: 3,\n  EMPTY: 4,\n  ABORT: 5\n};\n","/**\n * @module ol/easing\n */\n\n\n/**\n * Start slow and speed up.\n * @param {number} t Input between 0 and 1.\n * @return {number} Output between 0 and 1.\n * @api\n */\nexport function easeIn(t) {\n  return Math.pow(t, 3);\n}\n\n\n/**\n * Start fast and slow down.\n * @param {number} t Input between 0 and 1.\n * @return {number} Output between 0 and 1.\n * @api\n */\nexport function easeOut(t) {\n  return 1 - easeIn(1 - t);\n}\n\n\n/**\n * Start slow, speed up, and then slow down again.\n * @param {number} t Input between 0 and 1.\n * @return {number} Output between 0 and 1.\n * @api\n */\nexport function inAndOut(t) {\n  return 3 * t * t - 2 * t * t * t;\n}\n\n\n/**\n * Maintain a constant speed over time.\n * @param {number} t Input between 0 and 1.\n * @return {number} Output between 0 and 1.\n * @api\n */\nexport function linear(t) {\n  return t;\n}\n\n\n/**\n * Start slow, speed up, and at the very end slow down again.  This has the\n * same general behavior as {@link module:ol/easing~inAndOut}, but the final\n * slowdown is delayed.\n * @param {number} t Input between 0 and 1.\n * @return {number} Output between 0 and 1.\n * @api\n */\nexport function upAndDown(t) {\n  if (t < 0.5) {\n    return inAndOut(2 * t);\n  } else {\n    return 1 - inAndOut(2 * (t - 0.5));\n  }\n}\n","/**\n * @module ol/Tile\n */\nimport TileState from './TileState.js';\nimport {easeIn} from './easing.js';\nimport EventTarget from './events/EventTarget.js';\nimport EventType from './events/EventType.js';\n\n\n/**\n * A function that takes an {@link module:ol/Tile} for the tile and a\n * `{string}` for the url as arguments.\n *\n * @typedef {function(module:ol/Tile, string)} LoadFunction\n * @api\n */\n\n/**\n * {@link module:ol/source/Tile~Tile} sources use a function of this type to get\n * the url that provides a tile for a given tile coordinate.\n *\n * This function takes an {@link module:ol/tilecoord~TileCoord} for the tile\n * coordinate, a `{number}` representing the pixel ratio and a\n * {@link module:ol/proj/Projection} for the projection  as arguments\n * and returns a `{string}` representing the tile URL, or undefined if no tile\n * should be requested for the passed tile coordinate.\n *\n * @typedef {function(module:ol/tilecoord~TileCoord, number,\n *           module:ol/proj/Projection): (string|undefined)} UrlFunction\n * @api\n */\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [transition=250] A duration for tile opacity\n * transitions in milliseconds. A duration of 0 disables the opacity transition.\n * @api\n */\n\n\n/**\n * @classdesc\n * Base class for tiles.\n *\n * @abstract\n  */\nclass Tile extends EventTarget {\n\n  /**\n   * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n   * @param {module:ol/TileState} state State.\n   * @param {module:ol/Tile~Options=} opt_options Tile options.\n   */\n  constructor(tileCoord, state, opt_options) {\n    super();\n\n    const options = opt_options ? opt_options : {};\n\n    /**\n     * @type {module:ol/tilecoord~TileCoord}\n     */\n    this.tileCoord = tileCoord;\n\n    /**\n     * @protected\n     * @type {module:ol/TileState}\n     */\n    this.state = state;\n\n    /**\n     * An \"interim\" tile for this tile. The interim tile may be used while this\n     * one is loading, for \"smooth\" transitions when changing params/dimensions\n     * on the source.\n     * @type {module:ol/Tile}\n     */\n    this.interimTile = null;\n\n    /**\n     * A key assigned to the tile. This is used by the tile source to determine\n     * if this tile can effectively be used, or if a new tile should be created\n     * and this one be used as an interim tile for this new tile.\n     * @type {string}\n     */\n    this.key = '';\n\n    /**\n     * The duration for the opacity transition.\n     * @type {number}\n     */\n    this.transition_ = options.transition === undefined ? 250 : options.transition;\n\n    /**\n     * Lookup of start times for rendering transitions.  If the start time is\n     * equal to -1, the transition is complete.\n     * @type {Object.<number, number>}\n     */\n    this.transitionStarts_ = {};\n\n  }\n\n  /**\n   * @protected\n   */\n  changed() {\n    this.dispatchEvent(EventType.CHANGE);\n  }\n\n  /**\n   * @return {string} Key.\n   */\n  getKey() {\n    return this.key + '/' + this.tileCoord;\n  }\n\n  /**\n   * Get the interim tile most suitable for rendering using the chain of interim\n   * tiles. This corresponds to the  most recent tile that has been loaded, if no\n   * such tile exists, the original tile is returned.\n   * @return {!module:ol/Tile} Best tile for rendering.\n   */\n  getInterimTile() {\n    if (!this.interimTile) {\n      //empty chain\n      return this;\n    }\n    let tile = this.interimTile;\n\n    // find the first loaded tile and return it. Since the chain is sorted in\n    // decreasing order of creation time, there is no need to search the remainder\n    // of the list (all those tiles correspond to older requests and will be\n    // cleaned up by refreshInterimChain)\n    do {\n      if (tile.getState() == TileState.LOADED) {\n        return tile;\n      }\n      tile = tile.interimTile;\n    } while (tile);\n\n    // we can not find a better tile\n    return this;\n  }\n\n  /**\n   * Goes through the chain of interim tiles and discards sections of the chain\n   * that are no longer relevant.\n   */\n  refreshInterimChain() {\n    if (!this.interimTile) {\n      return;\n    }\n\n    let tile = this.interimTile;\n    let prev = this;\n\n    do {\n      if (tile.getState() == TileState.LOADED) {\n        //we have a loaded tile, we can discard the rest of the list\n        //we would could abort any LOADING tile request\n        //older than this tile (i.e. any LOADING tile following this entry in the chain)\n        tile.interimTile = null;\n        break;\n      } else if (tile.getState() == TileState.LOADING) {\n        //keep this LOADING tile any loaded tiles later in the chain are\n        //older than this tile, so we're still interested in the request\n        prev = tile;\n      } else if (tile.getState() == TileState.IDLE) {\n        //the head of the list is the most current tile, we don't need\n        //to start any other requests for this chain\n        prev.interimTile = tile.interimTile;\n      } else {\n        prev = tile;\n      }\n      tile = prev.interimTile;\n    } while (tile);\n  }\n\n  /**\n   * Get the tile coordinate for this tile.\n   * @return {module:ol/tilecoord~TileCoord} The tile coordinate.\n   * @api\n   */\n  getTileCoord() {\n    return this.tileCoord;\n  }\n\n  /**\n   * @return {module:ol/TileState} State.\n   */\n  getState() {\n    return this.state;\n  }\n\n  /**\n   * @param {module:ol/TileState} state State.\n   */\n  setState(state) {\n    this.state = state;\n    this.changed();\n  }\n\n  /**\n   * Load the image or retry if loading previously failed.\n   * Loading is taken care of by the tile queue, and calling this method is\n   * only needed for preloading or for reloading in case of an error.\n   * @abstract\n   * @api\n   */\n  load() {}\n\n  /**\n   * Get the alpha value for rendering.\n   * @param {number} id An id for the renderer.\n   * @param {number} time The render frame time.\n   * @return {number} A number between 0 and 1.\n   */\n  getAlpha(id, time) {\n    if (!this.transition_) {\n      return 1;\n    }\n\n    let start = this.transitionStarts_[id];\n    if (!start) {\n      start = time;\n      this.transitionStarts_[id] = start;\n    } else if (start === -1) {\n      return 1;\n    }\n\n    const delta = time - start + (1000 / 60); // avoid rendering at 0\n    if (delta >= this.transition_) {\n      return 1;\n    }\n    return easeIn(delta / this.transition_);\n  }\n\n  /**\n   * Determine if a tile is in an alpha transition.  A tile is considered in\n   * transition if tile.getAlpha() has not yet been called or has been called\n   * and returned 1.\n   * @param {number} id An id for the renderer.\n   * @return {boolean} The tile is in transition.\n   */\n  inTransition(id) {\n    if (!this.transition_) {\n      return false;\n    }\n    return this.transitionStarts_[id] !== -1;\n  }\n\n  /**\n   * Mark a transition as complete.\n   * @param {number} id An id for the renderer.\n   */\n  endTransition(id) {\n    if (this.transition_) {\n      this.transitionStarts_[id] = -1;\n    }\n  }\n}\n\n\nexport default Tile;\n","/**\n * @module ol/ImageTile\n */\nimport Tile from './Tile.js';\nimport TileState from './TileState.js';\nimport {createCanvasContext2D} from './dom.js';\nimport {listenOnce, unlistenByKey} from './events.js';\nimport EventType from './events/EventType.js';\n\n/**\n * @typedef {function(new: module:ol/ImageTile, module:ol/tilecoord~TileCoord,\n * module:ol/TileState, string, ?string, module:ol/Tile~LoadFunction)} TileClass\n * @api\n */\n\nclass ImageTile extends Tile {\n\n  /**\n   * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n   * @param {module:ol/TileState} state State.\n   * @param {string} src Image source URI.\n   * @param {?string} crossOrigin Cross origin.\n   * @param {module:ol/Tile~LoadFunction} tileLoadFunction Tile load function.\n   * @param {module:ol/Tile~Options=} opt_options Tile options.\n   */\n  constructor(tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options) {\n\n    super(tileCoord, state, opt_options);\n\n    /**\n     * @private\n     * @type {?string}\n     */\n    this.crossOrigin_ = crossOrigin;\n\n    /**\n     * Image URI\n     *\n     * @private\n     * @type {string}\n     */\n    this.src_ = src;\n\n    /**\n     * @private\n     * @type {HTMLImageElement|HTMLCanvasElement}\n     */\n    this.image_ = new Image();\n    if (crossOrigin !== null) {\n      this.image_.crossOrigin = crossOrigin;\n    }\n\n    /**\n     * @private\n     * @type {Array.<module:ol/events~EventsKey>}\n     */\n    this.imageListenerKeys_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/Tile~LoadFunction}\n     */\n    this.tileLoadFunction_ = tileLoadFunction;\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  disposeInternal() {\n    if (this.state == TileState.LOADING) {\n      this.unlistenImage_();\n      this.image_ = getBlankImage();\n    }\n    if (this.interimTile) {\n      this.interimTile.dispose();\n    }\n    this.state = TileState.ABORT;\n    this.changed();\n    super.disposeInternal();\n  }\n\n  /**\n   * Get the HTML image element for this tile (may be a Canvas, Image, or Video).\n   * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.\n   * @api\n   */\n  getImage() {\n    return this.image_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getKey() {\n    return this.src_;\n  }\n\n  /**\n   * Tracks loading or read errors.\n   *\n   * @private\n   */\n  handleImageError_() {\n    this.state = TileState.ERROR;\n    this.unlistenImage_();\n    this.image_ = getBlankImage();\n    this.changed();\n  }\n\n  /**\n   * Tracks successful image load.\n   *\n   * @private\n   */\n  handleImageLoad_() {\n    if (this.image_.naturalWidth && this.image_.naturalHeight) {\n      this.state = TileState.LOADED;\n    } else {\n      this.state = TileState.EMPTY;\n    }\n    this.unlistenImage_();\n    this.changed();\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  load() {\n    if (this.state == TileState.ERROR) {\n      this.state = TileState.IDLE;\n      this.image_ = new Image();\n      if (this.crossOrigin_ !== null) {\n        this.image_.crossOrigin = this.crossOrigin_;\n      }\n    }\n    if (this.state == TileState.IDLE) {\n      this.state = TileState.LOADING;\n      this.changed();\n      this.imageListenerKeys_ = [\n        listenOnce(this.image_, EventType.ERROR,\n          this.handleImageError_, this),\n        listenOnce(this.image_, EventType.LOAD,\n          this.handleImageLoad_, this)\n      ];\n      this.tileLoadFunction_(this, this.src_);\n    }\n  }\n\n  /**\n   * Discards event handlers which listen for load completion or errors.\n   *\n   * @private\n   */\n  unlistenImage_() {\n    this.imageListenerKeys_.forEach(unlistenByKey);\n    this.imageListenerKeys_ = null;\n  }\n}\n\n\n/**\n * Get a 1-pixel blank image.\n * @return {HTMLCanvasElement} Blank image.\n */\nfunction getBlankImage() {\n  const ctx = createCanvasContext2D(1, 1);\n  ctx.fillStyle = 'rgba(0,0,0,0)';\n  ctx.fillRect(0, 0, 1, 1);\n  return ctx.canvas;\n}\n\nexport default ImageTile;\n","/**\n * @module ol/Kinetic\n */\n\n/**\n * @classdesc\n * Implementation of inertial deceleration for map movement.\n *\n * @api\n */\nclass Kinetic {\n\n  /**\n   * @param {number} decay Rate of decay (must be negative).\n   * @param {number} minVelocity Minimum velocity (pixels/millisecond).\n   * @param {number} delay Delay to consider to calculate the kinetic\n   *     initial values (milliseconds).\n   */\n  constructor(decay, minVelocity, delay) {\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.decay_ = decay;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.minVelocity_ = minVelocity;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.delay_ = delay;\n\n    /**\n     * @private\n     * @type {Array.<number>}\n     */\n    this.points_ = [];\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.angle_ = 0;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.initialVelocity_ = 0;\n  }\n\n  /**\n   * FIXME empty description for jsdoc\n   */\n  begin() {\n    this.points_.length = 0;\n    this.angle_ = 0;\n    this.initialVelocity_ = 0;\n  }\n\n  /**\n   * @param {number} x X.\n   * @param {number} y Y.\n   */\n  update(x, y) {\n    this.points_.push(x, y, Date.now());\n  }\n\n  /**\n   * @return {boolean} Whether we should do kinetic animation.\n   */\n  end() {\n    if (this.points_.length < 6) {\n      // at least 2 points are required (i.e. there must be at least 6 elements\n      // in the array)\n      return false;\n    }\n    const delay = Date.now() - this.delay_;\n    const lastIndex = this.points_.length - 3;\n    if (this.points_[lastIndex + 2] < delay) {\n      // the last tracked point is too old, which means that the user stopped\n      // panning before releasing the map\n      return false;\n    }\n\n    // get the first point which still falls into the delay time\n    let firstIndex = lastIndex - 3;\n    while (firstIndex > 0 && this.points_[firstIndex + 2] > delay) {\n      firstIndex -= 3;\n    }\n\n    const duration = this.points_[lastIndex + 2] - this.points_[firstIndex + 2];\n    // we don't want a duration of 0 (divide by zero)\n    // we also make sure the user panned for a duration of at least one frame\n    // (1/60s) to compute sane displacement values\n    if (duration < 1000 / 60) {\n      return false;\n    }\n\n    const dx = this.points_[lastIndex] - this.points_[firstIndex];\n    const dy = this.points_[lastIndex + 1] - this.points_[firstIndex + 1];\n    this.angle_ = Math.atan2(dy, dx);\n    this.initialVelocity_ = Math.sqrt(dx * dx + dy * dy) / duration;\n    return this.initialVelocity_ > this.minVelocity_;\n  }\n\n  /**\n   * @return {number} Total distance travelled (pixels).\n   */\n  getDistance() {\n    return (this.minVelocity_ - this.initialVelocity_) / this.decay_;\n  }\n\n  /**\n   * @return {number} Angle of the kinetic panning animation (radians).\n   */\n  getAngle() {\n    return this.angle_;\n  }\n}\n\nexport default Kinetic;\n","/**\n * @module ol/MapEvent\n */\nimport Event from './events/Event.js';\n\n/**\n * @classdesc\n * Events emitted as map events are instances of this type.\n * See {@link module:ol/Map~Map} for which events trigger a map event.\n */\nclass MapEvent extends Event {\n\n  /**\n   * @param {string} type Event type.\n   * @param {module:ol/PluggableMap} map Map.\n   * @param {?module:ol/PluggableMap~FrameState=} opt_frameState Frame state.\n   */\n  constructor(type, map, opt_frameState) {\n\n    super(type);\n\n    /**\n     * The map where the event occurred.\n     * @type {module:ol/PluggableMap}\n     * @api\n     */\n    this.map = map;\n\n    /**\n     * The frame state at the time of the event.\n     * @type {?module:ol/PluggableMap~FrameState}\n     * @api\n     */\n    this.frameState = opt_frameState !== undefined ? opt_frameState : null;\n\n  }\n\n}\n\nexport default MapEvent;\n","/**\n * @module ol/MapBrowserEvent\n */\nimport MapEvent from './MapEvent.js';\n\n/**\n * @classdesc\n * Events emitted as map browser events are instances of this type.\n * See {@link module:ol/Map~Map} for which events trigger a map browser event.\n */\nclass MapBrowserEvent extends MapEvent {\n\n  /**\n   * @param {string} type Event type.\n   * @param {module:ol/PluggableMap} map Map.\n   * @param {Event} browserEvent Browser event.\n   * @param {boolean=} opt_dragging Is the map currently being dragged?\n   * @param {?module:ol/PluggableMap~FrameState=} opt_frameState Frame state.\n   */\n  constructor(type, map, browserEvent, opt_dragging, opt_frameState) {\n\n    super(type, map, opt_frameState);\n\n    /**\n     * The original browser event.\n     * @const\n     * @type {Event}\n     * @api\n     */\n    this.originalEvent = browserEvent;\n\n    /**\n     * The map pixel relative to the viewport corresponding to the original browser event.\n     * @type {module:ol/pixel~Pixel}\n     * @api\n     */\n    this.pixel = map.getEventPixel(browserEvent);\n\n    /**\n     * The coordinate in view projection corresponding to the original browser event.\n     * @type {module:ol/coordinate~Coordinate}\n     * @api\n     */\n    this.coordinate = map.getCoordinateFromPixel(this.pixel);\n\n    /**\n     * Indicates if the map is currently being dragged. Only set for\n     * `POINTERDRAG` and `POINTERMOVE` events. Default is `false`.\n     *\n     * @type {boolean}\n     * @api\n     */\n    this.dragging = opt_dragging !== undefined ? opt_dragging : false;\n\n  }\n\n  /**\n   * Prevents the default browser action.\n   * See https://developer.mozilla.org/en-US/docs/Web/API/event.preventDefault.\n   * @override\n   * @api\n   */\n  preventDefault() {\n    super.preventDefault();\n    this.originalEvent.preventDefault();\n  }\n\n  /**\n   * Prevents further propagation of the current event.\n   * See https://developer.mozilla.org/en-US/docs/Web/API/event.stopPropagation.\n   * @override\n   * @api\n   */\n  stopPropagation() {\n    super.stopPropagation();\n    this.originalEvent.stopPropagation();\n  }\n}\n\n\nexport default MapBrowserEvent;\n","/**\n * @module ol/MapBrowserEventType\n */\nimport EventType from './events/EventType.js';\n\n/**\n * Constants for event names.\n * @enum {string}\n */\nexport default {\n\n  /**\n   * A true single click with no dragging and no double click. Note that this\n   * event is delayed by 250 ms to ensure that it is not a double click.\n   * @event module:ol/MapBrowserEvent~MapBrowserEvent#singleclick\n   * @api\n   */\n  SINGLECLICK: 'singleclick',\n\n  /**\n   * A click with no dragging. A double click will fire two of this.\n   * @event module:ol/MapBrowserEvent~MapBrowserEvent#click\n   * @api\n   */\n  CLICK: EventType.CLICK,\n\n  /**\n   * A true double click, with no dragging.\n   * @event module:ol/MapBrowserEvent~MapBrowserEvent#dblclick\n   * @api\n   */\n  DBLCLICK: EventType.DBLCLICK,\n\n  /**\n   * Triggered when a pointer is dragged.\n   * @event module:ol/MapBrowserEvent~MapBrowserEvent#pointerdrag\n   * @api\n   */\n  POINTERDRAG: 'pointerdrag',\n\n  /**\n   * Triggered when a pointer is moved. Note that on touch devices this is\n   * triggered when the map is panned, so is not the same as mousemove.\n   * @event module:ol/MapBrowserEvent~MapBrowserEvent#pointermove\n   * @api\n   */\n  POINTERMOVE: 'pointermove',\n\n  POINTERDOWN: 'pointerdown',\n  POINTERUP: 'pointerup',\n  POINTEROVER: 'pointerover',\n  POINTEROUT: 'pointerout',\n  POINTERENTER: 'pointerenter',\n  POINTERLEAVE: 'pointerleave',\n  POINTERCANCEL: 'pointercancel'\n};\n","/**\n * @module ol/MapBrowserPointerEvent\n */\nimport MapBrowserEvent from './MapBrowserEvent.js';\n\nclass MapBrowserPointerEvent extends MapBrowserEvent {\n\n  /**\n   * @param {string} type Event type.\n   * @param {module:ol/PluggableMap} map Map.\n   * @param {module:ol/pointer/PointerEvent} pointerEvent Pointer event.\n   * @param {boolean=} opt_dragging Is the map currently being dragged?\n   * @param {?module:ol/PluggableMap~FrameState=} opt_frameState Frame state.\n   */\n  constructor(type, map, pointerEvent, opt_dragging, opt_frameState) {\n\n    super(type, map, pointerEvent.originalEvent, opt_dragging, opt_frameState);\n\n    /**\n     * @const\n     * @type {module:ol/pointer/PointerEvent}\n     */\n    this.pointerEvent = pointerEvent;\n\n  }\n\n}\n\nexport default MapBrowserPointerEvent;\n","/**\n * @module ol/pointer/EventType\n */\n\n/**\n * Constants for event names.\n * @enum {string}\n */\nexport default {\n  POINTERMOVE: 'pointermove',\n  POINTERDOWN: 'pointerdown',\n  POINTERUP: 'pointerup',\n  POINTEROVER: 'pointerover',\n  POINTEROUT: 'pointerout',\n  POINTERENTER: 'pointerenter',\n  POINTERLEAVE: 'pointerleave',\n  POINTERCANCEL: 'pointercancel'\n};\n","/**\n * @module ol/pointer/EventSource\n */\n\nclass EventSource {\n\n  /**\n   * @param {module:ol/pointer/PointerEventHandler} dispatcher Event handler.\n   * @param {!Object.<string, function(Event)>} mapping Event mapping.\n   */\n  constructor(dispatcher, mapping) {\n\n    /**\n     * @type {module:ol/pointer/PointerEventHandler}\n     */\n    this.dispatcher = dispatcher;\n\n    /**\n     * @private\n     * @const\n     * @type {!Object.<string, function(Event)>}\n     */\n    this.mapping_ = mapping;\n  }\n\n  /**\n   * List of events supported by this source.\n   * @return {Array.<string>} Event names\n   */\n  getEvents() {\n    return Object.keys(this.mapping_);\n  }\n\n  /**\n   * Returns the handler that should handle a given event type.\n   * @param {string} eventType The event type.\n   * @return {function(Event)} Handler\n   */\n  getHandlerForEvent(eventType) {\n    return this.mapping_[eventType];\n  }\n\n}\n\nexport default EventSource;\n","/**\n * @module ol/pointer/MouseSource\n */\n\n// Based on https://github.com/Polymer/PointerEvents\n\n// Copyright (c) 2013 The Polymer Authors. All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n// * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n// * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n// * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nimport EventSource from '../pointer/EventSource.js';\n\n\n/**\n * @type {number}\n */\nexport const POINTER_ID = 1;\n\n\n/**\n * @type {string}\n */\nexport const POINTER_TYPE = 'mouse';\n\n\n/**\n * Radius around touchend that swallows mouse events.\n *\n * @type {number}\n */\nconst DEDUP_DIST = 25;\n\n/**\n * Handler for `mousedown`.\n *\n * @this {module:ol/pointer/MouseSource}\n * @param {MouseEvent} inEvent The in event.\n */\nfunction mousedown(inEvent) {\n  if (!this.isEventSimulatedFromTouch_(inEvent)) {\n    // TODO(dfreedman) workaround for some elements not sending mouseup\n    // http://crbug/149091\n    if (POINTER_ID.toString() in this.pointerMap) {\n      this.cancel(inEvent);\n    }\n    const e = prepareEvent(inEvent, this.dispatcher);\n    this.pointerMap[POINTER_ID.toString()] = inEvent;\n    this.dispatcher.down(e, inEvent);\n  }\n}\n\n/**\n * Handler for `mousemove`.\n *\n * @this {module:ol/pointer/MouseSource}\n * @param {MouseEvent} inEvent The in event.\n */\nfunction mousemove(inEvent) {\n  if (!this.isEventSimulatedFromTouch_(inEvent)) {\n    const e = prepareEvent(inEvent, this.dispatcher);\n    this.dispatcher.move(e, inEvent);\n  }\n}\n\n/**\n * Handler for `mouseup`.\n *\n * @this {module:ol/pointer/MouseSource}\n * @param {MouseEvent} inEvent The in event.\n */\nfunction mouseup(inEvent) {\n  if (!this.isEventSimulatedFromTouch_(inEvent)) {\n    const p = this.pointerMap[POINTER_ID.toString()];\n\n    if (p && p.button === inEvent.button) {\n      const e = prepareEvent(inEvent, this.dispatcher);\n      this.dispatcher.up(e, inEvent);\n      this.cleanupMouse();\n    }\n  }\n}\n\n/**\n * Handler for `mouseover`.\n *\n * @this {module:ol/pointer/MouseSource}\n * @param {MouseEvent} inEvent The in event.\n */\nfunction mouseover(inEvent) {\n  if (!this.isEventSimulatedFromTouch_(inEvent)) {\n    const e = prepareEvent(inEvent, this.dispatcher);\n    this.dispatcher.enterOver(e, inEvent);\n  }\n}\n\n/**\n * Handler for `mouseout`.\n *\n * @this {module:ol/pointer/MouseSource}\n * @param {MouseEvent} inEvent The in event.\n */\nfunction mouseout(inEvent) {\n  if (!this.isEventSimulatedFromTouch_(inEvent)) {\n    const e = prepareEvent(inEvent, this.dispatcher);\n    this.dispatcher.leaveOut(e, inEvent);\n  }\n}\n\n\nclass MouseSource extends EventSource {\n\n  /**\n   * @param {module:ol/pointer/PointerEventHandler} dispatcher Event handler.\n   */\n  constructor(dispatcher) {\n    const mapping = {\n      'mousedown': mousedown,\n      'mousemove': mousemove,\n      'mouseup': mouseup,\n      'mouseover': mouseover,\n      'mouseout': mouseout\n    };\n    super(dispatcher, mapping);\n\n    /**\n     * @const\n     * @type {!Object.<string, Event|Object>}\n     */\n    this.pointerMap = dispatcher.pointerMap;\n\n    /**\n     * @const\n     * @type {Array.<module:ol/pixel~Pixel>}\n     */\n    this.lastTouches = [];\n  }\n\n  /**\n   * Detect if a mouse event was simulated from a touch by\n   * checking if previously there was a touch event at the\n   * same position.\n   *\n   * FIXME - Known problem with the native Android browser on\n   * Samsung GT-I9100 (Android 4.1.2):\n   * In case the page is scrolled, this function does not work\n   * correctly when a canvas is used (WebGL or canvas renderer).\n   * Mouse listeners on canvas elements (for this browser), create\n   * two mouse events: One 'good' and one 'bad' one (on other browsers or\n   * when a div is used, there is only one event). For the 'bad' one,\n   * clientX/clientY and also pageX/pageY are wrong when the page\n   * is scrolled. Because of that, this function can not detect if\n   * the events were simulated from a touch event. As result, a\n   * pointer event at a wrong position is dispatched, which confuses\n   * the map interactions.\n   * It is unclear, how one can get the correct position for the event\n   * or detect that the positions are invalid.\n   *\n   * @private\n   * @param {MouseEvent} inEvent The in event.\n   * @return {boolean} True, if the event was generated by a touch.\n   */\n  isEventSimulatedFromTouch_(inEvent) {\n    const lts = this.lastTouches;\n    const x = inEvent.clientX;\n    const y = inEvent.clientY;\n    for (let i = 0, l = lts.length, t; i < l && (t = lts[i]); i++) {\n      // simulated mouse events will be swallowed near a primary touchend\n      const dx = Math.abs(x - t[0]);\n      const dy = Math.abs(y - t[1]);\n      if (dx <= DEDUP_DIST && dy <= DEDUP_DIST) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /**\n   * Dispatches a `pointercancel` event.\n   *\n   * @param {Event} inEvent The in event.\n   */\n  cancel(inEvent) {\n    const e = prepareEvent(inEvent, this.dispatcher);\n    this.dispatcher.cancel(e, inEvent);\n    this.cleanupMouse();\n  }\n\n  /**\n   * Remove the mouse from the list of active pointers.\n   */\n  cleanupMouse() {\n    delete this.pointerMap[POINTER_ID.toString()];\n  }\n}\n\n\n/**\n * Creates a copy of the original event that will be used\n * for the fake pointer event.\n *\n * @param {Event} inEvent The in event.\n * @param {module:ol/pointer/PointerEventHandler} dispatcher Event handler.\n * @return {Object} The copied event.\n */\nfunction prepareEvent(inEvent, dispatcher) {\n  const e = dispatcher.cloneEvent(inEvent, inEvent);\n\n  // forward mouse preventDefault\n  const pd = e.preventDefault;\n  e.preventDefault = function() {\n    inEvent.preventDefault();\n    pd();\n  };\n\n  e.pointerId = POINTER_ID;\n  e.isPrimary = true;\n  e.pointerType = POINTER_TYPE;\n\n  return e;\n}\n\n\nexport default MouseSource;\n","/**\n * @module ol/pointer/MsSource\n */\n// Based on https://github.com/Polymer/PointerEvents\n\n// Copyright (c) 2013 The Polymer Authors. All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n// * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n// * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n// * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nimport EventSource from '../pointer/EventSource.js';\n\n\n/**\n * @const\n * @type {Array.<string>}\n */\nconst POINTER_TYPES = [\n  '',\n  'unavailable',\n  'touch',\n  'pen',\n  'mouse'\n];\n\n/**\n * Handler for `msPointerDown`.\n *\n * @this {module:ol/pointer/MsSource}\n * @param {MSPointerEvent} inEvent The in event.\n */\nfunction msPointerDown(inEvent) {\n  this.pointerMap[inEvent.pointerId.toString()] = inEvent;\n  const e = this.prepareEvent_(inEvent);\n  this.dispatcher.down(e, inEvent);\n}\n\n/**\n * Handler for `msPointerMove`.\n *\n * @this {module:ol/pointer/MsSource}\n * @param {MSPointerEvent} inEvent The in event.\n */\nfunction msPointerMove(inEvent) {\n  const e = this.prepareEvent_(inEvent);\n  this.dispatcher.move(e, inEvent);\n}\n\n/**\n * Handler for `msPointerUp`.\n *\n * @this {module:ol/pointer/MsSource}\n * @param {MSPointerEvent} inEvent The in event.\n */\nfunction msPointerUp(inEvent) {\n  const e = this.prepareEvent_(inEvent);\n  this.dispatcher.up(e, inEvent);\n  this.cleanup(inEvent.pointerId);\n}\n\n/**\n * Handler for `msPointerOut`.\n *\n * @this {module:ol/pointer/MsSource}\n * @param {MSPointerEvent} inEvent The in event.\n */\nfunction msPointerOut(inEvent) {\n  const e = this.prepareEvent_(inEvent);\n  this.dispatcher.leaveOut(e, inEvent);\n}\n\n/**\n * Handler for `msPointerOver`.\n *\n * @this {module:ol/pointer/MsSource}\n * @param {MSPointerEvent} inEvent The in event.\n */\nfunction msPointerOver(inEvent) {\n  const e = this.prepareEvent_(inEvent);\n  this.dispatcher.enterOver(e, inEvent);\n}\n\n/**\n * Handler for `msPointerCancel`.\n *\n * @this {module:ol/pointer/MsSource}\n * @param {MSPointerEvent} inEvent The in event.\n */\nfunction msPointerCancel(inEvent) {\n  const e = this.prepareEvent_(inEvent);\n  this.dispatcher.cancel(e, inEvent);\n  this.cleanup(inEvent.pointerId);\n}\n\n/**\n * Handler for `msLostPointerCapture`.\n *\n * @this {module:ol/pointer/MsSource}\n * @param {MSPointerEvent} inEvent The in event.\n */\nfunction msLostPointerCapture(inEvent) {\n  const e = this.dispatcher.makeEvent('lostpointercapture', inEvent, inEvent);\n  this.dispatcher.dispatchEvent(e);\n}\n\n/**\n * Handler for `msGotPointerCapture`.\n *\n * @this {module:ol/pointer/MsSource}\n * @param {MSPointerEvent} inEvent The in event.\n */\nfunction msGotPointerCapture(inEvent) {\n  const e = this.dispatcher.makeEvent('gotpointercapture', inEvent, inEvent);\n  this.dispatcher.dispatchEvent(e);\n}\n\nclass MsSource extends EventSource {\n\n  /**\n   * @param {module:ol/pointer/PointerEventHandler} dispatcher Event handler.\n   */\n  constructor(dispatcher) {\n    const mapping = {\n      'MSPointerDown': msPointerDown,\n      'MSPointerMove': msPointerMove,\n      'MSPointerUp': msPointerUp,\n      'MSPointerOut': msPointerOut,\n      'MSPointerOver': msPointerOver,\n      'MSPointerCancel': msPointerCancel,\n      'MSGotPointerCapture': msGotPointerCapture,\n      'MSLostPointerCapture': msLostPointerCapture\n    };\n    super(dispatcher, mapping);\n\n    /**\n     * @const\n     * @type {!Object.<string, MSPointerEvent|Object>}\n     */\n    this.pointerMap = dispatcher.pointerMap;\n  }\n\n  /**\n   * Creates a copy of the original event that will be used\n   * for the fake pointer event.\n   *\n   * @private\n   * @param {MSPointerEvent} inEvent The in event.\n   * @return {Object} The copied event.\n   */\n  prepareEvent_(inEvent) {\n    let e = inEvent;\n    if (typeof inEvent.pointerType === 'number') {\n      e = this.dispatcher.cloneEvent(inEvent, inEvent);\n      e.pointerType = POINTER_TYPES[inEvent.pointerType];\n    }\n\n    return e;\n  }\n\n  /**\n   * Remove this pointer from the list of active pointers.\n   * @param {number} pointerId Pointer identifier.\n   */\n  cleanup(pointerId) {\n    delete this.pointerMap[pointerId.toString()];\n  }\n\n}\n\nexport default MsSource;\n","/**\n * @module ol/pointer/NativeSource\n */\n\n// Based on https://github.com/Polymer/PointerEvents\n\n// Copyright (c) 2013 The Polymer Authors. All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n// * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n// * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n// * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nimport EventSource from '../pointer/EventSource.js';\n\n/**\n * Handler for `pointerdown`.\n *\n * @this {module:ol/pointer/NativeSource}\n * @param {Event} inEvent The in event.\n */\nfunction pointerDown(inEvent) {\n  this.dispatcher.fireNativeEvent(inEvent);\n}\n\n/**\n * Handler for `pointermove`.\n *\n * @this {module:ol/pointer/NativeSource}\n * @param {Event} inEvent The in event.\n */\nfunction pointerMove(inEvent) {\n  this.dispatcher.fireNativeEvent(inEvent);\n}\n\n/**\n * Handler for `pointerup`.\n *\n * @this {module:ol/pointer/NativeSource}\n * @param {Event} inEvent The in event.\n */\nfunction pointerUp(inEvent) {\n  this.dispatcher.fireNativeEvent(inEvent);\n}\n\n/**\n * Handler for `pointerout`.\n *\n * @this {module:ol/pointer/NativeSource}\n * @param {Event} inEvent The in event.\n */\nfunction pointerOut(inEvent) {\n  this.dispatcher.fireNativeEvent(inEvent);\n}\n\n/**\n * Handler for `pointerover`.\n *\n * @this {module:ol/pointer/NativeSource}\n * @param {Event} inEvent The in event.\n */\nfunction pointerOver(inEvent) {\n  this.dispatcher.fireNativeEvent(inEvent);\n}\n\n/**\n * Handler for `pointercancel`.\n *\n * @this {module:ol/pointer/NativeSource}\n * @param {Event} inEvent The in event.\n */\nfunction pointerCancel(inEvent) {\n  this.dispatcher.fireNativeEvent(inEvent);\n}\n\n/**\n * Handler for `lostpointercapture`.\n *\n * @this {module:ol/pointer/NativeSource}\n * @param {Event} inEvent The in event.\n */\nfunction lostPointerCapture(inEvent) {\n  this.dispatcher.fireNativeEvent(inEvent);\n}\n\n/**\n * Handler for `gotpointercapture`.\n *\n * @this {module:ol/pointer/NativeSource}\n * @param {Event} inEvent The in event.\n */\nfunction gotPointerCapture(inEvent) {\n  this.dispatcher.fireNativeEvent(inEvent);\n}\n\nclass NativeSource extends EventSource {\n\n  /**\n   * @param {module:ol/pointer/PointerEventHandler} dispatcher Event handler.\n   */\n  constructor(dispatcher) {\n    const mapping = {\n      'pointerdown': pointerDown,\n      'pointermove': pointerMove,\n      'pointerup': pointerUp,\n      'pointerout': pointerOut,\n      'pointerover': pointerOver,\n      'pointercancel': pointerCancel,\n      'gotpointercapture': gotPointerCapture,\n      'lostpointercapture': lostPointerCapture\n    };\n    super(dispatcher, mapping);\n  }\n\n}\n\nexport default NativeSource;\n","/**\n * @module ol/pointer/PointerEvent\n */\n\n// Based on https://github.com/Polymer/PointerEvents\n\n// Copyright (c) 2013 The Polymer Authors. All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n// * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n// * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n// * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nimport Event from '../events/Event.js';\n\n\n/**\n * Is the `buttons` property supported?\n * @type {boolean}\n */\nlet HAS_BUTTONS = false;\n\n\nclass PointerEvent extends Event {\n\n  /**\n   * A class for pointer events.\n   *\n   * This class is used as an abstraction for mouse events,\n   * touch events and even native pointer events.\n   *\n   * @param {string} type The type of the event to create.\n   * @param {Event} originalEvent The event.\n   * @param {Object.<string, ?>=} opt_eventDict An optional dictionary of\n   *    initial event properties.\n   */\n  constructor(type, originalEvent, opt_eventDict) {\n    super(type);\n\n    /**\n     * @const\n     * @type {Event}\n     */\n    this.originalEvent = originalEvent;\n\n    const eventDict = opt_eventDict ? opt_eventDict : {};\n\n    /**\n     * @type {number}\n     */\n    this.buttons = this.getButtons_(eventDict);\n\n    /**\n     * @type {number}\n     */\n    this.pressure = this.getPressure_(eventDict, this.buttons);\n\n    // MouseEvent related properties\n\n    /**\n     * @type {boolean}\n     */\n    this.bubbles = 'bubbles' in eventDict ? eventDict['bubbles'] : false;\n\n    /**\n     * @type {boolean}\n     */\n    this.cancelable = 'cancelable' in eventDict ? eventDict['cancelable'] : false;\n\n    /**\n     * @type {Object}\n     */\n    this.view = 'view' in eventDict ? eventDict['view'] : null;\n\n    /**\n     * @type {number}\n     */\n    this.detail = 'detail' in eventDict ? eventDict['detail'] : null;\n\n    /**\n     * @type {number}\n     */\n    this.screenX = 'screenX' in eventDict ? eventDict['screenX'] : 0;\n\n    /**\n     * @type {number}\n     */\n    this.screenY = 'screenY' in eventDict ? eventDict['screenY'] : 0;\n\n    /**\n     * @type {number}\n     */\n    this.clientX = 'clientX' in eventDict ? eventDict['clientX'] : 0;\n\n    /**\n     * @type {number}\n     */\n    this.clientY = 'clientY' in eventDict ? eventDict['clientY'] : 0;\n\n    /**\n     * @type {boolean}\n     */\n    this.ctrlKey = 'ctrlKey' in eventDict ? eventDict['ctrlKey'] : false;\n\n    /**\n     * @type {boolean}\n     */\n    this.altKey = 'altKey' in eventDict ? eventDict['altKey'] : false;\n\n    /**\n     * @type {boolean}\n     */\n    this.shiftKey = 'shiftKey' in eventDict ? eventDict['shiftKey'] : false;\n\n    /**\n     * @type {boolean}\n     */\n    this.metaKey = 'metaKey' in eventDict ? eventDict['metaKey'] : false;\n\n    /**\n     * @type {number}\n     */\n    this.button = 'button' in eventDict ? eventDict['button'] : 0;\n\n    /**\n     * @type {Node}\n     */\n    this.relatedTarget = 'relatedTarget' in eventDict ?\n      eventDict['relatedTarget'] : null;\n\n    // PointerEvent related properties\n\n    /**\n     * @const\n     * @type {number}\n     */\n    this.pointerId = 'pointerId' in eventDict ? eventDict['pointerId'] : 0;\n\n    /**\n     * @type {number}\n     */\n    this.width = 'width' in eventDict ? eventDict['width'] : 0;\n\n    /**\n     * @type {number}\n     */\n    this.height = 'height' in eventDict ? eventDict['height'] : 0;\n\n    /**\n     * @type {number}\n     */\n    this.tiltX = 'tiltX' in eventDict ? eventDict['tiltX'] : 0;\n\n    /**\n     * @type {number}\n     */\n    this.tiltY = 'tiltY' in eventDict ? eventDict['tiltY'] : 0;\n\n    /**\n     * @type {string}\n     */\n    this.pointerType = 'pointerType' in eventDict ? eventDict['pointerType'] : '';\n\n    /**\n     * @type {number}\n     */\n    this.hwTimestamp = 'hwTimestamp' in eventDict ? eventDict['hwTimestamp'] : 0;\n\n    /**\n     * @type {boolean}\n     */\n    this.isPrimary = 'isPrimary' in eventDict ? eventDict['isPrimary'] : false;\n\n    // keep the semantics of preventDefault\n    if (originalEvent.preventDefault) {\n      this.preventDefault = function() {\n        originalEvent.preventDefault();\n      };\n    }\n  }\n\n  /**\n   * @private\n   * @param {Object.<string, ?>} eventDict The event dictionary.\n   * @return {number} Button indicator.\n   */\n  getButtons_(eventDict) {\n    // According to the w3c spec,\n    // http://www.w3.org/TR/DOM-Level-3-Events/#events-MouseEvent-button\n    // MouseEvent.button == 0 can mean either no mouse button depressed, or the\n    // left mouse button depressed.\n    //\n    // As of now, the only way to distinguish between the two states of\n    // MouseEvent.button is by using the deprecated MouseEvent.which property, as\n    // this maps mouse buttons to positive integers > 0, and uses 0 to mean that\n    // no mouse button is held.\n    //\n    // MouseEvent.which is derived from MouseEvent.button at MouseEvent creation,\n    // but initMouseEvent does not expose an argument with which to set\n    // MouseEvent.which. Calling initMouseEvent with a buttonArg of 0 will set\n    // MouseEvent.button == 0 and MouseEvent.which == 1, breaking the expectations\n    // of app developers.\n    //\n    // The only way to propagate the correct state of MouseEvent.which and\n    // MouseEvent.button to a new MouseEvent.button == 0 and MouseEvent.which == 0\n    // is to call initMouseEvent with a buttonArg value of -1.\n    //\n    // This is fixed with DOM Level 4's use of buttons\n    let buttons;\n    if (eventDict.buttons || HAS_BUTTONS) {\n      buttons = eventDict.buttons;\n    } else {\n      switch (eventDict.which) {\n        case 1: buttons = 1; break;\n        case 2: buttons = 4; break;\n        case 3: buttons = 2; break;\n        default: buttons = 0;\n      }\n    }\n    return buttons;\n  }\n\n  /**\n   * @private\n   * @param {Object.<string, ?>} eventDict The event dictionary.\n   * @param {number} buttons Button indicator.\n   * @return {number} The pressure.\n   */\n  getPressure_(eventDict, buttons) {\n    // Spec requires that pointers without pressure specified use 0.5 for down\n    // state and 0 for up state.\n    let pressure = 0;\n    if (eventDict.pressure) {\n      pressure = eventDict.pressure;\n    } else {\n      pressure = buttons ? 0.5 : 0;\n    }\n    return pressure;\n  }\n}\n\n\n/**\n * Checks if the `buttons` property is supported.\n */\n(function() {\n  try {\n    const ev = new MouseEvent('click', {buttons: 1});\n    HAS_BUTTONS = ev.buttons === 1;\n  } catch (e) {\n    // pass\n  }\n})();\n\nexport default PointerEvent;\n","/**\n * @module ol/pointer/TouchSource\n */\n\n// Based on https://github.com/Polymer/PointerEvents\n\n// Copyright (c) 2013 The Polymer Authors. All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n// * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n// * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n// * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nimport {remove} from '../array.js';\nimport EventSource from '../pointer/EventSource.js';\nimport {POINTER_ID} from '../pointer/MouseSource.js';\n\n\n/**\n * @type {number}\n */\nconst CLICK_COUNT_TIMEOUT = 200;\n\n/**\n * @type {string}\n */\nconst POINTER_TYPE = 'touch';\n\n/**\n * Handler for `touchstart`, triggers `pointerover`,\n * `pointerenter` and `pointerdown` events.\n *\n * @this {module:ol/pointer/TouchSource}\n * @param {TouchEvent} inEvent The in event.\n */\nfunction touchstart(inEvent) {\n  this.vacuumTouches_(inEvent);\n  this.setPrimaryTouch_(inEvent.changedTouches[0]);\n  this.dedupSynthMouse_(inEvent);\n  this.clickCount_++;\n  this.processTouches_(inEvent, this.overDown_);\n}\n\n/**\n * Handler for `touchmove`.\n *\n * @this {module:ol/pointer/TouchSource}\n * @param {TouchEvent} inEvent The in event.\n */\nfunction touchmove(inEvent) {\n  inEvent.preventDefault();\n  this.processTouches_(inEvent, this.moveOverOut_);\n}\n\n/**\n * Handler for `touchend`, triggers `pointerup`,\n * `pointerout` and `pointerleave` events.\n *\n * @this {module:ol/pointer/TouchSource}\n * @param {TouchEvent} inEvent The event.\n */\nfunction touchend(inEvent) {\n  this.dedupSynthMouse_(inEvent);\n  this.processTouches_(inEvent, this.upOut_);\n}\n\n/**\n * Handler for `touchcancel`, triggers `pointercancel`,\n * `pointerout` and `pointerleave` events.\n *\n * @this {module:ol/pointer/TouchSource}\n * @param {TouchEvent} inEvent The in event.\n */\nfunction touchcancel(inEvent) {\n  this.processTouches_(inEvent, this.cancelOut_);\n}\n\n\nclass TouchSource extends EventSource {\n\n  /**\n   * @param {module:ol/pointer/PointerEventHandler} dispatcher The event handler.\n   * @param {module:ol/pointer/MouseSource} mouseSource Mouse source.\n   */\n  constructor(dispatcher, mouseSource) {\n    const mapping = {\n      'touchstart': touchstart,\n      'touchmove': touchmove,\n      'touchend': touchend,\n      'touchcancel': touchcancel\n    };\n    super(dispatcher, mapping);\n\n    /**\n     * @const\n     * @type {!Object.<string, Event|Object>}\n     */\n    this.pointerMap = dispatcher.pointerMap;\n\n    /**\n     * @const\n     * @type {module:ol/pointer/MouseSource}\n     */\n    this.mouseSource = mouseSource;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.firstTouchId_ = undefined;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.clickCount_ = 0;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.resetId_ = undefined;\n\n    /**\n     * Mouse event timeout: This should be long enough to\n     * ignore compat mouse events made by touch.\n     * @private\n     * @type {number}\n     */\n    this.dedupTimeout_ = 2500;\n  }\n\n  /**\n   * @private\n   * @param {Touch} inTouch The in touch.\n   * @return {boolean} True, if this is the primary touch.\n   */\n  isPrimaryTouch_(inTouch) {\n    return this.firstTouchId_ === inTouch.identifier;\n  }\n\n  /**\n   * Set primary touch if there are no pointers, or the only pointer is the mouse.\n   * @param {Touch} inTouch The in touch.\n   * @private\n   */\n  setPrimaryTouch_(inTouch) {\n    const count = Object.keys(this.pointerMap).length;\n    if (count === 0 || (count === 1 && POINTER_ID.toString() in this.pointerMap)) {\n      this.firstTouchId_ = inTouch.identifier;\n      this.cancelResetClickCount_();\n    }\n  }\n\n  /**\n   * @private\n   * @param {PointerEvent} inPointer The in pointer object.\n   */\n  removePrimaryPointer_(inPointer) {\n    if (inPointer.isPrimary) {\n      this.firstTouchId_ = undefined;\n      this.resetClickCount_();\n    }\n  }\n\n  /**\n   * @private\n   */\n  resetClickCount_() {\n    this.resetId_ = setTimeout(\n      this.resetClickCountHandler_.bind(this),\n      CLICK_COUNT_TIMEOUT);\n  }\n\n  /**\n   * @private\n   */\n  resetClickCountHandler_() {\n    this.clickCount_ = 0;\n    this.resetId_ = undefined;\n  }\n\n  /**\n   * @private\n   */\n  cancelResetClickCount_() {\n    if (this.resetId_ !== undefined) {\n      clearTimeout(this.resetId_);\n    }\n  }\n\n  /**\n   * @private\n   * @param {TouchEvent} browserEvent Browser event\n   * @param {Touch} inTouch Touch event\n   * @return {PointerEvent} A pointer object.\n   */\n  touchToPointer_(browserEvent, inTouch) {\n    const e = this.dispatcher.cloneEvent(browserEvent, inTouch);\n    // Spec specifies that pointerId 1 is reserved for Mouse.\n    // Touch identifiers can start at 0.\n    // Add 2 to the touch identifier for compatibility.\n    e.pointerId = inTouch.identifier + 2;\n    // TODO: check if this is necessary?\n    //e.target = findTarget(e);\n    e.bubbles = true;\n    e.cancelable = true;\n    e.detail = this.clickCount_;\n    e.button = 0;\n    e.buttons = 1;\n    e.width = inTouch.webkitRadiusX || inTouch.radiusX || 0;\n    e.height = inTouch.webkitRadiusY || inTouch.radiusY || 0;\n    e.pressure = inTouch.webkitForce || inTouch.force || 0.5;\n    e.isPrimary = this.isPrimaryTouch_(inTouch);\n    e.pointerType = POINTER_TYPE;\n\n    // make sure that the properties that are different for\n    // each `Touch` object are not copied from the BrowserEvent object\n    e.clientX = inTouch.clientX;\n    e.clientY = inTouch.clientY;\n    e.screenX = inTouch.screenX;\n    e.screenY = inTouch.screenY;\n\n    return e;\n  }\n\n  /**\n   * @private\n   * @param {TouchEvent} inEvent Touch event\n   * @param {function(TouchEvent, PointerEvent)} inFunction In function.\n   */\n  processTouches_(inEvent, inFunction) {\n    const touches = Array.prototype.slice.call(inEvent.changedTouches);\n    const count = touches.length;\n    function preventDefault() {\n      inEvent.preventDefault();\n    }\n    for (let i = 0; i < count; ++i) {\n      const pointer = this.touchToPointer_(inEvent, touches[i]);\n      // forward touch preventDefaults\n      pointer.preventDefault = preventDefault;\n      inFunction.call(this, inEvent, pointer);\n    }\n  }\n\n  /**\n   * @private\n   * @param {TouchList} touchList The touch list.\n   * @param {number} searchId Search identifier.\n   * @return {boolean} True, if the `Touch` with the given id is in the list.\n   */\n  findTouch_(touchList, searchId) {\n    const l = touchList.length;\n    for (let i = 0; i < l; i++) {\n      const touch = touchList[i];\n      if (touch.identifier === searchId) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /**\n   * In some instances, a touchstart can happen without a touchend. This\n   * leaves the pointermap in a broken state.\n   * Therefore, on every touchstart, we remove the touches that did not fire a\n   * touchend event.\n   * To keep state globally consistent, we fire a pointercancel for\n   * this \"abandoned\" touch\n   *\n   * @private\n   * @param {TouchEvent} inEvent The in event.\n   */\n  vacuumTouches_(inEvent) {\n    const touchList = inEvent.touches;\n    // pointerMap.getCount() should be < touchList.length here,\n    // as the touchstart has not been processed yet.\n    const keys = Object.keys(this.pointerMap);\n    const count = keys.length;\n    if (count >= touchList.length) {\n      const d = [];\n      for (let i = 0; i < count; ++i) {\n        const key = keys[i];\n        const value = this.pointerMap[key];\n        // Never remove pointerId == 1, which is mouse.\n        // Touch identifiers are 2 smaller than their pointerId, which is the\n        // index in pointermap.\n        if (key != POINTER_ID && !this.findTouch_(touchList, key - 2)) {\n          d.push(value.out);\n        }\n      }\n      for (let i = 0; i < d.length; ++i) {\n        this.cancelOut_(inEvent, d[i]);\n      }\n    }\n  }\n\n  /**\n   * @private\n   * @param {TouchEvent} browserEvent The event.\n   * @param {PointerEvent} inPointer The in pointer object.\n   */\n  overDown_(browserEvent, inPointer) {\n    this.pointerMap[inPointer.pointerId] = {\n      target: inPointer.target,\n      out: inPointer,\n      outTarget: inPointer.target\n    };\n    this.dispatcher.over(inPointer, browserEvent);\n    this.dispatcher.enter(inPointer, browserEvent);\n    this.dispatcher.down(inPointer, browserEvent);\n  }\n\n  /**\n   * @private\n   * @param {TouchEvent} browserEvent The event.\n   * @param {PointerEvent} inPointer The in pointer.\n   */\n  moveOverOut_(browserEvent, inPointer) {\n    const event = inPointer;\n    const pointer = this.pointerMap[event.pointerId];\n    // a finger drifted off the screen, ignore it\n    if (!pointer) {\n      return;\n    }\n    const outEvent = pointer.out;\n    const outTarget = pointer.outTarget;\n    this.dispatcher.move(event, browserEvent);\n    if (outEvent && outTarget !== event.target) {\n      outEvent.relatedTarget = event.target;\n      event.relatedTarget = outTarget;\n      // recover from retargeting by shadow\n      outEvent.target = outTarget;\n      if (event.target) {\n        this.dispatcher.leaveOut(outEvent, browserEvent);\n        this.dispatcher.enterOver(event, browserEvent);\n      } else {\n        // clean up case when finger leaves the screen\n        event.target = outTarget;\n        event.relatedTarget = null;\n        this.cancelOut_(browserEvent, event);\n      }\n    }\n    pointer.out = event;\n    pointer.outTarget = event.target;\n  }\n\n  /**\n   * @private\n   * @param {TouchEvent} browserEvent An event.\n   * @param {PointerEvent} inPointer The inPointer object.\n   */\n  upOut_(browserEvent, inPointer) {\n    this.dispatcher.up(inPointer, browserEvent);\n    this.dispatcher.out(inPointer, browserEvent);\n    this.dispatcher.leave(inPointer, browserEvent);\n    this.cleanUpPointer_(inPointer);\n  }\n\n  /**\n   * @private\n   * @param {TouchEvent} browserEvent The event.\n   * @param {PointerEvent} inPointer The in pointer.\n   */\n  cancelOut_(browserEvent, inPointer) {\n    this.dispatcher.cancel(inPointer, browserEvent);\n    this.dispatcher.out(inPointer, browserEvent);\n    this.dispatcher.leave(inPointer, browserEvent);\n    this.cleanUpPointer_(inPointer);\n  }\n\n  /**\n   * @private\n   * @param {PointerEvent} inPointer The inPointer object.\n   */\n  cleanUpPointer_(inPointer) {\n    delete this.pointerMap[inPointer.pointerId];\n    this.removePrimaryPointer_(inPointer);\n  }\n\n  /**\n   * Prevent synth mouse events from creating pointer events.\n   *\n   * @private\n   * @param {TouchEvent} inEvent The in event.\n   */\n  dedupSynthMouse_(inEvent) {\n    const lts = this.mouseSource.lastTouches;\n    const t = inEvent.changedTouches[0];\n    // only the primary finger will synth mouse events\n    if (this.isPrimaryTouch_(t)) {\n      // remember x/y of last touch\n      const lt = [t.clientX, t.clientY];\n      lts.push(lt);\n\n      setTimeout(function() {\n        // remove touch after timeout\n        remove(lts, lt);\n      }, this.dedupTimeout_);\n    }\n  }\n}\n\nexport default TouchSource;\n","/**\n * @module ol/pointer/PointerEventHandler\n */\n\n// Based on https://github.com/Polymer/PointerEvents\n\n// Copyright (c) 2013 The Polymer Authors. All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n// * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n// * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n// * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nimport {listen, unlisten} from '../events.js';\nimport EventTarget from '../events/EventTarget.js';\nimport {POINTER, MSPOINTER, TOUCH} from '../has.js';\nimport PointerEventType from '../pointer/EventType.js';\nimport MouseSource from '../pointer/MouseSource.js';\nimport MsSource from '../pointer/MsSource.js';\nimport NativeSource from '../pointer/NativeSource.js';\nimport PointerEvent from '../pointer/PointerEvent.js';\nimport TouchSource from '../pointer/TouchSource.js';\n\n\n/**\n * Properties to copy when cloning an event, with default values.\n * @type {Array.<Array>}\n */\nconst CLONE_PROPS = [\n  // MouseEvent\n  ['bubbles', false],\n  ['cancelable', false],\n  ['view', null],\n  ['detail', null],\n  ['screenX', 0],\n  ['screenY', 0],\n  ['clientX', 0],\n  ['clientY', 0],\n  ['ctrlKey', false],\n  ['altKey', false],\n  ['shiftKey', false],\n  ['metaKey', false],\n  ['button', 0],\n  ['relatedTarget', null],\n  // DOM Level 3\n  ['buttons', 0],\n  // PointerEvent\n  ['pointerId', 0],\n  ['width', 0],\n  ['height', 0],\n  ['pressure', 0],\n  ['tiltX', 0],\n  ['tiltY', 0],\n  ['pointerType', ''],\n  ['hwTimestamp', 0],\n  ['isPrimary', false],\n  // event instance\n  ['type', ''],\n  ['target', null],\n  ['currentTarget', null],\n  ['which', 0]\n];\n\n\nclass PointerEventHandler extends EventTarget {\n\n  /**\n   * @param {Element|HTMLDocument} element Viewport element.\n   */\n  constructor(element) {\n    super();\n\n    /**\n     * @const\n     * @private\n     * @type {Element|HTMLDocument}\n     */\n    this.element_ = element;\n\n    /**\n     * @const\n     * @type {!Object.<string, Event|Object>}\n     */\n    this.pointerMap = {};\n\n    /**\n     * @type {Object.<string, function(Event)>}\n     * @private\n     */\n    this.eventMap_ = {};\n\n    /**\n     * @type {Array.<module:ol/pointer/EventSource>}\n     * @private\n     */\n    this.eventSourceList_ = [];\n\n    this.registerSources();\n  }\n\n  /**\n   * Set up the event sources (mouse, touch and native pointers)\n   * that generate pointer events.\n   */\n  registerSources() {\n    if (POINTER) {\n      this.registerSource('native', new NativeSource(this));\n    } else if (MSPOINTER) {\n      this.registerSource('ms', new MsSource(this));\n    } else {\n      const mouseSource = new MouseSource(this);\n      this.registerSource('mouse', mouseSource);\n\n      if (TOUCH) {\n        this.registerSource('touch', new TouchSource(this, mouseSource));\n      }\n    }\n\n    // register events on the viewport element\n    this.register_();\n  }\n\n  /**\n   * Add a new event source that will generate pointer events.\n   *\n   * @param {string} name A name for the event source\n   * @param {module:ol/pointer/EventSource} source The source event.\n   */\n  registerSource(name, source) {\n    const s = source;\n    const newEvents = s.getEvents();\n\n    if (newEvents) {\n      newEvents.forEach(function(e) {\n        const handler = s.getHandlerForEvent(e);\n\n        if (handler) {\n          this.eventMap_[e] = handler.bind(s);\n        }\n      }.bind(this));\n      this.eventSourceList_.push(s);\n    }\n  }\n\n  /**\n   * Set up the events for all registered event sources.\n   * @private\n   */\n  register_() {\n    const l = this.eventSourceList_.length;\n    for (let i = 0; i < l; i++) {\n      const eventSource = this.eventSourceList_[i];\n      this.addEvents_(eventSource.getEvents());\n    }\n  }\n\n  /**\n   * Remove all registered events.\n   * @private\n   */\n  unregister_() {\n    const l = this.eventSourceList_.length;\n    for (let i = 0; i < l; i++) {\n      const eventSource = this.eventSourceList_[i];\n      this.removeEvents_(eventSource.getEvents());\n    }\n  }\n\n  /**\n   * Calls the right handler for a new event.\n   * @private\n   * @param {Event} inEvent Browser event.\n   */\n  eventHandler_(inEvent) {\n    const type = inEvent.type;\n    const handler = this.eventMap_[type];\n    if (handler) {\n      handler(inEvent);\n    }\n  }\n\n  /**\n   * Setup listeners for the given events.\n   * @private\n   * @param {Array.<string>} events List of events.\n   */\n  addEvents_(events) {\n    events.forEach(function(eventName) {\n      listen(this.element_, eventName, this.eventHandler_, this);\n    }.bind(this));\n  }\n\n  /**\n   * Unregister listeners for the given events.\n   * @private\n   * @param {Array.<string>} events List of events.\n   */\n  removeEvents_(events) {\n    events.forEach(function(e) {\n      unlisten(this.element_, e, this.eventHandler_, this);\n    }.bind(this));\n  }\n\n  /**\n   * Returns a snapshot of inEvent, with writable properties.\n   *\n   * @param {Event} event Browser event.\n   * @param {Event|Touch} inEvent An event that contains\n   *    properties to copy.\n   * @return {Object} An object containing shallow copies of\n   *    `inEvent`'s properties.\n   */\n  cloneEvent(event, inEvent) {\n    const eventCopy = {};\n    for (let i = 0, ii = CLONE_PROPS.length; i < ii; i++) {\n      const p = CLONE_PROPS[i][0];\n      eventCopy[p] = event[p] || inEvent[p] || CLONE_PROPS[i][1];\n    }\n\n    return eventCopy;\n  }\n\n  // EVENTS\n\n\n  /**\n   * Triggers a 'pointerdown' event.\n   * @param {Object} data Pointer event data.\n   * @param {Event} event The event.\n   */\n  down(data, event) {\n    this.fireEvent(PointerEventType.POINTERDOWN, data, event);\n  }\n\n  /**\n   * Triggers a 'pointermove' event.\n   * @param {Object} data Pointer event data.\n   * @param {Event} event The event.\n   */\n  move(data, event) {\n    this.fireEvent(PointerEventType.POINTERMOVE, data, event);\n  }\n\n  /**\n   * Triggers a 'pointerup' event.\n   * @param {Object} data Pointer event data.\n   * @param {Event} event The event.\n   */\n  up(data, event) {\n    this.fireEvent(PointerEventType.POINTERUP, data, event);\n  }\n\n  /**\n   * Triggers a 'pointerenter' event.\n   * @param {Object} data Pointer event data.\n   * @param {Event} event The event.\n   */\n  enter(data, event) {\n    data.bubbles = false;\n    this.fireEvent(PointerEventType.POINTERENTER, data, event);\n  }\n\n  /**\n   * Triggers a 'pointerleave' event.\n   * @param {Object} data Pointer event data.\n   * @param {Event} event The event.\n   */\n  leave(data, event) {\n    data.bubbles = false;\n    this.fireEvent(PointerEventType.POINTERLEAVE, data, event);\n  }\n\n  /**\n   * Triggers a 'pointerover' event.\n   * @param {Object} data Pointer event data.\n   * @param {Event} event The event.\n   */\n  over(data, event) {\n    data.bubbles = true;\n    this.fireEvent(PointerEventType.POINTEROVER, data, event);\n  }\n\n  /**\n   * Triggers a 'pointerout' event.\n   * @param {Object} data Pointer event data.\n   * @param {Event} event The event.\n   */\n  out(data, event) {\n    data.bubbles = true;\n    this.fireEvent(PointerEventType.POINTEROUT, data, event);\n  }\n\n  /**\n   * Triggers a 'pointercancel' event.\n   * @param {Object} data Pointer event data.\n   * @param {Event} event The event.\n   */\n  cancel(data, event) {\n    this.fireEvent(PointerEventType.POINTERCANCEL, data, event);\n  }\n\n  /**\n   * Triggers a combination of 'pointerout' and 'pointerleave' events.\n   * @param {Object} data Pointer event data.\n   * @param {Event} event The event.\n   */\n  leaveOut(data, event) {\n    this.out(data, event);\n    if (!this.contains_(data.target, data.relatedTarget)) {\n      this.leave(data, event);\n    }\n  }\n\n  /**\n   * Triggers a combination of 'pointerover' and 'pointerevents' events.\n   * @param {Object} data Pointer event data.\n   * @param {Event} event The event.\n   */\n  enterOver(data, event) {\n    this.over(data, event);\n    if (!this.contains_(data.target, data.relatedTarget)) {\n      this.enter(data, event);\n    }\n  }\n\n  /**\n   * @private\n   * @param {Element} container The container element.\n   * @param {Element} contained The contained element.\n   * @return {boolean} Returns true if the container element\n   *   contains the other element.\n   */\n  contains_(container, contained) {\n    if (!container || !contained) {\n      return false;\n    }\n    return container.contains(contained);\n  }\n\n  // EVENT CREATION AND TRACKING\n  /**\n   * Creates a new Event of type `inType`, based on the information in\n   * `data`.\n   *\n   * @param {string} inType A string representing the type of event to create.\n   * @param {Object} data Pointer event data.\n   * @param {Event} event The event.\n   * @return {module:ol/pointer/PointerEvent} A PointerEvent of type `inType`.\n   */\n  makeEvent(inType, data, event) {\n    return new PointerEvent(inType, event, data);\n  }\n\n  /**\n   * Make and dispatch an event in one call.\n   * @param {string} inType A string representing the type of event.\n   * @param {Object} data Pointer event data.\n   * @param {Event} event The event.\n   */\n  fireEvent(inType, data, event) {\n    const e = this.makeEvent(inType, data, event);\n    this.dispatchEvent(e);\n  }\n\n  /**\n   * Creates a pointer event from a native pointer event\n   * and dispatches this event.\n   * @param {Event} event A platform event with a target.\n   */\n  fireNativeEvent(event) {\n    const e = this.makeEvent(event.type, event, event);\n    this.dispatchEvent(e);\n  }\n\n  /**\n   * Wrap a native mouse event into a pointer event.\n   * This proxy method is required for the legacy IE support.\n   * @param {string} eventType The pointer event type.\n   * @param {Event} event The event.\n   * @return {module:ol/pointer/PointerEvent} The wrapped event.\n   */\n  wrapMouseEvent(eventType, event) {\n    const pointerEvent = this.makeEvent(\n      eventType, MouseSource.prepareEvent(event, this), event);\n    return pointerEvent;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  disposeInternal() {\n    this.unregister_();\n    EventTarget.prototype.disposeInternal.call(this);\n  }\n}\n\nexport default PointerEventHandler;\n","/**\n * @module ol/MapBrowserEventHandler\n */\nimport {DEVICE_PIXEL_RATIO} from './has.js';\nimport MapBrowserEventType from './MapBrowserEventType.js';\nimport MapBrowserPointerEvent from './MapBrowserPointerEvent.js';\nimport {listen, unlistenByKey} from './events.js';\nimport EventTarget from './events/EventTarget.js';\nimport PointerEventType from './pointer/EventType.js';\nimport PointerEventHandler from './pointer/PointerEventHandler.js';\n\nclass MapBrowserEventHandler extends EventTarget {\n\n  /**\n   * @param {module:ol/PluggableMap} map The map with the viewport to listen to events on.\n   * @param {number=} moveTolerance The minimal distance the pointer must travel to trigger a move.\n   */\n  constructor(map, moveTolerance) {\n\n    super();\n\n    /**\n     * This is the element that we will listen to the real events on.\n     * @type {module:ol/PluggableMap}\n     * @private\n     */\n    this.map_ = map;\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.clickTimeoutId_ = 0;\n\n    /**\n     * @type {boolean}\n     * @private\n     */\n    this.dragging_ = false;\n\n    /**\n     * @type {!Array.<module:ol/events~EventsKey>}\n     * @private\n     */\n    this.dragListenerKeys_ = [];\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.moveTolerance_ = moveTolerance ?\n      moveTolerance * DEVICE_PIXEL_RATIO : DEVICE_PIXEL_RATIO;\n\n    /**\n     * The most recent \"down\" type event (or null if none have occurred).\n     * Set on pointerdown.\n     * @type {module:ol/pointer/PointerEvent}\n     * @private\n     */\n    this.down_ = null;\n\n    const element = this.map_.getViewport();\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.activePointers_ = 0;\n\n    /**\n     * @type {!Object.<number, boolean>}\n     * @private\n     */\n    this.trackedTouches_ = {};\n\n    /**\n     * Event handler which generates pointer events for\n     * the viewport element.\n     *\n     * @type {module:ol/pointer/PointerEventHandler}\n     * @private\n     */\n    this.pointerEventHandler_ = new PointerEventHandler(element);\n\n    /**\n     * Event handler which generates pointer events for\n     * the document (used when dragging).\n     *\n     * @type {module:ol/pointer/PointerEventHandler}\n     * @private\n     */\n    this.documentPointerEventHandler_ = null;\n\n    /**\n     * @type {?module:ol/events~EventsKey}\n     * @private\n     */\n    this.pointerdownListenerKey_ = listen(this.pointerEventHandler_,\n      PointerEventType.POINTERDOWN,\n      this.handlePointerDown_, this);\n\n    /**\n     * @type {?module:ol/events~EventsKey}\n     * @private\n     */\n    this.relayedListenerKey_ = listen(this.pointerEventHandler_,\n      PointerEventType.POINTERMOVE,\n      this.relayEvent_, this);\n\n  }\n\n  /**\n   * @param {module:ol/pointer/PointerEvent} pointerEvent Pointer\n   * event.\n   * @private\n   */\n  emulateClick_(pointerEvent) {\n    let newEvent = new MapBrowserPointerEvent(\n      MapBrowserEventType.CLICK, this.map_, pointerEvent);\n    this.dispatchEvent(newEvent);\n    if (this.clickTimeoutId_ !== 0) {\n      // double-click\n      clearTimeout(this.clickTimeoutId_);\n      this.clickTimeoutId_ = 0;\n      newEvent = new MapBrowserPointerEvent(\n        MapBrowserEventType.DBLCLICK, this.map_, pointerEvent);\n      this.dispatchEvent(newEvent);\n    } else {\n      // click\n      this.clickTimeoutId_ = setTimeout(function() {\n        this.clickTimeoutId_ = 0;\n        const newEvent = new MapBrowserPointerEvent(\n          MapBrowserEventType.SINGLECLICK, this.map_, pointerEvent);\n        this.dispatchEvent(newEvent);\n      }.bind(this), 250);\n    }\n  }\n\n  /**\n   * Keeps track on how many pointers are currently active.\n   *\n   * @param {module:ol/pointer/PointerEvent} pointerEvent Pointer\n   * event.\n   * @private\n   */\n  updateActivePointers_(pointerEvent) {\n    const event = pointerEvent;\n\n    if (event.type == MapBrowserEventType.POINTERUP ||\n        event.type == MapBrowserEventType.POINTERCANCEL) {\n      delete this.trackedTouches_[event.pointerId];\n    } else if (event.type == MapBrowserEventType.POINTERDOWN) {\n      this.trackedTouches_[event.pointerId] = true;\n    }\n    this.activePointers_ = Object.keys(this.trackedTouches_).length;\n  }\n\n  /**\n   * @param {module:ol/pointer/PointerEvent} pointerEvent Pointer\n   * event.\n   * @private\n   */\n  handlePointerUp_(pointerEvent) {\n    this.updateActivePointers_(pointerEvent);\n    const newEvent = new MapBrowserPointerEvent(\n      MapBrowserEventType.POINTERUP, this.map_, pointerEvent);\n    this.dispatchEvent(newEvent);\n\n    // We emulate click events on left mouse button click, touch contact, and pen\n    // contact. isMouseActionButton returns true in these cases (evt.button is set\n    // to 0).\n    // See http://www.w3.org/TR/pointerevents/#button-states\n    // We only fire click, singleclick, and doubleclick if nobody has called\n    // event.stopPropagation() or event.preventDefault().\n    if (!newEvent.propagationStopped && !this.dragging_ && this.isMouseActionButton_(pointerEvent)) {\n      this.emulateClick_(this.down_);\n    }\n\n    if (this.activePointers_ === 0) {\n      this.dragListenerKeys_.forEach(unlistenByKey);\n      this.dragListenerKeys_.length = 0;\n      this.dragging_ = false;\n      this.down_ = null;\n      this.documentPointerEventHandler_.dispose();\n      this.documentPointerEventHandler_ = null;\n    }\n  }\n\n  /**\n   * @param {module:ol/pointer/PointerEvent} pointerEvent Pointer\n   * event.\n   * @return {boolean} If the left mouse button was pressed.\n   * @private\n   */\n  isMouseActionButton_(pointerEvent) {\n    return pointerEvent.button === 0;\n  }\n\n  /**\n   * @param {module:ol/pointer/PointerEvent} pointerEvent Pointer\n   * event.\n   * @private\n   */\n  handlePointerDown_(pointerEvent) {\n    this.updateActivePointers_(pointerEvent);\n    const newEvent = new MapBrowserPointerEvent(\n      MapBrowserEventType.POINTERDOWN, this.map_, pointerEvent);\n    this.dispatchEvent(newEvent);\n\n    this.down_ = pointerEvent;\n\n    if (this.dragListenerKeys_.length === 0) {\n      /* Set up a pointer event handler on the `document`,\n       * which is required when the pointer is moved outside\n       * the viewport when dragging.\n       */\n      this.documentPointerEventHandler_ =\n          new PointerEventHandler(document);\n\n      this.dragListenerKeys_.push(\n        listen(this.documentPointerEventHandler_,\n          MapBrowserEventType.POINTERMOVE,\n          this.handlePointerMove_, this),\n        listen(this.documentPointerEventHandler_,\n          MapBrowserEventType.POINTERUP,\n          this.handlePointerUp_, this),\n        /* Note that the listener for `pointercancel is set up on\n         * `pointerEventHandler_` and not `documentPointerEventHandler_` like\n         * the `pointerup` and `pointermove` listeners.\n         *\n         * The reason for this is the following: `TouchSource.vacuumTouches_()`\n         * issues `pointercancel` events, when there was no `touchend` for a\n         * `touchstart`. Now, let's say a first `touchstart` is registered on\n         * `pointerEventHandler_`. The `documentPointerEventHandler_` is set up.\n         * But `documentPointerEventHandler_` doesn't know about the first\n         * `touchstart`. If there is no `touchend` for the `touchstart`, we can\n         * only receive a `touchcancel` from `pointerEventHandler_`, because it is\n         * only registered there.\n         */\n        listen(this.pointerEventHandler_,\n          MapBrowserEventType.POINTERCANCEL,\n          this.handlePointerUp_, this)\n      );\n    }\n  }\n\n  /**\n   * @param {module:ol/pointer/PointerEvent} pointerEvent Pointer\n   * event.\n   * @private\n   */\n  handlePointerMove_(pointerEvent) {\n    // Between pointerdown and pointerup, pointermove events are triggered.\n    // To avoid a 'false' touchmove event to be dispatched, we test if the pointer\n    // moved a significant distance.\n    if (this.isMoving_(pointerEvent)) {\n      this.dragging_ = true;\n      const newEvent = new MapBrowserPointerEvent(\n        MapBrowserEventType.POINTERDRAG, this.map_, pointerEvent,\n        this.dragging_);\n      this.dispatchEvent(newEvent);\n    }\n\n    // Some native android browser triggers mousemove events during small period\n    // of time. See: https://code.google.com/p/android/issues/detail?id=5491 or\n    // https://code.google.com/p/android/issues/detail?id=19827\n    // ex: Galaxy Tab P3110 + Android 4.1.1\n    pointerEvent.preventDefault();\n  }\n\n  /**\n   * Wrap and relay a pointer event.  Note that this requires that the type\n   * string for the MapBrowserPointerEvent matches the PointerEvent type.\n   * @param {module:ol/pointer/PointerEvent} pointerEvent Pointer\n   * event.\n   * @private\n   */\n  relayEvent_(pointerEvent) {\n    const dragging = !!(this.down_ && this.isMoving_(pointerEvent));\n    this.dispatchEvent(new MapBrowserPointerEvent(\n      pointerEvent.type, this.map_, pointerEvent, dragging));\n  }\n\n  /**\n   * @param {module:ol/pointer/PointerEvent} pointerEvent Pointer\n   * event.\n   * @return {boolean} Is moving.\n   * @private\n   */\n  isMoving_(pointerEvent) {\n    return this.dragging_ ||\n        Math.abs(pointerEvent.clientX - this.down_.clientX) > this.moveTolerance_ ||\n        Math.abs(pointerEvent.clientY - this.down_.clientY) > this.moveTolerance_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  disposeInternal() {\n    if (this.relayedListenerKey_) {\n      unlistenByKey(this.relayedListenerKey_);\n      this.relayedListenerKey_ = null;\n    }\n    if (this.pointerdownListenerKey_) {\n      unlistenByKey(this.pointerdownListenerKey_);\n      this.pointerdownListenerKey_ = null;\n    }\n\n    this.dragListenerKeys_.forEach(unlistenByKey);\n    this.dragListenerKeys_.length = 0;\n\n    if (this.documentPointerEventHandler_) {\n      this.documentPointerEventHandler_.dispose();\n      this.documentPointerEventHandler_ = null;\n    }\n    if (this.pointerEventHandler_) {\n      this.pointerEventHandler_.dispose();\n      this.pointerEventHandler_ = null;\n    }\n    super.disposeInternal();\n  }\n}\n\n\nexport default MapBrowserEventHandler;\n","/**\n * @module ol/MapEventType\n */\n\n/**\n * @enum {string}\n */\nexport default {\n\n  /**\n   * Triggered after a map frame is rendered.\n   * @event module:ol/MapEvent~MapEvent#postrender\n   * @api\n   */\n  POSTRENDER: 'postrender',\n\n  /**\n   * Triggered when the map starts moving.\n   * @event module:ol/MapEvent~MapEvent#movestart\n   * @api\n   */\n  MOVESTART: 'movestart',\n\n  /**\n   * Triggered after the map is moved.\n   * @event module:ol/MapEvent~MapEvent#moveend\n   * @api\n   */\n  MOVEEND: 'moveend'\n\n};\n","/**\n * @module ol/MapProperty\n */\n\n/**\n * @enum {string}\n */\nexport default {\n  LAYERGROUP: 'layergroup',\n  SIZE: 'size',\n  TARGET: 'target',\n  VIEW: 'view'\n};\n","/**\n * @module ol/structs/PriorityQueue\n */\nimport {assert} from '../asserts.js';\nimport {clear} from '../obj.js';\n\n\n/**\n * @type {number}\n */\nexport const DROP = Infinity;\n\n\n/**\n * @classdesc\n * Priority queue.\n *\n * The implementation is inspired from the Closure Library's Heap class and\n * Python's heapq module.\n *\n * See http://closure-library.googlecode.com/svn/docs/closure_goog_structs_heap.js.source.html\n * and http://hg.python.org/cpython/file/2.7/Lib/heapq.py.\n *\n * @template T\n */\nclass PriorityQueue {\n\n  /**\n   * @param {function(T): number} priorityFunction Priority function.\n   * @param {function(T): string} keyFunction Key function.\n   */\n  constructor(priorityFunction, keyFunction) {\n\n    /**\n     * @type {function(T): number}\n     * @private\n     */\n    this.priorityFunction_ = priorityFunction;\n\n    /**\n     * @type {function(T): string}\n     * @private\n     */\n    this.keyFunction_ = keyFunction;\n\n    /**\n     * @type {Array.<T>}\n     * @private\n     */\n    this.elements_ = [];\n\n    /**\n     * @type {Array.<number>}\n     * @private\n     */\n    this.priorities_ = [];\n\n    /**\n     * @type {!Object.<string, boolean>}\n     * @private\n     */\n    this.queuedElements_ = {};\n\n  }\n\n  /**\n   * FIXME empty description for jsdoc\n   */\n  clear() {\n    this.elements_.length = 0;\n    this.priorities_.length = 0;\n    clear(this.queuedElements_);\n  }\n\n\n  /**\n   * Remove and return the highest-priority element. O(log N).\n   * @return {T} Element.\n   */\n  dequeue() {\n    const elements = this.elements_;\n    const priorities = this.priorities_;\n    const element = elements[0];\n    if (elements.length == 1) {\n      elements.length = 0;\n      priorities.length = 0;\n    } else {\n      elements[0] = elements.pop();\n      priorities[0] = priorities.pop();\n      this.siftUp_(0);\n    }\n    const elementKey = this.keyFunction_(element);\n    delete this.queuedElements_[elementKey];\n    return element;\n  }\n\n\n  /**\n   * Enqueue an element. O(log N).\n   * @param {T} element Element.\n   * @return {boolean} The element was added to the queue.\n   */\n  enqueue(element) {\n    assert(!(this.keyFunction_(element) in this.queuedElements_),\n      31); // Tried to enqueue an `element` that was already added to the queue\n    const priority = this.priorityFunction_(element);\n    if (priority != DROP) {\n      this.elements_.push(element);\n      this.priorities_.push(priority);\n      this.queuedElements_[this.keyFunction_(element)] = true;\n      this.siftDown_(0, this.elements_.length - 1);\n      return true;\n    }\n    return false;\n  }\n\n\n  /**\n   * @return {number} Count.\n   */\n  getCount() {\n    return this.elements_.length;\n  }\n\n\n  /**\n   * Gets the index of the left child of the node at the given index.\n   * @param {number} index The index of the node to get the left child for.\n   * @return {number} The index of the left child.\n   * @private\n   */\n  getLeftChildIndex_(index) {\n    return index * 2 + 1;\n  }\n\n\n  /**\n   * Gets the index of the right child of the node at the given index.\n   * @param {number} index The index of the node to get the right child for.\n   * @return {number} The index of the right child.\n   * @private\n   */\n  getRightChildIndex_(index) {\n    return index * 2 + 2;\n  }\n\n\n  /**\n   * Gets the index of the parent of the node at the given index.\n   * @param {number} index The index of the node to get the parent for.\n   * @return {number} The index of the parent.\n   * @private\n   */\n  getParentIndex_(index) {\n    return (index - 1) >> 1;\n  }\n\n\n  /**\n   * Make this a heap. O(N).\n   * @private\n   */\n  heapify_() {\n    let i;\n    for (i = (this.elements_.length >> 1) - 1; i >= 0; i--) {\n      this.siftUp_(i);\n    }\n  }\n\n\n  /**\n   * @return {boolean} Is empty.\n   */\n  isEmpty() {\n    return this.elements_.length === 0;\n  }\n\n\n  /**\n   * @param {string} key Key.\n   * @return {boolean} Is key queued.\n   */\n  isKeyQueued(key) {\n    return key in this.queuedElements_;\n  }\n\n\n  /**\n   * @param {T} element Element.\n   * @return {boolean} Is queued.\n   */\n  isQueued(element) {\n    return this.isKeyQueued(this.keyFunction_(element));\n  }\n\n\n  /**\n   * @param {number} index The index of the node to move down.\n   * @private\n   */\n  siftUp_(index) {\n    const elements = this.elements_;\n    const priorities = this.priorities_;\n    const count = elements.length;\n    const element = elements[index];\n    const priority = priorities[index];\n    const startIndex = index;\n\n    while (index < (count >> 1)) {\n      const lIndex = this.getLeftChildIndex_(index);\n      const rIndex = this.getRightChildIndex_(index);\n\n      const smallerChildIndex = rIndex < count &&\n          priorities[rIndex] < priorities[lIndex] ?\n        rIndex : lIndex;\n\n      elements[index] = elements[smallerChildIndex];\n      priorities[index] = priorities[smallerChildIndex];\n      index = smallerChildIndex;\n    }\n\n    elements[index] = element;\n    priorities[index] = priority;\n    this.siftDown_(startIndex, index);\n  }\n\n\n  /**\n   * @param {number} startIndex The index of the root.\n   * @param {number} index The index of the node to move up.\n   * @private\n   */\n  siftDown_(startIndex, index) {\n    const elements = this.elements_;\n    const priorities = this.priorities_;\n    const element = elements[index];\n    const priority = priorities[index];\n\n    while (index > startIndex) {\n      const parentIndex = this.getParentIndex_(index);\n      if (priorities[parentIndex] > priority) {\n        elements[index] = elements[parentIndex];\n        priorities[index] = priorities[parentIndex];\n        index = parentIndex;\n      } else {\n        break;\n      }\n    }\n    elements[index] = element;\n    priorities[index] = priority;\n  }\n\n\n  /**\n   * FIXME empty description for jsdoc\n   */\n  reprioritize() {\n    const priorityFunction = this.priorityFunction_;\n    const elements = this.elements_;\n    const priorities = this.priorities_;\n    let index = 0;\n    const n = elements.length;\n    let element, i, priority;\n    for (i = 0; i < n; ++i) {\n      element = elements[i];\n      priority = priorityFunction(element);\n      if (priority == DROP) {\n        delete this.queuedElements_[this.keyFunction_(element)];\n      } else {\n        priorities[index] = priority;\n        elements[index++] = element;\n      }\n    }\n    elements.length = index;\n    priorities.length = index;\n    this.heapify_();\n  }\n\n}\n\n\nexport default PriorityQueue;\n","/**\n * @module ol/TileQueue\n */\nimport TileState from './TileState.js';\nimport {listen, unlisten} from './events.js';\nimport EventType from './events/EventType.js';\nimport PriorityQueue from './structs/PriorityQueue.js';\n\n\n/**\n * @typedef {function(module:ol/Tile, string, module:ol/coordinate~Coordinate, number): number} PriorityFunction\n */\n\n\nclass TileQueue extends PriorityQueue {\n\n  /**\n   * @param {module:ol/TileQueue~PriorityFunction} tilePriorityFunction Tile priority function.\n   * @param {function(): ?} tileChangeCallback Function called on each tile change event.\n   */\n  constructor(tilePriorityFunction, tileChangeCallback) {\n\n    super(\n      /**\n       * @param {Array} element Element.\n       * @return {number} Priority.\n       */\n      function(element) {\n        return tilePriorityFunction.apply(null, element);\n      },\n      /**\n       * @param {Array} element Element.\n       * @return {string} Key.\n       */\n      function(element) {\n        return (/** @type {module:ol/Tile} */ (element[0]).getKey());\n      });\n\n    /**\n     * @private\n     * @type {function(): ?}\n     */\n    this.tileChangeCallback_ = tileChangeCallback;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.tilesLoading_ = 0;\n\n    /**\n     * @private\n     * @type {!Object.<string,boolean>}\n     */\n    this.tilesLoadingKeys_ = {};\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  enqueue(element) {\n    const added = super.enqueue(element);\n    if (added) {\n      const tile = element[0];\n      listen(tile, EventType.CHANGE, this.handleTileChange, this);\n    }\n    return added;\n  }\n\n  /**\n   * @return {number} Number of tiles loading.\n   */\n  getTilesLoading() {\n    return this.tilesLoading_;\n  }\n\n  /**\n   * @param {module:ol/events/Event} event Event.\n   * @protected\n   */\n  handleTileChange(event) {\n    const tile = /** @type {module:ol/Tile} */ (event.target);\n    const state = tile.getState();\n    if (state === TileState.LOADED || state === TileState.ERROR ||\n        state === TileState.EMPTY || state === TileState.ABORT) {\n      unlisten(tile, EventType.CHANGE, this.handleTileChange, this);\n      const tileKey = tile.getKey();\n      if (tileKey in this.tilesLoadingKeys_) {\n        delete this.tilesLoadingKeys_[tileKey];\n        --this.tilesLoading_;\n      }\n      this.tileChangeCallback_();\n    }\n  }\n\n  /**\n   * @param {number} maxTotalLoading Maximum number tiles to load simultaneously.\n   * @param {number} maxNewLoads Maximum number of new tiles to load.\n   */\n  loadMoreTiles(maxTotalLoading, maxNewLoads) {\n    let newLoads = 0;\n    let abortedTiles = false;\n    let state, tile, tileKey;\n    while (this.tilesLoading_ < maxTotalLoading && newLoads < maxNewLoads &&\n           this.getCount() > 0) {\n      tile = /** @type {module:ol/Tile} */ (this.dequeue()[0]);\n      tileKey = tile.getKey();\n      state = tile.getState();\n      if (state === TileState.ABORT) {\n        abortedTiles = true;\n      } else if (state === TileState.IDLE && !(tileKey in this.tilesLoadingKeys_)) {\n        this.tilesLoadingKeys_[tileKey] = true;\n        ++this.tilesLoading_;\n        ++newLoads;\n        tile.load();\n      }\n    }\n    if (newLoads === 0 && abortedTiles) {\n      // Do not stop the render loop when all wanted tiles were aborted due to\n      // a small, saturated tile cache.\n      this.tileChangeCallback_();\n    }\n  }\n}\n\n\nexport default TileQueue;\n","/**\n * @module ol/tilegrid/common\n */\n\n/**\n * Default maximum zoom for default tile grids.\n * @type {number}\n */\nexport const DEFAULT_MAX_ZOOM = 42;\n\n/**\n * Default tile size.\n * @type {number}\n */\nexport const DEFAULT_TILE_SIZE = 256;\n","/**\n * @module ol/centerconstraint\n */\nimport {clamp} from './math.js';\n\n\n/**\n * @typedef {function((module:ol/coordinate~Coordinate|undefined)): (module:ol/coordinate~Coordinate|undefined)} Type\n */\n\n\n/**\n * @param {module:ol/extent~Extent} extent Extent.\n * @return {module:ol/centerconstraint~Type} The constraint.\n */\nexport function createExtent(extent) {\n  return (\n    /**\n     * @param {module:ol/coordinate~Coordinate=} center Center.\n     * @return {module:ol/coordinate~Coordinate|undefined} Center.\n     */\n    function(center) {\n      if (center) {\n        return [\n          clamp(center[0], extent[0], extent[2]),\n          clamp(center[1], extent[1], extent[3])\n        ];\n      } else {\n        return undefined;\n      }\n    }\n  );\n}\n\n\n/**\n * @param {module:ol/coordinate~Coordinate=} center Center.\n * @return {module:ol/coordinate~Coordinate|undefined} Center.\n */\nexport function none(center) {\n  return center;\n}\n","/**\n * @module ol/rotationconstraint\n */\nimport {toRadians} from './math.js';\n\n\n/**\n * @typedef {function((number|undefined), number): (number|undefined)} Type\n */\n\n\n/**\n * @param {number|undefined} rotation Rotation.\n * @param {number} delta Delta.\n * @return {number|undefined} Rotation.\n */\nexport function disable(rotation, delta) {\n  if (rotation !== undefined) {\n    return 0;\n  } else {\n    return undefined;\n  }\n}\n\n\n/**\n * @param {number|undefined} rotation Rotation.\n * @param {number} delta Delta.\n * @return {number|undefined} Rotation.\n */\nexport function none(rotation, delta) {\n  if (rotation !== undefined) {\n    return rotation + delta;\n  } else {\n    return undefined;\n  }\n}\n\n\n/**\n * @param {number} n N.\n * @return {module:ol/rotationconstraint~Type} Rotation constraint.\n */\nexport function createSnapToN(n) {\n  const theta = 2 * Math.PI / n;\n  return (\n    /**\n     * @param {number|undefined} rotation Rotation.\n     * @param {number} delta Delta.\n     * @return {number|undefined} Rotation.\n     */\n    function(rotation, delta) {\n      if (rotation !== undefined) {\n        rotation = Math.floor((rotation + delta) / theta + 0.5) * theta;\n        return rotation;\n      } else {\n        return undefined;\n      }\n    });\n}\n\n\n/**\n * @param {number=} opt_tolerance Tolerance.\n * @return {module:ol/rotationconstraint~Type} Rotation constraint.\n */\nexport function createSnapToZero(opt_tolerance) {\n  const tolerance = opt_tolerance || toRadians(5);\n  return (\n    /**\n     * @param {number|undefined} rotation Rotation.\n     * @param {number} delta Delta.\n     * @return {number|undefined} Rotation.\n     */\n    function(rotation, delta) {\n      if (rotation !== undefined) {\n        if (Math.abs(rotation + delta) <= tolerance) {\n          return 0;\n        } else {\n          return rotation + delta;\n        }\n      } else {\n        return undefined;\n      }\n    });\n}\n","/**\n * @module ol/ViewHint\n */\n\n/**\n * @enum {number}\n */\nexport default {\n  ANIMATING: 0,\n  INTERACTING: 1\n};\n","/**\n * @module ol/ViewProperty\n */\n\n/**\n * @enum {string}\n */\nexport default {\n  CENTER: 'center',\n  RESOLUTION: 'resolution',\n  ROTATION: 'rotation'\n};\n","/**\n * @module ol/View\n */\nimport {DEFAULT_TILE_SIZE} from './tilegrid/common.js';\nimport {getUid} from './util.js';\nimport {UNDEFINED} from './functions.js';\nimport {createExtent, none as centerNone} from './centerconstraint.js';\nimport BaseObject from './Object.js';\nimport {createSnapToResolutions, createSnapToPower} from './resolutionconstraint.js';\nimport {createSnapToZero, createSnapToN, none as rotationNone, disable} from './rotationconstraint.js';\nimport ViewHint from './ViewHint.js';\nimport ViewProperty from './ViewProperty.js';\nimport {linearFindNearest} from './array.js';\nimport {assert} from './asserts.js';\nimport {add as addCoordinate, rotate as rotateCoordinate, equals as coordinatesEqual} from './coordinate.js';\nimport {inAndOut} from './easing.js';\nimport {getForViewAndSize, getCenter, getHeight, getWidth, isEmpty} from './extent.js';\nimport GeometryType from './geom/GeometryType.js';\nimport {fromExtent as polygonFromExtent} from './geom/Polygon.js';\nimport SimpleGeometry from './geom/SimpleGeometry.js';\nimport {clamp, modulo} from './math.js';\nimport {assign} from './obj.js';\nimport {createProjection, METERS_PER_UNIT} from './proj.js';\nimport Units from './proj/Units.js';\n\n\n/**\n * An animation configuration\n *\n * @typedef {Object} Animation\n * @property {module:ol/coordinate~Coordinate} [sourceCenter]\n * @property {module:ol/coordinate~Coordinate} [targetCenter]\n * @property {number} [sourceResolution]\n * @property {number} [targetResolution]\n * @property {number} [sourceRotation]\n * @property {number} [targetRotation]\n * @property {module:ol/coordinate~Coordinate} [anchor]\n * @property {number} start\n * @property {number} duration\n * @property {boolean} complete\n * @property {function(number):number} easing\n * @property {function(boolean)} callback\n */\n\n\n/**\n * @typedef {Object} Constraints\n * @property {module:ol/centerconstraint~Type} center\n * @property {module:ol/resolutionconstraint~Type} resolution\n * @property {module:ol/rotationconstraint~Type} rotation\n */\n\n\n/**\n * @typedef {Object} FitOptions\n * @property {module:ol/size~Size} [size] The size in pixels of the box to fit\n * the extent into. Default is the current size of the first map in the DOM that\n * uses this view, or `[100, 100]` if no such map is found.\n * @property {!Array.<number>} [padding=[0, 0, 0, 0]] Padding (in pixels) to be\n * cleared inside the view. Values in the array are top, right, bottom and left\n * padding.\n * @property {boolean} [constrainResolution=true] Constrain the resolution.\n * @property {boolean} [nearest=false] If `constrainResolution` is `true`, get\n * the nearest extent instead of the closest that actually fits the view.\n * @property {number} [minResolution=0] Minimum resolution that we zoom to.\n * @property {number} [maxZoom] Maximum zoom level that we zoom to. If\n * `minResolution` is given, this property is ignored.\n * @property {number} [duration] The duration of the animation in milliseconds.\n * By default, there is no animation to the target extent.\n * @property {function(number):number} [easing] The easing function used during\n * the animation (defaults to {@link module:ol/easing~inAndOut}).\n * The function will be called for each frame with a number representing a\n * fraction of the animation's duration.  The function should return a number\n * between 0 and 1 representing the progress toward the destination state.\n * @property {function(boolean)} [callback] Function called when the view is in\n * its final position. The callback will be called with `true` if the animation\n * series completed on its own or `false` if it was cancelled.\n */\n\n\n/**\n * @typedef {Object} ViewOptions\n * @property {module:ol/coordinate~Coordinate} [center] The initial center for\n * the view. The coordinate system for the center is specified with the\n * `projection` option. Layer sources will not be fetched if this is not set,\n * but the center can be set later with {@link #setCenter}.\n * @property {boolean|number} [constrainRotation=true] Rotation constraint.\n * `false` means no constraint. `true` means no constraint, but snap to zero\n * near zero. A number constrains the rotation to that number of values. For\n * example, `4` will constrain the rotation to 0, 90, 180, and 270 degrees.\n * @property {boolean} [enableRotation=true] Enable rotation.\n * If `false`, a rotation constraint that always sets the rotation to zero is\n * used. The `constrainRotation` option has no effect if `enableRotation` is\n * `false`.\n * @property {module:ol/extent~Extent} [extent] The extent that constrains the\n * center, in other words, center cannot be set outside this extent.\n * @property {number} [maxResolution] The maximum resolution used to determine\n * the resolution constraint. It is used together with `minResolution` (or\n * `maxZoom`) and `zoomFactor`. If unspecified it is calculated in such a way\n * that the projection's validity extent fits in a 256x256 px tile. If the\n * projection is Spherical Mercator (the default) then `maxResolution` defaults\n * to `40075016.68557849 / 256 = 156543.03392804097`.\n * @property {number} [minResolution] The minimum resolution used to determine\n * the resolution constraint.  It is used together with `maxResolution` (or\n * `minZoom`) and `zoomFactor`.  If unspecified it is calculated assuming 29\n * zoom levels (with a factor of 2). If the projection is Spherical Mercator\n * (the default) then `minResolution` defaults to\n * `40075016.68557849 / 256 / Math.pow(2, 28) = 0.0005831682455839253`.\n * @property {number} [maxZoom=28] The maximum zoom level used to determine the\n * resolution constraint. It is used together with `minZoom` (or\n * `maxResolution`) and `zoomFactor`.  Note that if `minResolution` is also\n * provided, it is given precedence over `maxZoom`.\n * @property {number} [minZoom=0] The minimum zoom level used to determine the\n * resolution constraint. It is used together with `maxZoom` (or\n * `minResolution`) and `zoomFactor`.  Note that if `maxResolution` is also\n * provided, it is given precedence over `minZoom`.\n * @property {module:ol/proj~ProjectionLike} [projection='EPSG:3857'] The\n * projection. The default is Spherical Mercator.\n * @property {number} [resolution] The initial resolution for the view. The\n * units are `projection` units per pixel (e.g. meters per pixel). An\n * alternative to setting this is to set `zoom`. Layer sources will not be\n * fetched if neither this nor `zoom` are defined, but they can be set later\n * with {@link #setZoom} or {@link #setResolution}.\n * @property {Array.<number>} [resolutions] Resolutions to determine the\n * resolution constraint. If set the `maxResolution`, `minResolution`,\n * `minZoom`, `maxZoom`, and `zoomFactor` options are ignored.\n * @property {number} [rotation=0] The initial rotation for the view in radians\n * (positive rotation clockwise, 0 means North).\n * @property {number} [zoom] Only used if `resolution` is not defined. Zoom\n * level used to calculate the initial resolution for the view. The initial\n * resolution is determined using the {@link #constrainResolution} method.\n * @property {number} [zoomFactor=2] The zoom factor used to determine the\n * resolution constraint.\n */\n\n\n/**\n * @typedef {Object} AnimationOptions\n * @property {module:ol/coordinate~Coordinate|undefined} center The center of the view at the end of\n * the animation.\n * @property {number|undefined} zoom The zoom level of the view at the end of the\n * animation. This takes precedence over `resolution`.\n * @property {number|undefined} resolution The resolution of the view at the end\n * of the animation.  If `zoom` is also provided, this option will be ignored.\n * @property {number|undefined} rotation The rotation of the view at the end of\n * the animation.\n * @property {module:ol/coordinate~Coordinate|undefined} anchor Optional anchor to remained fixed\n * during a rotation or resolution animation.\n * @property {number} [duration=1000] The duration of the animation in milliseconds.\n * @property {function(number):number} [easing] The easing function used\n * during the animation (defaults to {@link module:ol/easing~inAndOut}).\n * The function will be called for each frame with a number representing a\n * fraction of the animation's duration.  The function should return a number\n * between 0 and 1 representing the progress toward the destination state.\n */\n\n\n/**\n * @typedef {Object} State\n * @property {module:ol/coordinate~Coordinate} center\n * @property {module:ol/proj/Projection} projection\n * @property {number} resolution\n * @property {number} rotation\n * @property {number} zoom\n */\n\n\n/**\n * Default min zoom level for the map view.\n * @type {number}\n */\nconst DEFAULT_MIN_ZOOM = 0;\n\n\n/**\n * @classdesc\n * A View object represents a simple 2D view of the map.\n *\n * This is the object to act upon to change the center, resolution,\n * and rotation of the map.\n *\n * ### The view states\n *\n * An View is determined by three states: `center`, `resolution`,\n * and `rotation`. Each state has a corresponding getter and setter, e.g.\n * `getCenter` and `setCenter` for the `center` state.\n *\n * An View has a `projection`. The projection determines the\n * coordinate system of the center, and its units determine the units of the\n * resolution (projection units per pixel). The default projection is\n * Spherical Mercator (EPSG:3857).\n *\n * ### The constraints\n *\n * `setCenter`, `setResolution` and `setRotation` can be used to change the\n * states of the view. Any value can be passed to the setters. And the value\n * that is passed to a setter will effectively be the value set in the view,\n * and returned by the corresponding getter.\n *\n * But a View object also has a *resolution constraint*, a\n * *rotation constraint* and a *center constraint*.\n *\n * As said above, no constraints are applied when the setters are used to set\n * new states for the view. Applying constraints is done explicitly through\n * the use of the `constrain*` functions (`constrainResolution` and\n * `constrainRotation` and `constrainCenter`).\n *\n * The main users of the constraints are the interactions and the\n * controls. For example, double-clicking on the map changes the view to\n * the \"next\" resolution. And releasing the fingers after pinch-zooming\n * snaps to the closest resolution (with an animation).\n *\n * The *resolution constraint* snaps to specific resolutions. It is\n * determined by the following options: `resolutions`, `maxResolution`,\n * `maxZoom`, and `zoomFactor`. If `resolutions` is set, the other three\n * options are ignored. See documentation for each option for more\n * information.\n *\n * The *rotation constraint* snaps to specific angles. It is determined\n * by the following options: `enableRotation` and `constrainRotation`.\n * By default the rotation value is snapped to zero when approaching the\n * horizontal.\n *\n * The *center constraint* is determined by the `extent` option. By\n * default the center is not constrained at all.\n *\n  * @api\n */\nclass View extends BaseObject {\n\n  /**\n   * @param {module:ol/View~ViewOptions=} opt_options View options.\n   */\n  constructor(opt_options) {\n    super();\n\n    const options = assign({}, opt_options);\n\n    /**\n     * @private\n     * @type {Array.<number>}\n     */\n    this.hints_ = [0, 0];\n\n    /**\n     * @private\n     * @type {Array.<Array.<module:ol/View~Animation>>}\n     */\n    this.animations_ = [];\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.updateAnimationKey_;\n\n    this.updateAnimations_ = this.updateAnimations_.bind(this);\n\n    /**\n     * @private\n     * @const\n     * @type {module:ol/proj/Projection}\n     */\n    this.projection_ = createProjection(options.projection, 'EPSG:3857');\n\n    this.applyOptions_(options);\n  }\n\n  /**\n   * Set up the view with the given options.\n   * @param {module:ol/View~ViewOptions} options View options.\n   */\n  applyOptions_(options) {\n\n    /**\n     * @type {Object.<string, *>}\n     */\n    const properties = {};\n    properties[ViewProperty.CENTER] = options.center !== undefined ?\n      options.center : null;\n\n    const resolutionConstraintInfo = createResolutionConstraint(options);\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.maxResolution_ = resolutionConstraintInfo.maxResolution;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.minResolution_ = resolutionConstraintInfo.minResolution;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.zoomFactor_ = resolutionConstraintInfo.zoomFactor;\n\n    /**\n     * @private\n     * @type {Array.<number>|undefined}\n     */\n    this.resolutions_ = options.resolutions;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.minZoom_ = resolutionConstraintInfo.minZoom;\n\n    const centerConstraint = createCenterConstraint(options);\n    const resolutionConstraint = resolutionConstraintInfo.constraint;\n    const rotationConstraint = createRotationConstraint(options);\n\n    /**\n     * @private\n     * @type {module:ol/View~Constraints}\n     */\n    this.constraints_ = {\n      center: centerConstraint,\n      resolution: resolutionConstraint,\n      rotation: rotationConstraint\n    };\n\n    if (options.resolution !== undefined) {\n      properties[ViewProperty.RESOLUTION] = options.resolution;\n    } else if (options.zoom !== undefined) {\n      properties[ViewProperty.RESOLUTION] = this.constrainResolution(\n        this.maxResolution_, options.zoom - this.minZoom_);\n\n      if (this.resolutions_) { // in case map zoom is out of min/max zoom range\n        properties[ViewProperty.RESOLUTION] = clamp(\n          Number(this.getResolution() || properties[ViewProperty.RESOLUTION]),\n          this.minResolution_, this.maxResolution_);\n      }\n    }\n    properties[ViewProperty.ROTATION] = options.rotation !== undefined ? options.rotation : 0;\n    this.setProperties(properties);\n\n    /**\n     * @private\n     * @type {module:ol/View~ViewOptions}\n     */\n    this.options_ = options;\n\n  }\n\n  /**\n   * Get an updated version of the view options used to construct the view.  The\n   * current resolution (or zoom), center, and rotation are applied to any stored\n   * options.  The provided options can be used to apply new min/max zoom or\n   * resolution limits.\n   * @param {module:ol/View~ViewOptions} newOptions New options to be applied.\n   * @return {module:ol/View~ViewOptions} New options updated with the current view state.\n   */\n  getUpdatedOptions_(newOptions) {\n    const options = assign({}, this.options_);\n\n    // preserve resolution (or zoom)\n    if (options.resolution !== undefined) {\n      options.resolution = this.getResolution();\n    } else {\n      options.zoom = this.getZoom();\n    }\n\n    // preserve center\n    options.center = this.getCenter();\n\n    // preserve rotation\n    options.rotation = this.getRotation();\n\n    return assign({}, options, newOptions);\n  }\n\n  /**\n   * Animate the view.  The view's center, zoom (or resolution), and rotation\n   * can be animated for smooth transitions between view states.  For example,\n   * to animate the view to a new zoom level:\n   *\n   *     view.animate({zoom: view.getZoom() + 1});\n   *\n   * By default, the animation lasts one second and uses in-and-out easing.  You\n   * can customize this behavior by including `duration` (in milliseconds) and\n   * `easing` options (see {@link module:ol/easing}).\n   *\n   * To chain together multiple animations, call the method with multiple\n   * animation objects.  For example, to first zoom and then pan:\n   *\n   *     view.animate({zoom: 10}, {center: [0, 0]});\n   *\n   * If you provide a function as the last argument to the animate method, it\n   * will get called at the end of an animation series.  The callback will be\n   * called with `true` if the animation series completed on its own or `false`\n   * if it was cancelled.\n   *\n   * Animations are cancelled by user interactions (e.g. dragging the map) or by\n   * calling `view.setCenter()`, `view.setResolution()`, or `view.setRotation()`\n   * (or another method that calls one of these).\n   *\n   * @param {...(module:ol/View~AnimationOptions|function(boolean))} var_args Animation\n   *     options.  Multiple animations can be run in series by passing multiple\n   *     options objects.  To run multiple animations in parallel, call the method\n   *     multiple times.  An optional callback can be provided as a final\n   *     argument.  The callback will be called with a boolean indicating whether\n   *     the animation completed without being cancelled.\n   * @api\n   */\n  animate(var_args) {\n    let animationCount = arguments.length;\n    let callback;\n    if (animationCount > 1 && typeof arguments[animationCount - 1] === 'function') {\n      callback = arguments[animationCount - 1];\n      --animationCount;\n    }\n    if (!this.isDef()) {\n      // if view properties are not yet set, shortcut to the final state\n      const state = arguments[animationCount - 1];\n      if (state.center) {\n        this.setCenter(state.center);\n      }\n      if (state.zoom !== undefined) {\n        this.setZoom(state.zoom);\n      }\n      if (state.rotation !== undefined) {\n        this.setRotation(state.rotation);\n      }\n      if (callback) {\n        setTimeout(function() {\n          callback(true);\n        }, 0);\n      }\n      return;\n    }\n    let start = Date.now();\n    let center = this.getCenter().slice();\n    let resolution = this.getResolution();\n    let rotation = this.getRotation();\n    const series = [];\n    for (let i = 0; i < animationCount; ++i) {\n      const options = /** @type {module:ol/View~AnimationOptions} */ (arguments[i]);\n\n      const animation = /** @type {module:ol/View~Animation} */ ({\n        start: start,\n        complete: false,\n        anchor: options.anchor,\n        duration: options.duration !== undefined ? options.duration : 1000,\n        easing: options.easing || inAndOut\n      });\n\n      if (options.center) {\n        animation.sourceCenter = center;\n        animation.targetCenter = options.center;\n        center = animation.targetCenter;\n      }\n\n      if (options.zoom !== undefined) {\n        animation.sourceResolution = resolution;\n        animation.targetResolution = this.constrainResolution(\n          this.maxResolution_, options.zoom - this.minZoom_, 0);\n        resolution = animation.targetResolution;\n      } else if (options.resolution) {\n        animation.sourceResolution = resolution;\n        animation.targetResolution = options.resolution;\n        resolution = animation.targetResolution;\n      }\n\n      if (options.rotation !== undefined) {\n        animation.sourceRotation = rotation;\n        const delta = modulo(options.rotation - rotation + Math.PI, 2 * Math.PI) - Math.PI;\n        animation.targetRotation = rotation + delta;\n        rotation = animation.targetRotation;\n      }\n\n      animation.callback = callback;\n\n      // check if animation is a no-op\n      if (isNoopAnimation(animation)) {\n        animation.complete = true;\n        // we still push it onto the series for callback handling\n      } else {\n        start += animation.duration;\n      }\n      series.push(animation);\n    }\n    this.animations_.push(series);\n    this.setHint(ViewHint.ANIMATING, 1);\n    this.updateAnimations_();\n  }\n\n  /**\n   * Determine if the view is being animated.\n   * @return {boolean} The view is being animated.\n   * @api\n   */\n  getAnimating() {\n    return this.hints_[ViewHint.ANIMATING] > 0;\n  }\n\n  /**\n   * Determine if the user is interacting with the view, such as panning or zooming.\n   * @return {boolean} The view is being interacted with.\n   * @api\n   */\n  getInteracting() {\n    return this.hints_[ViewHint.INTERACTING] > 0;\n  }\n\n  /**\n   * Cancel any ongoing animations.\n   * @api\n   */\n  cancelAnimations() {\n    this.setHint(ViewHint.ANIMATING, -this.hints_[ViewHint.ANIMATING]);\n    for (let i = 0, ii = this.animations_.length; i < ii; ++i) {\n      const series = this.animations_[i];\n      if (series[0].callback) {\n        series[0].callback(false);\n      }\n    }\n    this.animations_.length = 0;\n  }\n\n  /**\n   * Update all animations.\n   */\n  updateAnimations_() {\n    if (this.updateAnimationKey_ !== undefined) {\n      cancelAnimationFrame(this.updateAnimationKey_);\n      this.updateAnimationKey_ = undefined;\n    }\n    if (!this.getAnimating()) {\n      return;\n    }\n    const now = Date.now();\n    let more = false;\n    for (let i = this.animations_.length - 1; i >= 0; --i) {\n      const series = this.animations_[i];\n      let seriesComplete = true;\n      for (let j = 0, jj = series.length; j < jj; ++j) {\n        const animation = series[j];\n        if (animation.complete) {\n          continue;\n        }\n        const elapsed = now - animation.start;\n        let fraction = animation.duration > 0 ? elapsed / animation.duration : 1;\n        if (fraction >= 1) {\n          animation.complete = true;\n          fraction = 1;\n        } else {\n          seriesComplete = false;\n        }\n        const progress = animation.easing(fraction);\n        if (animation.sourceCenter) {\n          const x0 = animation.sourceCenter[0];\n          const y0 = animation.sourceCenter[1];\n          const x1 = animation.targetCenter[0];\n          const y1 = animation.targetCenter[1];\n          const x = x0 + progress * (x1 - x0);\n          const y = y0 + progress * (y1 - y0);\n          this.set(ViewProperty.CENTER, [x, y]);\n        }\n        if (animation.sourceResolution && animation.targetResolution) {\n          const resolution = progress === 1 ?\n            animation.targetResolution :\n            animation.sourceResolution + progress * (animation.targetResolution - animation.sourceResolution);\n          if (animation.anchor) {\n            this.set(ViewProperty.CENTER,\n              this.calculateCenterZoom(resolution, animation.anchor));\n          }\n          this.set(ViewProperty.RESOLUTION, resolution);\n        }\n        if (animation.sourceRotation !== undefined && animation.targetRotation !== undefined) {\n          const rotation = progress === 1 ?\n            modulo(animation.targetRotation + Math.PI, 2 * Math.PI) - Math.PI :\n            animation.sourceRotation + progress * (animation.targetRotation - animation.sourceRotation);\n          if (animation.anchor) {\n            this.set(ViewProperty.CENTER,\n              this.calculateCenterRotate(rotation, animation.anchor));\n          }\n          this.set(ViewProperty.ROTATION, rotation);\n        }\n        more = true;\n        if (!animation.complete) {\n          break;\n        }\n      }\n      if (seriesComplete) {\n        this.animations_[i] = null;\n        this.setHint(ViewHint.ANIMATING, -1);\n        const callback = series[0].callback;\n        if (callback) {\n          setTimeout(function() {\n            callback(true);\n          }, 0);\n        }\n      }\n    }\n    // prune completed series\n    this.animations_ = this.animations_.filter(Boolean);\n    if (more && this.updateAnimationKey_ === undefined) {\n      this.updateAnimationKey_ = requestAnimationFrame(this.updateAnimations_);\n    }\n  }\n\n  /**\n   * @param {number} rotation Target rotation.\n   * @param {module:ol/coordinate~Coordinate} anchor Rotation anchor.\n   * @return {module:ol/coordinate~Coordinate|undefined} Center for rotation and anchor.\n   */\n  calculateCenterRotate(rotation, anchor) {\n    let center;\n    const currentCenter = this.getCenter();\n    if (currentCenter !== undefined) {\n      center = [currentCenter[0] - anchor[0], currentCenter[1] - anchor[1]];\n      rotateCoordinate(center, rotation - this.getRotation());\n      addCoordinate(center, anchor);\n    }\n    return center;\n  }\n\n  /**\n   * @param {number} resolution Target resolution.\n   * @param {module:ol/coordinate~Coordinate} anchor Zoom anchor.\n   * @return {module:ol/coordinate~Coordinate|undefined} Center for resolution and anchor.\n   */\n  calculateCenterZoom(resolution, anchor) {\n    let center;\n    const currentCenter = this.getCenter();\n    const currentResolution = this.getResolution();\n    if (currentCenter !== undefined && currentResolution !== undefined) {\n      const x = anchor[0] - resolution * (anchor[0] - currentCenter[0]) / currentResolution;\n      const y = anchor[1] - resolution * (anchor[1] - currentCenter[1]) / currentResolution;\n      center = [x, y];\n    }\n    return center;\n  }\n\n  /**\n   * @private\n   * @return {module:ol/size~Size} Viewport size or `[100, 100]` when no viewport is found.\n   */\n  getSizeFromViewport_() {\n    const size = [100, 100];\n    const selector = '.ol-viewport[data-view=\"' + getUid(this) + '\"]';\n    const element = document.querySelector(selector);\n    if (element) {\n      const metrics = getComputedStyle(element);\n      size[0] = parseInt(metrics.width, 10);\n      size[1] = parseInt(metrics.height, 10);\n    }\n    return size;\n  }\n\n  /**\n   * Get the constrained center of this view.\n   * @param {module:ol/coordinate~Coordinate|undefined} center Center.\n   * @return {module:ol/coordinate~Coordinate|undefined} Constrained center.\n   * @api\n   */\n  constrainCenter(center) {\n    return this.constraints_.center(center);\n  }\n\n  /**\n   * Get the constrained resolution of this view.\n   * @param {number|undefined} resolution Resolution.\n   * @param {number=} opt_delta Delta. Default is `0`.\n   * @param {number=} opt_direction Direction. Default is `0`.\n   * @return {number|undefined} Constrained resolution.\n   * @api\n   */\n  constrainResolution(resolution, opt_delta, opt_direction) {\n    const delta = opt_delta || 0;\n    const direction = opt_direction || 0;\n    return this.constraints_.resolution(resolution, delta, direction);\n  }\n\n  /**\n   * Get the constrained rotation of this view.\n   * @param {number|undefined} rotation Rotation.\n   * @param {number=} opt_delta Delta. Default is `0`.\n   * @return {number|undefined} Constrained rotation.\n   * @api\n   */\n  constrainRotation(rotation, opt_delta) {\n    const delta = opt_delta || 0;\n    return this.constraints_.rotation(rotation, delta);\n  }\n\n  /**\n   * Get the view center.\n   * @return {module:ol/coordinate~Coordinate|undefined} The center of the view.\n   * @observable\n   * @api\n   */\n  getCenter() {\n    return (\n      /** @type {module:ol/coordinate~Coordinate|undefined} */ (this.get(ViewProperty.CENTER))\n    );\n  }\n\n  /**\n   * @return {module:ol/View~Constraints} Constraints.\n   */\n  getConstraints() {\n    return this.constraints_;\n  }\n\n  /**\n   * @param {Array.<number>=} opt_hints Destination array.\n   * @return {Array.<number>} Hint.\n   */\n  getHints(opt_hints) {\n    if (opt_hints !== undefined) {\n      opt_hints[0] = this.hints_[0];\n      opt_hints[1] = this.hints_[1];\n      return opt_hints;\n    } else {\n      return this.hints_.slice();\n    }\n  }\n\n  /**\n   * Calculate the extent for the current view state and the passed size.\n   * The size is the pixel dimensions of the box into which the calculated extent\n   * should fit. In most cases you want to get the extent of the entire map,\n   * that is `map.getSize()`.\n   * @param {module:ol/size~Size=} opt_size Box pixel size. If not provided, the size of the\n   * first map that uses this view will be used.\n   * @return {module:ol/extent~Extent} Extent.\n   * @api\n   */\n  calculateExtent(opt_size) {\n    const size = opt_size || this.getSizeFromViewport_();\n    const center = /** @type {!module:ol/coordinate~Coordinate} */ (this.getCenter());\n    assert(center, 1); // The view center is not defined\n    const resolution = /** @type {!number} */ (this.getResolution());\n    assert(resolution !== undefined, 2); // The view resolution is not defined\n    const rotation = /** @type {!number} */ (this.getRotation());\n    assert(rotation !== undefined, 3); // The view rotation is not defined\n\n    return getForViewAndSize(center, resolution, rotation, size);\n  }\n\n  /**\n   * Get the maximum resolution of the view.\n   * @return {number} The maximum resolution of the view.\n   * @api\n   */\n  getMaxResolution() {\n    return this.maxResolution_;\n  }\n\n  /**\n   * Get the minimum resolution of the view.\n   * @return {number} The minimum resolution of the view.\n   * @api\n   */\n  getMinResolution() {\n    return this.minResolution_;\n  }\n\n  /**\n   * Get the maximum zoom level for the view.\n   * @return {number} The maximum zoom level.\n   * @api\n   */\n  getMaxZoom() {\n    return /** @type {number} */ (this.getZoomForResolution(this.minResolution_));\n  }\n\n  /**\n   * Set a new maximum zoom level for the view.\n   * @param {number} zoom The maximum zoom level.\n   * @api\n   */\n  setMaxZoom(zoom) {\n    this.applyOptions_(this.getUpdatedOptions_({maxZoom: zoom}));\n  }\n\n  /**\n   * Get the minimum zoom level for the view.\n   * @return {number} The minimum zoom level.\n   * @api\n   */\n  getMinZoom() {\n    return /** @type {number} */ (this.getZoomForResolution(this.maxResolution_));\n  }\n\n  /**\n   * Set a new minimum zoom level for the view.\n   * @param {number} zoom The minimum zoom level.\n   * @api\n   */\n  setMinZoom(zoom) {\n    this.applyOptions_(this.getUpdatedOptions_({minZoom: zoom}));\n  }\n\n  /**\n   * Get the view projection.\n   * @return {module:ol/proj/Projection} The projection of the view.\n   * @api\n   */\n  getProjection() {\n    return this.projection_;\n  }\n\n  /**\n   * Get the view resolution.\n   * @return {number|undefined} The resolution of the view.\n   * @observable\n   * @api\n   */\n  getResolution() {\n    return /** @type {number|undefined} */ (this.get(ViewProperty.RESOLUTION));\n  }\n\n  /**\n   * Get the resolutions for the view. This returns the array of resolutions\n   * passed to the constructor of the View, or undefined if none were given.\n   * @return {Array.<number>|undefined} The resolutions of the view.\n   * @api\n   */\n  getResolutions() {\n    return this.resolutions_;\n  }\n\n  /**\n   * Get the resolution for a provided extent (in map units) and size (in pixels).\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {module:ol/size~Size=} opt_size Box pixel size.\n   * @return {number} The resolution at which the provided extent will render at\n   *     the given size.\n   * @api\n   */\n  getResolutionForExtent(extent, opt_size) {\n    const size = opt_size || this.getSizeFromViewport_();\n    const xResolution = getWidth(extent) / size[0];\n    const yResolution = getHeight(extent) / size[1];\n    return Math.max(xResolution, yResolution);\n  }\n\n  /**\n   * Return a function that returns a value between 0 and 1 for a\n   * resolution. Exponential scaling is assumed.\n   * @param {number=} opt_power Power.\n   * @return {function(number): number} Resolution for value function.\n   */\n  getResolutionForValueFunction(opt_power) {\n    const power = opt_power || 2;\n    const maxResolution = this.maxResolution_;\n    const minResolution = this.minResolution_;\n    const max = Math.log(maxResolution / minResolution) / Math.log(power);\n    return (\n      /**\n       * @param {number} value Value.\n       * @return {number} Resolution.\n       */\n      function(value) {\n        const resolution = maxResolution / Math.pow(power, value * max);\n        return resolution;\n      });\n  }\n\n  /**\n   * Get the view rotation.\n   * @return {number} The rotation of the view in radians.\n   * @observable\n   * @api\n   */\n  getRotation() {\n    return /** @type {number} */ (this.get(ViewProperty.ROTATION));\n  }\n\n  /**\n   * Return a function that returns a resolution for a value between\n   * 0 and 1. Exponential scaling is assumed.\n   * @param {number=} opt_power Power.\n   * @return {function(number): number} Value for resolution function.\n   */\n  getValueForResolutionFunction(opt_power) {\n    const power = opt_power || 2;\n    const maxResolution = this.maxResolution_;\n    const minResolution = this.minResolution_;\n    const max = Math.log(maxResolution / minResolution) / Math.log(power);\n    return (\n      /**\n       * @param {number} resolution Resolution.\n       * @return {number} Value.\n       */\n      function(resolution) {\n        const value = (Math.log(maxResolution / resolution) / Math.log(power)) / max;\n        return value;\n      });\n  }\n\n  /**\n   * @return {module:ol/View~State} View state.\n   */\n  getState() {\n    const center = /** @type {module:ol/coordinate~Coordinate} */ (this.getCenter());\n    const projection = this.getProjection();\n    const resolution = /** @type {number} */ (this.getResolution());\n    const rotation = this.getRotation();\n    return (\n      /** @type {module:ol/View~State} */ ({\n        center: center.slice(),\n        projection: projection !== undefined ? projection : null,\n        resolution: resolution,\n        rotation: rotation,\n        zoom: this.getZoom()\n      })\n    );\n  }\n\n  /**\n   * Get the current zoom level.  If you configured your view with a resolutions\n   * array (this is rare), this method may return non-integer zoom levels (so\n   * the zoom level is not safe to use as an index into a resolutions array).\n   * @return {number|undefined} Zoom.\n   * @api\n   */\n  getZoom() {\n    let zoom;\n    const resolution = this.getResolution();\n    if (resolution !== undefined) {\n      zoom = this.getZoomForResolution(resolution);\n    }\n    return zoom;\n  }\n\n  /**\n   * Get the zoom level for a resolution.\n   * @param {number} resolution The resolution.\n   * @return {number|undefined} The zoom level for the provided resolution.\n   * @api\n   */\n  getZoomForResolution(resolution) {\n    let offset = this.minZoom_ || 0;\n    let max, zoomFactor;\n    if (this.resolutions_) {\n      const nearest = linearFindNearest(this.resolutions_, resolution, 1);\n      offset = nearest;\n      max = this.resolutions_[nearest];\n      if (nearest == this.resolutions_.length - 1) {\n        zoomFactor = 2;\n      } else {\n        zoomFactor = max / this.resolutions_[nearest + 1];\n      }\n    } else {\n      max = this.maxResolution_;\n      zoomFactor = this.zoomFactor_;\n    }\n    return offset + Math.log(max / resolution) / Math.log(zoomFactor);\n  }\n\n  /**\n   * Get the resolution for a zoom level.\n   * @param {number} zoom Zoom level.\n   * @return {number} The view resolution for the provided zoom level.\n   * @api\n   */\n  getResolutionForZoom(zoom) {\n    return /** @type {number} */ (this.constrainResolution(\n      this.maxResolution_, zoom - this.minZoom_, 0));\n  }\n\n  /**\n   * Fit the given geometry or extent based on the given map size and border.\n   * The size is pixel dimensions of the box to fit the extent into.\n   * In most cases you will want to use the map size, that is `map.getSize()`.\n   * Takes care of the map angle.\n   * @param {module:ol/geom/SimpleGeometry|module:ol/extent~Extent} geometryOrExtent The geometry or\n   *     extent to fit the view to.\n   * @param {module:ol/View~FitOptions=} opt_options Options.\n   * @api\n   */\n  fit(geometryOrExtent, opt_options) {\n    const options = opt_options || {};\n    let size = options.size;\n    if (!size) {\n      size = this.getSizeFromViewport_();\n    }\n    /** @type {module:ol/geom/SimpleGeometry} */\n    let geometry;\n    if (!(geometryOrExtent instanceof SimpleGeometry)) {\n      assert(Array.isArray(geometryOrExtent),\n        24); // Invalid extent or geometry provided as `geometry`\n      assert(!isEmpty(geometryOrExtent),\n        25); // Cannot fit empty extent provided as `geometry`\n      geometry = polygonFromExtent(geometryOrExtent);\n    } else if (geometryOrExtent.getType() === GeometryType.CIRCLE) {\n      geometryOrExtent = geometryOrExtent.getExtent();\n      geometry = polygonFromExtent(geometryOrExtent);\n      geometry.rotate(this.getRotation(), getCenter(geometryOrExtent));\n    } else {\n      geometry = geometryOrExtent;\n    }\n\n    const padding = options.padding !== undefined ? options.padding : [0, 0, 0, 0];\n    const constrainResolution = options.constrainResolution !== undefined ?\n      options.constrainResolution : true;\n    const nearest = options.nearest !== undefined ? options.nearest : false;\n    let minResolution;\n    if (options.minResolution !== undefined) {\n      minResolution = options.minResolution;\n    } else if (options.maxZoom !== undefined) {\n      minResolution = this.constrainResolution(\n        this.maxResolution_, options.maxZoom - this.minZoom_, 0);\n    } else {\n      minResolution = 0;\n    }\n    const coords = geometry.getFlatCoordinates();\n\n    // calculate rotated extent\n    const rotation = this.getRotation();\n    const cosAngle = Math.cos(-rotation);\n    let sinAngle = Math.sin(-rotation);\n    let minRotX = +Infinity;\n    let minRotY = +Infinity;\n    let maxRotX = -Infinity;\n    let maxRotY = -Infinity;\n    const stride = geometry.getStride();\n    for (let i = 0, ii = coords.length; i < ii; i += stride) {\n      const rotX = coords[i] * cosAngle - coords[i + 1] * sinAngle;\n      const rotY = coords[i] * sinAngle + coords[i + 1] * cosAngle;\n      minRotX = Math.min(minRotX, rotX);\n      minRotY = Math.min(minRotY, rotY);\n      maxRotX = Math.max(maxRotX, rotX);\n      maxRotY = Math.max(maxRotY, rotY);\n    }\n\n    // calculate resolution\n    let resolution = this.getResolutionForExtent(\n      [minRotX, minRotY, maxRotX, maxRotY],\n      [size[0] - padding[1] - padding[3], size[1] - padding[0] - padding[2]]);\n    resolution = isNaN(resolution) ? minResolution :\n      Math.max(resolution, minResolution);\n    if (constrainResolution) {\n      let constrainedResolution = this.constrainResolution(resolution, 0, 0);\n      if (!nearest && constrainedResolution < resolution) {\n        constrainedResolution = this.constrainResolution(\n          constrainedResolution, -1, 0);\n      }\n      resolution = constrainedResolution;\n    }\n\n    // calculate center\n    sinAngle = -sinAngle; // go back to original rotation\n    let centerRotX = (minRotX + maxRotX) / 2;\n    let centerRotY = (minRotY + maxRotY) / 2;\n    centerRotX += (padding[1] - padding[3]) / 2 * resolution;\n    centerRotY += (padding[0] - padding[2]) / 2 * resolution;\n    const centerX = centerRotX * cosAngle - centerRotY * sinAngle;\n    const centerY = centerRotY * cosAngle + centerRotX * sinAngle;\n    const center = [centerX, centerY];\n    const callback = options.callback ? options.callback : UNDEFINED;\n\n    if (options.duration !== undefined) {\n      this.animate({\n        resolution: resolution,\n        center: center,\n        duration: options.duration,\n        easing: options.easing\n      }, callback);\n    } else {\n      this.setResolution(resolution);\n      this.setCenter(center);\n      setTimeout(callback.bind(undefined, true), 0);\n    }\n  }\n\n  /**\n   * Center on coordinate and view position.\n   * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n   * @param {module:ol/size~Size} size Box pixel size.\n   * @param {module:ol/pixel~Pixel} position Position on the view to center on.\n   * @api\n   */\n  centerOn(coordinate, size, position) {\n    // calculate rotated position\n    const rotation = this.getRotation();\n    const cosAngle = Math.cos(-rotation);\n    let sinAngle = Math.sin(-rotation);\n    let rotX = coordinate[0] * cosAngle - coordinate[1] * sinAngle;\n    let rotY = coordinate[1] * cosAngle + coordinate[0] * sinAngle;\n    const resolution = this.getResolution();\n    rotX += (size[0] / 2 - position[0]) * resolution;\n    rotY += (position[1] - size[1] / 2) * resolution;\n\n    // go back to original angle\n    sinAngle = -sinAngle; // go back to original rotation\n    const centerX = rotX * cosAngle - rotY * sinAngle;\n    const centerY = rotY * cosAngle + rotX * sinAngle;\n\n    this.setCenter([centerX, centerY]);\n  }\n\n  /**\n   * @return {boolean} Is defined.\n   */\n  isDef() {\n    return !!this.getCenter() && this.getResolution() !== undefined;\n  }\n\n  /**\n   * Rotate the view around a given coordinate.\n   * @param {number} rotation New rotation value for the view.\n   * @param {module:ol/coordinate~Coordinate=} opt_anchor The rotation center.\n   * @api\n   */\n  rotate(rotation, opt_anchor) {\n    if (opt_anchor !== undefined) {\n      const center = this.calculateCenterRotate(rotation, opt_anchor);\n      this.setCenter(center);\n    }\n    this.setRotation(rotation);\n  }\n\n  /**\n   * Set the center of the current view.\n   * @param {module:ol/coordinate~Coordinate|undefined} center The center of the view.\n   * @observable\n   * @api\n   */\n  setCenter(center) {\n    this.set(ViewProperty.CENTER, center);\n    if (this.getAnimating()) {\n      this.cancelAnimations();\n    }\n  }\n\n  /**\n   * @param {module:ol/ViewHint} hint Hint.\n   * @param {number} delta Delta.\n   * @return {number} New value.\n   */\n  setHint(hint, delta) {\n    this.hints_[hint] += delta;\n    this.changed();\n    return this.hints_[hint];\n  }\n\n  /**\n   * Set the resolution for this view.\n   * @param {number|undefined} resolution The resolution of the view.\n   * @observable\n   * @api\n   */\n  setResolution(resolution) {\n    this.set(ViewProperty.RESOLUTION, resolution);\n    if (this.getAnimating()) {\n      this.cancelAnimations();\n    }\n  }\n\n  /**\n   * Set the rotation for this view.\n   * @param {number} rotation The rotation of the view in radians.\n   * @observable\n   * @api\n   */\n  setRotation(rotation) {\n    this.set(ViewProperty.ROTATION, rotation);\n    if (this.getAnimating()) {\n      this.cancelAnimations();\n    }\n  }\n\n  /**\n   * Zoom to a specific zoom level.\n   * @param {number} zoom Zoom level.\n   * @api\n   */\n  setZoom(zoom) {\n    this.setResolution(this.getResolutionForZoom(zoom));\n  }\n}\n\n\n/**\n * @param {module:ol/View~ViewOptions} options View options.\n * @return {module:ol/centerconstraint~Type} The constraint.\n */\nexport function createCenterConstraint(options) {\n  if (options.extent !== undefined) {\n    return createExtent(options.extent);\n  } else {\n    return centerNone;\n  }\n}\n\n\n/**\n * @param {module:ol/View~ViewOptions} options View options.\n * @return {{constraint: module:ol/resolutionconstraint~Type, maxResolution: number,\n *     minResolution: number, minZoom: number, zoomFactor: number}} The constraint.\n */\nexport function createResolutionConstraint(options) {\n  let resolutionConstraint;\n  let maxResolution;\n  let minResolution;\n\n  // TODO: move these to be ol constants\n  // see https://github.com/openlayers/openlayers/issues/2076\n  const defaultMaxZoom = 28;\n  const defaultZoomFactor = 2;\n\n  let minZoom = options.minZoom !== undefined ?\n    options.minZoom : DEFAULT_MIN_ZOOM;\n\n  let maxZoom = options.maxZoom !== undefined ?\n    options.maxZoom : defaultMaxZoom;\n\n  const zoomFactor = options.zoomFactor !== undefined ?\n    options.zoomFactor : defaultZoomFactor;\n\n  if (options.resolutions !== undefined) {\n    const resolutions = options.resolutions;\n    maxResolution = resolutions[minZoom];\n    minResolution = resolutions[maxZoom] !== undefined ?\n      resolutions[maxZoom] : resolutions[resolutions.length - 1];\n    resolutionConstraint = createSnapToResolutions(\n      resolutions);\n  } else {\n    // calculate the default min and max resolution\n    const projection = createProjection(options.projection, 'EPSG:3857');\n    const extent = projection.getExtent();\n    const size = !extent ?\n      // use an extent that can fit the whole world if need be\n      360 * METERS_PER_UNIT[Units.DEGREES] /\n            projection.getMetersPerUnit() :\n      Math.max(getWidth(extent), getHeight(extent));\n\n    const defaultMaxResolution = size / DEFAULT_TILE_SIZE / Math.pow(\n      defaultZoomFactor, DEFAULT_MIN_ZOOM);\n\n    const defaultMinResolution = defaultMaxResolution / Math.pow(\n      defaultZoomFactor, defaultMaxZoom - DEFAULT_MIN_ZOOM);\n\n    // user provided maxResolution takes precedence\n    maxResolution = options.maxResolution;\n    if (maxResolution !== undefined) {\n      minZoom = 0;\n    } else {\n      maxResolution = defaultMaxResolution / Math.pow(zoomFactor, minZoom);\n    }\n\n    // user provided minResolution takes precedence\n    minResolution = options.minResolution;\n    if (minResolution === undefined) {\n      if (options.maxZoom !== undefined) {\n        if (options.maxResolution !== undefined) {\n          minResolution = maxResolution / Math.pow(zoomFactor, maxZoom);\n        } else {\n          minResolution = defaultMaxResolution / Math.pow(zoomFactor, maxZoom);\n        }\n      } else {\n        minResolution = defaultMinResolution;\n      }\n    }\n\n    // given discrete zoom levels, minResolution may be different than provided\n    maxZoom = minZoom + Math.floor(\n      Math.log(maxResolution / minResolution) / Math.log(zoomFactor));\n    minResolution = maxResolution / Math.pow(zoomFactor, maxZoom - minZoom);\n\n    resolutionConstraint = createSnapToPower(\n      zoomFactor, maxResolution, maxZoom - minZoom);\n  }\n  return {constraint: resolutionConstraint, maxResolution: maxResolution,\n    minResolution: minResolution, minZoom: minZoom, zoomFactor: zoomFactor};\n}\n\n\n/**\n * @param {module:ol/View~ViewOptions} options View options.\n * @return {module:ol/rotationconstraint~Type} Rotation constraint.\n */\nexport function createRotationConstraint(options) {\n  const enableRotation = options.enableRotation !== undefined ?\n    options.enableRotation : true;\n  if (enableRotation) {\n    const constrainRotation = options.constrainRotation;\n    if (constrainRotation === undefined || constrainRotation === true) {\n      return createSnapToZero();\n    } else if (constrainRotation === false) {\n      return rotationNone;\n    } else if (typeof constrainRotation === 'number') {\n      return createSnapToN(constrainRotation);\n    } else {\n      return rotationNone;\n    }\n  } else {\n    return disable;\n  }\n}\n\n\n/**\n * Determine if an animation involves no view change.\n * @param {module:ol/View~Animation} animation The animation.\n * @return {boolean} The animation involves no view change.\n */\nexport function isNoopAnimation(animation) {\n  if (animation.sourceCenter && animation.targetCenter) {\n    if (!coordinatesEqual(animation.sourceCenter, animation.targetCenter)) {\n      return false;\n    }\n  }\n  if (animation.sourceResolution !== animation.targetResolution) {\n    return false;\n  }\n  if (animation.sourceRotation !== animation.targetRotation) {\n    return false;\n  }\n  return true;\n}\n\nexport default View;\n","/**\n * @module ol/resolutionconstraint\n */\nimport {linearFindNearest} from './array.js';\nimport {clamp} from './math.js';\n\n\n/**\n * @typedef {function((number|undefined), number, number): (number|undefined)} Type\n */\n\n\n/**\n * @param {Array.<number>} resolutions Resolutions.\n * @return {module:ol/resolutionconstraint~Type} Zoom function.\n */\nexport function createSnapToResolutions(resolutions) {\n  return (\n    /**\n     * @param {number|undefined} resolution Resolution.\n     * @param {number} delta Delta.\n     * @param {number} direction Direction.\n     * @return {number|undefined} Resolution.\n     */\n    function(resolution, delta, direction) {\n      if (resolution !== undefined) {\n        let z = linearFindNearest(resolutions, resolution, direction);\n        z = clamp(z + delta, 0, resolutions.length - 1);\n        const index = Math.floor(z);\n        if (z != index && index < resolutions.length - 1) {\n          const power = resolutions[index] / resolutions[index + 1];\n          return resolutions[index] / Math.pow(power, z - index);\n        } else {\n          return resolutions[index];\n        }\n      } else {\n        return undefined;\n      }\n    }\n  );\n}\n\n\n/**\n * @param {number} power Power.\n * @param {number} maxResolution Maximum resolution.\n * @param {number=} opt_maxLevel Maximum level.\n * @return {module:ol/resolutionconstraint~Type} Zoom function.\n */\nexport function createSnapToPower(power, maxResolution, opt_maxLevel) {\n  return (\n    /**\n     * @param {number|undefined} resolution Resolution.\n     * @param {number} delta Delta.\n     * @param {number} direction Direction.\n     * @return {number|undefined} Resolution.\n     */\n    function(resolution, delta, direction) {\n      if (resolution !== undefined) {\n        const offset = -direction / 2 + 0.5;\n        const oldLevel = Math.floor(\n          Math.log(maxResolution / resolution) / Math.log(power) + offset);\n        let newLevel = Math.max(oldLevel + delta, 0);\n        if (opt_maxLevel !== undefined) {\n          newLevel = Math.min(newLevel, opt_maxLevel);\n        }\n        return maxResolution / Math.pow(power, newLevel);\n      } else {\n        return undefined;\n      }\n    });\n}\n","/**\n * @module ol/layer/Property\n */\n\n/**\n * @enum {string}\n */\nexport default {\n  OPACITY: 'opacity',\n  VISIBLE: 'visible',\n  EXTENT: 'extent',\n  Z_INDEX: 'zIndex',\n  MAX_RESOLUTION: 'maxResolution',\n  MIN_RESOLUTION: 'minResolution',\n  SOURCE: 'source'\n};\n","/**\n * @module ol/layer/Base\n */\nimport BaseObject from '../Object.js';\nimport LayerProperty from '../layer/Property.js';\nimport {clamp} from '../math.js';\nimport {assign} from '../obj.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {module:ol/extent~Extent} [extent] The bounding extent for layer rendering.  The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex=0] The z-index for layer rendering.  At rendering time, the layers\n * will be ordered, first by Z-index and then by position.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n */\n\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Note that with {@link module:ol/layer/Base} and all its subclasses, any property set in\n * the options is set as a {@link module:ol/Object} property on the layer object, so\n * is observable, and has get/set accessors.\n *\n * @api\n */\nclass BaseLayer extends BaseObject {\n  /**\n   * @param {module:ol/layer/Base~Options} options Layer options.\n   */\n  constructor(options) {\n\n    super();\n\n    /**\n    * @type {Object.<string, *>}\n    */\n    const properties = assign({}, options);\n    properties[LayerProperty.OPACITY] =\n       options.opacity !== undefined ? options.opacity : 1;\n    properties[LayerProperty.VISIBLE] =\n       options.visible !== undefined ? options.visible : true;\n    properties[LayerProperty.Z_INDEX] =\n       options.zIndex !== undefined ? options.zIndex : 0;\n    properties[LayerProperty.MAX_RESOLUTION] =\n       options.maxResolution !== undefined ? options.maxResolution : Infinity;\n    properties[LayerProperty.MIN_RESOLUTION] =\n       options.minResolution !== undefined ? options.minResolution : 0;\n\n    this.setProperties(properties);\n\n    /**\n    * @type {module:ol/layer/Layer~State}\n    * @private\n    */\n    this.state_ = /** @type {module:ol/layer/Layer~State} */ ({\n      layer: /** @type {module:ol/layer/Layer} */ (this),\n      managed: true\n    });\n\n    /**\n    * The layer type.\n    * @type {module:ol/LayerType}\n    * @protected;\n    */\n    this.type;\n\n  }\n\n  /**\n  * Get the layer type (used when creating a layer renderer).\n  * @return {module:ol/LayerType} The layer type.\n  */\n  getType() {\n    return this.type;\n  }\n\n  /**\n  * @return {module:ol/layer/Layer~State} Layer state.\n  */\n  getLayerState() {\n    this.state_.opacity = clamp(this.getOpacity(), 0, 1);\n    this.state_.sourceState = this.getSourceState();\n    this.state_.visible = this.getVisible();\n    this.state_.extent = this.getExtent();\n    this.state_.zIndex = this.getZIndex();\n    this.state_.maxResolution = this.getMaxResolution();\n    this.state_.minResolution = Math.max(this.getMinResolution(), 0);\n\n    return this.state_;\n  }\n\n  /**\n  * @abstract\n  * @param {Array.<module:ol/layer/Layer>=} opt_array Array of layers (to be\n  *     modified in place).\n  * @return {Array.<module:ol/layer/Layer>} Array of layers.\n  */\n  getLayersArray(opt_array) {}\n\n  /**\n  * @abstract\n  * @param {Array.<module:ol/layer/Layer~State>=} opt_states Optional list of layer\n  *     states (to be modified in place).\n  * @return {Array.<module:ol/layer/Layer~State>} List of layer states.\n  */\n  getLayerStatesArray(opt_states) {}\n\n  /**\n  * Return the {@link module:ol/extent~Extent extent} of the layer or `undefined` if it\n  * will be visible regardless of extent.\n  * @return {module:ol/extent~Extent|undefined} The layer extent.\n  * @observable\n  * @api\n  */\n  getExtent() {\n    return (\n    /** @type {module:ol/extent~Extent|undefined} */ (this.get(LayerProperty.EXTENT))\n    );\n  }\n\n  /**\n  * Return the maximum resolution of the layer.\n  * @return {number} The maximum resolution of the layer.\n  * @observable\n  * @api\n  */\n  getMaxResolution() {\n    return /** @type {number} */ (this.get(LayerProperty.MAX_RESOLUTION));\n  }\n\n  /**\n  * Return the minimum resolution of the layer.\n  * @return {number} The minimum resolution of the layer.\n  * @observable\n  * @api\n  */\n  getMinResolution() {\n    return /** @type {number} */ (this.get(LayerProperty.MIN_RESOLUTION));\n  }\n\n  /**\n  * Return the opacity of the layer (between 0 and 1).\n  * @return {number} The opacity of the layer.\n  * @observable\n  * @api\n  */\n  getOpacity() {\n    return /** @type {number} */ (this.get(LayerProperty.OPACITY));\n  }\n\n  /**\n  * @abstract\n  * @return {module:ol/source/State} Source state.\n  */\n  getSourceState() {}\n\n  /**\n  * Return the visibility of the layer (`true` or `false`).\n  * @return {boolean} The visibility of the layer.\n  * @observable\n  * @api\n  */\n  getVisible() {\n    return /** @type {boolean} */ (this.get(LayerProperty.VISIBLE));\n  }\n\n  /**\n  * Return the Z-index of the layer, which is used to order layers before\n  * rendering. The default Z-index is 0.\n  * @return {number} The Z-index of the layer.\n  * @observable\n  * @api\n  */\n  getZIndex() {\n    return /** @type {number} */ (this.get(LayerProperty.Z_INDEX));\n  }\n\n  /**\n  * Set the extent at which the layer is visible.  If `undefined`, the layer\n  * will be visible at all extents.\n  * @param {module:ol/extent~Extent|undefined} extent The extent of the layer.\n  * @observable\n  * @api\n  */\n  setExtent(extent) {\n    this.set(LayerProperty.EXTENT, extent);\n  }\n\n  /**\n  * Set the maximum resolution at which the layer is visible.\n  * @param {number} maxResolution The maximum resolution of the layer.\n  * @observable\n  * @api\n  */\n  setMaxResolution(maxResolution) {\n    this.set(LayerProperty.MAX_RESOLUTION, maxResolution);\n  }\n\n  /**\n  * Set the minimum resolution at which the layer is visible.\n  * @param {number} minResolution The minimum resolution of the layer.\n  * @observable\n  * @api\n  */\n  setMinResolution(minResolution) {\n    this.set(LayerProperty.MIN_RESOLUTION, minResolution);\n  }\n\n  /**\n  * Set the opacity of the layer, allowed values range from 0 to 1.\n  * @param {number} opacity The opacity of the layer.\n  * @observable\n  * @api\n  */\n  setOpacity(opacity) {\n    this.set(LayerProperty.OPACITY, opacity);\n  }\n\n  /**\n  * Set the visibility of the layer (`true` or `false`).\n  * @param {boolean} visible The visibility of the layer.\n  * @observable\n  * @api\n  */\n  setVisible(visible) {\n    this.set(LayerProperty.VISIBLE, visible);\n  }\n\n  /**\n  * Set Z-index of the layer, which is used to order layers before rendering.\n  * The default Z-index is 0.\n  * @param {number} zindex The z-index of the layer.\n  * @observable\n  * @api\n  */\n  setZIndex(zindex) {\n    this.set(LayerProperty.Z_INDEX, zindex);\n  }\n}\n\n\nexport default BaseLayer;\n","/**\n * @module ol/source/State\n */\n\n/**\n * State of the source, one of 'undefined', 'loading', 'ready' or 'error'.\n * @enum {string}\n */\nexport default {\n  UNDEFINED: 'undefined',\n  LOADING: 'loading',\n  READY: 'ready',\n  ERROR: 'error'\n};\n","/**\n * @module ol/layer/Group\n */\nimport {getUid} from '../util.js';\nimport Collection from '../Collection.js';\nimport CollectionEventType from '../CollectionEventType.js';\nimport {getChangeEventType} from '../Object.js';\nimport ObjectEventType from '../ObjectEventType.js';\nimport {assert} from '../asserts.js';\nimport {listen, unlistenByKey} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport {getIntersection} from '../extent.js';\nimport BaseLayer from '../layer/Base.js';\nimport {assign, clear} from '../obj.js';\nimport SourceState from '../source/State.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {module:ol/extent~Extent} [extent] The bounding extent for layer rendering.  The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex=0] The z-index for layer rendering.  At rendering time, the layers\n * will be ordered, first by Z-index and then by position.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {(Array.<module:ol/layer/Base>|module:ol/Collection.<module:ol/layer/Base>)} [layers] Child layers.\n */\n\n\n/**\n * @enum {string}\n * @private\n */\nconst Property = {\n  LAYERS: 'layers'\n};\n\n\n/**\n * @classdesc\n * A {@link module:ol/Collection~Collection} of layers that are handled together.\n *\n * A generic `change` event is triggered when the group/Collection changes.\n *\n * @api\n */\nclass LayerGroup extends BaseLayer {\n  /**\n   * @param {module:ol/layer/Group~Options=} opt_options Layer options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options || {};\n    const baseOptions = /** @type {module:ol/layer/Group~Options} */ (assign({}, options));\n    delete baseOptions.layers;\n\n    let layers = options.layers;\n\n    super(baseOptions);\n\n    /**\n     * @private\n     * @type {Array.<module:ol/events~EventsKey>}\n     */\n    this.layersListenerKeys_ = [];\n\n    /**\n     * @private\n     * @type {Object.<string, Array.<module:ol/events~EventsKey>>}\n     */\n    this.listenerKeys_ = {};\n\n    listen(this,\n      getChangeEventType(Property.LAYERS),\n      this.handleLayersChanged_, this);\n\n    if (layers) {\n      if (Array.isArray(layers)) {\n        layers = new Collection(layers.slice(), {unique: true});\n      } else {\n        assert(layers instanceof Collection,\n          43); // Expected `layers` to be an array or a `Collection`\n        layers = layers;\n      }\n    } else {\n      layers = new Collection(undefined, {unique: true});\n    }\n\n    this.setLayers(layers);\n\n  }\n\n  /**\n   * @private\n   */\n  handleLayerChange_() {\n    this.changed();\n  }\n\n  /**\n   * @param {module:ol/events/Event} event Event.\n   * @private\n   */\n  handleLayersChanged_() {\n    this.layersListenerKeys_.forEach(unlistenByKey);\n    this.layersListenerKeys_.length = 0;\n\n    const layers = this.getLayers();\n    this.layersListenerKeys_.push(\n      listen(layers, CollectionEventType.ADD, this.handleLayersAdd_, this),\n      listen(layers, CollectionEventType.REMOVE, this.handleLayersRemove_, this)\n    );\n\n    for (const id in this.listenerKeys_) {\n      this.listenerKeys_[id].forEach(unlistenByKey);\n    }\n    clear(this.listenerKeys_);\n\n    const layersArray = layers.getArray();\n    for (let i = 0, ii = layersArray.length; i < ii; i++) {\n      const layer = layersArray[i];\n      this.listenerKeys_[getUid(layer).toString()] = [\n        listen(layer, ObjectEventType.PROPERTYCHANGE, this.handleLayerChange_, this),\n        listen(layer, EventType.CHANGE, this.handleLayerChange_, this)\n      ];\n    }\n\n    this.changed();\n  }\n\n  /**\n   * @param {module:ol/Collection~CollectionEvent} collectionEvent CollectionEvent.\n   * @private\n   */\n  handleLayersAdd_(collectionEvent) {\n    const layer = /** @type {module:ol/layer/Base} */ (collectionEvent.element);\n    const key = getUid(layer).toString();\n    this.listenerKeys_[key] = [\n      listen(layer, ObjectEventType.PROPERTYCHANGE, this.handleLayerChange_, this),\n      listen(layer, EventType.CHANGE, this.handleLayerChange_, this)\n    ];\n    this.changed();\n  }\n\n  /**\n   * @param {module:ol/Collection~CollectionEvent} collectionEvent CollectionEvent.\n   * @private\n   */\n  handleLayersRemove_(collectionEvent) {\n    const layer = /** @type {module:ol/layer/Base} */ (collectionEvent.element);\n    const key = getUid(layer).toString();\n    this.listenerKeys_[key].forEach(unlistenByKey);\n    delete this.listenerKeys_[key];\n    this.changed();\n  }\n\n  /**\n   * Returns the {@link module:ol/Collection collection} of {@link module:ol/layer/Layer~Layer layers}\n   * in this group.\n   * @return {!module:ol/Collection.<module:ol/layer/Base>} Collection of\n   *   {@link module:ol/layer/Base layers} that are part of this group.\n   * @observable\n   * @api\n   */\n  getLayers() {\n    return (\n      /** @type {!module:ol/Collection.<module:ol/layer/Base>} */ (this.get(Property.LAYERS))\n    );\n  }\n\n  /**\n   * Set the {@link module:ol/Collection collection} of {@link module:ol/layer/Layer~Layer layers}\n   * in this group.\n   * @param {!module:ol/Collection.<module:ol/layer/Base>} layers Collection of\n   *   {@link module:ol/layer/Base layers} that are part of this group.\n   * @observable\n   * @api\n   */\n  setLayers(layers) {\n    this.set(Property.LAYERS, layers);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getLayersArray(opt_array) {\n    const array = opt_array !== undefined ? opt_array : [];\n    this.getLayers().forEach(function(layer) {\n      layer.getLayersArray(array);\n    });\n    return array;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getLayerStatesArray(opt_states) {\n    const states = opt_states !== undefined ? opt_states : [];\n\n    const pos = states.length;\n\n    this.getLayers().forEach(function(layer) {\n      layer.getLayerStatesArray(states);\n    });\n\n    const ownLayerState = this.getLayerState();\n    for (let i = pos, ii = states.length; i < ii; i++) {\n      const layerState = states[i];\n      layerState.opacity *= ownLayerState.opacity;\n      layerState.visible = layerState.visible && ownLayerState.visible;\n      layerState.maxResolution = Math.min(\n        layerState.maxResolution, ownLayerState.maxResolution);\n      layerState.minResolution = Math.max(\n        layerState.minResolution, ownLayerState.minResolution);\n      if (ownLayerState.extent !== undefined) {\n        if (layerState.extent !== undefined) {\n          layerState.extent = getIntersection(layerState.extent, ownLayerState.extent);\n        } else {\n          layerState.extent = ownLayerState.extent;\n        }\n      }\n    }\n\n    return states;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getSourceState() {\n    return SourceState.READY;\n  }\n}\n\n\nexport default LayerGroup;\n","/**\n * @module ol/size\n */\n\n\n/**\n * An array of numbers representing a size: `[width, height]`.\n * @typedef {Array.<number>} Size\n * @api\n */\n\n\n/**\n * Returns a buffered size.\n * @param {module:ol/size~Size} size Size.\n * @param {number} num The amount by which to buffer.\n * @param {module:ol/size~Size=} opt_size Optional reusable size array.\n * @return {module:ol/size~Size} The buffered size.\n */\nexport function buffer(size, num, opt_size) {\n  if (opt_size === undefined) {\n    opt_size = [0, 0];\n  }\n  opt_size[0] = size[0] + 2 * num;\n  opt_size[1] = size[1] + 2 * num;\n  return opt_size;\n}\n\n\n/**\n * Determines if a size has a positive area.\n * @param {module:ol/size~Size} size The size to test.\n * @return {boolean} The size has a positive area.\n */\nexport function hasArea(size) {\n  return size[0] > 0 && size[1] > 0;\n}\n\n\n/**\n * Returns a size scaled by a ratio. The result will be an array of integers.\n * @param {module:ol/size~Size} size Size.\n * @param {number} ratio Ratio.\n * @param {module:ol/size~Size=} opt_size Optional reusable size array.\n * @return {module:ol/size~Size} The scaled size.\n */\nexport function scale(size, ratio, opt_size) {\n  if (opt_size === undefined) {\n    opt_size = [0, 0];\n  }\n  opt_size[0] = (size[0] * ratio + 0.5) | 0;\n  opt_size[1] = (size[1] * ratio + 0.5) | 0;\n  return opt_size;\n}\n\n\n/**\n * Returns an `module:ol/size~Size` array for the passed in number (meaning: square) or\n * `module:ol/size~Size` array.\n * (meaning: non-square),\n * @param {number|module:ol/size~Size} size Width and height.\n * @param {module:ol/size~Size=} opt_size Optional reusable size array.\n * @return {module:ol/size~Size} Size.\n * @api\n */\nexport function toSize(size, opt_size) {\n  if (Array.isArray(size)) {\n    return size;\n  } else {\n    if (opt_size === undefined) {\n      opt_size = [size, size];\n    } else {\n      opt_size[0] = opt_size[1] = /** @type {number} */ (size);\n    }\n    return opt_size;\n  }\n}\n","/**\n * @module ol/PluggableMap\n */\nimport {getUid} from './util.js';\nimport Collection from './Collection.js';\nimport CollectionEventType from './CollectionEventType.js';\nimport MapBrowserEvent from './MapBrowserEvent.js';\nimport MapBrowserEventHandler from './MapBrowserEventHandler.js';\nimport MapBrowserEventType from './MapBrowserEventType.js';\nimport MapEvent from './MapEvent.js';\nimport MapEventType from './MapEventType.js';\nimport MapProperty from './MapProperty.js';\nimport BaseObject, {getChangeEventType} from './Object.js';\nimport ObjectEventType from './ObjectEventType.js';\nimport TileQueue from './TileQueue.js';\nimport View from './View.js';\nimport ViewHint from './ViewHint.js';\nimport {assert} from './asserts.js';\nimport {removeNode} from './dom.js';\nimport {listen, unlistenByKey, unlisten} from './events.js';\nimport {stopPropagation} from './events/Event.js';\nimport EventType from './events/EventType.js';\nimport {createEmpty, clone, createOrUpdateEmpty, equals, getForViewAndSize, isEmpty} from './extent.js';\nimport {TRUE} from './functions.js';\nimport {DEVICE_PIXEL_RATIO, TOUCH} from './has.js';\nimport LayerGroup from './layer/Group.js';\nimport {hasArea} from './size.js';\nimport {DROP} from './structs/PriorityQueue.js';\nimport {create as createTransform, apply as applyTransform} from './transform.js';\n\n\n/**\n * State of the current frame. Only `pixelRatio`, `time` and `viewState` should\n * be used in applications.\n * @typedef {Object} FrameState\n * @property {number} pixelRatio The pixel ratio of the frame.\n * @property {number} time The time when rendering of the frame was requested.\n * @property {module:ol/View~State} viewState The state of the current view.\n * @property {boolean} animate\n * @property {module:ol/transform~Transform} coordinateToPixelTransform\n * @property {null|module:ol/extent~Extent} extent\n * @property {module:ol/coordinate~Coordinate} focus\n * @property {number} index\n * @property {Object.<number, module:ol/layer/Layer~State>} layerStates\n * @property {Array.<module:ol/layer/Layer~State>} layerStatesArray\n * @property {module:ol/transform~Transform} pixelToCoordinateTransform\n * @property {Array.<module:ol/PluggableMap~PostRenderFunction>} postRenderFunctions\n * @property {module:ol/size~Size} size\n * @property {!Object.<string, boolean>} skippedFeatureUids\n * @property {module:ol/TileQueue} tileQueue\n * @property {Object.<string, Object.<string, module:ol/TileRange>>} usedTiles\n * @property {Array.<number>} viewHints\n * @property {!Object.<string, Object.<string, boolean>>} wantedTiles\n */\n\n\n/**\n * @typedef {function(module:ol/PluggableMap, ?module:ol/PluggableMap~FrameState): boolean} PostRenderFunction\n */\n\n\n/**\n * @typedef {Object} AtPixelOptions\n * @property {((function(module:ol/layer/Layer): boolean)|undefined)} layerFilter Layer filter\n * function. The filter function will receive one argument, the\n * {@link module:ol/layer/Layer layer-candidate} and it should return a boolean value.\n * Only layers which are visible and for which this function returns `true`\n * will be tested for features. By default, all visible layers will be tested.\n * @property {number} [hitTolerance=0] Hit-detection tolerance in pixels. Pixels\n * inside the radius around the given position will be checked for features. This only\n * works for the canvas renderer and not for WebGL.\n */\n\n\n/**\n * @typedef {Object} MapOptionsInternal\n * @property {module:ol/Collection.<module:ol/control/Control>} [controls]\n * @property {module:ol/Collection.<module:ol/interaction/Interaction>} [interactions]\n * @property {HTMLElement|Document} keyboardEventTarget\n * @property {module:ol/Collection.<module:ol/Overlay>} overlays\n * @property {Object.<string, *>} values\n */\n\n\n/**\n * Object literal with config options for the map.\n * @typedef {Object} MapOptions\n * @property {module:ol/Collection.<module:ol/control/Control>|Array.<module:ol/control/Control>} [controls]\n * Controls initially added to the map. If not specified,\n * {@link module:ol/control/util~defaults} is used.\n * @property {number} [pixelRatio=window.devicePixelRatio] The ratio between\n * physical pixels and device-independent pixels (dips) on the device.\n * @property {module:ol/Collection.<module:ol/interaction/Interaction>|Array.<module:ol/interaction/Interaction>} [interactions]\n * Interactions that are initially added to the map. If not specified,\n * {@link module:ol/interaction~defaults} is used.\n * @property {HTMLElement|Document|string} [keyboardEventTarget] The element to\n * listen to keyboard events on. This determines when the `KeyboardPan` and\n * `KeyboardZoom` interactions trigger. For example, if this option is set to\n * `document` the keyboard interactions will always trigger. If this option is\n * not specified, the element the library listens to keyboard events on is the\n * map target (i.e. the user-provided div for the map). If this is not\n * `document`, the target element needs to be focused for key events to be\n * emitted, requiring that the target element has a `tabindex` attribute.\n * @property {Array.<module:ol/layer/Base>|module:ol/Collection.<module:ol/layer/Base>} [layers]\n * Layers. If this is not defined, a map with no layers will be rendered. Note\n * that layers are rendered in the order supplied, so if you want, for example,\n * a vector layer to appear on top of a tile layer, it must come after the tile\n * layer.\n * @property {number} [maxTilesLoading=16] Maximum number tiles to load\n * simultaneously.\n * @property {boolean} [loadTilesWhileAnimating=false] When set to `true`, tiles\n * will be loaded during animations. This may improve the user experience, but\n * can also make animations stutter on devices with slow memory.\n * @property {boolean} [loadTilesWhileInteracting=false] When set to `true`,\n * tiles will be loaded while interacting with the map. This may improve the\n * user experience, but can also make map panning and zooming choppy on devices\n * with slow memory.\n * @property {number} [moveTolerance=1] The minimum distance in pixels the\n * cursor must move to be detected as a map move event instead of a click.\n * Increasing this value can make it easier to click on the map.\n * @property {module:ol/Collection.<module:ol/Overlay>|Array.<module:ol/Overlay>} [overlays]\n * Overlays initially added to the map. By default, no overlays are added.\n * @property {HTMLElement|string} [target] The container for the map, either the\n * element itself or the `id` of the element. If not specified at construction\n * time, {@link module:ol/Map~Map#setTarget} must be called for the map to be\n * rendered.\n * @property {module:ol/View} [view] The map's view.  No layer sources will be\n * fetched unless this is specified at construction time or through\n * {@link module:ol/Map~Map#setView}.\n */\n\n\n/**\n * @fires module:ol/MapBrowserEvent~MapBrowserEvent\n * @fires module:ol/MapEvent~MapEvent\n * @fires module:ol/render/Event~RenderEvent#postcompose\n * @fires module:ol/render/Event~RenderEvent#precompose\n * @api\n */\nclass PluggableMap extends BaseObject {\n\n  /**\n   * @param {module:ol/PluggableMap~MapOptions} options Map options.\n   */\n  constructor(options) {\n\n    super();\n\n    const optionsInternal = createOptionsInternal(options);\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.maxTilesLoading_ = options.maxTilesLoading !== undefined ? options.maxTilesLoading : 16;\n\n    /**\n     * @type {boolean}\n     * @private\n     */\n    this.loadTilesWhileAnimating_ =\n        options.loadTilesWhileAnimating !== undefined ?\n          options.loadTilesWhileAnimating : false;\n\n    /**\n     * @type {boolean}\n     * @private\n     */\n    this.loadTilesWhileInteracting_ =\n        options.loadTilesWhileInteracting !== undefined ?\n          options.loadTilesWhileInteracting : false;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.pixelRatio_ = options.pixelRatio !== undefined ?\n      options.pixelRatio : DEVICE_PIXEL_RATIO;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.animationDelayKey_;\n\n    /**\n     * @private\n     */\n    this.animationDelay_ = function() {\n      this.animationDelayKey_ = undefined;\n      this.renderFrame_.call(this, Date.now());\n    }.bind(this);\n\n    /**\n     * @private\n     * @type {module:ol/transform~Transform}\n     */\n    this.coordinateToPixelTransform_ = createTransform();\n\n    /**\n     * @private\n     * @type {module:ol/transform~Transform}\n     */\n    this.pixelToCoordinateTransform_ = createTransform();\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.frameIndex_ = 0;\n\n    /**\n     * @private\n     * @type {?module:ol/PluggableMap~FrameState}\n     */\n    this.frameState_ = null;\n\n    /**\n     * The extent at the previous 'moveend' event.\n     * @private\n     * @type {module:ol/extent~Extent}\n     */\n    this.previousExtent_ = null;\n\n    /**\n     * @private\n     * @type {?module:ol/events~EventsKey}\n     */\n    this.viewPropertyListenerKey_ = null;\n\n    /**\n     * @private\n     * @type {?module:ol/events~EventsKey}\n     */\n    this.viewChangeListenerKey_ = null;\n\n    /**\n     * @private\n     * @type {Array.<module:ol/events~EventsKey>}\n     */\n    this.layerGroupPropertyListenerKeys_ = null;\n\n    /**\n     * @private\n     * @type {!HTMLElement}\n     */\n    this.viewport_ = document.createElement('DIV');\n    this.viewport_.className = 'ol-viewport' + (TOUCH ? ' ol-touch' : '');\n    this.viewport_.style.position = 'relative';\n    this.viewport_.style.overflow = 'hidden';\n    this.viewport_.style.width = '100%';\n    this.viewport_.style.height = '100%';\n    // prevent page zoom on IE >= 10 browsers\n    this.viewport_.style.msTouchAction = 'none';\n    this.viewport_.style.touchAction = 'none';\n\n    /**\n     * @private\n     * @type {!HTMLElement}\n     */\n    this.overlayContainer_ = document.createElement('DIV');\n    this.overlayContainer_.className = 'ol-overlaycontainer';\n    this.viewport_.appendChild(this.overlayContainer_);\n\n    /**\n     * @private\n     * @type {!HTMLElement}\n     */\n    this.overlayContainerStopEvent_ = document.createElement('DIV');\n    this.overlayContainerStopEvent_.className = 'ol-overlaycontainer-stopevent';\n    const overlayEvents = [\n      EventType.CLICK,\n      EventType.DBLCLICK,\n      EventType.MOUSEDOWN,\n      EventType.TOUCHSTART,\n      EventType.MSPOINTERDOWN,\n      MapBrowserEventType.POINTERDOWN,\n      EventType.MOUSEWHEEL,\n      EventType.WHEEL\n    ];\n    for (let i = 0, ii = overlayEvents.length; i < ii; ++i) {\n      listen(this.overlayContainerStopEvent_, overlayEvents[i], stopPropagation);\n    }\n    this.viewport_.appendChild(this.overlayContainerStopEvent_);\n\n    /**\n     * @private\n     * @type {module:ol/MapBrowserEventHandler}\n     */\n    this.mapBrowserEventHandler_ = new MapBrowserEventHandler(this, options.moveTolerance);\n    for (const key in MapBrowserEventType) {\n      listen(this.mapBrowserEventHandler_, MapBrowserEventType[key],\n        this.handleMapBrowserEvent, this);\n    }\n\n    /**\n     * @private\n     * @type {HTMLElement|Document}\n     */\n    this.keyboardEventTarget_ = optionsInternal.keyboardEventTarget;\n\n    /**\n     * @private\n     * @type {Array.<module:ol/events~EventsKey>}\n     */\n    this.keyHandlerKeys_ = null;\n\n    listen(this.viewport_, EventType.CONTEXTMENU, this.handleBrowserEvent, this);\n    listen(this.viewport_, EventType.WHEEL, this.handleBrowserEvent, this);\n    listen(this.viewport_, EventType.MOUSEWHEEL, this.handleBrowserEvent, this);\n\n    /**\n     * @type {module:ol/Collection.<module:ol/control/Control>}\n     * @protected\n     */\n    this.controls = optionsInternal.controls || new Collection();\n\n    /**\n     * @type {module:ol/Collection.<module:ol/interaction/Interaction>}\n     * @protected\n     */\n    this.interactions = optionsInternal.interactions || new Collection();\n\n    /**\n     * @type {module:ol/Collection.<module:ol/Overlay>}\n     * @private\n     */\n    this.overlays_ = optionsInternal.overlays;\n\n    /**\n     * A lookup of overlays by id.\n     * @private\n     * @type {Object.<string, module:ol/Overlay>}\n     */\n    this.overlayIdIndex_ = {};\n\n    /**\n     * @type {module:ol/renderer/Map}\n     * @private\n     */\n    this.renderer_ = this.createRenderer();\n\n    /**\n     * @type {function(Event)|undefined}\n     * @private\n     */\n    this.handleResize_;\n\n    /**\n     * @private\n     * @type {module:ol/coordinate~Coordinate}\n     */\n    this.focus_ = null;\n\n    /**\n     * @private\n     * @type {!Array.<module:ol/PluggableMap~PostRenderFunction>}\n     */\n    this.postRenderFunctions_ = [];\n\n    /**\n     * @private\n     * @type {module:ol/TileQueue}\n     */\n    this.tileQueue_ = new TileQueue(\n      this.getTilePriority.bind(this),\n      this.handleTileChange_.bind(this));\n\n    /**\n     * Uids of features to skip at rendering time.\n     * @type {Object.<string, boolean>}\n     * @private\n     */\n    this.skippedFeatureUids_ = {};\n\n    listen(\n      this, getChangeEventType(MapProperty.LAYERGROUP),\n      this.handleLayerGroupChanged_, this);\n    listen(this, getChangeEventType(MapProperty.VIEW),\n      this.handleViewChanged_, this);\n    listen(this, getChangeEventType(MapProperty.SIZE),\n      this.handleSizeChanged_, this);\n    listen(this, getChangeEventType(MapProperty.TARGET),\n      this.handleTargetChanged_, this);\n\n    // setProperties will trigger the rendering of the map if the map\n    // is \"defined\" already.\n    this.setProperties(optionsInternal.values);\n\n    this.controls.forEach(\n      /**\n       * @param {module:ol/control/Control} control Control.\n       * @this {module:ol/PluggableMap}\n       */\n      (function(control) {\n        control.setMap(this);\n      }).bind(this));\n\n    listen(this.controls, CollectionEventType.ADD,\n      /**\n       * @param {module:ol/Collection~CollectionEvent} event CollectionEvent.\n       */\n      function(event) {\n        event.element.setMap(this);\n      }, this);\n\n    listen(this.controls, CollectionEventType.REMOVE,\n      /**\n       * @param {module:ol/Collection~CollectionEvent} event CollectionEvent.\n       */\n      function(event) {\n        event.element.setMap(null);\n      }, this);\n\n    this.interactions.forEach(\n      /**\n       * @param {module:ol/interaction/Interaction} interaction Interaction.\n       * @this {module:ol/PluggableMap}\n       */\n      (function(interaction) {\n        interaction.setMap(this);\n      }).bind(this));\n\n    listen(this.interactions, CollectionEventType.ADD,\n      /**\n       * @param {module:ol/Collection~CollectionEvent} event CollectionEvent.\n       */\n      function(event) {\n        event.element.setMap(this);\n      }, this);\n\n    listen(this.interactions, CollectionEventType.REMOVE,\n      /**\n       * @param {module:ol/Collection~CollectionEvent} event CollectionEvent.\n       */\n      function(event) {\n        event.element.setMap(null);\n      }, this);\n\n    this.overlays_.forEach(this.addOverlayInternal_.bind(this));\n\n    listen(this.overlays_, CollectionEventType.ADD,\n      /**\n       * @param {module:ol/Collection~CollectionEvent} event CollectionEvent.\n       */\n      function(event) {\n        this.addOverlayInternal_(/** @type {module:ol/Overlay} */ (event.element));\n      }, this);\n\n    listen(this.overlays_, CollectionEventType.REMOVE,\n      /**\n       * @param {module:ol/Collection~CollectionEvent} event CollectionEvent.\n       */\n      function(event) {\n        const overlay = /** @type {module:ol/Overlay} */ (event.element);\n        const id = overlay.getId();\n        if (id !== undefined) {\n          delete this.overlayIdIndex_[id.toString()];\n        }\n        event.element.setMap(null);\n      }, this);\n\n  }\n\n  createRenderer() {\n    throw new Error('Use a map type that has a createRenderer method');\n  }\n\n  /**\n   * Add the given control to the map.\n   * @param {module:ol/control/Control} control Control.\n   * @api\n   */\n  addControl(control) {\n    this.getControls().push(control);\n  }\n\n  /**\n   * Add the given interaction to the map.\n   * @param {module:ol/interaction/Interaction} interaction Interaction to add.\n   * @api\n   */\n  addInteraction(interaction) {\n    this.getInteractions().push(interaction);\n  }\n\n  /**\n   * Adds the given layer to the top of this map. If you want to add a layer\n   * elsewhere in the stack, use `getLayers()` and the methods available on\n   * {@link module:ol/Collection~Collection}.\n   * @param {module:ol/layer/Base} layer Layer.\n   * @api\n   */\n  addLayer(layer) {\n    const layers = this.getLayerGroup().getLayers();\n    layers.push(layer);\n  }\n\n  /**\n   * Add the given overlay to the map.\n   * @param {module:ol/Overlay} overlay Overlay.\n   * @api\n   */\n  addOverlay(overlay) {\n    this.getOverlays().push(overlay);\n  }\n\n  /**\n   * This deals with map's overlay collection changes.\n   * @param {module:ol/Overlay} overlay Overlay.\n   * @private\n   */\n  addOverlayInternal_(overlay) {\n    const id = overlay.getId();\n    if (id !== undefined) {\n      this.overlayIdIndex_[id.toString()] = overlay;\n    }\n    overlay.setMap(this);\n  }\n\n  /**\n   *\n   * @inheritDoc\n   */\n  disposeInternal() {\n    this.mapBrowserEventHandler_.dispose();\n    unlisten(this.viewport_, EventType.CONTEXTMENU, this.handleBrowserEvent, this);\n    unlisten(this.viewport_, EventType.WHEEL, this.handleBrowserEvent, this);\n    unlisten(this.viewport_, EventType.MOUSEWHEEL, this.handleBrowserEvent, this);\n    if (this.handleResize_ !== undefined) {\n      removeEventListener(EventType.RESIZE, this.handleResize_, false);\n      this.handleResize_ = undefined;\n    }\n    if (this.animationDelayKey_) {\n      cancelAnimationFrame(this.animationDelayKey_);\n      this.animationDelayKey_ = undefined;\n    }\n    this.setTarget(null);\n    super.disposeInternal();\n  }\n\n  /**\n   * Detect features that intersect a pixel on the viewport, and execute a\n   * callback with each intersecting feature. Layers included in the detection can\n   * be configured through the `layerFilter` option in `opt_options`.\n   * @param {module:ol/pixel~Pixel} pixel Pixel.\n   * @param {function(this: S, (module:ol/Feature|module:ol/render/Feature),\n   *     module:ol/layer/Layer): T} callback Feature callback. The callback will be\n   *     called with two arguments. The first argument is one\n   *     {@link module:ol/Feature feature} or\n   *     {@link module:ol/render/Feature render feature} at the pixel, the second is\n   *     the {@link module:ol/layer/Layer layer} of the feature and will be null for\n   *     unmanaged layers. To stop detection, callback functions can return a\n   *     truthy value.\n   * @param {module:ol/PluggableMap~AtPixelOptions=} opt_options Optional options.\n   * @return {T|undefined} Callback result, i.e. the return value of last\n   * callback execution, or the first truthy callback return value.\n   * @template S,T\n   * @api\n   */\n  forEachFeatureAtPixel(pixel, callback, opt_options) {\n    if (!this.frameState_) {\n      return;\n    }\n    const coordinate = this.getCoordinateFromPixel(pixel);\n    opt_options = opt_options !== undefined ? opt_options : {};\n    const hitTolerance = opt_options.hitTolerance !== undefined ?\n      opt_options.hitTolerance * this.frameState_.pixelRatio : 0;\n    const layerFilter = opt_options.layerFilter !== undefined ?\n      opt_options.layerFilter : TRUE;\n    return this.renderer_.forEachFeatureAtCoordinate(\n      coordinate, this.frameState_, hitTolerance, callback, null,\n      layerFilter, null);\n  }\n\n  /**\n   * Get all features that intersect a pixel on the viewport.\n   * @param {module:ol/pixel~Pixel} pixel Pixel.\n   * @param {module:ol/PluggableMap~AtPixelOptions=} opt_options Optional options.\n   * @return {Array.<module:ol/Feature|module:ol/render/Feature>} The detected features or\n   * `null` if none were found.\n   * @api\n   */\n  getFeaturesAtPixel(pixel, opt_options) {\n    let features = null;\n    this.forEachFeatureAtPixel(pixel, function(feature) {\n      if (!features) {\n        features = [];\n      }\n      features.push(feature);\n    }, opt_options);\n    return features;\n  }\n\n  /**\n   * Detect layers that have a color value at a pixel on the viewport, and\n   * execute a callback with each matching layer. Layers included in the\n   * detection can be configured through `opt_layerFilter`.\n   * @param {module:ol/pixel~Pixel} pixel Pixel.\n   * @param {function(this: S, module:ol/layer/Layer, (Uint8ClampedArray|Uint8Array)): T} callback\n   *     Layer callback. This callback will receive two arguments: first is the\n   *     {@link module:ol/layer/Layer layer}, second argument is an array representing\n   *     [R, G, B, A] pixel values (0 - 255) and will be `null` for layer types\n   *     that do not currently support this argument. To stop detection, callback\n   *     functions can return a truthy value.\n   * @param {module:ol/PluggableMap~AtPixelOptions=} opt_options Configuration options.\n   * @return {T|undefined} Callback result, i.e. the return value of last\n   * callback execution, or the first truthy callback return value.\n   * @template S,T\n   * @api\n   */\n  forEachLayerAtPixel(pixel, callback, opt_options) {\n    if (!this.frameState_) {\n      return;\n    }\n    const options = opt_options || {};\n    const hitTolerance = options.hitTolerance !== undefined ?\n      opt_options.hitTolerance * this.frameState_.pixelRatio : 0;\n    const layerFilter = options.layerFilter || TRUE;\n    return this.renderer_.forEachLayerAtPixel(\n      pixel, this.frameState_, hitTolerance, callback, null, layerFilter, null);\n  }\n\n  /**\n   * Detect if features intersect a pixel on the viewport. Layers included in the\n   * detection can be configured through `opt_layerFilter`.\n   * @param {module:ol/pixel~Pixel} pixel Pixel.\n   * @param {module:ol/PluggableMap~AtPixelOptions=} opt_options Optional options.\n   * @return {boolean} Is there a feature at the given pixel?\n   * @template U\n   * @api\n   */\n  hasFeatureAtPixel(pixel, opt_options) {\n    if (!this.frameState_) {\n      return false;\n    }\n    const coordinate = this.getCoordinateFromPixel(pixel);\n    opt_options = opt_options !== undefined ? opt_options : {};\n    const layerFilter = opt_options.layerFilter !== undefined ? opt_options.layerFilter : TRUE;\n    const hitTolerance = opt_options.hitTolerance !== undefined ?\n      opt_options.hitTolerance * this.frameState_.pixelRatio : 0;\n    return this.renderer_.hasFeatureAtCoordinate(\n      coordinate, this.frameState_, hitTolerance, layerFilter, null);\n  }\n\n  /**\n   * Returns the coordinate in view projection for a browser event.\n   * @param {Event} event Event.\n   * @return {module:ol/coordinate~Coordinate} Coordinate.\n   * @api\n   */\n  getEventCoordinate(event) {\n    return this.getCoordinateFromPixel(this.getEventPixel(event));\n  }\n\n  /**\n   * Returns the map pixel position for a browser event relative to the viewport.\n   * @param {Event} event Event.\n   * @return {module:ol/pixel~Pixel} Pixel.\n   * @api\n   */\n  getEventPixel(event) {\n    const viewportPosition = this.viewport_.getBoundingClientRect();\n    const eventPosition = event.changedTouches ? event.changedTouches[0] : event;\n    return [\n      eventPosition.clientX - viewportPosition.left,\n      eventPosition.clientY - viewportPosition.top\n    ];\n  }\n\n  /**\n   * Get the target in which this map is rendered.\n   * Note that this returns what is entered as an option or in setTarget:\n   * if that was an element, it returns an element; if a string, it returns that.\n   * @return {HTMLElement|string|undefined} The Element or id of the Element that the\n   *     map is rendered in.\n   * @observable\n   * @api\n   */\n  getTarget() {\n    return /** @type {HTMLElement|string|undefined} */ (this.get(MapProperty.TARGET));\n  }\n\n  /**\n   * Get the DOM element into which this map is rendered. In contrast to\n   * `getTarget` this method always return an `Element`, or `null` if the\n   * map has no target.\n   * @return {HTMLElement} The element that the map is rendered in.\n   * @api\n   */\n  getTargetElement() {\n    const target = this.getTarget();\n    if (target !== undefined) {\n      return typeof target === 'string' ? document.getElementById(target) : target;\n    } else {\n      return null;\n    }\n  }\n\n  /**\n   * Get the coordinate for a given pixel.  This returns a coordinate in the\n   * map view projection.\n   * @param {module:ol/pixel~Pixel} pixel Pixel position in the map viewport.\n   * @return {module:ol/coordinate~Coordinate} The coordinate for the pixel position.\n   * @api\n   */\n  getCoordinateFromPixel(pixel) {\n    const frameState = this.frameState_;\n    if (!frameState) {\n      return null;\n    } else {\n      return applyTransform(frameState.pixelToCoordinateTransform, pixel.slice());\n    }\n  }\n\n  /**\n   * Get the map controls. Modifying this collection changes the controls\n   * associated with the map.\n   * @return {module:ol/Collection.<module:ol/control/Control>} Controls.\n   * @api\n   */\n  getControls() {\n    return this.controls;\n  }\n\n  /**\n   * Get the map overlays. Modifying this collection changes the overlays\n   * associated with the map.\n   * @return {module:ol/Collection.<module:ol/Overlay>} Overlays.\n   * @api\n   */\n  getOverlays() {\n    return this.overlays_;\n  }\n\n  /**\n   * Get an overlay by its identifier (the value returned by overlay.getId()).\n   * Note that the index treats string and numeric identifiers as the same. So\n   * `map.getOverlayById(2)` will return an overlay with id `'2'` or `2`.\n   * @param {string|number} id Overlay identifier.\n   * @return {module:ol/Overlay} Overlay.\n   * @api\n   */\n  getOverlayById(id) {\n    const overlay = this.overlayIdIndex_[id.toString()];\n    return overlay !== undefined ? overlay : null;\n  }\n\n  /**\n   * Get the map interactions. Modifying this collection changes the interactions\n   * associated with the map.\n   *\n   * Interactions are used for e.g. pan, zoom and rotate.\n   * @return {module:ol/Collection.<module:ol/interaction/Interaction>} Interactions.\n   * @api\n   */\n  getInteractions() {\n    return this.interactions;\n  }\n\n  /**\n   * Get the layergroup associated with this map.\n   * @return {module:ol/layer/Group} A layer group containing the layers in this map.\n   * @observable\n   * @api\n   */\n  getLayerGroup() {\n    return (\n      /** @type {module:ol/layer/Group} */ (this.get(MapProperty.LAYERGROUP))\n    );\n  }\n\n  /**\n   * Get the collection of layers associated with this map.\n   * @return {!module:ol/Collection.<module:ol/layer/Base>} Layers.\n   * @api\n   */\n  getLayers() {\n    const layers = this.getLayerGroup().getLayers();\n    return layers;\n  }\n\n  /**\n   * Get the pixel for a coordinate.  This takes a coordinate in the map view\n   * projection and returns the corresponding pixel.\n   * @param {module:ol/coordinate~Coordinate} coordinate A map coordinate.\n   * @return {module:ol/pixel~Pixel} A pixel position in the map viewport.\n   * @api\n   */\n  getPixelFromCoordinate(coordinate) {\n    const frameState = this.frameState_;\n    if (!frameState) {\n      return null;\n    } else {\n      return applyTransform(frameState.coordinateToPixelTransform, coordinate.slice(0, 2));\n    }\n  }\n\n  /**\n   * Get the map renderer.\n   * @return {module:ol/renderer/Map} Renderer\n   */\n  getRenderer() {\n    return this.renderer_;\n  }\n\n  /**\n   * Get the size of this map.\n   * @return {module:ol/size~Size|undefined} The size in pixels of the map in the DOM.\n   * @observable\n   * @api\n   */\n  getSize() {\n    return (\n      /** @type {module:ol/size~Size|undefined} */ (this.get(MapProperty.SIZE))\n    );\n  }\n\n  /**\n   * Get the view associated with this map. A view manages properties such as\n   * center and resolution.\n   * @return {module:ol/View} The view that controls this map.\n   * @observable\n   * @api\n   */\n  getView() {\n    return (\n      /** @type {module:ol/View} */ (this.get(MapProperty.VIEW))\n    );\n  }\n\n  /**\n   * Get the element that serves as the map viewport.\n   * @return {HTMLElement} Viewport.\n   * @api\n   */\n  getViewport() {\n    return this.viewport_;\n  }\n\n  /**\n   * Get the element that serves as the container for overlays.  Elements added to\n   * this container will let mousedown and touchstart events through to the map,\n   * so clicks and gestures on an overlay will trigger {@link module:ol/MapBrowserEvent~MapBrowserEvent}\n   * events.\n   * @return {!HTMLElement} The map's overlay container.\n   */\n  getOverlayContainer() {\n    return this.overlayContainer_;\n  }\n\n  /**\n   * Get the element that serves as a container for overlays that don't allow\n   * event propagation. Elements added to this container won't let mousedown and\n   * touchstart events through to the map, so clicks and gestures on an overlay\n   * don't trigger any {@link module:ol/MapBrowserEvent~MapBrowserEvent}.\n   * @return {!HTMLElement} The map's overlay container that stops events.\n   */\n  getOverlayContainerStopEvent() {\n    return this.overlayContainerStopEvent_;\n  }\n\n  /**\n   * @param {module:ol/Tile} tile Tile.\n   * @param {string} tileSourceKey Tile source key.\n   * @param {module:ol/coordinate~Coordinate} tileCenter Tile center.\n   * @param {number} tileResolution Tile resolution.\n   * @return {number} Tile priority.\n   */\n  getTilePriority(tile, tileSourceKey, tileCenter, tileResolution) {\n    // Filter out tiles at higher zoom levels than the current zoom level, or that\n    // are outside the visible extent.\n    const frameState = this.frameState_;\n    if (!frameState || !(tileSourceKey in frameState.wantedTiles)) {\n      return DROP;\n    }\n    if (!frameState.wantedTiles[tileSourceKey][tile.getKey()]) {\n      return DROP;\n    }\n    // Prioritize the highest zoom level tiles closest to the focus.\n    // Tiles at higher zoom levels are prioritized using Math.log(tileResolution).\n    // Within a zoom level, tiles are prioritized by the distance in pixels\n    // between the center of the tile and the focus.  The factor of 65536 means\n    // that the prioritization should behave as desired for tiles up to\n    // 65536 * Math.log(2) = 45426 pixels from the focus.\n    const deltaX = tileCenter[0] - frameState.focus[0];\n    const deltaY = tileCenter[1] - frameState.focus[1];\n    return 65536 * Math.log(tileResolution) +\n        Math.sqrt(deltaX * deltaX + deltaY * deltaY) / tileResolution;\n  }\n\n  /**\n   * @param {Event} browserEvent Browser event.\n   * @param {string=} opt_type Type.\n   */\n  handleBrowserEvent(browserEvent, opt_type) {\n    const type = opt_type || browserEvent.type;\n    const mapBrowserEvent = new MapBrowserEvent(type, this, browserEvent);\n    this.handleMapBrowserEvent(mapBrowserEvent);\n  }\n\n  /**\n   * @param {module:ol/MapBrowserEvent} mapBrowserEvent The event to handle.\n   */\n  handleMapBrowserEvent(mapBrowserEvent) {\n    if (!this.frameState_) {\n      // With no view defined, we cannot translate pixels into geographical\n      // coordinates so interactions cannot be used.\n      return;\n    }\n    this.focus_ = mapBrowserEvent.coordinate;\n    mapBrowserEvent.frameState = this.frameState_;\n    const interactionsArray = this.getInteractions().getArray();\n    if (this.dispatchEvent(mapBrowserEvent) !== false) {\n      for (let i = interactionsArray.length - 1; i >= 0; i--) {\n        const interaction = interactionsArray[i];\n        if (!interaction.getActive()) {\n          continue;\n        }\n        const cont = interaction.handleEvent(mapBrowserEvent);\n        if (!cont) {\n          break;\n        }\n      }\n    }\n  }\n\n  /**\n   * @protected\n   */\n  handlePostRender() {\n\n    const frameState = this.frameState_;\n\n    // Manage the tile queue\n    // Image loads are expensive and a limited resource, so try to use them\n    // efficiently:\n    // * When the view is static we allow a large number of parallel tile loads\n    //   to complete the frame as quickly as possible.\n    // * When animating or interacting, image loads can cause janks, so we reduce\n    //   the maximum number of loads per frame and limit the number of parallel\n    //   tile loads to remain reactive to view changes and to reduce the chance of\n    //   loading tiles that will quickly disappear from view.\n    const tileQueue = this.tileQueue_;\n    if (!tileQueue.isEmpty()) {\n      let maxTotalLoading = this.maxTilesLoading_;\n      let maxNewLoads = maxTotalLoading;\n      if (frameState) {\n        const hints = frameState.viewHints;\n        if (hints[ViewHint.ANIMATING]) {\n          maxTotalLoading = this.loadTilesWhileAnimating_ ? 8 : 0;\n          maxNewLoads = 2;\n        }\n        if (hints[ViewHint.INTERACTING]) {\n          maxTotalLoading = this.loadTilesWhileInteracting_ ? 8 : 0;\n          maxNewLoads = 2;\n        }\n      }\n      if (tileQueue.getTilesLoading() < maxTotalLoading) {\n        tileQueue.reprioritize(); // FIXME only call if view has changed\n        tileQueue.loadMoreTiles(maxTotalLoading, maxNewLoads);\n      }\n    }\n\n    const postRenderFunctions = this.postRenderFunctions_;\n    for (let i = 0, ii = postRenderFunctions.length; i < ii; ++i) {\n      postRenderFunctions[i](this, frameState);\n    }\n    postRenderFunctions.length = 0;\n  }\n\n  /**\n   * @private\n   */\n  handleSizeChanged_() {\n    this.render();\n  }\n\n  /**\n   * @private\n   */\n  handleTargetChanged_() {\n    // target may be undefined, null, a string or an Element.\n    // If it's a string we convert it to an Element before proceeding.\n    // If it's not now an Element we remove the viewport from the DOM.\n    // If it's an Element we append the viewport element to it.\n\n    let targetElement;\n    if (this.getTarget()) {\n      targetElement = this.getTargetElement();\n    }\n\n    if (this.keyHandlerKeys_) {\n      for (let i = 0, ii = this.keyHandlerKeys_.length; i < ii; ++i) {\n        unlistenByKey(this.keyHandlerKeys_[i]);\n      }\n      this.keyHandlerKeys_ = null;\n    }\n\n    if (!targetElement) {\n      this.renderer_.removeLayerRenderers();\n      removeNode(this.viewport_);\n      if (this.handleResize_ !== undefined) {\n        removeEventListener(EventType.RESIZE, this.handleResize_, false);\n        this.handleResize_ = undefined;\n      }\n    } else {\n      targetElement.appendChild(this.viewport_);\n\n      const keyboardEventTarget = !this.keyboardEventTarget_ ?\n        targetElement : this.keyboardEventTarget_;\n      this.keyHandlerKeys_ = [\n        listen(keyboardEventTarget, EventType.KEYDOWN, this.handleBrowserEvent, this),\n        listen(keyboardEventTarget, EventType.KEYPRESS, this.handleBrowserEvent, this)\n      ];\n\n      if (!this.handleResize_) {\n        this.handleResize_ = this.updateSize.bind(this);\n        addEventListener(EventType.RESIZE, this.handleResize_, false);\n      }\n    }\n\n    this.updateSize();\n    // updateSize calls setSize, so no need to call this.render\n    // ourselves here.\n  }\n\n  /**\n   * @private\n   */\n  handleTileChange_() {\n    this.render();\n  }\n\n  /**\n   * @private\n   */\n  handleViewPropertyChanged_() {\n    this.render();\n  }\n\n  /**\n   * @private\n   */\n  handleViewChanged_() {\n    if (this.viewPropertyListenerKey_) {\n      unlistenByKey(this.viewPropertyListenerKey_);\n      this.viewPropertyListenerKey_ = null;\n    }\n    if (this.viewChangeListenerKey_) {\n      unlistenByKey(this.viewChangeListenerKey_);\n      this.viewChangeListenerKey_ = null;\n    }\n    const view = this.getView();\n    if (view) {\n      this.viewport_.setAttribute('data-view', getUid(view));\n      this.viewPropertyListenerKey_ = listen(\n        view, ObjectEventType.PROPERTYCHANGE,\n        this.handleViewPropertyChanged_, this);\n      this.viewChangeListenerKey_ = listen(\n        view, EventType.CHANGE,\n        this.handleViewPropertyChanged_, this);\n    }\n    this.render();\n  }\n\n  /**\n   * @private\n   */\n  handleLayerGroupChanged_() {\n    if (this.layerGroupPropertyListenerKeys_) {\n      this.layerGroupPropertyListenerKeys_.forEach(unlistenByKey);\n      this.layerGroupPropertyListenerKeys_ = null;\n    }\n    const layerGroup = this.getLayerGroup();\n    if (layerGroup) {\n      this.layerGroupPropertyListenerKeys_ = [\n        listen(\n          layerGroup, ObjectEventType.PROPERTYCHANGE,\n          this.render, this),\n        listen(\n          layerGroup, EventType.CHANGE,\n          this.render, this)\n      ];\n    }\n    this.render();\n  }\n\n  /**\n   * @return {boolean} Is rendered.\n   */\n  isRendered() {\n    return !!this.frameState_;\n  }\n\n  /**\n   * Requests an immediate render in a synchronous manner.\n   * @api\n   */\n  renderSync() {\n    if (this.animationDelayKey_) {\n      cancelAnimationFrame(this.animationDelayKey_);\n    }\n    this.animationDelay_();\n  }\n\n  /**\n   * Request a map rendering (at the next animation frame).\n   * @api\n   */\n  render() {\n    if (this.animationDelayKey_ === undefined) {\n      this.animationDelayKey_ = requestAnimationFrame(this.animationDelay_);\n    }\n  }\n\n  /**\n   * Remove the given control from the map.\n   * @param {module:ol/control/Control} control Control.\n   * @return {module:ol/control/Control|undefined} The removed control (or undefined\n   *     if the control was not found).\n   * @api\n   */\n  removeControl(control) {\n    return this.getControls().remove(control);\n  }\n\n  /**\n   * Remove the given interaction from the map.\n   * @param {module:ol/interaction/Interaction} interaction Interaction to remove.\n   * @return {module:ol/interaction/Interaction|undefined} The removed interaction (or\n   *     undefined if the interaction was not found).\n   * @api\n   */\n  removeInteraction(interaction) {\n    return this.getInteractions().remove(interaction);\n  }\n\n  /**\n   * Removes the given layer from the map.\n   * @param {module:ol/layer/Base} layer Layer.\n   * @return {module:ol/layer/Base|undefined} The removed layer (or undefined if the\n   *     layer was not found).\n   * @api\n   */\n  removeLayer(layer) {\n    const layers = this.getLayerGroup().getLayers();\n    return layers.remove(layer);\n  }\n\n  /**\n   * Remove the given overlay from the map.\n   * @param {module:ol/Overlay} overlay Overlay.\n   * @return {module:ol/Overlay|undefined} The removed overlay (or undefined\n   *     if the overlay was not found).\n   * @api\n   */\n  removeOverlay(overlay) {\n    return this.getOverlays().remove(overlay);\n  }\n\n  /**\n   * @param {number} time Time.\n   * @private\n   */\n  renderFrame_(time) {\n    let viewState;\n\n    const size = this.getSize();\n    const view = this.getView();\n    const extent = createEmpty();\n    const previousFrameState = this.frameState_;\n    /** @type {?module:ol/PluggableMap~FrameState} */\n    let frameState = null;\n    if (size !== undefined && hasArea(size) && view && view.isDef()) {\n      const viewHints = view.getHints(this.frameState_ ? this.frameState_.viewHints : undefined);\n      const layerStatesArray = this.getLayerGroup().getLayerStatesArray();\n      const layerStates = {};\n      for (let i = 0, ii = layerStatesArray.length; i < ii; ++i) {\n        layerStates[getUid(layerStatesArray[i].layer)] = layerStatesArray[i];\n      }\n      viewState = view.getState();\n      let focus = this.focus_;\n      if (!focus) {\n        focus = viewState.center;\n        const pixelResolution = viewState.resolution / this.pixelRatio_;\n        focus[0] = Math.round(focus[0] / pixelResolution) * pixelResolution;\n        focus[1] = Math.round(focus[1] / pixelResolution) * pixelResolution;\n      }\n      frameState = /** @type {module:ol/PluggableMap~FrameState} */ ({\n        animate: false,\n        coordinateToPixelTransform: this.coordinateToPixelTransform_,\n        extent: extent,\n        focus: focus,\n        index: this.frameIndex_++,\n        layerStates: layerStates,\n        layerStatesArray: layerStatesArray,\n        pixelRatio: this.pixelRatio_,\n        pixelToCoordinateTransform: this.pixelToCoordinateTransform_,\n        postRenderFunctions: [],\n        size: size,\n        skippedFeatureUids: this.skippedFeatureUids_,\n        tileQueue: this.tileQueue_,\n        time: time,\n        usedTiles: {},\n        viewState: viewState,\n        viewHints: viewHints,\n        wantedTiles: {}\n      });\n    }\n\n    if (frameState) {\n      frameState.extent = getForViewAndSize(viewState.center,\n        viewState.resolution, viewState.rotation, frameState.size, extent);\n    }\n\n    this.frameState_ = frameState;\n    this.renderer_.renderFrame(frameState);\n\n    if (frameState) {\n      if (frameState.animate) {\n        this.render();\n      }\n      Array.prototype.push.apply(this.postRenderFunctions_, frameState.postRenderFunctions);\n\n      if (previousFrameState) {\n        const moveStart = !this.previousExtent_ ||\n                    (!isEmpty(this.previousExtent_) &&\n                    !equals(frameState.extent, this.previousExtent_));\n        if (moveStart) {\n          this.dispatchEvent(\n            new MapEvent(MapEventType.MOVESTART, this, previousFrameState));\n          this.previousExtent_ = createOrUpdateEmpty(this.previousExtent_);\n        }\n      }\n\n      const idle = this.previousExtent_ &&\n          !frameState.viewHints[ViewHint.ANIMATING] &&\n          !frameState.viewHints[ViewHint.INTERACTING] &&\n          !equals(frameState.extent, this.previousExtent_);\n\n      if (idle) {\n        this.dispatchEvent(new MapEvent(MapEventType.MOVEEND, this, frameState));\n        clone(frameState.extent, this.previousExtent_);\n      }\n    }\n\n    this.dispatchEvent(new MapEvent(MapEventType.POSTRENDER, this, frameState));\n\n    setTimeout(this.handlePostRender.bind(this), 0);\n\n  }\n\n  /**\n   * Sets the layergroup of this map.\n   * @param {module:ol/layer/Group} layerGroup A layer group containing the layers in this map.\n   * @observable\n   * @api\n   */\n  setLayerGroup(layerGroup) {\n    this.set(MapProperty.LAYERGROUP, layerGroup);\n  }\n\n  /**\n   * Set the size of this map.\n   * @param {module:ol/size~Size|undefined} size The size in pixels of the map in the DOM.\n   * @observable\n   * @api\n   */\n  setSize(size) {\n    this.set(MapProperty.SIZE, size);\n  }\n\n  /**\n   * Set the target element to render this map into.\n   * @param {HTMLElement|string|undefined} target The Element or id of the Element\n   *     that the map is rendered in.\n   * @observable\n   * @api\n   */\n  setTarget(target) {\n    this.set(MapProperty.TARGET, target);\n  }\n\n  /**\n   * Set the view for this map.\n   * @param {module:ol/View} view The view that controls this map.\n   * @observable\n   * @api\n   */\n  setView(view) {\n    this.set(MapProperty.VIEW, view);\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature.\n   */\n  skipFeature(feature) {\n    const featureUid = getUid(feature).toString();\n    this.skippedFeatureUids_[featureUid] = true;\n    this.render();\n  }\n\n  /**\n   * Force a recalculation of the map viewport size.  This should be called when\n   * third-party code changes the size of the map viewport.\n   * @api\n   */\n  updateSize() {\n    const targetElement = this.getTargetElement();\n\n    if (!targetElement) {\n      this.setSize(undefined);\n    } else {\n      const computedStyle = getComputedStyle(targetElement);\n      this.setSize([\n        targetElement.offsetWidth -\n            parseFloat(computedStyle['borderLeftWidth']) -\n            parseFloat(computedStyle['paddingLeft']) -\n            parseFloat(computedStyle['paddingRight']) -\n            parseFloat(computedStyle['borderRightWidth']),\n        targetElement.offsetHeight -\n            parseFloat(computedStyle['borderTopWidth']) -\n            parseFloat(computedStyle['paddingTop']) -\n            parseFloat(computedStyle['paddingBottom']) -\n            parseFloat(computedStyle['borderBottomWidth'])\n      ]);\n    }\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature.\n   */\n  unskipFeature(feature) {\n    const featureUid = getUid(feature).toString();\n    delete this.skippedFeatureUids_[featureUid];\n    this.render();\n  }\n}\n\n\n/**\n * @param {MapOptions} options Map options.\n * @return {module:ol/PluggableMap~MapOptionsInternal} Internal map options.\n */\nfunction createOptionsInternal(options) {\n\n  /**\n   * @type {HTMLElement|Document}\n   */\n  let keyboardEventTarget = null;\n  if (options.keyboardEventTarget !== undefined) {\n    keyboardEventTarget = typeof options.keyboardEventTarget === 'string' ?\n      document.getElementById(options.keyboardEventTarget) :\n      options.keyboardEventTarget;\n  }\n\n  /**\n   * @type {Object.<string, *>}\n   */\n  const values = {};\n\n  const layerGroup = (options.layers instanceof LayerGroup) ?\n    options.layers : new LayerGroup({layers: options.layers});\n  values[MapProperty.LAYERGROUP] = layerGroup;\n\n  values[MapProperty.TARGET] = options.target;\n\n  values[MapProperty.VIEW] = options.view !== undefined ?\n    options.view : new View();\n\n  let controls;\n  if (options.controls !== undefined) {\n    if (Array.isArray(options.controls)) {\n      controls = new Collection(options.controls.slice());\n    } else {\n      assert(options.controls instanceof Collection,\n        47); // Expected `controls` to be an array or an `module:ol/Collection~Collection`\n      controls = options.controls;\n    }\n  }\n\n  let interactions;\n  if (options.interactions !== undefined) {\n    if (Array.isArray(options.interactions)) {\n      interactions = new Collection(options.interactions.slice());\n    } else {\n      assert(options.interactions instanceof Collection,\n        48); // Expected `interactions` to be an array or an `module:ol/Collection~Collection`\n      interactions = options.interactions;\n    }\n  }\n\n  let overlays;\n  if (options.overlays !== undefined) {\n    if (Array.isArray(options.overlays)) {\n      overlays = new Collection(options.overlays.slice());\n    } else {\n      assert(options.overlays instanceof Collection,\n        49); // Expected `overlays` to be an array or an `module:ol/Collection~Collection`\n      overlays = options.overlays;\n    }\n  } else {\n    overlays = new Collection();\n  }\n\n  return {\n    controls: controls,\n    interactions: interactions,\n    keyboardEventTarget: keyboardEventTarget,\n    overlays: overlays,\n    values: values\n  };\n\n}\nexport default PluggableMap;\n","/**\n * @module ol/control/Control\n */\nimport {UNDEFINED} from '../functions.js';\nimport MapEventType from '../MapEventType.js';\nimport BaseObject from '../Object.js';\nimport {removeNode} from '../dom.js';\nimport {listen, unlistenByKey} from '../events.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {HTMLElement} [element] The element is the control's\n * container element. This only needs to be specified if you're developing\n * a custom control.\n * @property {function(module:ol/MapEvent)} [render] Function called when\n * the control should be re-rendered. This is called in a `requestAnimationFrame`\n * callback.\n * @property {HTMLElement|string} [target] Specify a target if you want\n * the control to be rendered outside of the map's viewport.\n */\n\n\n/**\n * @classdesc\n * A control is a visible widget with a DOM element in a fixed position on the\n * screen. They can involve user input (buttons), or be informational only;\n * the position is determined using CSS. By default these are placed in the\n * container with CSS class name `ol-overlaycontainer-stopevent`, but can use\n * any outside DOM element.\n *\n * This is the base class for controls. You can use it for simple custom\n * controls by creating the element with listeners, creating an instance:\n * ```js\n * var myControl = new Control({element: myElement});\n * ```\n * and then adding this to the map.\n *\n * The main advantage of having this as a control rather than a simple separate\n * DOM element is that preventing propagation is handled for you. Controls\n * will also be objects in a {@link module:ol/Collection~Collection}, so you can use their methods.\n *\n * You can also extend this base for your own control class. See\n * examples/custom-controls for an example of how to do this.\n *\n * @api\n */\nclass Control extends BaseObject {\n\n  /**\n   * @param {module:ol/control/Control~Options} options Control options.\n   */\n  constructor(options) {\n\n    super();\n\n    /**\n     * @protected\n     * @type {HTMLElement}\n     */\n    this.element = options.element ? options.element : null;\n\n    /**\n     * @private\n     * @type {HTMLElement}\n     */\n    this.target_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/PluggableMap}\n     */\n    this.map_ = null;\n\n    /**\n     * @protected\n     * @type {!Array.<module:ol/events~EventsKey>}\n     */\n    this.listenerKeys = [];\n\n    /**\n     * @type {function(module:ol/MapEvent)}\n     */\n    this.render = options.render ? options.render : UNDEFINED;\n\n    if (options.target) {\n      this.setTarget(options.target);\n    }\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  disposeInternal() {\n    removeNode(this.element);\n    super.disposeInternal();\n  }\n\n  /**\n   * Get the map associated with this control.\n   * @return {module:ol/PluggableMap} Map.\n   * @api\n   */\n  getMap() {\n    return this.map_;\n  }\n\n  /**\n   * Remove the control from its current map and attach it to the new map.\n   * Subclasses may set up event handlers to get notified about changes to\n   * the map here.\n   * @param {module:ol/PluggableMap} map Map.\n   * @api\n   */\n  setMap(map) {\n    if (this.map_) {\n      removeNode(this.element);\n    }\n    for (let i = 0, ii = this.listenerKeys.length; i < ii; ++i) {\n      unlistenByKey(this.listenerKeys[i]);\n    }\n    this.listenerKeys.length = 0;\n    this.map_ = map;\n    if (this.map_) {\n      const target = this.target_ ?\n        this.target_ : map.getOverlayContainerStopEvent();\n      target.appendChild(this.element);\n      if (this.render !== UNDEFINED) {\n        this.listenerKeys.push(listen(map,\n          MapEventType.POSTRENDER, this.render, this));\n      }\n      map.render();\n    }\n  }\n\n  /**\n   * This function is used to set a target element for the control. It has no\n   * effect if it is called after the control has been added to the map (i.e.\n   * after `setMap` is called on the control). If no `target` is set in the\n   * options passed to the control constructor and if `setTarget` is not called\n   * then the control is added to the map's overlay container.\n   * @param {HTMLElement|string} target Target.\n   * @api\n   */\n  setTarget(target) {\n    this.target_ = typeof target === 'string' ?\n      document.getElementById(target) :\n      target;\n  }\n}\n\n\nexport default Control;\n","/**\n * @module ol/layer/Layer\n */\nimport {listen, unlistenByKey} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport {getUid} from '../util.js';\nimport {getChangeEventType} from '../Object.js';\nimport BaseLayer from '../layer/Base.js';\nimport LayerProperty from '../layer/Property.js';\nimport {assign} from '../obj.js';\nimport RenderEventType from '../render/EventType.js';\nimport SourceState from '../source/State.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {module:ol/extent~Extent} [extent] The bounding extent for layer rendering.  The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex=0] The z-index for layer rendering.  At rendering time, the layers\n * will be ordered, first by Z-index and then by position.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {module:ol/source/Source} [source] Source for this layer.  If not provided to the constructor,\n * the source can be set by calling {@link module:ol/layer/Layer#setSource layer.setSource(source)} after\n * construction.\n */\n\n\n/**\n * @typedef {Object} State\n * @property {module:ol/layer/Layer} layer\n * @property {number} opacity\n * @property {module:ol/source/Source~State} sourceState\n * @property {boolean} visible\n * @property {boolean} managed\n * @property {module:ol/extent~Extent} [extent]\n * @property {number} zIndex\n * @property {number} maxResolution\n * @property {number} minResolution\n */\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * A visual representation of raster or vector map data.\n * Layers group together those properties that pertain to how the data is to be\n * displayed, irrespective of the source of that data.\n *\n * Layers are usually added to a map with {@link module:ol/Map#addLayer}. Components\n * like {@link module:ol/interaction/Select~Select} use unmanaged layers\n * internally. These unmanaged layers are associated with the map using\n * {@link module:ol/layer/Layer~Layer#setMap} instead.\n *\n * A generic `change` event is fired when the state of the source changes.\n *\n * @fires module:ol/render/Event~RenderEvent\n */\nclass Layer extends BaseLayer {\n  /**\n   * @param {module:ol/layer/Layer~Options} options Layer options.\n   */\n  constructor(options) {\n\n    const baseOptions = assign({}, options);\n    delete baseOptions.source;\n\n    super(baseOptions);\n\n    /**\n     * @private\n     * @type {?module:ol/events~EventsKey}\n     */\n    this.mapPrecomposeKey_ = null;\n\n    /**\n     * @private\n     * @type {?module:ol/events~EventsKey}\n     */\n    this.mapRenderKey_ = null;\n\n    /**\n     * @private\n     * @type {?module:ol/events~EventsKey}\n     */\n    this.sourceChangeKey_ = null;\n\n    if (options.map) {\n      this.setMap(options.map);\n    }\n\n    listen(this,\n      getChangeEventType(LayerProperty.SOURCE),\n      this.handleSourcePropertyChange_, this);\n\n    const source = options.source ? options.source : null;\n    this.setSource(source);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getLayersArray(opt_array) {\n    const array = opt_array ? opt_array : [];\n    array.push(this);\n    return array;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getLayerStatesArray(opt_states) {\n    const states = opt_states ? opt_states : [];\n    states.push(this.getLayerState());\n    return states;\n  }\n\n  /**\n   * Get the layer source.\n   * @return {module:ol/source/Source} The layer source (or `null` if not yet set).\n   * @observable\n   * @api\n   */\n  getSource() {\n    const source = this.get(LayerProperty.SOURCE);\n    return (\n      /** @type {module:ol/source/Source} */ (source) || null\n    );\n  }\n\n  /**\n    * @inheritDoc\n    */\n  getSourceState() {\n    const source = this.getSource();\n    return !source ? SourceState.UNDEFINED : source.getState();\n  }\n\n  /**\n   * @private\n   */\n  handleSourceChange_() {\n    this.changed();\n  }\n\n  /**\n   * @private\n   */\n  handleSourcePropertyChange_() {\n    if (this.sourceChangeKey_) {\n      unlistenByKey(this.sourceChangeKey_);\n      this.sourceChangeKey_ = null;\n    }\n    const source = this.getSource();\n    if (source) {\n      this.sourceChangeKey_ = listen(source,\n        EventType.CHANGE, this.handleSourceChange_, this);\n    }\n    this.changed();\n  }\n\n  /**\n   * Sets the layer to be rendered on top of other layers on a map. The map will\n   * not manage this layer in its layers collection, and the callback in\n   * {@link module:ol/Map#forEachLayerAtPixel} will receive `null` as layer. This\n   * is useful for temporary layers. To remove an unmanaged layer from the map,\n   * use `#setMap(null)`.\n   *\n   * To add the layer to a map and have it managed by the map, use\n   * {@link module:ol/Map#addLayer} instead.\n   * @param {module:ol/PluggableMap} map Map.\n   * @api\n   */\n  setMap(map) {\n    if (this.mapPrecomposeKey_) {\n      unlistenByKey(this.mapPrecomposeKey_);\n      this.mapPrecomposeKey_ = null;\n    }\n    if (!map) {\n      this.changed();\n    }\n    if (this.mapRenderKey_) {\n      unlistenByKey(this.mapRenderKey_);\n      this.mapRenderKey_ = null;\n    }\n    if (map) {\n      this.mapPrecomposeKey_ = listen(map, RenderEventType.PRECOMPOSE, function(evt) {\n        const layerState = this.getLayerState();\n        layerState.managed = false;\n        layerState.zIndex = Infinity;\n        evt.frameState.layerStatesArray.push(layerState);\n        evt.frameState.layerStates[getUid(this)] = layerState;\n      }, this);\n      this.mapRenderKey_ = listen(this, EventType.CHANGE, map.render, map);\n      this.changed();\n    }\n  }\n\n  /**\n   * Set the layer source.\n   * @param {module:ol/source/Source} source The layer source.\n   * @observable\n   * @api\n   */\n  setSource(source) {\n    this.set(LayerProperty.SOURCE, source);\n  }\n}\n\n\n/**\n * Return `true` if the layer is visible, and if the passed resolution is\n * between the layer's minResolution and maxResolution. The comparison is\n * inclusive for `minResolution` and exclusive for `maxResolution`.\n * @param {module:ol/layer/Layer~State} layerState Layer state.\n * @param {number} resolution Resolution.\n * @return {boolean} The layer is visible at the given resolution.\n */\nexport function visibleAtResolution(layerState, resolution) {\n  return layerState.visible && resolution >= layerState.minResolution &&\n      resolution < layerState.maxResolution;\n}\n\n\nexport default Layer;\n","/**\n * @module ol/control/Attribution\n */\nimport {equals} from '../array.js';\nimport Control from '../control/Control.js';\nimport {CLASS_CONTROL, CLASS_UNSELECTABLE, CLASS_COLLAPSED} from '../css.js';\nimport {removeChildren, replaceNode} from '../dom.js';\nimport {listen} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport {visibleAtResolution} from '../layer/Layer.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-attribution'] CSS class name.\n * @property {HTMLElement|string} [target] Specify a target if you\n * want the control to be rendered outside of the map's\n * viewport.\n * @property {boolean} [collapsible=true] Specify if attributions can\n * be collapsed. If you use an OSM source, should be set to `false` — see\n * {@link https://www.openstreetmap.org/copyright OSM Copyright} —\n * @property {boolean} [collapsed=true] Specify if attributions should\n * be collapsed at startup.\n * @property {string} [tipLabel='Attributions'] Text label to use for the button tip.\n * @property {string} [label='i'] Text label to use for the\n * collapsed attributions button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string|HTMLElement} [collapseLabel='»'] Text label to use\n * for the expanded attributions button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {function(module:ol/MapEvent)} [render] Function called when\n * the control should be re-rendered. This is called in a `requestAnimationFrame`\n * callback.\n */\n\n\n/**\n * @classdesc\n * Control to show all the attributions associated with the layer sources\n * in the map. This control is one of the default controls included in maps.\n * By default it will show in the bottom right portion of the map, but this can\n * be changed by using a css selector for `.ol-attribution`.\n *\n * @api\n */\nclass Attribution extends Control {\n\n  /**\n   * @param {module:ol/control/Attribution~Options=} opt_options Attribution options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options ? opt_options : {};\n\n    super({\n      element: document.createElement('div'),\n      render: options.render || render,\n      target: options.target\n    });\n\n    /**\n     * @private\n     * @type {HTMLElement}\n     */\n    this.ulElement_ = document.createElement('UL');\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.collapsed_ = options.collapsed !== undefined ? options.collapsed : true;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.collapsible_ = options.collapsible !== undefined ?\n      options.collapsible : true;\n\n    if (!this.collapsible_) {\n      this.collapsed_ = false;\n    }\n\n    const className = options.className !== undefined ? options.className : 'ol-attribution';\n\n    const tipLabel = options.tipLabel !== undefined ? options.tipLabel : 'Attributions';\n\n    const collapseLabel = options.collapseLabel !== undefined ? options.collapseLabel : '\\u00BB';\n\n    if (typeof collapseLabel === 'string') {\n      /**\n       * @private\n       * @type {HTMLElement}\n       */\n      this.collapseLabel_ = document.createElement('span');\n      this.collapseLabel_.textContent = collapseLabel;\n    } else {\n      this.collapseLabel_ = collapseLabel;\n    }\n\n    const label = options.label !== undefined ? options.label : 'i';\n\n    if (typeof label === 'string') {\n      /**\n       * @private\n       * @type {HTMLElement}\n       */\n      this.label_ = document.createElement('span');\n      this.label_.textContent = label;\n    } else {\n      this.label_ = label;\n    }\n\n\n    const activeLabel = (this.collapsible_ && !this.collapsed_) ?\n      this.collapseLabel_ : this.label_;\n    const button = document.createElement('button');\n    button.setAttribute('type', 'button');\n    button.title = tipLabel;\n    button.appendChild(activeLabel);\n\n    listen(button, EventType.CLICK, this.handleClick_, this);\n\n    const cssClasses = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL +\n        (this.collapsed_ && this.collapsible_ ? ' ' + CLASS_COLLAPSED : '') +\n        (this.collapsible_ ? '' : ' ol-uncollapsible');\n    const element = this.element;\n    element.className = cssClasses;\n    element.appendChild(this.ulElement_);\n    element.appendChild(button);\n\n    /**\n     * A list of currently rendered resolutions.\n     * @type {Array.<string>}\n     * @private\n     */\n    this.renderedAttributions_ = [];\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.renderedVisible_ = true;\n\n  }\n\n  /**\n   * Get a list of visible attributions.\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @return {Array.<string>} Attributions.\n   * @private\n   */\n  getSourceAttributions_(frameState) {\n    /**\n     * Used to determine if an attribution already exists.\n     * @type {!Object.<string, boolean>}\n     */\n    const lookup = {};\n\n    /**\n     * A list of visible attributions.\n     * @type {Array.<string>}\n     */\n    const visibleAttributions = [];\n\n    const layerStatesArray = frameState.layerStatesArray;\n    const resolution = frameState.viewState.resolution;\n    for (let i = 0, ii = layerStatesArray.length; i < ii; ++i) {\n      const layerState = layerStatesArray[i];\n      if (!visibleAtResolution(layerState, resolution)) {\n        continue;\n      }\n\n      const source = layerState.layer.getSource();\n      if (!source) {\n        continue;\n      }\n\n      const attributionGetter = source.getAttributions();\n      if (!attributionGetter) {\n        continue;\n      }\n\n      const attributions = attributionGetter(frameState);\n      if (!attributions) {\n        continue;\n      }\n\n      if (Array.isArray(attributions)) {\n        for (let j = 0, jj = attributions.length; j < jj; ++j) {\n          if (!(attributions[j] in lookup)) {\n            visibleAttributions.push(attributions[j]);\n            lookup[attributions[j]] = true;\n          }\n        }\n      } else {\n        if (!(attributions in lookup)) {\n          visibleAttributions.push(attributions);\n          lookup[attributions] = true;\n        }\n      }\n    }\n    return visibleAttributions;\n  }\n\n  /**\n   * @private\n   * @param {?module:ol/PluggableMap~FrameState} frameState Frame state.\n   */\n  updateElement_(frameState) {\n    if (!frameState) {\n      if (this.renderedVisible_) {\n        this.element.style.display = 'none';\n        this.renderedVisible_ = false;\n      }\n      return;\n    }\n\n    const attributions = this.getSourceAttributions_(frameState);\n\n    const visible = attributions.length > 0;\n    if (this.renderedVisible_ != visible) {\n      this.element.style.display = visible ? '' : 'none';\n      this.renderedVisible_ = visible;\n    }\n\n    if (equals(attributions, this.renderedAttributions_)) {\n      return;\n    }\n\n    removeChildren(this.ulElement_);\n\n    // append the attributions\n    for (let i = 0, ii = attributions.length; i < ii; ++i) {\n      const element = document.createElement('LI');\n      element.innerHTML = attributions[i];\n      this.ulElement_.appendChild(element);\n    }\n\n    this.renderedAttributions_ = attributions;\n  }\n\n  /**\n   * @param {MouseEvent} event The event to handle\n   * @private\n   */\n  handleClick_(event) {\n    event.preventDefault();\n    this.handleToggle_();\n  }\n\n  /**\n   * @private\n   */\n  handleToggle_() {\n    this.element.classList.toggle(CLASS_COLLAPSED);\n    if (this.collapsed_) {\n      replaceNode(this.collapseLabel_, this.label_);\n    } else {\n      replaceNode(this.label_, this.collapseLabel_);\n    }\n    this.collapsed_ = !this.collapsed_;\n  }\n\n  /**\n   * Return `true` if the attribution is collapsible, `false` otherwise.\n   * @return {boolean} True if the widget is collapsible.\n   * @api\n   */\n  getCollapsible() {\n    return this.collapsible_;\n  }\n\n  /**\n   * Set whether the attribution should be collapsible.\n   * @param {boolean} collapsible True if the widget is collapsible.\n   * @api\n   */\n  setCollapsible(collapsible) {\n    if (this.collapsible_ === collapsible) {\n      return;\n    }\n    this.collapsible_ = collapsible;\n    this.element.classList.toggle('ol-uncollapsible');\n    if (!collapsible && this.collapsed_) {\n      this.handleToggle_();\n    }\n  }\n\n  /**\n   * Collapse or expand the attribution according to the passed parameter. Will\n   * not do anything if the attribution isn't collapsible or if the current\n   * collapsed state is already the one requested.\n   * @param {boolean} collapsed True if the widget is collapsed.\n   * @api\n   */\n  setCollapsed(collapsed) {\n    if (!this.collapsible_ || this.collapsed_ === collapsed) {\n      return;\n    }\n    this.handleToggle_();\n  }\n\n  /**\n   * Return `true` when the attribution is currently collapsed or `false`\n   * otherwise.\n   * @return {boolean} True if the widget is collapsed.\n   * @api\n   */\n  getCollapsed() {\n    return this.collapsed_;\n  }\n}\n\n\n/**\n * Update the attribution element.\n * @param {module:ol/MapEvent} mapEvent Map event.\n * @this {module:ol/control/Attribution}\n * @api\n */\nexport function render(mapEvent) {\n  this.updateElement_(mapEvent.frameState);\n}\n\n\nexport default Attribution;\n","/**\n * @module ol/control/Rotate\n */\nimport Control from '../control/Control.js';\nimport {CLASS_CONTROL, CLASS_HIDDEN, CLASS_UNSELECTABLE} from '../css.js';\nimport {easeOut} from '../easing.js';\nimport {listen} from '../events.js';\nimport EventType from '../events/EventType.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-rotate'] CSS class name.\n * @property {string|HTMLElement} [label='⇧'] Text label to use for the rotate button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string} [tipLabel='Reset rotation'] Text label to use for the rotate tip.\n * @property {number} [duration=250] Animation duration in milliseconds.\n * @property {boolean} [autoHide=true] Hide the control when rotation is 0.\n * @property {function(module:ol/MapEvent)} [render] Function called when the control should\n * be re-rendered. This is called in a `requestAnimationFrame` callback.\n * @property {function()} [resetNorth] Function called when the control is clicked.\n * This will override the default `resetNorth`.\n * @property {HTMLElement|string} [target] Specify a target if you want the control to be\n * rendered outside of the map's viewport.\n */\n\n\n/**\n * @classdesc\n * A button control to reset rotation to 0.\n * To style this control use css selector `.ol-rotate`. A `.ol-hidden` css\n * selector is added to the button when the rotation is 0.\n *\n * @api\n */\nclass Rotate extends Control {\n\n  /**\n   * @param {module:ol/control/Rotate~Options=} opt_options Rotate options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options ? opt_options : {};\n\n    super({\n      element: document.createElement('div'),\n      render: options.render || render,\n      target: options.target\n    });\n\n    const className = options.className !== undefined ? options.className : 'ol-rotate';\n\n    const label = options.label !== undefined ? options.label : '\\u21E7';\n\n    /**\n     * @type {HTMLElement}\n     * @private\n     */\n    this.label_ = null;\n\n    if (typeof label === 'string') {\n      this.label_ = document.createElement('span');\n      this.label_.className = 'ol-compass';\n      this.label_.textContent = label;\n    } else {\n      this.label_ = label;\n      this.label_.classList.add('ol-compass');\n    }\n\n    const tipLabel = options.tipLabel ? options.tipLabel : 'Reset rotation';\n\n    const button = document.createElement('button');\n    button.className = className + '-reset';\n    button.setAttribute('type', 'button');\n    button.title = tipLabel;\n    button.appendChild(this.label_);\n\n    listen(button, EventType.CLICK, this.handleClick_, this);\n\n    const cssClasses = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL;\n    const element = this.element;\n    element.className = cssClasses;\n    element.appendChild(button);\n\n    this.callResetNorth_ = options.resetNorth ? options.resetNorth : undefined;\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.duration_ = options.duration !== undefined ? options.duration : 250;\n\n    /**\n     * @type {boolean}\n     * @private\n     */\n    this.autoHide_ = options.autoHide !== undefined ? options.autoHide : true;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.rotation_ = undefined;\n\n    if (this.autoHide_) {\n      this.element.classList.add(CLASS_HIDDEN);\n    }\n\n  }\n\n  /**\n   * @param {MouseEvent} event The event to handle\n   * @private\n   */\n  handleClick_(event) {\n    event.preventDefault();\n    if (this.callResetNorth_ !== undefined) {\n      this.callResetNorth_();\n    } else {\n      this.resetNorth_();\n    }\n  }\n\n  /**\n   * @private\n   */\n  resetNorth_() {\n    const map = this.getMap();\n    const view = map.getView();\n    if (!view) {\n      // the map does not have a view, so we can't act\n      // upon it\n      return;\n    }\n    if (view.getRotation() !== undefined) {\n      if (this.duration_ > 0) {\n        view.animate({\n          rotation: 0,\n          duration: this.duration_,\n          easing: easeOut\n        });\n      } else {\n        view.setRotation(0);\n      }\n    }\n  }\n}\n\n\n/**\n * Update the rotate control element.\n * @param {module:ol/MapEvent} mapEvent Map event.\n * @this {module:ol/control/Rotate}\n * @api\n */\nexport function render(mapEvent) {\n  const frameState = mapEvent.frameState;\n  if (!frameState) {\n    return;\n  }\n  const rotation = frameState.viewState.rotation;\n  if (rotation != this.rotation_) {\n    const transform = 'rotate(' + rotation + 'rad)';\n    if (this.autoHide_) {\n      const contains = this.element.classList.contains(CLASS_HIDDEN);\n      if (!contains && rotation === 0) {\n        this.element.classList.add(CLASS_HIDDEN);\n      } else if (contains && rotation !== 0) {\n        this.element.classList.remove(CLASS_HIDDEN);\n      }\n    }\n    this.label_.style.msTransform = transform;\n    this.label_.style.webkitTransform = transform;\n    this.label_.style.transform = transform;\n  }\n  this.rotation_ = rotation;\n}\n\nexport default Rotate;\n","/**\n * @module ol/control/Zoom\n */\nimport {listen} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport Control from '../control/Control.js';\nimport {CLASS_CONTROL, CLASS_UNSELECTABLE} from '../css.js';\nimport {easeOut} from '../easing.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [duration=250] Animation duration in milliseconds.\n * @property {string} [className='ol-zoom'] CSS class name.\n * @property {string|HTMLElement} [zoomInLabel='+'] Text label to use for the zoom-in\n * button. Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string|HTMLElement} [zoomOutLabel='-'] Text label to use for the zoom-out button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string} [zoomInTipLabel='Zoom in'] Text label to use for the button tip.\n * @property {string} [zoomOutTipLabel='Zoom out'] Text label to use for the button tip.\n * @property {number} [delta=1] The zoom delta applied on each click.\n * @property {HTMLElement|string} [target] Specify a target if you want the control to be\n * rendered outside of the map's viewport.\n */\n\n\n/**\n * @classdesc\n * A control with 2 buttons, one for zoom in and one for zoom out.\n * This control is one of the default controls of a map. To style this control\n * use css selectors `.ol-zoom-in` and `.ol-zoom-out`.\n *\n * @api\n */\nclass Zoom extends Control {\n\n  /**\n   * @param {module:ol/control/Zoom~Options=} opt_options Zoom options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options ? opt_options : {};\n\n    super({\n      element: document.createElement('div'),\n      target: options.target\n    });\n\n    const className = options.className !== undefined ? options.className : 'ol-zoom';\n\n    const delta = options.delta !== undefined ? options.delta : 1;\n\n    const zoomInLabel = options.zoomInLabel !== undefined ? options.zoomInLabel : '+';\n    const zoomOutLabel = options.zoomOutLabel !== undefined ? options.zoomOutLabel : '\\u2212';\n\n    const zoomInTipLabel = options.zoomInTipLabel !== undefined ?\n      options.zoomInTipLabel : 'Zoom in';\n    const zoomOutTipLabel = options.zoomOutTipLabel !== undefined ?\n      options.zoomOutTipLabel : 'Zoom out';\n\n    const inElement = document.createElement('button');\n    inElement.className = className + '-in';\n    inElement.setAttribute('type', 'button');\n    inElement.title = zoomInTipLabel;\n    inElement.appendChild(\n      typeof zoomInLabel === 'string' ? document.createTextNode(zoomInLabel) : zoomInLabel\n    );\n\n    listen(inElement, EventType.CLICK, this.handleClick_.bind(this, delta));\n\n    const outElement = document.createElement('button');\n    outElement.className = className + '-out';\n    outElement.setAttribute('type', 'button');\n    outElement.title = zoomOutTipLabel;\n    outElement.appendChild(\n      typeof zoomOutLabel === 'string' ? document.createTextNode(zoomOutLabel) : zoomOutLabel\n    );\n\n    listen(outElement, EventType.CLICK, this.handleClick_.bind(this, -delta));\n\n    const cssClasses = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL;\n    const element = this.element;\n    element.className = cssClasses;\n    element.appendChild(inElement);\n    element.appendChild(outElement);\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.duration_ = options.duration !== undefined ? options.duration : 250;\n\n  }\n\n  /**\n   * @param {number} delta Zoom delta.\n   * @param {MouseEvent} event The event to handle\n   * @private\n   */\n  handleClick_(delta, event) {\n    event.preventDefault();\n    this.zoomByDelta_(delta);\n  }\n\n  /**\n   * @param {number} delta Zoom delta.\n   * @private\n   */\n  zoomByDelta_(delta) {\n    const map = this.getMap();\n    const view = map.getView();\n    if (!view) {\n      // the map does not have a view, so we can't act\n      // upon it\n      return;\n    }\n    const currentResolution = view.getResolution();\n    if (currentResolution) {\n      const newResolution = view.constrainResolution(currentResolution, delta);\n      if (this.duration_ > 0) {\n        if (view.getAnimating()) {\n          view.cancelAnimations();\n        }\n        view.animate({\n          resolution: newResolution,\n          duration: this.duration_,\n          easing: easeOut\n        });\n      } else {\n        view.setResolution(newResolution);\n      }\n    }\n  }\n}\n\n\nexport default Zoom;\n","/**\n * @module ol/control/util\n */\nimport Collection from '../Collection.js';\nimport Attribution from './Attribution.js';\nimport Rotate from './Rotate.js';\nimport Zoom from './Zoom.js';\n\n\n/**\n * @typedef {Object} DefaultsOptions\n * @property {boolean} [attribution=true] Include\n * {@link module:ol/control/Attribution~Attribution}.\n * @property {module:ol/control/Attribution~Options} [attributionOptions]\n * Options for {@link module:ol/control/Attribution~Attribution}.\n * @property {boolean} [rotate=true] Include\n * {@link module:ol/control/Rotate~Rotate}.\n * @property {module:ol/control/Rotate~Options} [rotateOptions] Options\n * for {@link module:ol/control/Rotate~Rotate}.\n * @property {boolean} [zoom] Include {@link module:ol/control/Zoom~Zoom}.\n * @property {module:ol/control/Zoom~Options} [zoomOptions] Options for\n * {@link module:ol/control/Zoom~Zoom}.\n * @api\n */\n\n\n/**\n * Set of controls included in maps by default. Unless configured otherwise,\n * this returns a collection containing an instance of each of the following\n * controls:\n * * {@link module:ol/control/Zoom~Zoom}\n * * {@link module:ol/control/Rotate~Rotate}\n * * {@link module:ol/control/Attribution~Attribution}\n *\n * @param {module:ol/control/util~DefaultsOptions=} opt_options\n * Defaults options.\n * @return {module:ol/Collection.<module:ol/control/Control>}\n * Controls.\n * @function module:ol/control.defaults\n * @api\n */\nexport function defaults(opt_options) {\n\n  const options = opt_options ? opt_options : {};\n\n  const controls = new Collection();\n\n  const zoomControl = options.zoom !== undefined ? options.zoom : true;\n  if (zoomControl) {\n    controls.push(new Zoom(options.zoomOptions));\n  }\n\n  const rotateControl = options.rotate !== undefined ? options.rotate : true;\n  if (rotateControl) {\n    controls.push(new Rotate(options.rotateOptions));\n  }\n\n  const attributionControl = options.attribution !== undefined ?\n    options.attribution : true;\n  if (attributionControl) {\n    controls.push(new Attribution(options.attributionOptions));\n  }\n\n  return controls;\n}\n","/**\n * @module ol/interaction/Property\n */\n\n/**\n * @enum {string}\n */\nexport default {\n  ACTIVE: 'active'\n};\n","/**\n * @module ol/interaction/Interaction\n */\nimport BaseObject from '../Object.js';\nimport {easeOut, linear} from '../easing.js';\nimport InteractionProperty from '../interaction/Property.js';\nimport {clamp} from '../math.js';\n\n\n/**\n * Object literal with config options for interactions.\n * @typedef {Object} InteractionOptions\n * @property {function(module:ol/MapBrowserEvent):boolean} handleEvent\n * Method called by the map to notify the interaction that a browser event was\n * dispatched to the map. If the function returns a falsy value, propagation of\n * the event to other interactions in the map's interactions chain will be\n * prevented (this includes functions with no explicit return).\n */\n\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * User actions that change the state of the map. Some are similar to controls,\n * but are not associated with a DOM element.\n * For example, {@link module:ol/interaction/KeyboardZoom~KeyboardZoom} is\n * functionally the same as {@link module:ol/control/Zoom~Zoom}, but triggered\n * by a keyboard event not a button element event.\n * Although interactions do not have a DOM element, some of them do render\n * vectors and so are visible on the screen.\n * @api\n */\nclass Interaction extends BaseObject {\n  /**\n   * @param {module:ol/interaction/Interaction~InteractionOptions} options Options.\n   */\n  constructor(options) {\n    super();\n\n    /**\n     * @private\n     * @type {module:ol/PluggableMap}\n     */\n    this.map_ = null;\n\n    this.setActive(true);\n\n    /**\n     * @type {function(module:ol/MapBrowserEvent):boolean}\n     */\n    this.handleEvent = options.handleEvent;\n\n  }\n\n  /**\n   * Return whether the interaction is currently active.\n   * @return {boolean} `true` if the interaction is active, `false` otherwise.\n   * @observable\n   * @api\n   */\n  getActive() {\n    return /** @type {boolean} */ (this.get(InteractionProperty.ACTIVE));\n  }\n\n  /**\n   * Get the map associated with this interaction.\n   * @return {module:ol/PluggableMap} Map.\n   * @api\n   */\n  getMap() {\n    return this.map_;\n  }\n\n  /**\n   * Activate or deactivate the interaction.\n   * @param {boolean} active Active.\n   * @observable\n   * @api\n   */\n  setActive(active) {\n    this.set(InteractionProperty.ACTIVE, active);\n  }\n\n  /**\n   * Remove the interaction from its current map and attach it to the new map.\n   * Subclasses may set up event handlers to get notified about changes to\n   * the map here.\n   * @param {module:ol/PluggableMap} map Map.\n   */\n  setMap(map) {\n    this.map_ = map;\n  }\n}\n\n\n/**\n * @param {module:ol/View} view View.\n * @param {module:ol/coordinate~Coordinate} delta Delta.\n * @param {number=} opt_duration Duration.\n */\nexport function pan(view, delta, opt_duration) {\n  const currentCenter = view.getCenter();\n  if (currentCenter) {\n    const center = view.constrainCenter(\n      [currentCenter[0] + delta[0], currentCenter[1] + delta[1]]);\n    if (opt_duration) {\n      view.animate({\n        duration: opt_duration,\n        easing: linear,\n        center: center\n      });\n    } else {\n      view.setCenter(center);\n    }\n  }\n}\n\n\n/**\n * @param {module:ol/View} view View.\n * @param {number|undefined} rotation Rotation.\n * @param {module:ol/coordinate~Coordinate=} opt_anchor Anchor coordinate.\n * @param {number=} opt_duration Duration.\n */\nexport function rotate(view, rotation, opt_anchor, opt_duration) {\n  rotation = view.constrainRotation(rotation, 0);\n  rotateWithoutConstraints(view, rotation, opt_anchor, opt_duration);\n}\n\n\n/**\n * @param {module:ol/View} view View.\n * @param {number|undefined} rotation Rotation.\n * @param {module:ol/coordinate~Coordinate=} opt_anchor Anchor coordinate.\n * @param {number=} opt_duration Duration.\n */\nexport function rotateWithoutConstraints(view, rotation, opt_anchor, opt_duration) {\n  if (rotation !== undefined) {\n    const currentRotation = view.getRotation();\n    const currentCenter = view.getCenter();\n    if (currentRotation !== undefined && currentCenter && opt_duration > 0) {\n      view.animate({\n        rotation: rotation,\n        anchor: opt_anchor,\n        duration: opt_duration,\n        easing: easeOut\n      });\n    } else {\n      view.rotate(rotation, opt_anchor);\n    }\n  }\n}\n\n\n/**\n * @param {module:ol/View} view View.\n * @param {number|undefined} resolution Resolution to go to.\n * @param {module:ol/coordinate~Coordinate=} opt_anchor Anchor coordinate.\n * @param {number=} opt_duration Duration.\n * @param {number=} opt_direction Zooming direction; > 0 indicates\n *     zooming out, in which case the constraints system will select\n *     the largest nearest resolution; < 0 indicates zooming in, in\n *     which case the constraints system will select the smallest\n *     nearest resolution; == 0 indicates that the zooming direction\n *     is unknown/not relevant, in which case the constraints system\n *     will select the nearest resolution. If not defined 0 is\n *     assumed.\n */\nexport function zoom(view, resolution, opt_anchor, opt_duration, opt_direction) {\n  resolution = view.constrainResolution(resolution, 0, opt_direction);\n  zoomWithoutConstraints(view, resolution, opt_anchor, opt_duration);\n}\n\n\n/**\n * @param {module:ol/View} view View.\n * @param {number} delta Delta from previous zoom level.\n * @param {module:ol/coordinate~Coordinate=} opt_anchor Anchor coordinate.\n * @param {number=} opt_duration Duration.\n */\nexport function zoomByDelta(view, delta, opt_anchor, opt_duration) {\n  const currentResolution = view.getResolution();\n  let resolution = view.constrainResolution(currentResolution, delta, 0);\n\n  if (resolution !== undefined) {\n    const resolutions = view.getResolutions();\n    resolution = clamp(\n      resolution,\n      view.getMinResolution() || resolutions[resolutions.length - 1],\n      view.getMaxResolution() || resolutions[0]);\n  }\n\n  // If we have a constraint on center, we need to change the anchor so that the\n  // new center is within the extent. We first calculate the new center, apply\n  // the constraint to it, and then calculate back the anchor\n  if (opt_anchor && resolution !== undefined && resolution !== currentResolution) {\n    const currentCenter = view.getCenter();\n    let center = view.calculateCenterZoom(resolution, opt_anchor);\n    center = view.constrainCenter(center);\n\n    opt_anchor = [\n      (resolution * currentCenter[0] - currentResolution * center[0]) /\n          (resolution - currentResolution),\n      (resolution * currentCenter[1] - currentResolution * center[1]) /\n          (resolution - currentResolution)\n    ];\n  }\n\n  zoomWithoutConstraints(view, resolution, opt_anchor, opt_duration);\n}\n\n\n/**\n * @param {module:ol/View} view View.\n * @param {number|undefined} resolution Resolution to go to.\n * @param {module:ol/coordinate~Coordinate=} opt_anchor Anchor coordinate.\n * @param {number=} opt_duration Duration.\n */\nexport function zoomWithoutConstraints(view, resolution, opt_anchor, opt_duration) {\n  if (resolution) {\n    const currentResolution = view.getResolution();\n    const currentCenter = view.getCenter();\n    if (currentResolution !== undefined && currentCenter &&\n        resolution !== currentResolution && opt_duration) {\n      view.animate({\n        resolution: resolution,\n        anchor: opt_anchor,\n        duration: opt_duration,\n        easing: easeOut\n      });\n    } else {\n      if (opt_anchor) {\n        const center = view.calculateCenterZoom(resolution, opt_anchor);\n        view.setCenter(center);\n      }\n      view.setResolution(resolution);\n    }\n  }\n}\n\nexport default Interaction;\n","/**\n * @module ol/interaction/DoubleClickZoom\n */\nimport MapBrowserEventType from '../MapBrowserEventType.js';\nimport Interaction, {zoomByDelta} from '../interaction/Interaction.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [duration=250] Animation duration in milliseconds.\n * @property {number} [delta=1] The zoom delta applied on each double click.\n */\n\n\n/**\n * @classdesc\n * Allows the user to zoom by double-clicking on the map.\n * @api\n */\nclass DoubleClickZoom extends Interaction {\n\n  /**\n   * @param {module:ol/interaction/DoubleClickZoom~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n    super({\n      handleEvent: handleEvent\n    });\n\n    const options = opt_options ? opt_options : {};\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.delta_ = options.delta ? options.delta : 1;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.duration_ = options.duration !== undefined ? options.duration : 250;\n\n  }\n\n}\n\n\n/**\n * Handles the {@link module:ol/MapBrowserEvent map browser event} (if it was a\n * doubleclick) and eventually zooms the map.\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @this {module:ol/interaction/DoubleClickZoom}\n */\nfunction handleEvent(mapBrowserEvent) {\n  let stopEvent = false;\n  const browserEvent = mapBrowserEvent.originalEvent;\n  if (mapBrowserEvent.type == MapBrowserEventType.DBLCLICK) {\n    const map = mapBrowserEvent.map;\n    const anchor = mapBrowserEvent.coordinate;\n    const delta = browserEvent.shiftKey ? -this.delta_ : this.delta_;\n    const view = map.getView();\n    zoomByDelta(view, delta, anchor, this.duration_);\n    mapBrowserEvent.preventDefault();\n    stopEvent = true;\n  }\n  return !stopEvent;\n}\n\nexport default DoubleClickZoom;\n","/**\n * @module ol/events/condition\n */\nimport MapBrowserEventType from '../MapBrowserEventType.js';\nimport {assert} from '../asserts.js';\nimport {TRUE, FALSE} from '../functions.js';\nimport {WEBKIT, MAC} from '../has.js';\n\n\n/**\n * A function that takes an {@link module:ol/MapBrowserEvent} and returns a\n * `{boolean}`. If the condition is met, true should be returned.\n *\n * @typedef {function(this: ?, module:ol/MapBrowserEvent): boolean} Condition\n */\n\n\n/**\n * Return `true` if only the alt-key is pressed, `false` otherwise (e.g. when\n * additionally the shift-key is pressed).\n *\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the alt key is pressed.\n * @api\n */\nexport const altKeyOnly = function(mapBrowserEvent) {\n  const originalEvent = mapBrowserEvent.originalEvent;\n  return (\n    originalEvent.altKey &&\n      !(originalEvent.metaKey || originalEvent.ctrlKey) &&\n      !originalEvent.shiftKey);\n};\n\n\n/**\n * Return `true` if only the alt-key and shift-key is pressed, `false` otherwise\n * (e.g. when additionally the platform-modifier-key is pressed).\n *\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the alt and shift keys are pressed.\n * @api\n */\nexport const altShiftKeysOnly = function(mapBrowserEvent) {\n  const originalEvent = mapBrowserEvent.originalEvent;\n  return (\n    originalEvent.altKey &&\n      !(originalEvent.metaKey || originalEvent.ctrlKey) &&\n      originalEvent.shiftKey);\n};\n\n\n/**\n * Return `true` if the map has the focus. This condition requires a map target\n * element with a `tabindex` attribute, e.g. `<div id=\"map\" tabindex=\"1\">`.\n *\n * @param {module:ol/MapBrowserEvent} event Map browser event.\n * @return {boolean} The map has the focus.\n * @api\n */\nexport const focus = function(event) {\n  return event.target.getTargetElement() === document.activeElement;\n};\n\n\n/**\n * Return always true.\n *\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} True.\n * @function\n * @api\n */\nexport const always = TRUE;\n\n\n/**\n * Return `true` if the event is a `click` event, `false` otherwise.\n *\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event is a map `click` event.\n * @api\n */\nexport const click = function(mapBrowserEvent) {\n  return mapBrowserEvent.type == MapBrowserEventType.CLICK;\n};\n\n\n/**\n * Return `true` if the event has an \"action\"-producing mouse button.\n *\n * By definition, this includes left-click on windows/linux, and left-click\n * without the ctrl key on Macs.\n *\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} The result.\n */\nexport const mouseActionButton = function(mapBrowserEvent) {\n  const originalEvent = mapBrowserEvent.originalEvent;\n  return originalEvent.button == 0 &&\n      !(WEBKIT && MAC && originalEvent.ctrlKey);\n};\n\n\n/**\n * Return always false.\n *\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} False.\n * @function\n * @api\n */\nexport const never = FALSE;\n\n\n/**\n * Return `true` if the browser event is a `pointermove` event, `false`\n * otherwise.\n *\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} True if the browser event is a `pointermove` event.\n * @api\n */\nexport const pointerMove = function(mapBrowserEvent) {\n  return mapBrowserEvent.type == 'pointermove';\n};\n\n\n/**\n * Return `true` if the event is a map `singleclick` event, `false` otherwise.\n *\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event is a map `singleclick` event.\n * @api\n */\nexport const singleClick = function(mapBrowserEvent) {\n  return mapBrowserEvent.type == MapBrowserEventType.SINGLECLICK;\n};\n\n\n/**\n * Return `true` if the event is a map `dblclick` event, `false` otherwise.\n *\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event is a map `dblclick` event.\n * @api\n */\nexport const doubleClick = function(mapBrowserEvent) {\n  return mapBrowserEvent.type == MapBrowserEventType.DBLCLICK;\n};\n\n\n/**\n * Return `true` if no modifier key (alt-, shift- or platform-modifier-key) is\n * pressed.\n *\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} True only if there no modifier keys are pressed.\n * @api\n */\nexport const noModifierKeys = function(mapBrowserEvent) {\n  const originalEvent = mapBrowserEvent.originalEvent;\n  return (\n    !originalEvent.altKey &&\n      !(originalEvent.metaKey || originalEvent.ctrlKey) &&\n      !originalEvent.shiftKey);\n};\n\n\n/**\n * Return `true` if only the platform-modifier-key (the meta-key on Mac,\n * ctrl-key otherwise) is pressed, `false` otherwise (e.g. when additionally\n * the shift-key is pressed).\n *\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the platform modifier key is pressed.\n * @api\n */\nexport const platformModifierKeyOnly = function(mapBrowserEvent) {\n  const originalEvent = mapBrowserEvent.originalEvent;\n  return !originalEvent.altKey &&\n    (MAC ? originalEvent.metaKey : originalEvent.ctrlKey) &&\n    !originalEvent.shiftKey;\n};\n\n\n/**\n * Return `true` if only the shift-key is pressed, `false` otherwise (e.g. when\n * additionally the alt-key is pressed).\n *\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the shift key is pressed.\n * @api\n */\nexport const shiftKeyOnly = function(mapBrowserEvent) {\n  const originalEvent = mapBrowserEvent.originalEvent;\n  return (\n    !originalEvent.altKey &&\n      !(originalEvent.metaKey || originalEvent.ctrlKey) &&\n      originalEvent.shiftKey);\n};\n\n\n/**\n * Return `true` if the target element is not editable, i.e. not a `<input>`-,\n * `<select>`- or `<textarea>`-element, `false` otherwise.\n *\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} True only if the target element is not editable.\n * @api\n */\nexport const targetNotEditable = function(mapBrowserEvent) {\n  const target = mapBrowserEvent.originalEvent.target;\n  const tagName = target.tagName;\n  return (\n    tagName !== 'INPUT' &&\n      tagName !== 'SELECT' &&\n      tagName !== 'TEXTAREA');\n};\n\n\n/**\n * Return `true` if the event originates from a mouse device.\n *\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a mouse device.\n * @api\n */\nexport const mouseOnly = function(mapBrowserEvent) {\n  assert(mapBrowserEvent.pointerEvent, 56); // mapBrowserEvent must originate from a pointer event\n  // see http://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType\n  return (\n    /** @type {module:ol/MapBrowserEvent} */ (mapBrowserEvent).pointerEvent.pointerType == 'mouse'\n  );\n};\n\n\n/**\n * Return `true` if the event originates from a primary pointer in\n * contact with the surface or if the left mouse button is pressed.\n * See http://www.w3.org/TR/pointerevents/#button-states.\n *\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a primary pointer.\n * @api\n */\nexport const primaryAction = function(mapBrowserEvent) {\n  const pointerEvent = mapBrowserEvent.pointerEvent;\n  return pointerEvent.isPrimary && pointerEvent.button === 0;\n};\n","/**\n * @module ol/interaction/Pointer\n */\nimport {FALSE, UNDEFINED} from '../functions.js';\nimport MapBrowserEventType from '../MapBrowserEventType.js';\nimport MapBrowserPointerEvent from '../MapBrowserPointerEvent.js';\nimport Interaction from '../interaction/Interaction.js';\nimport {getValues} from '../obj.js';\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @this {module:ol/interaction/Pointer}\n */\nconst handleDragEvent = UNDEFINED;\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @return {boolean} Capture dragging.\n * @this {module:ol/interaction/Pointer}\n */\nconst handleUpEvent = FALSE;\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @return {boolean} Capture dragging.\n * @this {module:ol/interaction/Pointer}\n */\nconst handleDownEvent = FALSE;\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @this {module:ol/interaction/Pointer}\n */\nconst handleMoveEvent = UNDEFINED;\n\n\n/**\n * @typedef {Object} Options\n * @property {(function(module:ol/MapBrowserPointerEvent):boolean)} [handleDownEvent]\n * Function handling \"down\" events. If the function returns `true` then a drag\n * sequence is started.\n * @property {(function(module:ol/MapBrowserPointerEvent))} [handleDragEvent]\n * Function handling \"drag\" events. This function is called on \"move\" events\n * during a drag sequence.\n * @property {(function(module:ol/MapBrowserEvent):boolean)} [handleEvent]\n * Method called by the map to notify the interaction that a browser event was\n * dispatched to the map. The function may return `false` to prevent the\n * propagation of the event to other interactions in the map's interactions\n * chain.\n * @property {(function(module:ol/MapBrowserPointerEvent))} [handleMoveEvent]\n * Function handling \"move\" events. This function is called on \"move\" events,\n * also during a drag sequence (so during a drag sequence both the\n * `handleDragEvent` function and this function are called).\n * @property {(function(module:ol/MapBrowserPointerEvent):boolean)} [handleUpEvent]\n *  Function handling \"up\" events. If the function returns `false` then the\n * current drag sequence is stopped.\n * @property {function(boolean):boolean} stopDown\n * Should the down event be propagated to other interactions, or should be\n * stopped?\n */\n\n\n/**\n * @classdesc\n * Base class that calls user-defined functions on `down`, `move` and `up`\n * events. This class also manages \"drag sequences\".\n *\n * When the `handleDownEvent` user function returns `true` a drag sequence is\n * started. During a drag sequence the `handleDragEvent` user function is\n * called on `move` events. The drag sequence ends when the `handleUpEvent`\n * user function is called and returns `false`.\n * @api\n */\nclass PointerInteraction extends Interaction {\n  /**\n   * @param {module:ol/interaction/Pointer~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options ? opt_options : {};\n\n    super({\n      handleEvent: options.handleEvent || handleEvent\n    });\n\n    /**\n     * @type {function(module:ol/MapBrowserPointerEvent):boolean}\n     * @private\n     */\n    this.handleDownEvent_ = options.handleDownEvent ?\n      options.handleDownEvent : handleDownEvent;\n\n    /**\n     * @type {function(module:ol/MapBrowserPointerEvent)}\n     * @private\n     */\n    this.handleDragEvent_ = options.handleDragEvent ?\n      options.handleDragEvent : handleDragEvent;\n\n    /**\n     * @type {function(module:ol/MapBrowserPointerEvent)}\n     * @private\n     */\n    this.handleMoveEvent_ = options.handleMoveEvent ?\n      options.handleMoveEvent : handleMoveEvent;\n\n    /**\n     * @type {function(module:ol/MapBrowserPointerEvent):boolean}\n     * @private\n     */\n    this.handleUpEvent_ = options.handleUpEvent ?\n      options.handleUpEvent : handleUpEvent;\n\n    /**\n     * @type {boolean}\n     * @protected\n     */\n    this.handlingDownUpSequence = false;\n\n    /**\n     * This function is used to determine if \"down\" events should be propagated\n     * to other interactions or should be stopped.\n     * @type {function(boolean):boolean}\n     * @protected\n     */\n    this.stopDown = options.stopDown ? options.stopDown : stopDown;\n\n    /**\n     * @type {!Object.<string, module:ol/pointer/PointerEvent>}\n     * @private\n     */\n    this.trackedPointers_ = {};\n\n    /**\n     * @type {Array.<module:ol/pointer/PointerEvent>}\n     * @protected\n     */\n    this.targetPointers = [];\n\n  }\n\n  /**\n   * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n   * @private\n   */\n  updateTrackedPointers_(mapBrowserEvent) {\n    if (isPointerDraggingEvent(mapBrowserEvent)) {\n      const event = mapBrowserEvent.pointerEvent;\n\n      const id = event.pointerId.toString();\n      if (mapBrowserEvent.type == MapBrowserEventType.POINTERUP) {\n        delete this.trackedPointers_[id];\n      } else if (mapBrowserEvent.type ==\n          MapBrowserEventType.POINTERDOWN) {\n        this.trackedPointers_[id] = event;\n      } else if (id in this.trackedPointers_) {\n        // update only when there was a pointerdown event for this pointer\n        this.trackedPointers_[id] = event;\n      }\n      this.targetPointers = getValues(this.trackedPointers_);\n    }\n  }\n\n}\n\n\n/**\n * @param {Array.<module:ol/pointer/PointerEvent>} pointerEvents List of events.\n * @return {module:ol/pixel~Pixel} Centroid pixel.\n */\nexport function centroid(pointerEvents) {\n  const length = pointerEvents.length;\n  let clientX = 0;\n  let clientY = 0;\n  for (let i = 0; i < length; i++) {\n    clientX += pointerEvents[i].clientX;\n    clientY += pointerEvents[i].clientY;\n  }\n  return [clientX / length, clientY / length];\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @return {boolean} Whether the event is a pointerdown, pointerdrag\n *     or pointerup event.\n */\nfunction isPointerDraggingEvent(mapBrowserEvent) {\n  const type = mapBrowserEvent.type;\n  return type === MapBrowserEventType.POINTERDOWN ||\n    type === MapBrowserEventType.POINTERDRAG ||\n    type === MapBrowserEventType.POINTERUP;\n}\n\n\n/**\n * Handles the {@link module:ol/MapBrowserEvent map browser event} and may call into\n * other functions, if event sequences like e.g. 'drag' or 'down-up' etc. are\n * detected.\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @this {module:ol/interaction/Pointer}\n * @api\n */\nexport function handleEvent(mapBrowserEvent) {\n  if (!(mapBrowserEvent instanceof MapBrowserPointerEvent)) {\n    return true;\n  }\n\n  let stopEvent = false;\n  this.updateTrackedPointers_(mapBrowserEvent);\n  if (this.handlingDownUpSequence) {\n    if (mapBrowserEvent.type == MapBrowserEventType.POINTERDRAG) {\n      this.handleDragEvent_(mapBrowserEvent);\n    } else if (mapBrowserEvent.type == MapBrowserEventType.POINTERUP) {\n      const handledUp = this.handleUpEvent_(mapBrowserEvent);\n      this.handlingDownUpSequence = handledUp && this.targetPointers.length > 0;\n    }\n  } else {\n    if (mapBrowserEvent.type == MapBrowserEventType.POINTERDOWN) {\n      const handled = this.handleDownEvent_(mapBrowserEvent);\n      this.handlingDownUpSequence = handled;\n      stopEvent = this.stopDown(handled);\n    } else if (mapBrowserEvent.type == MapBrowserEventType.POINTERMOVE) {\n      this.handleMoveEvent_(mapBrowserEvent);\n    }\n  }\n  return !stopEvent;\n}\n\n\nexport default PointerInteraction;\n\n/**\n * @param {boolean} handled Was the event handled by the interaction?\n * @return {boolean} Should the `down` event be stopped?\n */\nfunction stopDown(handled) {\n  return handled;\n}\n","/**\n * @module ol/interaction/DragPan\n */\nimport ViewHint from '../ViewHint.js';\nimport {scale as scaleCoordinate, rotate as rotateCoordinate, add as addCoordinate} from '../coordinate.js';\nimport {easeOut} from '../easing.js';\nimport {noModifierKeys} from '../events/condition.js';\nimport {FALSE} from '../functions.js';\nimport PointerInteraction, {centroid as centroidFromPointers} from '../interaction/Pointer.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/events/condition~Condition} [condition] A function that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a boolean\n * to indicate whether that event should be handled.\n * Default is {@link module:ol/events/condition~noModifierKeys}.\n * @property {module:ol/Kinetic} [kinetic] Kinetic inertia to apply to the pan.\n */\n\n\n/**\n * @classdesc\n * Allows the user to pan the map by dragging the map.\n * @api\n */\nclass DragPan extends PointerInteraction {\n  /**\n   * @param {module:ol/interaction/DragPan~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    super({\n      handleDownEvent: handleDownEvent,\n      handleDragEvent: handleDragEvent,\n      handleUpEvent: handleUpEvent,\n      stopDown: FALSE\n    });\n\n    const options = opt_options ? opt_options : {};\n\n    /**\n     * @private\n     * @type {module:ol/Kinetic|undefined}\n     */\n    this.kinetic_ = options.kinetic;\n\n    /**\n     * @type {module:ol/pixel~Pixel}\n     */\n    this.lastCentroid = null;\n\n    /**\n     * @type {number}\n     */\n    this.lastPointersCount_;\n\n    /**\n     * @private\n     * @type {module:ol/events/condition~Condition}\n     */\n    this.condition_ = options.condition ? options.condition : noModifierKeys;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.noKinetic_ = false;\n\n  }\n\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @this {module:ol/interaction/DragPan}\n */\nfunction handleDragEvent(mapBrowserEvent) {\n  const targetPointers = this.targetPointers;\n  const centroid = centroidFromPointers(targetPointers);\n  if (targetPointers.length == this.lastPointersCount_) {\n    if (this.kinetic_) {\n      this.kinetic_.update(centroid[0], centroid[1]);\n    }\n    if (this.lastCentroid) {\n      const deltaX = this.lastCentroid[0] - centroid[0];\n      const deltaY = centroid[1] - this.lastCentroid[1];\n      const map = mapBrowserEvent.map;\n      const view = map.getView();\n      let center = [deltaX, deltaY];\n      scaleCoordinate(center, view.getResolution());\n      rotateCoordinate(center, view.getRotation());\n      addCoordinate(center, view.getCenter());\n      center = view.constrainCenter(center);\n      view.setCenter(center);\n    }\n  } else if (this.kinetic_) {\n    // reset so we don't overestimate the kinetic energy after\n    // after one finger down, tiny drag, second finger down\n    this.kinetic_.begin();\n  }\n  this.lastCentroid = centroid;\n  this.lastPointersCount_ = targetPointers.length;\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @return {boolean} Stop drag sequence?\n * @this {module:ol/interaction/DragPan}\n */\nfunction handleUpEvent(mapBrowserEvent) {\n  const map = mapBrowserEvent.map;\n  const view = map.getView();\n  if (this.targetPointers.length === 0) {\n    if (!this.noKinetic_ && this.kinetic_ && this.kinetic_.end()) {\n      const distance = this.kinetic_.getDistance();\n      const angle = this.kinetic_.getAngle();\n      const center = /** @type {!module:ol/coordinate~Coordinate} */ (view.getCenter());\n      const centerpx = map.getPixelFromCoordinate(center);\n      const dest = map.getCoordinateFromPixel([\n        centerpx[0] - distance * Math.cos(angle),\n        centerpx[1] - distance * Math.sin(angle)\n      ]);\n      view.animate({\n        center: view.constrainCenter(dest),\n        duration: 500,\n        easing: easeOut\n      });\n    }\n    view.setHint(ViewHint.INTERACTING, -1);\n    return false;\n  } else {\n    if (this.kinetic_) {\n      // reset so we don't overestimate the kinetic energy after\n      // after one finger up, tiny drag, second finger up\n      this.kinetic_.begin();\n    }\n    this.lastCentroid = null;\n    return true;\n  }\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @return {boolean} Start drag sequence?\n * @this {module:ol/interaction/DragPan}\n */\nfunction handleDownEvent(mapBrowserEvent) {\n  if (this.targetPointers.length > 0 && this.condition_(mapBrowserEvent)) {\n    const map = mapBrowserEvent.map;\n    const view = map.getView();\n    this.lastCentroid = null;\n    if (!this.handlingDownUpSequence) {\n      view.setHint(ViewHint.INTERACTING, 1);\n    }\n    // stop any current animation\n    if (view.getAnimating()) {\n      view.setCenter(mapBrowserEvent.frameState.viewState.center);\n    }\n    if (this.kinetic_) {\n      this.kinetic_.begin();\n    }\n    // No kinetic as soon as more than one pointer on the screen is\n    // detected. This is to prevent nasty pans after pinch.\n    this.noKinetic_ = this.targetPointers.length > 1;\n    return true;\n  } else {\n    return false;\n  }\n}\n\n\nexport default DragPan;\n","/**\n * @module ol/interaction/DragRotate\n */\nimport {disable} from '../rotationconstraint.js';\nimport ViewHint from '../ViewHint.js';\nimport {altShiftKeysOnly, mouseOnly, mouseActionButton} from '../events/condition.js';\nimport {FALSE} from '../functions.js';\nimport {rotate, rotateWithoutConstraints} from '../interaction/Interaction.js';\nimport PointerInteraction from '../interaction/Pointer.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/events/condition~Condition} [condition] A function that takes an\n * {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a boolean\n * to indicate whether that event should be handled.\n * Default is {@link module:ol/events/condition~altShiftKeysOnly}.\n * @property {number} [duration=250] Animation duration in milliseconds.\n */\n\n\n/**\n * @classdesc\n * Allows the user to rotate the map by clicking and dragging on the map,\n * normally combined with an {@link module:ol/events/condition} that limits\n * it to when the alt and shift keys are held down.\n *\n * This interaction is only supported for mouse devices.\n * @api\n */\nclass DragRotate extends PointerInteraction {\n\n  /**\n   * @param {module:ol/interaction/DragRotate~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options ? opt_options : {};\n\n    super({\n      handleDownEvent: handleDownEvent,\n      handleDragEvent: handleDragEvent,\n      handleUpEvent: handleUpEvent,\n      stopDown: FALSE\n    });\n\n    /**\n     * @private\n     * @type {module:ol/events/condition~Condition}\n     */\n    this.condition_ = options.condition ? options.condition : altShiftKeysOnly;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.lastAngle_ = undefined;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.duration_ = options.duration !== undefined ? options.duration : 250;\n\n  }\n\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @this {module:ol/interaction/DragRotate}\n */\nfunction handleDragEvent(mapBrowserEvent) {\n  if (!mouseOnly(mapBrowserEvent)) {\n    return;\n  }\n\n  const map = mapBrowserEvent.map;\n  const view = map.getView();\n  if (view.getConstraints().rotation === disable) {\n    return;\n  }\n  const size = map.getSize();\n  const offset = mapBrowserEvent.pixel;\n  const theta =\n      Math.atan2(size[1] / 2 - offset[1], offset[0] - size[0] / 2);\n  if (this.lastAngle_ !== undefined) {\n    const delta = theta - this.lastAngle_;\n    const rotation = view.getRotation();\n    rotateWithoutConstraints(view, rotation - delta);\n  }\n  this.lastAngle_ = theta;\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @return {boolean} Stop drag sequence?\n * @this {module:ol/interaction/DragRotate}\n */\nfunction handleUpEvent(mapBrowserEvent) {\n  if (!mouseOnly(mapBrowserEvent)) {\n    return true;\n  }\n\n  const map = mapBrowserEvent.map;\n  const view = map.getView();\n  view.setHint(ViewHint.INTERACTING, -1);\n  const rotation = view.getRotation();\n  rotate(view, rotation, undefined, this.duration_);\n  return false;\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @return {boolean} Start drag sequence?\n * @this {module:ol/interaction/DragRotate}\n */\nfunction handleDownEvent(mapBrowserEvent) {\n  if (!mouseOnly(mapBrowserEvent)) {\n    return false;\n  }\n\n  if (mouseActionButton(mapBrowserEvent) && this.condition_(mapBrowserEvent)) {\n    const map = mapBrowserEvent.map;\n    map.getView().setHint(ViewHint.INTERACTING, 1);\n    this.lastAngle_ = undefined;\n    return true;\n  } else {\n    return false;\n  }\n}\n\nexport default DragRotate;\n","/**\n * @module ol/render/Box\n */\n\nimport Disposable from '../Disposable.js';\nimport Polygon from '../geom/Polygon.js';\n\nclass RenderBox extends Disposable {\n  /**\n   * @param {string} className CSS class name.\n   */\n  constructor(className) {\n    super();\n\n    /**\n     * @type {module:ol/geom/Polygon}\n     * @private\n     */\n    this.geometry_ = null;\n\n    /**\n     * @type {HTMLDivElement}\n     * @private\n     */\n    this.element_ = /** @type {HTMLDivElement} */ (document.createElement('div'));\n    this.element_.style.position = 'absolute';\n    this.element_.className = 'ol-box ' + className;\n\n    /**\n     * @private\n     * @type {module:ol/PluggableMap}\n     */\n    this.map_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/pixel~Pixel}\n     */\n    this.startPixel_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/pixel~Pixel}\n     */\n    this.endPixel_ = null;\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  disposeInternal() {\n    this.setMap(null);\n  }\n\n  /**\n   * @private\n   */\n  render_() {\n    const startPixel = this.startPixel_;\n    const endPixel = this.endPixel_;\n    const px = 'px';\n    const style = this.element_.style;\n    style.left = Math.min(startPixel[0], endPixel[0]) + px;\n    style.top = Math.min(startPixel[1], endPixel[1]) + px;\n    style.width = Math.abs(endPixel[0] - startPixel[0]) + px;\n    style.height = Math.abs(endPixel[1] - startPixel[1]) + px;\n  }\n\n  /**\n   * @param {module:ol/PluggableMap} map Map.\n   */\n  setMap(map) {\n    if (this.map_) {\n      this.map_.getOverlayContainer().removeChild(this.element_);\n      const style = this.element_.style;\n      style.left = style.top = style.width = style.height = 'inherit';\n    }\n    this.map_ = map;\n    if (this.map_) {\n      this.map_.getOverlayContainer().appendChild(this.element_);\n    }\n  }\n\n  /**\n   * @param {module:ol/pixel~Pixel} startPixel Start pixel.\n   * @param {module:ol/pixel~Pixel} endPixel End pixel.\n   */\n  setPixels(startPixel, endPixel) {\n    this.startPixel_ = startPixel;\n    this.endPixel_ = endPixel;\n    this.createOrUpdateGeometry();\n    this.render_();\n  }\n\n  /**\n   * Creates or updates the cached geometry.\n   */\n  createOrUpdateGeometry() {\n    const startPixel = this.startPixel_;\n    const endPixel = this.endPixel_;\n    const pixels = [\n      startPixel,\n      [startPixel[0], endPixel[1]],\n      endPixel,\n      [endPixel[0], startPixel[1]]\n    ];\n    const coordinates = pixels.map(this.map_.getCoordinateFromPixel, this.map_);\n    // close the polygon\n    coordinates[4] = coordinates[0].slice();\n    if (!this.geometry_) {\n      this.geometry_ = new Polygon([coordinates]);\n    } else {\n      this.geometry_.setCoordinates([coordinates]);\n    }\n  }\n\n  /**\n   * @return {module:ol/geom/Polygon} Geometry.\n   */\n  getGeometry() {\n    return this.geometry_;\n  }\n}\n\n\nexport default RenderBox;\n","/**\n * @module ol/interaction/DragBox\n */\n// FIXME draw drag box\nimport Event from '../events/Event.js';\nimport {always, mouseOnly, mouseActionButton} from '../events/condition.js';\nimport {UNDEFINED} from '../functions.js';\nimport PointerInteraction from '../interaction/Pointer.js';\nimport RenderBox from '../render/Box.js';\n\n\n/**\n * A function that takes a {@link module:ol/MapBrowserEvent} and two\n * {@link module:ol/pixel~Pixel}s and returns a `{boolean}`. If the condition is met,\n * true should be returned.\n * @typedef {function(this: ?, module:ol/MapBrowserEvent, module:ol/pixel~Pixel, module:ol/pixel~Pixel):boolean} EndCondition\n */\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-dragbox'] CSS class name for styling the box.\n * @property {module:ol/events/condition~Condition} [condition] A function that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a boolean\n * to indicate whether that event should be handled.\n * Default is {@link ol/events/condition~always}.\n * @property {number} [minArea=64] The minimum area of the box in pixel, this value is used by the default\n * `boxEndCondition` function.\n * @property {module:ol/interaction/DragBox~EndCondition} [boxEndCondition] A function that takes a {@link module:ol/MapBrowserEvent~MapBrowserEvent} and two\n * {@link module:ol/pixel~Pixel}s to indicate whether a `boxend` event should be fired.\n * Default is `true` if the area of the box is bigger than the `minArea` option.\n * @property {function(this:module:ol/interaction/DragBox, module:ol/MapBrowserEvent)} onBoxEnd Code to execute just\n * before `boxend` is fired.\n */\n\n\n/**\n * @enum {string}\n */\nconst DragBoxEventType = {\n  /**\n   * Triggered upon drag box start.\n   * @event module:ol/interaction/DragBox~DragBoxEvent#boxstart\n   * @api\n   */\n  BOXSTART: 'boxstart',\n\n  /**\n   * Triggered on drag when box is active.\n   * @event module:ol/interaction/DragBox~DragBoxEvent#boxdrag\n   * @api\n   */\n  BOXDRAG: 'boxdrag',\n\n  /**\n   * Triggered upon drag box end.\n   * @event module:ol/interaction/DragBox~DragBoxEvent#boxend\n   * @api\n   */\n  BOXEND: 'boxend'\n};\n\n\n/**\n * @classdesc\n * Events emitted by {@link module:ol/interaction/DragBox~DragBox} instances are instances of\n * this type.\n */\nclass DragBoxEvent extends Event {\n\n  /**\n   * @param {string} type The event type.\n   * @param {module:ol/coordinate~Coordinate} coordinate The event coordinate.\n   * @param {module:ol/MapBrowserEvent} mapBrowserEvent Originating event.\n   */\n  constructor(type, coordinate, mapBrowserEvent) {\n    super(type);\n\n    /**\n     * The coordinate of the drag event.\n     * @const\n     * @type {module:ol/coordinate~Coordinate}\n     * @api\n     */\n    this.coordinate = coordinate;\n\n    /**\n     * @const\n     * @type {module:ol/MapBrowserEvent}\n     * @api\n     */\n    this.mapBrowserEvent = mapBrowserEvent;\n\n  }\n\n}\n\n\n/**\n * @classdesc\n * Allows the user to draw a vector box by clicking and dragging on the map,\n * normally combined with an {@link module:ol/events/condition} that limits\n * it to when the shift or other key is held down. This is used, for example,\n * for zooming to a specific area of the map\n * (see {@link module:ol/interaction/DragZoom~DragZoom} and\n * {@link module:ol/interaction/DragRotateAndZoom}).\n *\n * This interaction is only supported for mouse devices.\n *\n * @fires module:ol/interaction/DragBox~DragBoxEvent\n * @api\n */\nclass DragBox extends PointerInteraction {\n  /**\n   * @param {module:ol/interaction/DragBox~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    super({\n      handleDownEvent: handleDownEvent,\n      handleDragEvent: handleDragEvent,\n      handleUpEvent: handleUpEvent\n    });\n\n    const options = opt_options ? opt_options : {};\n\n    /**\n    * @type {module:ol/render/Box}\n    * @private\n    */\n    this.box_ = new RenderBox(options.className || 'ol-dragbox');\n\n    /**\n    * @type {number}\n    * @private\n    */\n    this.minArea_ = options.minArea !== undefined ? options.minArea : 64;\n\n    /**\n     * Function to execute just before `onboxend` is fired\n     * @type {function(this:module:ol/interaction/DragBox, module:ol/MapBrowserEvent)}\n     * @private\n     */\n    this.onBoxEnd_ = options.onBoxEnd ? options.onBoxEnd : UNDEFINED;\n\n    /**\n    * @type {module:ol/pixel~Pixel}\n    * @private\n    */\n    this.startPixel_ = null;\n\n    /**\n    * @private\n    * @type {module:ol/events/condition~Condition}\n    */\n    this.condition_ = options.condition ? options.condition : always;\n\n    /**\n    * @private\n    * @type {module:ol/interaction/DragBox~EndCondition}\n    */\n    this.boxEndCondition_ = options.boxEndCondition ?\n      options.boxEndCondition : defaultBoxEndCondition;\n  }\n\n  /**\n  * Returns geometry of last drawn box.\n  * @return {module:ol/geom/Polygon} Geometry.\n  * @api\n  */\n  getGeometry() {\n    return this.box_.getGeometry();\n  }\n}\n\n\n/**\n * The default condition for determining whether the boxend event\n * should fire.\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent The originating MapBrowserEvent\n *     leading to the box end.\n * @param {module:ol/pixel~Pixel} startPixel The starting pixel of the box.\n * @param {module:ol/pixel~Pixel} endPixel The end pixel of the box.\n * @return {boolean} Whether or not the boxend condition should be fired.\n * @this {module:ol/interaction/DragBox}\n */\nfunction defaultBoxEndCondition(mapBrowserEvent, startPixel, endPixel) {\n  const width = endPixel[0] - startPixel[0];\n  const height = endPixel[1] - startPixel[1];\n  return width * width + height * height >= this.minArea_;\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @this {module:ol/interaction/DragBox}\n */\nfunction handleDragEvent(mapBrowserEvent) {\n  if (!mouseOnly(mapBrowserEvent)) {\n    return;\n  }\n\n  this.box_.setPixels(this.startPixel_, mapBrowserEvent.pixel);\n\n  this.dispatchEvent(new DragBoxEvent(DragBoxEventType.BOXDRAG,\n    mapBrowserEvent.coordinate, mapBrowserEvent));\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @return {boolean} Stop drag sequence?\n * @this {module:ol/interaction/DragBox}\n */\nfunction handleUpEvent(mapBrowserEvent) {\n  if (!mouseOnly(mapBrowserEvent)) {\n    return true;\n  }\n\n  this.box_.setMap(null);\n\n  if (this.boxEndCondition_(mapBrowserEvent, this.startPixel_, mapBrowserEvent.pixel)) {\n    this.onBoxEnd_(mapBrowserEvent);\n    this.dispatchEvent(new DragBoxEvent(DragBoxEventType.BOXEND,\n      mapBrowserEvent.coordinate, mapBrowserEvent));\n  }\n  return false;\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @return {boolean} Start drag sequence?\n * @this {module:ol/interaction/DragBox}\n */\nfunction handleDownEvent(mapBrowserEvent) {\n  if (!mouseOnly(mapBrowserEvent)) {\n    return false;\n  }\n\n  if (mouseActionButton(mapBrowserEvent) &&\n      this.condition_(mapBrowserEvent)) {\n    this.startPixel_ = mapBrowserEvent.pixel;\n    this.box_.setMap(mapBrowserEvent.map);\n    this.box_.setPixels(this.startPixel_, this.startPixel_);\n    this.dispatchEvent(new DragBoxEvent(DragBoxEventType.BOXSTART,\n      mapBrowserEvent.coordinate, mapBrowserEvent));\n    return true;\n  } else {\n    return false;\n  }\n}\n\n\nexport default DragBox;\n","/**\n * @module ol/interaction/DragZoom\n */\nimport {easeOut} from '../easing.js';\nimport {shiftKeyOnly} from '../events/condition.js';\nimport {createOrUpdateFromCoordinates, getBottomLeft, getCenter, getTopRight, scaleFromCenter} from '../extent.js';\nimport DragBox from '../interaction/DragBox.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-dragzoom'] CSS class name for styling the\n * box.\n * @property {module:ol/events/condition~Condition} [condition] A function that\n * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled.\n * Default is {@link module:ol/events/condition~shiftKeyOnly}.\n * @property {number} [duration=200] Animation duration in milliseconds.\n * @property {boolean} [out=false] Use interaction for zooming out.\n */\n\n\n/**\n * @classdesc\n * Allows the user to zoom the map by clicking and dragging on the map,\n * normally combined with an {@link module:ol/events/condition} that limits\n * it to when a key, shift by default, is held down.\n *\n * To change the style of the box, use CSS and the `.ol-dragzoom` selector, or\n * your custom one configured with `className`.\n * @api\n */\nclass DragZoom extends DragBox {\n  /**\n   * @param {module:ol/interaction/DragZoom~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n    const options = opt_options ? opt_options : {};\n\n    const condition = options.condition ? options.condition : shiftKeyOnly;\n\n    super({\n      condition: condition,\n      className: options.className || 'ol-dragzoom',\n      onBoxEnd: onBoxEnd\n    });\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.duration_ = options.duration !== undefined ? options.duration : 200;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.out_ = options.out !== undefined ? options.out : false;\n  }\n}\n\n\n/**\n * @this {module:ol/interaction/DragZoom}\n */\nfunction onBoxEnd() {\n  const map = this.getMap();\n  const view = /** @type {!module:ol/View} */ (map.getView());\n  const size = /** @type {!module:ol/size~Size} */ (map.getSize());\n  let extent = this.getGeometry().getExtent();\n\n  if (this.out_) {\n    const mapExtent = view.calculateExtent(size);\n    const boxPixelExtent = createOrUpdateFromCoordinates([\n      map.getPixelFromCoordinate(getBottomLeft(extent)),\n      map.getPixelFromCoordinate(getTopRight(extent))]);\n    const factor = view.getResolutionForExtent(boxPixelExtent, size);\n\n    scaleFromCenter(mapExtent, 1 / factor);\n    extent = mapExtent;\n  }\n\n  const resolution = view.constrainResolution(\n    view.getResolutionForExtent(extent, size));\n\n  let center = getCenter(extent);\n  center = view.constrainCenter(center);\n\n  view.animate({\n    resolution: resolution,\n    center: center,\n    duration: this.duration_,\n    easing: easeOut\n  });\n}\n\n\nexport default DragZoom;\n","/**\n * @module ol/events/KeyCode\n */\n\n/**\n * @enum {number}\n * @const\n */\nexport default {\n  LEFT: 37,\n  UP: 38,\n  RIGHT: 39,\n  DOWN: 40\n};\n","/**\n * @module ol/interaction/KeyboardPan\n */\nimport {rotate as rotateCoordinate} from '../coordinate.js';\nimport EventType from '../events/EventType.js';\nimport KeyCode from '../events/KeyCode.js';\nimport {noModifierKeys, targetNotEditable} from '../events/condition.js';\nimport Interaction, {pan} from '../interaction/Interaction.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/events/condition~Condition} [condition] A function that\n * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled. Default is\n * {@link module:ol/events/condition~noModifierKeys} and\n * {@link module:ol/events/condition~targetNotEditable}.\n * @property {number} [duration=100] Animation duration in milliseconds.\n * @property {number} [pixelDelta=128] The amount of pixels to pan on each key\n * press.\n */\n\n\n/**\n * @classdesc\n * Allows the user to pan the map using keyboard arrows.\n * Note that, although this interaction is by default included in maps,\n * the keys can only be used when browser focus is on the element to which\n * the keyboard events are attached. By default, this is the map div,\n * though you can change this with the `keyboardEventTarget` in\n * {@link module:ol/Map~Map}. `document` never loses focus but, for any other\n * element, focus will have to be on, and returned to, this element if the keys\n * are to function.\n * See also {@link module:ol/interaction/KeyboardZoom~KeyboardZoom}.\n * @api\n */\nclass KeyboardPan extends Interaction {\n  /**\n   * @param {module:ol/interaction/KeyboardPan~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    super({\n      handleEvent: handleEvent\n    });\n\n    const options = opt_options || {};\n\n    /**\n     * @private\n     * @param {module:ol/MapBrowserEvent} mapBrowserEvent Browser event.\n     * @return {boolean} Combined condition result.\n     */\n    this.defaultCondition_ = function(mapBrowserEvent) {\n      return noModifierKeys(mapBrowserEvent) &&\n        targetNotEditable(mapBrowserEvent);\n    };\n\n    /**\n     * @private\n     * @type {module:ol/events/condition~Condition}\n     */\n    this.condition_ = options.condition !== undefined ?\n      options.condition : this.defaultCondition_;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.duration_ = options.duration !== undefined ? options.duration : 100;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.pixelDelta_ = options.pixelDelta !== undefined ?\n      options.pixelDelta : 128;\n\n  }\n\n}\n\n\n/**\n * Handles the {@link module:ol/MapBrowserEvent map browser event} if it was a\n * `KeyEvent`, and decides the direction to pan to (if an arrow key was\n * pressed).\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @this {module:ol/interaction/KeyboardPan}\n */\nfunction handleEvent(mapBrowserEvent) {\n  let stopEvent = false;\n  if (mapBrowserEvent.type == EventType.KEYDOWN) {\n    const keyEvent = mapBrowserEvent.originalEvent;\n    const keyCode = keyEvent.keyCode;\n    if (this.condition_(mapBrowserEvent) &&\n        (keyCode == KeyCode.DOWN ||\n        keyCode == KeyCode.LEFT ||\n        keyCode == KeyCode.RIGHT ||\n        keyCode == KeyCode.UP)) {\n      const map = mapBrowserEvent.map;\n      const view = map.getView();\n      const mapUnitsDelta = view.getResolution() * this.pixelDelta_;\n      let deltaX = 0, deltaY = 0;\n      if (keyCode == KeyCode.DOWN) {\n        deltaY = -mapUnitsDelta;\n      } else if (keyCode == KeyCode.LEFT) {\n        deltaX = -mapUnitsDelta;\n      } else if (keyCode == KeyCode.RIGHT) {\n        deltaX = mapUnitsDelta;\n      } else {\n        deltaY = mapUnitsDelta;\n      }\n      const delta = [deltaX, deltaY];\n      rotateCoordinate(delta, view.getRotation());\n      pan(view, delta, this.duration_);\n      mapBrowserEvent.preventDefault();\n      stopEvent = true;\n    }\n  }\n  return !stopEvent;\n}\n\nexport default KeyboardPan;\n","/**\n * @module ol/interaction/KeyboardZoom\n */\nimport EventType from '../events/EventType.js';\nimport {targetNotEditable} from '../events/condition.js';\nimport Interaction, {zoomByDelta} from '../interaction/Interaction.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [duration=100] Animation duration in milliseconds.\n * @property {module:ol/events/condition~Condition} [condition] A function that\n * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled. Default is\n * {@link module:ol/events/condition~targetNotEditable}.\n * @property {number} [delta=1] The zoom level delta on each key press.\n */\n\n\n/**\n * @classdesc\n * Allows the user to zoom the map using keyboard + and -.\n * Note that, although this interaction is by default included in maps,\n * the keys can only be used when browser focus is on the element to which\n * the keyboard events are attached. By default, this is the map div,\n * though you can change this with the `keyboardEventTarget` in\n * {@link module:ol/Map~Map}. `document` never loses focus but, for any other\n * element, focus will have to be on, and returned to, this element if the keys\n * are to function.\n * See also {@link moudle:ol/interaction/KeyboardPan~KeyboardPan}.\n * @api\n */\nclass KeyboardZoom extends Interaction {\n  /**\n   * @param {module:ol/interaction/KeyboardZoom~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    super({\n      handleEvent: handleEvent\n    });\n\n    const options = opt_options ? opt_options : {};\n\n    /**\n     * @private\n     * @type {module:ol/events/condition~Condition}\n     */\n    this.condition_ = options.condition ? options.condition : targetNotEditable;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.delta_ = options.delta ? options.delta : 1;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.duration_ = options.duration !== undefined ? options.duration : 100;\n\n  }\n\n}\n\n\n/**\n * Handles the {@link module:ol/MapBrowserEvent map browser event} if it was a\n * `KeyEvent`, and decides whether to zoom in or out (depending on whether the\n * key pressed was '+' or '-').\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @this {module:ol/interaction/KeyboardZoom}\n */\nfunction handleEvent(mapBrowserEvent) {\n  let stopEvent = false;\n  if (mapBrowserEvent.type == EventType.KEYDOWN ||\n      mapBrowserEvent.type == EventType.KEYPRESS) {\n    const keyEvent = mapBrowserEvent.originalEvent;\n    const charCode = keyEvent.charCode;\n    if (this.condition_(mapBrowserEvent) &&\n        (charCode == '+'.charCodeAt(0) || charCode == '-'.charCodeAt(0))) {\n      const map = mapBrowserEvent.map;\n      const delta = (charCode == '+'.charCodeAt(0)) ? this.delta_ : -this.delta_;\n      const view = map.getView();\n      zoomByDelta(view, delta, undefined, this.duration_);\n      mapBrowserEvent.preventDefault();\n      stopEvent = true;\n    }\n  }\n  return !stopEvent;\n}\n\nexport default KeyboardZoom;\n","/**\n * @module ol/interaction/MouseWheelZoom\n */\nimport ViewHint from '../ViewHint.js';\nimport {always} from '../events/condition.js';\nimport {easeOut} from '../easing.js';\nimport EventType from '../events/EventType.js';\nimport {DEVICE_PIXEL_RATIO, FIREFOX, SAFARI} from '../has.js';\nimport Interaction, {zoomByDelta} from '../interaction/Interaction.js';\nimport {clamp} from '../math.js';\n\n\n/**\n * Maximum mouse wheel delta.\n * @type {number}\n */\nconst MAX_DELTA = 1;\n\n\n/**\n * @enum {string}\n */\nexport const Mode = {\n  TRACKPAD: 'trackpad',\n  WHEEL: 'wheel'\n};\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/events/condition~Condition} [condition] A function that\n * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled. Default is\n * {@link module:ol/events/condition~always}.\n * @property {number} [duration=250] Animation duration in milliseconds.\n * @property {number} [timeout=80] Mouse wheel timeout duration in milliseconds.\n * @property {boolean} [constrainResolution=false] When using a trackpad or\n * magic mouse, zoom to the closest integer zoom level after the scroll gesture\n * ends.\n * @property {boolean} [useAnchor=true] Enable zooming using the mouse's\n * location as the anchor. When set to `false`, zooming in and out will zoom to\n * the center of the screen instead of zooming on the mouse's location.\n */\n\n\n/**\n * @classdesc\n * Allows the user to zoom the map by scrolling the mouse wheel.\n * @api\n */\nclass MouseWheelZoom extends Interaction {\n  /**\n   * @param {module:ol/interaction/MouseWheelZoom~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    super({\n      handleEvent: handleEvent\n    });\n\n    const options = opt_options || {};\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.delta_ = 0;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.duration_ = options.duration !== undefined ? options.duration : 250;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.timeout_ = options.timeout !== undefined ? options.timeout : 80;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.useAnchor_ = options.useAnchor !== undefined ? options.useAnchor : true;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.constrainResolution_ = options.constrainResolution || false;\n\n    /**\n     * @private\n     * @type {module:ol/events/condition~Condition}\n     */\n    this.condition_ = options.condition ? options.condition : always;\n\n    /**\n     * @private\n     * @type {?module:ol/coordinate~Coordinate}\n     */\n    this.lastAnchor_ = null;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.startTime_ = undefined;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.timeoutId_ = undefined;\n\n    /**\n     * @private\n     * @type {module:ol/interaction/MouseWheelZoom~Mode|undefined}\n     */\n    this.mode_ = undefined;\n\n    /**\n     * Trackpad events separated by this delay will be considered separate\n     * interactions.\n     * @type {number}\n     */\n    this.trackpadEventGap_ = 400;\n\n    /**\n     * @type {number|undefined}\n     */\n    this.trackpadTimeoutId_ = undefined;\n\n    /**\n     * The number of delta values per zoom level\n     * @private\n     * @type {number}\n     */\n    this.trackpadDeltaPerZoom_ = 300;\n\n    /**\n     * The zoom factor by which scroll zooming is allowed to exceed the limits.\n     * @private\n     * @type {number}\n     */\n    this.trackpadZoomBuffer_ = 1.5;\n\n  }\n\n  /**\n   * @private\n   */\n  decrementInteractingHint_() {\n    this.trackpadTimeoutId_ = undefined;\n    const view = this.getMap().getView();\n    view.setHint(ViewHint.INTERACTING, -1);\n  }\n\n  /**\n   * @private\n   * @param {module:ol/PluggableMap} map Map.\n   */\n  handleWheelZoom_(map) {\n    const view = map.getView();\n    if (view.getAnimating()) {\n      view.cancelAnimations();\n    }\n    const maxDelta = MAX_DELTA;\n    const delta = clamp(this.delta_, -maxDelta, maxDelta);\n    zoomByDelta(view, -delta, this.lastAnchor_, this.duration_);\n    this.mode_ = undefined;\n    this.delta_ = 0;\n    this.lastAnchor_ = null;\n    this.startTime_ = undefined;\n    this.timeoutId_ = undefined;\n  }\n\n  /**\n   * Enable or disable using the mouse's location as an anchor when zooming\n   * @param {boolean} useAnchor true to zoom to the mouse's location, false\n   * to zoom to the center of the map\n   * @api\n   */\n  setMouseAnchor(useAnchor) {\n    this.useAnchor_ = useAnchor;\n    if (!useAnchor) {\n      this.lastAnchor_ = null;\n    }\n  }\n}\n\n\n/**\n * Handles the {@link module:ol/MapBrowserEvent map browser event} (if it was a\n * mousewheel-event) and eventually zooms the map.\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} Allow event propagation.\n * @this {module:ol/interaction/MouseWheelZoom}\n */\nfunction handleEvent(mapBrowserEvent) {\n  if (!this.condition_(mapBrowserEvent)) {\n    return true;\n  }\n  const type = mapBrowserEvent.type;\n  if (type !== EventType.WHEEL && type !== EventType.MOUSEWHEEL) {\n    return true;\n  }\n\n  mapBrowserEvent.preventDefault();\n\n  const map = mapBrowserEvent.map;\n  const wheelEvent = /** @type {WheelEvent} */ (mapBrowserEvent.originalEvent);\n\n  if (this.useAnchor_) {\n    this.lastAnchor_ = mapBrowserEvent.coordinate;\n  }\n\n  // Delta normalisation inspired by\n  // https://github.com/mapbox/mapbox-gl-js/blob/001c7b9/js/ui/handler/scroll_zoom.js\n  let delta;\n  if (mapBrowserEvent.type == EventType.WHEEL) {\n    delta = wheelEvent.deltaY;\n    if (FIREFOX &&\n        wheelEvent.deltaMode === WheelEvent.DOM_DELTA_PIXEL) {\n      delta /= DEVICE_PIXEL_RATIO;\n    }\n    if (wheelEvent.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n      delta *= 40;\n    }\n  } else if (mapBrowserEvent.type == EventType.MOUSEWHEEL) {\n    delta = -wheelEvent.wheelDeltaY;\n    if (SAFARI) {\n      delta /= 3;\n    }\n  }\n\n  if (delta === 0) {\n    return false;\n  }\n\n  const now = Date.now();\n\n  if (this.startTime_ === undefined) {\n    this.startTime_ = now;\n  }\n\n  if (!this.mode_ || now - this.startTime_ > this.trackpadEventGap_) {\n    this.mode_ = Math.abs(delta) < 4 ?\n      Mode.TRACKPAD :\n      Mode.WHEEL;\n  }\n\n  if (this.mode_ === Mode.TRACKPAD) {\n    const view = map.getView();\n    if (this.trackpadTimeoutId_) {\n      clearTimeout(this.trackpadTimeoutId_);\n    } else {\n      view.setHint(ViewHint.INTERACTING, 1);\n    }\n    this.trackpadTimeoutId_ = setTimeout(this.decrementInteractingHint_.bind(this), this.trackpadEventGap_);\n    let resolution = view.getResolution() * Math.pow(2, delta / this.trackpadDeltaPerZoom_);\n    const minResolution = view.getMinResolution();\n    const maxResolution = view.getMaxResolution();\n    let rebound = 0;\n    if (resolution < minResolution) {\n      resolution = Math.max(resolution, minResolution / this.trackpadZoomBuffer_);\n      rebound = 1;\n    } else if (resolution > maxResolution) {\n      resolution = Math.min(resolution, maxResolution * this.trackpadZoomBuffer_);\n      rebound = -1;\n    }\n    if (this.lastAnchor_) {\n      const center = view.calculateCenterZoom(resolution, this.lastAnchor_);\n      view.setCenter(view.constrainCenter(center));\n    }\n    view.setResolution(resolution);\n\n    if (rebound === 0 && this.constrainResolution_) {\n      view.animate({\n        resolution: view.constrainResolution(resolution, delta > 0 ? -1 : 1),\n        easing: easeOut,\n        anchor: this.lastAnchor_,\n        duration: this.duration_\n      });\n    }\n\n    if (rebound > 0) {\n      view.animate({\n        resolution: minResolution,\n        easing: easeOut,\n        anchor: this.lastAnchor_,\n        duration: 500\n      });\n    } else if (rebound < 0) {\n      view.animate({\n        resolution: maxResolution,\n        easing: easeOut,\n        anchor: this.lastAnchor_,\n        duration: 500\n      });\n    }\n    this.startTime_ = now;\n    return false;\n  }\n\n  this.delta_ += delta;\n\n  const timeLeft = Math.max(this.timeout_ - (now - this.startTime_), 0);\n\n  clearTimeout(this.timeoutId_);\n  this.timeoutId_ = setTimeout(this.handleWheelZoom_.bind(this, map), timeLeft);\n\n  return false;\n}\n\n\nexport default MouseWheelZoom;\n","/**\n * @module ol/interaction/PinchRotate\n */\nimport ViewHint from '../ViewHint.js';\nimport {FALSE} from '../functions.js';\nimport {rotate, rotateWithoutConstraints} from '../interaction/Interaction.js';\nimport PointerInteraction, {centroid as centroidFromPointers} from '../interaction/Pointer.js';\nimport {disable} from '../rotationconstraint.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [duration=250] The duration of the animation in\n * milliseconds.\n * @property {number} [threshold=0.3] Minimal angle in radians to start a rotation.\n */\n\n\n/**\n * @classdesc\n * Allows the user to rotate the map by twisting with two fingers\n * on a touch screen.\n * @api\n */\nclass PinchRotate extends PointerInteraction {\n  /**\n   * @param {module:ol/interaction/PinchRotate~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    super({\n      handleDownEvent: handleDownEvent,\n      handleDragEvent: handleDragEvent,\n      handleUpEvent: handleUpEvent,\n      stopDown: FALSE\n    });\n\n    const options = opt_options || {};\n\n    /**\n     * @private\n     * @type {module:ol/coordinate~Coordinate}\n     */\n    this.anchor_ = null;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.lastAngle_ = undefined;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.rotating_ = false;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.rotationDelta_ = 0.0;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.threshold_ = options.threshold !== undefined ? options.threshold : 0.3;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.duration_ = options.duration !== undefined ? options.duration : 250;\n\n  }\n\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @this {module:ol/interaction/PinchRotate}\n */\nfunction handleDragEvent(mapBrowserEvent) {\n  let rotationDelta = 0.0;\n\n  const touch0 = this.targetPointers[0];\n  const touch1 = this.targetPointers[1];\n\n  // angle between touches\n  const angle = Math.atan2(\n    touch1.clientY - touch0.clientY,\n    touch1.clientX - touch0.clientX);\n\n  if (this.lastAngle_ !== undefined) {\n    const delta = angle - this.lastAngle_;\n    this.rotationDelta_ += delta;\n    if (!this.rotating_ &&\n        Math.abs(this.rotationDelta_) > this.threshold_) {\n      this.rotating_ = true;\n    }\n    rotationDelta = delta;\n  }\n  this.lastAngle_ = angle;\n\n  const map = mapBrowserEvent.map;\n  const view = map.getView();\n  if (view.getConstraints().rotation === disable) {\n    return;\n  }\n\n  // rotate anchor point.\n  // FIXME: should be the intersection point between the lines:\n  //     touch0,touch1 and previousTouch0,previousTouch1\n  const viewportPosition = map.getViewport().getBoundingClientRect();\n  const centroid = centroidFromPointers(this.targetPointers);\n  centroid[0] -= viewportPosition.left;\n  centroid[1] -= viewportPosition.top;\n  this.anchor_ = map.getCoordinateFromPixel(centroid);\n\n  // rotate\n  if (this.rotating_) {\n    const rotation = view.getRotation();\n    map.render();\n    rotateWithoutConstraints(view, rotation + rotationDelta, this.anchor_);\n  }\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @return {boolean} Stop drag sequence?\n * @this {module:ol/interaction/PinchRotate}\n */\nfunction handleUpEvent(mapBrowserEvent) {\n  if (this.targetPointers.length < 2) {\n    const map = mapBrowserEvent.map;\n    const view = map.getView();\n    view.setHint(ViewHint.INTERACTING, -1);\n    if (this.rotating_) {\n      const rotation = view.getRotation();\n      rotate(view, rotation, this.anchor_, this.duration_);\n    }\n    return false;\n  } else {\n    return true;\n  }\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @return {boolean} Start drag sequence?\n * @this {module:ol/interaction/PinchRotate}\n */\nfunction handleDownEvent(mapBrowserEvent) {\n  if (this.targetPointers.length >= 2) {\n    const map = mapBrowserEvent.map;\n    this.anchor_ = null;\n    this.lastAngle_ = undefined;\n    this.rotating_ = false;\n    this.rotationDelta_ = 0.0;\n    if (!this.handlingDownUpSequence) {\n      map.getView().setHint(ViewHint.INTERACTING, 1);\n    }\n    return true;\n  } else {\n    return false;\n  }\n}\n\nexport default PinchRotate;\n","/**\n * @module ol/interaction/PinchZoom\n */\nimport ViewHint from '../ViewHint.js';\nimport {FALSE} from '../functions.js';\nimport {zoom, zoomWithoutConstraints} from '../interaction/Interaction.js';\nimport PointerInteraction, {centroid as centroidFromPointers} from '../interaction/Pointer.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [duration=400] Animation duration in milliseconds.\n * @property {boolean} [constrainResolution=false] Zoom to the closest integer\n * zoom level after the pinch gesture ends.\n */\n\n\n/**\n * @classdesc\n * Allows the user to zoom the map by pinching with two fingers\n * on a touch screen.\n * @api\n */\nclass PinchZoom extends PointerInteraction {\n  /**\n   * @param {module:ol/interaction/PinchZoom~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    super({\n      handleDownEvent: handleDownEvent,\n      handleDragEvent: handleDragEvent,\n      handleUpEvent: handleUpEvent,\n      stopDown: FALSE\n    });\n\n    const options = opt_options ? opt_options : {};\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.constrainResolution_ = options.constrainResolution || false;\n\n    /**\n     * @private\n     * @type {module:ol/coordinate~Coordinate}\n     */\n    this.anchor_ = null;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.duration_ = options.duration !== undefined ? options.duration : 400;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.lastDistance_ = undefined;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.lastScaleDelta_ = 1;\n\n  }\n\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @this {module:ol/interaction/PinchZoom}\n */\nfunction handleDragEvent(mapBrowserEvent) {\n  let scaleDelta = 1.0;\n\n  const touch0 = this.targetPointers[0];\n  const touch1 = this.targetPointers[1];\n  const dx = touch0.clientX - touch1.clientX;\n  const dy = touch0.clientY - touch1.clientY;\n\n  // distance between touches\n  const distance = Math.sqrt(dx * dx + dy * dy);\n\n  if (this.lastDistance_ !== undefined) {\n    scaleDelta = this.lastDistance_ / distance;\n  }\n  this.lastDistance_ = distance;\n\n\n  const map = mapBrowserEvent.map;\n  const view = map.getView();\n  const resolution = view.getResolution();\n  const maxResolution = view.getMaxResolution();\n  const minResolution = view.getMinResolution();\n  let newResolution = resolution * scaleDelta;\n  if (newResolution > maxResolution) {\n    scaleDelta = maxResolution / resolution;\n    newResolution = maxResolution;\n  } else if (newResolution < minResolution) {\n    scaleDelta = minResolution / resolution;\n    newResolution = minResolution;\n  }\n\n  if (scaleDelta != 1.0) {\n    this.lastScaleDelta_ = scaleDelta;\n  }\n\n  // scale anchor point.\n  const viewportPosition = map.getViewport().getBoundingClientRect();\n  const centroid = centroidFromPointers(this.targetPointers);\n  centroid[0] -= viewportPosition.left;\n  centroid[1] -= viewportPosition.top;\n  this.anchor_ = map.getCoordinateFromPixel(centroid);\n\n  // scale, bypass the resolution constraint\n  map.render();\n  zoomWithoutConstraints(view, newResolution, this.anchor_);\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @return {boolean} Stop drag sequence?\n * @this {module:ol/interaction/PinchZoom}\n */\nfunction handleUpEvent(mapBrowserEvent) {\n  if (this.targetPointers.length < 2) {\n    const map = mapBrowserEvent.map;\n    const view = map.getView();\n    view.setHint(ViewHint.INTERACTING, -1);\n    const resolution = view.getResolution();\n    if (this.constrainResolution_ ||\n        resolution < view.getMinResolution() ||\n        resolution > view.getMaxResolution()) {\n      // Zoom to final resolution, with an animation, and provide a\n      // direction not to zoom out/in if user was pinching in/out.\n      // Direction is > 0 if pinching out, and < 0 if pinching in.\n      const direction = this.lastScaleDelta_ - 1;\n      zoom(view, resolution, this.anchor_, this.duration_, direction);\n    }\n    return false;\n  } else {\n    return true;\n  }\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @return {boolean} Start drag sequence?\n * @this {module:ol/interaction/PinchZoom}\n */\nfunction handleDownEvent(mapBrowserEvent) {\n  if (this.targetPointers.length >= 2) {\n    const map = mapBrowserEvent.map;\n    this.anchor_ = null;\n    this.lastDistance_ = undefined;\n    this.lastScaleDelta_ = 1;\n    if (!this.handlingDownUpSequence) {\n      map.getView().setHint(ViewHint.INTERACTING, 1);\n    }\n    return true;\n  } else {\n    return false;\n  }\n}\n\nexport default PinchZoom;\n","/**\n * @module ol/interaction/DragAndDrop\n */\n// FIXME should handle all geo-referenced data, not just vector data\n\nimport {TRUE} from '../functions.js';\nimport {listen, unlistenByKey} from '../events.js';\nimport Event from '../events/Event.js';\nimport EventType from '../events/EventType.js';\nimport Interaction from '../interaction/Interaction.js';\nimport {get as getProjection} from '../proj.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {Array.<function(new: module:ol/format/Feature)>} [formatConstructors] Format constructors.\n * @property {module:ol/source/Vector} [source] Optional vector source where features will be added.  If a source is provided\n * all existing features will be removed and new features will be added when\n * they are dropped on the target.  If you want to add features to a vector\n * source without removing the existing features (append only), instead of\n * providing the source option listen for the \"addfeatures\" event.\n * @property {module:ol/proj~ProjectionLike} [projection] Target projection. By default, the map's view's projection is used.\n * @property {Element} [target] The element that is used as the drop target, default is the viewport element.\n */\n\n\n/**\n * @enum {string}\n */\nconst DragAndDropEventType = {\n  /**\n   * Triggered when features are added\n   * @event module:ol/interaction/DragAndDrop~DragAndDropEvent#addfeatures\n   * @api\n   */\n  ADD_FEATURES: 'addfeatures'\n};\n\n\n/**\n * @classdesc\n * Events emitted by {@link module:ol/interaction/DragAndDrop~DragAndDrop} instances are instances\n * of this type.\n */\nclass DragAndDropEvent extends Event {\n\n  /**\n   * @param {module:ol/interaction/DragAndDrop~DragAndDropEventType} type Type.\n   * @param {File} file File.\n   * @param {Array.<module:ol/Feature>=} opt_features Features.\n   * @param {module:ol/proj/Projection=} opt_projection Projection.\n   */\n  constructor(type, file, opt_features, opt_projection) {\n\n    super(type);\n\n    /**\n     * The features parsed from dropped data.\n     * @type {Array.<module:ol/Feature>|undefined}\n     * @api\n     */\n    this.features = opt_features;\n\n    /**\n     * The dropped file.\n     * @type {File}\n     * @api\n     */\n    this.file = file;\n\n    /**\n     * The feature projection.\n     * @type {module:ol/proj/Projection|undefined}\n     * @api\n     */\n    this.projection = opt_projection;\n\n  }\n\n}\n\n\n/**\n * @classdesc\n * Handles input of vector data by drag and drop.\n * @api\n *\n * @fires module:ol/interaction/DragAndDrop~DragAndDropEvent\n */\nclass DragAndDrop extends Interaction {\n  /**\n   * @param {module:ol/interaction/DragAndDrop~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options ? opt_options : {};\n\n    super({\n      handleEvent: TRUE\n    });\n\n    /**\n     * @private\n     * @type {Array.<function(new: module:ol/format/Feature)>}\n     */\n    this.formatConstructors_ = options.formatConstructors ?\n      options.formatConstructors : [];\n\n    /**\n     * @private\n     * @type {module:ol/proj/Projection}\n     */\n    this.projection_ = options.projection ?\n      getProjection(options.projection) : null;\n\n    /**\n     * @private\n     * @type {Array.<module:ol/events~EventsKey>}\n     */\n    this.dropListenKeys_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/source/Vector}\n     */\n    this.source_ = options.source || null;\n\n    /**\n     * @private\n     * @type {Element}\n     */\n    this.target = options.target ? options.target : null;\n\n  }\n\n  /**\n   * @param {File} file File.\n   * @param {Event} event Load event.\n   * @private\n   */\n  handleResult_(file, event) {\n    const result = event.target.result;\n    const map = this.getMap();\n    let projection = this.projection_;\n    if (!projection) {\n      const view = map.getView();\n      projection = view.getProjection();\n    }\n\n    const formatConstructors = this.formatConstructors_;\n    let features = [];\n    for (let i = 0, ii = formatConstructors.length; i < ii; ++i) {\n      /**\n       * Avoid \"cannot instantiate abstract class\" error.\n       * @type {Function}\n       */\n      const formatConstructor = formatConstructors[i];\n      /**\n       * @type {module:ol/format/Feature}\n       */\n      const format = new formatConstructor();\n      features = this.tryReadFeatures_(format, result, {\n        featureProjection: projection\n      });\n      if (features && features.length > 0) {\n        break;\n      }\n    }\n    if (this.source_) {\n      this.source_.clear();\n      this.source_.addFeatures(features);\n    }\n    this.dispatchEvent(\n      new DragAndDropEvent(\n        DragAndDropEventType.ADD_FEATURES, file,\n        features, projection));\n  }\n\n  /**\n   * @private\n   */\n  registerListeners_() {\n    const map = this.getMap();\n    if (map) {\n      const dropArea = this.target ? this.target : map.getViewport();\n      this.dropListenKeys_ = [\n        listen(dropArea, EventType.DROP, handleDrop, this),\n        listen(dropArea, EventType.DRAGENTER, handleStop, this),\n        listen(dropArea, EventType.DRAGOVER, handleStop, this),\n        listen(dropArea, EventType.DROP, handleStop, this)\n      ];\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setActive(active) {\n    super.setActive(active);\n    if (active) {\n      this.registerListeners_();\n    } else {\n      this.unregisterListeners_();\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setMap(map) {\n    this.unregisterListeners_();\n    super.setMap(map);\n    if (this.getActive()) {\n      this.registerListeners_();\n    }\n  }\n\n  /**\n   * @param {module:ol/format/Feature} format Format.\n   * @param {string} text Text.\n   * @param {module:ol/format/Feature~ReadOptions} options Read options.\n   * @private\n   * @return {Array.<module:ol/Feature>} Features.\n   */\n  tryReadFeatures_(format, text, options) {\n    try {\n      return format.readFeatures(text, options);\n    } catch (e) {\n      return null;\n    }\n  }\n\n  /**\n   * @private\n   */\n  unregisterListeners_() {\n    if (this.dropListenKeys_) {\n      this.dropListenKeys_.forEach(unlistenByKey);\n      this.dropListenKeys_ = null;\n    }\n  }\n}\n\n\n/**\n * @param {DragEvent} event Event.\n * @this {module:ol/interaction/DragAndDrop}\n */\nfunction handleDrop(event) {\n  const files = event.dataTransfer.files;\n  for (let i = 0, ii = files.length; i < ii; ++i) {\n    const file = files.item(i);\n    const reader = new FileReader();\n    reader.addEventListener(EventType.LOAD, this.handleResult_.bind(this, file));\n    reader.readAsText(file);\n  }\n}\n\n\n/**\n * @param {DragEvent} event Event.\n */\nfunction handleStop(event) {\n  event.stopPropagation();\n  event.preventDefault();\n  event.dataTransfer.dropEffect = 'copy';\n}\n\n\nexport default DragAndDrop;\n","/**\n * @module ol/interaction/DragRotateAndZoom\n */\nimport {disable} from '../rotationconstraint.js';\nimport ViewHint from '../ViewHint.js';\nimport {shiftKeyOnly, mouseOnly} from '../events/condition.js';\nimport {rotate, rotateWithoutConstraints, zoom, zoomWithoutConstraints} from '../interaction/Interaction.js';\nimport PointerInteraction from '../interaction/Pointer.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/events/condition~Condition} [condition] A function that\n * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled.\n * Default is {@link module:ol/events/condition~shiftKeyOnly}.\n * @property {number} [duration=400] Animation duration in milliseconds.\n */\n\n\n/**\n * @classdesc\n * Allows the user to zoom and rotate the map by clicking and dragging\n * on the map.  By default, this interaction is limited to when the shift\n * key is held down.\n *\n * This interaction is only supported for mouse devices.\n *\n * And this interaction is not included in the default interactions.\n * @api\n */\nclass DragRotateAndZoom extends PointerInteraction {\n\n  /**\n   * @param {module:ol/interaction/DragRotateAndZoom~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options ? opt_options : {};\n\n    super({\n      handleDownEvent: handleDownEvent,\n      handleDragEvent: handleDragEvent,\n      handleUpEvent: handleUpEvent\n    });\n\n    /**\n     * @private\n     * @type {module:ol/events/condition~Condition}\n     */\n    this.condition_ = options.condition ? options.condition : shiftKeyOnly;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.lastAngle_ = undefined;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.lastMagnitude_ = undefined;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.lastScaleDelta_ = 0;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.duration_ = options.duration !== undefined ? options.duration : 400;\n\n  }\n\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @this {module:ol/interaction/DragRotateAndZoom}\n */\nfunction handleDragEvent(mapBrowserEvent) {\n  if (!mouseOnly(mapBrowserEvent)) {\n    return;\n  }\n\n  const map = mapBrowserEvent.map;\n  const size = map.getSize();\n  const offset = mapBrowserEvent.pixel;\n  const deltaX = offset[0] - size[0] / 2;\n  const deltaY = size[1] / 2 - offset[1];\n  const theta = Math.atan2(deltaY, deltaX);\n  const magnitude = Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n  const view = map.getView();\n  if (view.getConstraints().rotation !== disable && this.lastAngle_ !== undefined) {\n    const angleDelta = theta - this.lastAngle_;\n    rotateWithoutConstraints(view, view.getRotation() - angleDelta);\n  }\n  this.lastAngle_ = theta;\n  if (this.lastMagnitude_ !== undefined) {\n    const resolution = this.lastMagnitude_ * (view.getResolution() / magnitude);\n    zoomWithoutConstraints(view, resolution);\n  }\n  if (this.lastMagnitude_ !== undefined) {\n    this.lastScaleDelta_ = this.lastMagnitude_ / magnitude;\n  }\n  this.lastMagnitude_ = magnitude;\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @return {boolean} Stop drag sequence?\n * @this {module:ol/interaction/DragRotateAndZoom}\n */\nfunction handleUpEvent(mapBrowserEvent) {\n  if (!mouseOnly(mapBrowserEvent)) {\n    return true;\n  }\n\n  const map = mapBrowserEvent.map;\n  const view = map.getView();\n  view.setHint(ViewHint.INTERACTING, -1);\n  const direction = this.lastScaleDelta_ - 1;\n  rotate(view, view.getRotation());\n  zoom(view, view.getResolution(), undefined, this.duration_, direction);\n  this.lastScaleDelta_ = 0;\n  return false;\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @return {boolean} Start drag sequence?\n * @this {module:ol/interaction/DragRotateAndZoom}\n */\nfunction handleDownEvent(mapBrowserEvent) {\n  if (!mouseOnly(mapBrowserEvent)) {\n    return false;\n  }\n\n  if (this.condition_(mapBrowserEvent)) {\n    mapBrowserEvent.map.getView().setHint(ViewHint.INTERACTING, 1);\n    this.lastAngle_ = undefined;\n    this.lastMagnitude_ = undefined;\n    return true;\n  } else {\n    return false;\n  }\n}\n\nexport default DragRotateAndZoom;\n","/**\n * @module ol/geom/Circle\n */\nimport {createOrUpdate, forEachCorner, intersects} from '../extent.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport SimpleGeometry from '../geom/SimpleGeometry.js';\nimport {deflateCoordinate} from '../geom/flat/deflate.js';\n\n/**\n * @classdesc\n * Circle geometry.\n *\n * @api\n */\nclass Circle extends SimpleGeometry {\n\n  /**\n   * @param {!module:ol/coordinate~Coordinate} center Center.\n   *     For internal use, flat coordinates in combination with `opt_layout` and no\n   *     `opt_radius` are also accepted.\n   * @param {number=} opt_radius Radius.\n   * @param {module:ol/geom/GeometryLayout=} opt_layout Layout.\n   */\n  constructor(center, opt_radius, opt_layout) {\n    super();\n    if (opt_layout !== undefined && opt_radius === undefined) {\n      this.setFlatCoordinates(opt_layout, center);\n    } else {\n      const radius = opt_radius ? opt_radius : 0;\n      this.setCenterAndRadius(center, radius, opt_layout);\n    }\n  }\n\n  /**\n   * Make a complete copy of the geometry.\n   * @return {!module:ol/geom/Circle} Clone.\n   * @override\n   * @api\n   */\n  clone() {\n    return new Circle(this.flatCoordinates.slice(), undefined, this.layout);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  closestPointXY(x, y, closestPoint, minSquaredDistance) {\n    const flatCoordinates = this.flatCoordinates;\n    const dx = x - flatCoordinates[0];\n    const dy = y - flatCoordinates[1];\n    const squaredDistance = dx * dx + dy * dy;\n    if (squaredDistance < minSquaredDistance) {\n      if (squaredDistance === 0) {\n        for (let i = 0; i < this.stride; ++i) {\n          closestPoint[i] = flatCoordinates[i];\n        }\n      } else {\n        const delta = this.getRadius() / Math.sqrt(squaredDistance);\n        closestPoint[0] = flatCoordinates[0] + delta * dx;\n        closestPoint[1] = flatCoordinates[1] + delta * dy;\n        for (let i = 2; i < this.stride; ++i) {\n          closestPoint[i] = flatCoordinates[i];\n        }\n      }\n      closestPoint.length = this.stride;\n      return squaredDistance;\n    } else {\n      return minSquaredDistance;\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  containsXY(x, y) {\n    const flatCoordinates = this.flatCoordinates;\n    const dx = x - flatCoordinates[0];\n    const dy = y - flatCoordinates[1];\n    return dx * dx + dy * dy <= this.getRadiusSquared_();\n  }\n\n  /**\n   * Return the center of the circle as {@link module:ol/coordinate~Coordinate coordinate}.\n   * @return {module:ol/coordinate~Coordinate} Center.\n   * @api\n   */\n  getCenter() {\n    return this.flatCoordinates.slice(0, this.stride);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  computeExtent(extent) {\n    const flatCoordinates = this.flatCoordinates;\n    const radius = flatCoordinates[this.stride] - flatCoordinates[0];\n    return createOrUpdate(\n      flatCoordinates[0] - radius, flatCoordinates[1] - radius,\n      flatCoordinates[0] + radius, flatCoordinates[1] + radius,\n      extent);\n  }\n\n  /**\n   * Return the radius of the circle.\n   * @return {number} Radius.\n   * @api\n   */\n  getRadius() {\n    return Math.sqrt(this.getRadiusSquared_());\n  }\n\n  /**\n   * @private\n   * @return {number} Radius squared.\n   */\n  getRadiusSquared_() {\n    const dx = this.flatCoordinates[this.stride] - this.flatCoordinates[0];\n    const dy = this.flatCoordinates[this.stride + 1] - this.flatCoordinates[1];\n    return dx * dx + dy * dy;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  getType() {\n    return GeometryType.CIRCLE;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  intersectsExtent(extent) {\n    const circleExtent = this.getExtent();\n    if (intersects(extent, circleExtent)) {\n      const center = this.getCenter();\n\n      if (extent[0] <= center[0] && extent[2] >= center[0]) {\n        return true;\n      }\n      if (extent[1] <= center[1] && extent[3] >= center[1]) {\n        return true;\n      }\n\n      return forEachCorner(extent, this.intersectsCoordinate, this);\n    }\n    return false;\n\n  }\n\n  /**\n   * Set the center of the circle as {@link module:ol/coordinate~Coordinate coordinate}.\n   * @param {module:ol/coordinate~Coordinate} center Center.\n   * @api\n   */\n  setCenter(center) {\n    const stride = this.stride;\n    const radius = this.flatCoordinates[stride] - this.flatCoordinates[0];\n    const flatCoordinates = center.slice();\n    flatCoordinates[stride] = flatCoordinates[0] + radius;\n    for (let i = 1; i < stride; ++i) {\n      flatCoordinates[stride + i] = center[i];\n    }\n    this.setFlatCoordinates(this.layout, flatCoordinates);\n    this.changed();\n  }\n\n  /**\n   * Set the center (as {@link module:ol/coordinate~Coordinate coordinate}) and the radius (as\n   * number) of the circle.\n   * @param {!module:ol/coordinate~Coordinate} center Center.\n   * @param {number} radius Radius.\n   * @param {module:ol/geom/GeometryLayout=} opt_layout Layout.\n   * @api\n   */\n  setCenterAndRadius(center, radius, opt_layout) {\n    this.setLayout(opt_layout, center, 0);\n    if (!this.flatCoordinates) {\n      this.flatCoordinates = [];\n    }\n    /** @type {Array.<number>} */\n    const flatCoordinates = this.flatCoordinates;\n    let offset = deflateCoordinate(\n      flatCoordinates, 0, center, this.stride);\n    flatCoordinates[offset++] = flatCoordinates[0] + radius;\n    for (let i = 1, ii = this.stride; i < ii; ++i) {\n      flatCoordinates[offset++] = flatCoordinates[i];\n    }\n    flatCoordinates.length = offset;\n    this.changed();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getCoordinates() {}\n\n  /**\n   * @inheritDoc\n   */\n  setCoordinates(coordinates, opt_layout) {}\n\n  /**\n   * Set the radius of the circle. The radius is in the units of the projection.\n   * @param {number} radius Radius.\n   * @api\n   */\n  setRadius(radius) {\n    this.flatCoordinates[this.stride] = this.flatCoordinates[0] + radius;\n    this.changed();\n  }\n}\n\n\n/**\n * Transform each coordinate of the circle from one coordinate reference system\n * to another. The geometry is modified in place.\n * If you do not want the geometry modified in place, first clone() it and\n * then use this function on the clone.\n *\n * Internally a circle is currently represented by two points: the center of\n * the circle `[cx, cy]`, and the point to the right of the circle\n * `[cx + r, cy]`. This `transform` function just transforms these two points.\n * So the resulting geometry is also a circle, and that circle does not\n * correspond to the shape that would be obtained by transforming every point\n * of the original circle.\n *\n * @param {module:ol/proj~ProjectionLike} source The current projection.  Can be a\n *     string identifier or a {@link module:ol/proj/Projection~Projection} object.\n * @param {module:ol/proj~ProjectionLike} destination The desired projection.  Can be a\n *     string identifier or a {@link module:ol/proj/Projection~Projection} object.\n * @return {module:ol/geom/Circle} This geometry.  Note that original geometry is\n *     modified in place.\n * @function\n * @api\n */\nCircle.prototype.transform;\nexport default Circle;\n","/**\n * @module ol/geom/MultiLineString\n */\nimport {extend} from '../array.js';\nimport {closestSquaredDistanceXY} from '../extent.js';\nimport GeometryLayout from '../geom/GeometryLayout.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport LineString from '../geom/LineString.js';\nimport SimpleGeometry from '../geom/SimpleGeometry.js';\nimport {assignClosestArrayPoint, arrayMaxSquaredDelta} from '../geom/flat/closest.js';\nimport {deflateCoordinatesArray} from '../geom/flat/deflate.js';\nimport {inflateCoordinatesArray} from '../geom/flat/inflate.js';\nimport {interpolatePoint, lineStringsCoordinateAtM} from '../geom/flat/interpolate.js';\nimport {intersectsLineStringArray} from '../geom/flat/intersectsextent.js';\nimport {douglasPeuckerArray} from '../geom/flat/simplify.js';\n\n/**\n * @classdesc\n * Multi-linestring geometry.\n *\n * @api\n */\nclass MultiLineString extends SimpleGeometry {\n\n  /**\n   * @param {Array.<Array.<module:ol/coordinate~Coordinate>|module:ol/geom~MultiLineString>|Array.<number>} coordinates\n   *     Coordinates or LineString geometries. (For internal use, flat coordinates in\n   *     combination with `opt_layout` and `opt_ends` are also accepted.)\n   * @param {module:ol/geom/GeometryLayout=} opt_layout Layout.\n   * @param {Array.<number>} opt_ends Flat coordinate ends for internal use.\n   */\n  constructor(coordinates, opt_layout, opt_ends) {\n\n    super();\n\n    /**\n     * @type {Array.<number>}\n     * @private\n     */\n    this.ends_ = [];\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.maxDelta_ = -1;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.maxDeltaRevision_ = -1;\n\n    if (Array.isArray(coordinates[0])) {\n      this.setCoordinates(coordinates, opt_layout);\n    } else if (opt_layout !== undefined && opt_ends) {\n      this.setFlatCoordinates(opt_layout, coordinates);\n      this.ends_ = opt_ends;\n    } else {\n      let layout = this.getLayout();\n      const flatCoordinates = [];\n      const ends = [];\n      for (let i = 0, ii = coordinates.length; i < ii; ++i) {\n        const lineString = coordinates[i];\n        if (i === 0) {\n          layout = lineString.getLayout();\n        }\n        extend(flatCoordinates, lineString.getFlatCoordinates());\n        ends.push(flatCoordinates.length);\n      }\n      this.setFlatCoordinates(layout, flatCoordinates);\n      this.ends_ = ends;\n    }\n\n  }\n\n  /**\n   * Append the passed linestring to the multilinestring.\n   * @param {module:ol/geom/LineString} lineString LineString.\n   * @api\n   */\n  appendLineString(lineString) {\n    if (!this.flatCoordinates) {\n      this.flatCoordinates = lineString.getFlatCoordinates().slice();\n    } else {\n      extend(this.flatCoordinates, lineString.getFlatCoordinates().slice());\n    }\n    this.ends_.push(this.flatCoordinates.length);\n    this.changed();\n  }\n\n  /**\n   * Make a complete copy of the geometry.\n   * @return {!module:ol/geom/MultiLineString} Clone.\n   * @override\n   * @api\n   */\n  clone() {\n    return new MultiLineString(this.flatCoordinates.slice(), this.layout, this.ends_.slice());\n  }\n\n  /**\n   * @inheritDoc\n   */\n  closestPointXY(x, y, closestPoint, minSquaredDistance) {\n    if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n      return minSquaredDistance;\n    }\n    if (this.maxDeltaRevision_ != this.getRevision()) {\n      this.maxDelta_ = Math.sqrt(arrayMaxSquaredDelta(\n        this.flatCoordinates, 0, this.ends_, this.stride, 0));\n      this.maxDeltaRevision_ = this.getRevision();\n    }\n    return assignClosestArrayPoint(\n      this.flatCoordinates, 0, this.ends_, this.stride,\n      this.maxDelta_, false, x, y, closestPoint, minSquaredDistance);\n  }\n\n  /**\n   * Returns the coordinate at `m` using linear interpolation, or `null` if no\n   * such coordinate exists.\n   *\n   * `opt_extrapolate` controls extrapolation beyond the range of Ms in the\n   * MultiLineString. If `opt_extrapolate` is `true` then Ms less than the first\n   * M will return the first coordinate and Ms greater than the last M will\n   * return the last coordinate.\n   *\n   * `opt_interpolate` controls interpolation between consecutive LineStrings\n   * within the MultiLineString. If `opt_interpolate` is `true` the coordinates\n   * will be linearly interpolated between the last coordinate of one LineString\n   * and the first coordinate of the next LineString.  If `opt_interpolate` is\n   * `false` then the function will return `null` for Ms falling between\n   * LineStrings.\n   *\n   * @param {number} m M.\n   * @param {boolean=} opt_extrapolate Extrapolate. Default is `false`.\n   * @param {boolean=} opt_interpolate Interpolate. Default is `false`.\n   * @return {module:ol/coordinate~Coordinate} Coordinate.\n   * @api\n   */\n  getCoordinateAtM(m, opt_extrapolate, opt_interpolate) {\n    if ((this.layout != GeometryLayout.XYM &&\n         this.layout != GeometryLayout.XYZM) ||\n        this.flatCoordinates.length === 0) {\n      return null;\n    }\n    const extrapolate = opt_extrapolate !== undefined ? opt_extrapolate : false;\n    const interpolate = opt_interpolate !== undefined ? opt_interpolate : false;\n    return lineStringsCoordinateAtM(this.flatCoordinates, 0,\n      this.ends_, this.stride, m, extrapolate, interpolate);\n  }\n\n  /**\n   * Return the coordinates of the multilinestring.\n   * @return {Array.<Array.<module:ol/coordinate~Coordinate>>} Coordinates.\n   * @override\n   * @api\n   */\n  getCoordinates() {\n    return inflateCoordinatesArray(\n      this.flatCoordinates, 0, this.ends_, this.stride);\n  }\n\n  /**\n   * @return {Array.<number>} Ends.\n   */\n  getEnds() {\n    return this.ends_;\n  }\n\n  /**\n   * Return the linestring at the specified index.\n   * @param {number} index Index.\n   * @return {module:ol/geom/LineString} LineString.\n   * @api\n   */\n  getLineString(index) {\n    if (index < 0 || this.ends_.length <= index) {\n      return null;\n    }\n    return new LineString(this.flatCoordinates.slice(\n      index === 0 ? 0 : this.ends_[index - 1], this.ends_[index]), this.layout);\n  }\n\n  /**\n   * Return the linestrings of this multilinestring.\n   * @return {Array.<module:ol/geom/LineString>} LineStrings.\n   * @api\n   */\n  getLineStrings() {\n    const flatCoordinates = this.flatCoordinates;\n    const ends = this.ends_;\n    const layout = this.layout;\n    /** @type {Array.<module:ol/geom/LineString>} */\n    const lineStrings = [];\n    let offset = 0;\n    for (let i = 0, ii = ends.length; i < ii; ++i) {\n      const end = ends[i];\n      const lineString = new LineString(flatCoordinates.slice(offset, end), layout);\n      lineStrings.push(lineString);\n      offset = end;\n    }\n    return lineStrings;\n  }\n\n  /**\n   * @return {Array.<number>} Flat midpoints.\n   */\n  getFlatMidpoints() {\n    const midpoints = [];\n    const flatCoordinates = this.flatCoordinates;\n    let offset = 0;\n    const ends = this.ends_;\n    const stride = this.stride;\n    for (let i = 0, ii = ends.length; i < ii; ++i) {\n      const end = ends[i];\n      const midpoint = interpolatePoint(\n        flatCoordinates, offset, end, stride, 0.5);\n      extend(midpoints, midpoint);\n      offset = end;\n    }\n    return midpoints;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getSimplifiedGeometryInternal(squaredTolerance) {\n    const simplifiedFlatCoordinates = [];\n    const simplifiedEnds = [];\n    simplifiedFlatCoordinates.length = douglasPeuckerArray(\n      this.flatCoordinates, 0, this.ends_, this.stride, squaredTolerance,\n      simplifiedFlatCoordinates, 0, simplifiedEnds);\n    return new MultiLineString(simplifiedFlatCoordinates, GeometryLayout.XY, simplifiedEnds);\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  getType() {\n    return GeometryType.MULTI_LINE_STRING;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  intersectsExtent(extent) {\n    return intersectsLineStringArray(\n      this.flatCoordinates, 0, this.ends_, this.stride, extent);\n  }\n\n  /**\n   * Set the coordinates of the multilinestring.\n   * @param {!Array.<Array.<module:ol/coordinate~Coordinate>>} coordinates Coordinates.\n   * @param {module:ol/geom/GeometryLayout=} opt_layout Layout.\n   * @override\n   * @api\n   */\n  setCoordinates(coordinates, opt_layout) {\n    this.setLayout(opt_layout, coordinates, 2);\n    if (!this.flatCoordinates) {\n      this.flatCoordinates = [];\n    }\n    const ends = deflateCoordinatesArray(\n      this.flatCoordinates, 0, coordinates, this.stride, this.ends_);\n    this.flatCoordinates.length = ends.length === 0 ? 0 : ends[ends.length - 1];\n    this.changed();\n  }\n}\n\n\nexport default MultiLineString;\n","/**\n * @module ol/geom/MultiPoint\n */\nimport {extend} from '../array.js';\nimport {closestSquaredDistanceXY, containsXY} from '../extent.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport Point from '../geom/Point.js';\nimport SimpleGeometry from '../geom/SimpleGeometry.js';\nimport {deflateCoordinates} from '../geom/flat/deflate.js';\nimport {inflateCoordinates} from '../geom/flat/inflate.js';\nimport {squaredDistance as squaredDx} from '../math.js';\n\n/**\n * @classdesc\n * Multi-point geometry.\n *\n * @api\n */\nclass MultiPoint extends SimpleGeometry {\n\n  /**\n   * @param {Array.<module:ol/coordinate~Coordinate>|Array.<number>} coordinates Coordinates.\n   *     For internal use, flat coordinates in combination with `opt_layout` are also accepted.\n   * @param {module:ol/geom/GeometryLayout=} opt_layout Layout.\n   */\n  constructor(coordinates, opt_layout) {\n    super();\n    if (opt_layout && !Array.isArray(coordinates[0])) {\n      this.setFlatCoordinates(opt_layout, coordinates);\n    } else {\n      this.setCoordinates(coordinates, opt_layout);\n    }\n  }\n\n  /**\n   * Append the passed point to this multipoint.\n   * @param {module:ol/geom/Point} point Point.\n   * @api\n   */\n  appendPoint(point) {\n    if (!this.flatCoordinates) {\n      this.flatCoordinates = point.getFlatCoordinates().slice();\n    } else {\n      extend(this.flatCoordinates, point.getFlatCoordinates());\n    }\n    this.changed();\n  }\n\n  /**\n   * Make a complete copy of the geometry.\n   * @return {!module:ol/geom/MultiPoint} Clone.\n   * @override\n   * @api\n   */\n  clone() {\n    const multiPoint = new MultiPoint(this.flatCoordinates.slice(), this.layout);\n    return multiPoint;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  closestPointXY(x, y, closestPoint, minSquaredDistance) {\n    if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n      return minSquaredDistance;\n    }\n    const flatCoordinates = this.flatCoordinates;\n    const stride = this.stride;\n    for (let i = 0, ii = flatCoordinates.length; i < ii; i += stride) {\n      const squaredDistance = squaredDx(\n        x, y, flatCoordinates[i], flatCoordinates[i + 1]);\n      if (squaredDistance < minSquaredDistance) {\n        minSquaredDistance = squaredDistance;\n        for (let j = 0; j < stride; ++j) {\n          closestPoint[j] = flatCoordinates[i + j];\n        }\n        closestPoint.length = stride;\n      }\n    }\n    return minSquaredDistance;\n  }\n\n  /**\n   * Return the coordinates of the multipoint.\n   * @return {Array.<module:ol/coordinate~Coordinate>} Coordinates.\n   * @override\n   * @api\n   */\n  getCoordinates() {\n    return inflateCoordinates(\n      this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);\n  }\n\n  /**\n   * Return the point at the specified index.\n   * @param {number} index Index.\n   * @return {module:ol/geom/Point} Point.\n   * @api\n   */\n  getPoint(index) {\n    const n = !this.flatCoordinates ? 0 : this.flatCoordinates.length / this.stride;\n    if (index < 0 || n <= index) {\n      return null;\n    }\n    return new Point(this.flatCoordinates.slice(\n      index * this.stride, (index + 1) * this.stride), this.layout);\n  }\n\n  /**\n   * Return the points of this multipoint.\n   * @return {Array.<module:ol/geom/Point>} Points.\n   * @api\n   */\n  getPoints() {\n    const flatCoordinates = this.flatCoordinates;\n    const layout = this.layout;\n    const stride = this.stride;\n    /** @type {Array.<module:ol/geom/Point>} */\n    const points = [];\n    for (let i = 0, ii = flatCoordinates.length; i < ii; i += stride) {\n      const point = new Point(flatCoordinates.slice(i, i + stride), layout);\n      points.push(point);\n    }\n    return points;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  getType() {\n    return GeometryType.MULTI_POINT;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  intersectsExtent(extent) {\n    const flatCoordinates = this.flatCoordinates;\n    const stride = this.stride;\n    for (let i = 0, ii = flatCoordinates.length; i < ii; i += stride) {\n      const x = flatCoordinates[i];\n      const y = flatCoordinates[i + 1];\n      if (containsXY(extent, x, y)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /**\n   * Set the coordinates of the multipoint.\n   * @param {!Array.<module:ol/coordinate~Coordinate>} coordinates Coordinates.\n   * @param {module:ol/geom/GeometryLayout=} opt_layout Layout.\n   * @override\n   * @api\n   */\n  setCoordinates(coordinates, opt_layout) {\n    this.setLayout(opt_layout, coordinates, 1);\n    if (!this.flatCoordinates) {\n      this.flatCoordinates = [];\n    }\n    this.flatCoordinates.length = deflateCoordinates(\n      this.flatCoordinates, 0, coordinates, this.stride);\n    this.changed();\n  }\n}\n\n\nexport default MultiPoint;\n","/**\n * @module ol/geom/flat/center\n */\nimport {createEmpty, createOrUpdateFromFlatCoordinates} from '../../extent.js';\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array.<Array.<number>>} endss Endss.\n * @param {number} stride Stride.\n * @return {Array.<number>} Flat centers.\n */\nexport function linearRingss(flatCoordinates, offset, endss, stride) {\n  const flatCenters = [];\n  let extent = createEmpty();\n  for (let i = 0, ii = endss.length; i < ii; ++i) {\n    const ends = endss[i];\n    extent = createOrUpdateFromFlatCoordinates(flatCoordinates, offset, ends[0], stride);\n    flatCenters.push((extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2);\n    offset = ends[ends.length - 1];\n  }\n  return flatCenters;\n}\n","/**\n * @module ol/geom/MultiPolygon\n */\nimport {extend} from '../array.js';\nimport {closestSquaredDistanceXY} from '../extent.js';\nimport GeometryLayout from '../geom/GeometryLayout.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport MultiPoint from '../geom/MultiPoint.js';\nimport Polygon from '../geom/Polygon.js';\nimport SimpleGeometry from '../geom/SimpleGeometry.js';\nimport {linearRingss as linearRingssArea} from '../geom/flat/area.js';\nimport {linearRingss as linearRingssCenter} from '../geom/flat/center.js';\nimport {assignClosestMultiArrayPoint, multiArrayMaxSquaredDelta} from '../geom/flat/closest.js';\nimport {linearRingssContainsXY} from '../geom/flat/contains.js';\nimport {deflateMultiCoordinatesArray} from '../geom/flat/deflate.js';\nimport {inflateMultiCoordinatesArray} from '../geom/flat/inflate.js';\nimport {getInteriorPointsOfMultiArray} from '../geom/flat/interiorpoint.js';\nimport {intersectsLinearRingMultiArray} from '../geom/flat/intersectsextent.js';\nimport {linearRingsAreOriented, orientLinearRingsArray} from '../geom/flat/orient.js';\nimport {quantizeMultiArray} from '../geom/flat/simplify.js';\n\n/**\n * @classdesc\n * Multi-polygon geometry.\n *\n * @api\n */\nclass MultiPolygon extends SimpleGeometry {\n\n  /**\n   * @param {Array.<Array.<Array.<module:ol/coordinate~Coordinate>>>|Array.<number>} coordinates Coordinates.\n   *     For internal use, flat coordinats in combination with `opt_layout` and `opt_endss` are also accepted.\n   * @param {module:ol/geom/GeometryLayout=} opt_layout Layout.\n   * @param {Array.<number>} opt_endss Array of ends for internal use with flat coordinates.\n   */\n  constructor(coordinates, opt_layout, opt_endss) {\n\n    super();\n\n    /**\n     * @type {Array.<Array.<number>>}\n     * @private\n     */\n    this.endss_ = [];\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.flatInteriorPointsRevision_ = -1;\n\n    /**\n     * @private\n     * @type {Array.<number>}\n     */\n    this.flatInteriorPoints_ = null;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.maxDelta_ = -1;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.maxDeltaRevision_ = -1;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.orientedRevision_ = -1;\n\n    /**\n     * @private\n     * @type {Array.<number>}\n     */\n    this.orientedFlatCoordinates_ = null;\n\n    if (!opt_endss && !Array.isArray(coordinates[0])) {\n      let layout = this.getLayout();\n      const flatCoordinates = [];\n      const endss = [];\n      for (let i = 0, ii = coordinates.length; i < ii; ++i) {\n        const polygon = coordinates[i];\n        if (i === 0) {\n          layout = polygon.getLayout();\n        }\n        const offset = flatCoordinates.length;\n        const ends = polygon.getEnds();\n        for (let j = 0, jj = ends.length; j < jj; ++j) {\n          ends[j] += offset;\n        }\n        extend(flatCoordinates, polygon.getFlatCoordinates());\n        endss.push(ends);\n      }\n      opt_layout = layout;\n      coordinates = flatCoordinates;\n      opt_endss = endss;\n    }\n    if (opt_layout !== undefined && opt_endss) {\n      this.setFlatCoordinates(opt_layout, coordinates);\n      this.endss_ = opt_endss;\n    } else {\n      this.setCoordinates(coordinates, opt_layout);\n    }\n\n  }\n\n  /**\n   * Append the passed polygon to this multipolygon.\n   * @param {module:ol/geom/Polygon} polygon Polygon.\n   * @api\n   */\n  appendPolygon(polygon) {\n    /** @type {Array.<number>} */\n    let ends;\n    if (!this.flatCoordinates) {\n      this.flatCoordinates = polygon.getFlatCoordinates().slice();\n      ends = polygon.getEnds().slice();\n      this.endss_.push();\n    } else {\n      const offset = this.flatCoordinates.length;\n      extend(this.flatCoordinates, polygon.getFlatCoordinates());\n      ends = polygon.getEnds().slice();\n      for (let i = 0, ii = ends.length; i < ii; ++i) {\n        ends[i] += offset;\n      }\n    }\n    this.endss_.push(ends);\n    this.changed();\n  }\n\n  /**\n   * Make a complete copy of the geometry.\n   * @return {!module:ol/geom/MultiPolygon} Clone.\n   * @override\n   * @api\n   */\n  clone() {\n    const len = this.endss_.length;\n    const newEndss = new Array(len);\n    for (let i = 0; i < len; ++i) {\n      newEndss[i] = this.endss_[i].slice();\n    }\n\n    return new MultiPolygon(\n      this.flatCoordinates.slice(), this.layout, newEndss);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  closestPointXY(x, y, closestPoint, minSquaredDistance) {\n    if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n      return minSquaredDistance;\n    }\n    if (this.maxDeltaRevision_ != this.getRevision()) {\n      this.maxDelta_ = Math.sqrt(multiArrayMaxSquaredDelta(\n        this.flatCoordinates, 0, this.endss_, this.stride, 0));\n      this.maxDeltaRevision_ = this.getRevision();\n    }\n    return assignClosestMultiArrayPoint(\n      this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride,\n      this.maxDelta_, true, x, y, closestPoint, minSquaredDistance);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  containsXY(x, y) {\n    return linearRingssContainsXY(this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, x, y);\n  }\n\n  /**\n   * Return the area of the multipolygon on projected plane.\n   * @return {number} Area (on projected plane).\n   * @api\n   */\n  getArea() {\n    return linearRingssArea(this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride);\n  }\n\n  /**\n   * Get the coordinate array for this geometry.  This array has the structure\n   * of a GeoJSON coordinate array for multi-polygons.\n   *\n   * @param {boolean=} opt_right Orient coordinates according to the right-hand\n   *     rule (counter-clockwise for exterior and clockwise for interior rings).\n   *     If `false`, coordinates will be oriented according to the left-hand rule\n   *     (clockwise for exterior and counter-clockwise for interior rings).\n   *     By default, coordinate orientation will depend on how the geometry was\n   *     constructed.\n   * @return {Array.<Array.<Array.<module:ol/coordinate~Coordinate>>>} Coordinates.\n   * @override\n   * @api\n   */\n  getCoordinates(opt_right) {\n    let flatCoordinates;\n    if (opt_right !== undefined) {\n      flatCoordinates = this.getOrientedFlatCoordinates().slice();\n      orientLinearRingsArray(\n        flatCoordinates, 0, this.endss_, this.stride, opt_right);\n    } else {\n      flatCoordinates = this.flatCoordinates;\n    }\n\n    return inflateMultiCoordinatesArray(\n      flatCoordinates, 0, this.endss_, this.stride);\n  }\n\n  /**\n   * @return {Array.<Array.<number>>} Endss.\n   */\n  getEndss() {\n    return this.endss_;\n  }\n\n  /**\n   * @return {Array.<number>} Flat interior points.\n   */\n  getFlatInteriorPoints() {\n    if (this.flatInteriorPointsRevision_ != this.getRevision()) {\n      const flatCenters = linearRingssCenter(\n        this.flatCoordinates, 0, this.endss_, this.stride);\n      this.flatInteriorPoints_ = getInteriorPointsOfMultiArray(\n        this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride,\n        flatCenters);\n      this.flatInteriorPointsRevision_ = this.getRevision();\n    }\n    return this.flatInteriorPoints_;\n  }\n\n  /**\n   * Return the interior points as {@link module:ol/geom/MultiPoint multipoint}.\n   * @return {module:ol/geom/MultiPoint} Interior points as XYM coordinates, where M is\n   * the length of the horizontal intersection that the point belongs to.\n   * @api\n   */\n  getInteriorPoints() {\n    return new MultiPoint(this.getFlatInteriorPoints().slice(), GeometryLayout.XYM);\n  }\n\n  /**\n   * @return {Array.<number>} Oriented flat coordinates.\n   */\n  getOrientedFlatCoordinates() {\n    if (this.orientedRevision_ != this.getRevision()) {\n      const flatCoordinates = this.flatCoordinates;\n      if (linearRingsAreOriented(\n        flatCoordinates, 0, this.endss_, this.stride)) {\n        this.orientedFlatCoordinates_ = flatCoordinates;\n      } else {\n        this.orientedFlatCoordinates_ = flatCoordinates.slice();\n        this.orientedFlatCoordinates_.length =\n            orientLinearRingsArray(\n              this.orientedFlatCoordinates_, 0, this.endss_, this.stride);\n      }\n      this.orientedRevision_ = this.getRevision();\n    }\n    return this.orientedFlatCoordinates_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getSimplifiedGeometryInternal(squaredTolerance) {\n    const simplifiedFlatCoordinates = [];\n    const simplifiedEndss = [];\n    simplifiedFlatCoordinates.length = quantizeMultiArray(\n      this.flatCoordinates, 0, this.endss_, this.stride,\n      Math.sqrt(squaredTolerance),\n      simplifiedFlatCoordinates, 0, simplifiedEndss);\n    return new MultiPolygon(simplifiedFlatCoordinates, GeometryLayout.XY, simplifiedEndss);\n  }\n\n  /**\n   * Return the polygon at the specified index.\n   * @param {number} index Index.\n   * @return {module:ol/geom/Polygon} Polygon.\n   * @api\n   */\n  getPolygon(index) {\n    if (index < 0 || this.endss_.length <= index) {\n      return null;\n    }\n    let offset;\n    if (index === 0) {\n      offset = 0;\n    } else {\n      const prevEnds = this.endss_[index - 1];\n      offset = prevEnds[prevEnds.length - 1];\n    }\n    const ends = this.endss_[index].slice();\n    const end = ends[ends.length - 1];\n    if (offset !== 0) {\n      for (let i = 0, ii = ends.length; i < ii; ++i) {\n        ends[i] -= offset;\n      }\n    }\n    return new Polygon(this.flatCoordinates.slice(offset, end), this.layout, ends);\n  }\n\n  /**\n   * Return the polygons of this multipolygon.\n   * @return {Array.<module:ol/geom/Polygon>} Polygons.\n   * @api\n   */\n  getPolygons() {\n    const layout = this.layout;\n    const flatCoordinates = this.flatCoordinates;\n    const endss = this.endss_;\n    const polygons = [];\n    let offset = 0;\n    for (let i = 0, ii = endss.length; i < ii; ++i) {\n      const ends = endss[i].slice();\n      const end = ends[ends.length - 1];\n      if (offset !== 0) {\n        for (let j = 0, jj = ends.length; j < jj; ++j) {\n          ends[j] -= offset;\n        }\n      }\n      const polygon = new Polygon(flatCoordinates.slice(offset, end), layout, ends);\n      polygons.push(polygon);\n      offset = end;\n    }\n    return polygons;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  getType() {\n    return GeometryType.MULTI_POLYGON;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  intersectsExtent(extent) {\n    return intersectsLinearRingMultiArray(\n      this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, extent);\n  }\n\n  /**\n   * Set the coordinates of the multipolygon.\n   * @param {!Array.<Array.<Array.<module:ol/coordinate~Coordinate>>>} coordinates Coordinates.\n   * @param {module:ol/geom/GeometryLayout=} opt_layout Layout.\n   * @override\n   * @api\n   */\n  setCoordinates(coordinates, opt_layout) {\n    this.setLayout(opt_layout, coordinates, 3);\n    if (!this.flatCoordinates) {\n      this.flatCoordinates = [];\n    }\n    const endss = deflateMultiCoordinatesArray(\n      this.flatCoordinates, 0, coordinates, this.stride, this.endss_);\n    if (endss.length === 0) {\n      this.flatCoordinates.length = 0;\n    } else {\n      const lastEnds = endss[endss.length - 1];\n      this.flatCoordinates.length = lastEnds.length === 0 ?\n        0 : lastEnds[lastEnds.length - 1];\n    }\n    this.changed();\n  }\n}\n\n\nexport default MultiPolygon;\n","/**\n * @module ol/LayerType\n */\n\n/**\n * A layer type used when creating layer renderers.\n * @enum {string}\n */\nexport default {\n  IMAGE: 'IMAGE',\n  TILE: 'TILE',\n  VECTOR_TILE: 'VECTOR_TILE',\n  VECTOR: 'VECTOR'\n};\n","/**\n * @module ol/layer/VectorRenderType\n */\n\n/**\n * @enum {string}\n * Render mode for vector layers:\n *  * `'image'`: Vector layers are rendered as images. Great performance, but\n *    point symbols and texts are always rotated with the view and pixels are\n *    scaled during zoom animations.\n *  * `'vector'`: Vector layers are rendered as vectors. Most accurate rendering\n *    even during animations, but slower performance.\n * @api\n */\nexport default {\n  IMAGE: 'image',\n  VECTOR: 'vector'\n};\n","/**\n * @module ol/layer/Vector\n */\nimport LayerType from '../LayerType.js';\nimport Layer from '../layer/Layer.js';\nimport VectorRenderType from '../layer/VectorRenderType.js';\nimport {assign} from '../obj.js';\nimport {createDefaultStyle, toFunction as toStyleFunction} from '../style/Style.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {module:ol/extent~Extent} [extent] The bounding extent for layer rendering.  The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex=0] The z-index for layer rendering.  At rendering time, the layers\n * will be ordered, first by Z-index and then by position.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {module:ol/render~OrderFunction} [renderOrder] Render order. Function to be used when sorting\n * features before rendering. By default features are drawn in the order that they are created. Use\n * `null` to avoid the sort, but get an undefined draw order.\n * @property {number} [renderBuffer=100] The buffer in pixels around the viewport extent used by the\n * renderer when getting features from the vector source for the rendering or hit-detection.\n * Recommended value: the size of the largest symbol, line width or label.\n * @property {module:ol/layer/VectorRenderType|string} [renderMode='vector'] Render mode for vector layers:\n *  * `'image'`: Vector layers are rendered as images. Great performance, but point symbols and\n *    texts are always rotated with the view and pixels are scaled during zoom animations.\n *  * `'vector'`: Vector layers are rendered as vectors. Most accurate rendering even during\n *    animations, but slower performance.\n * @property {module:ol/source/Vector} [source] Source.\n * @property {module:ol/PluggableMap} [map] Sets the layer as overlay on a map. The map will not manage\n * this layer in its layers collection, and the layer will be rendered on top. This is useful for\n * temporary layers. The standard way to add a layer to a map and have it managed by the map is to\n * use {@link module:ol/Map#addLayer}.\n * @property {boolean} [declutter=false] Declutter images and text. Decluttering is applied to all\n * image and text styles, and the priority is defined by the z-index of the style. Lower z-index\n * means higher priority.\n * @property {module:ol/style/Style|Array.<module:ol/style/Style>|module:ol/style/Style~StyleFunction} [style] Layer style. See\n * {@link module:ol/style} for default style which will be used if this is not defined.\n * @property {boolean} [updateWhileAnimating=false] When set to `true` and `renderMode`\n * is `vector`, feature batches will be recreated during animations. This means that no\n * vectors will be shown clipped, but the setting will have a performance impact for large\n * amounts of vector data. When set to `false`, batches will be recreated when no animation\n * is active.\n * @property {boolean} [updateWhileInteracting=false] When set to `true` and `renderMode`\n * is `vector`, feature batches will be recreated during interactions. See also\n * `updateWhileAnimating`.\n */\n\n\n/**\n * @enum {string}\n * Render mode for vector layers:\n *  * `'image'`: Vector layers are rendered as images. Great performance, but\n *    point symbols and texts are always rotated with the view and pixels are\n *    scaled during zoom animations.\n *  * `'vector'`: Vector layers are rendered as vectors. Most accurate rendering\n *    even during animations, but slower performance.\n * @api\n */\nexport const RenderType = {\n  IMAGE: 'image',\n  VECTOR: 'vector'\n};\n\n\n/**\n * @enum {string}\n * @private\n */\nconst Property = {\n  RENDER_ORDER: 'renderOrder'\n};\n\n\n/**\n * @classdesc\n * Vector data that is rendered client-side.\n * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}\n * property on the layer object; for example, setting `title: 'My Title'` in the\n * options means that `title` is observable, and has get/set accessors.\n *\n * @api\n */\nclass VectorLayer extends Layer {\n  /**\n   * @param {module:ol/layer/Vector~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n    const options = opt_options ?\n      opt_options : /** @type {module:ol/layer/Vector~Options} */ ({});\n\n    const baseOptions = assign({}, options);\n\n    delete baseOptions.style;\n    delete baseOptions.renderBuffer;\n    delete baseOptions.updateWhileAnimating;\n    delete baseOptions.updateWhileInteracting;\n    super(baseOptions);\n\n    /**\n    * @private\n    * @type {boolean}\n    */\n    this.declutter_ = options.declutter !== undefined ? options.declutter : false;\n\n    /**\n    * @type {number}\n    * @private\n    */\n    this.renderBuffer_ = options.renderBuffer !== undefined ?\n      options.renderBuffer : 100;\n\n    /**\n    * User provided style.\n    * @type {module:ol/style/Style|Array.<module:ol/style/Style>|module:ol/style/Style~StyleFunction}\n    * @private\n    */\n    this.style_ = null;\n\n    /**\n    * Style function for use within the library.\n    * @type {module:ol/style/Style~StyleFunction|undefined}\n    * @private\n    */\n    this.styleFunction_ = undefined;\n\n    this.setStyle(options.style);\n\n    /**\n    * @type {boolean}\n    * @private\n    */\n    this.updateWhileAnimating_ = options.updateWhileAnimating !== undefined ?\n      options.updateWhileAnimating : false;\n\n    /**\n    * @type {boolean}\n    * @private\n    */\n    this.updateWhileInteracting_ = options.updateWhileInteracting !== undefined ?\n      options.updateWhileInteracting : false;\n\n    /**\n    * @private\n    * @type {module:ol/layer/VectorTileRenderType|string}\n    */\n    this.renderMode_ = options.renderMode || VectorRenderType.VECTOR;\n\n    /**\n    * The layer type.\n    * @protected\n    * @type {module:ol/LayerType}\n    */\n    this.type = LayerType.VECTOR;\n\n  }\n\n  /**\n  * @return {boolean} Declutter.\n  */\n  getDeclutter() {\n    return this.declutter_;\n  }\n\n  /**\n  * @param {boolean} declutter Declutter.\n  */\n  setDeclutter(declutter) {\n    this.declutter_ = declutter;\n  }\n\n  /**\n  * @return {number|undefined} Render buffer.\n  */\n  getRenderBuffer() {\n    return this.renderBuffer_;\n  }\n\n  /**\n  * @return {function(module:ol/Feature, module:ol/Feature): number|null|undefined} Render\n  *     order.\n  */\n  getRenderOrder() {\n    return (\n    /** @type {module:ol/render~OrderFunction|null|undefined} */ (this.get(Property.RENDER_ORDER))\n    );\n  }\n\n  /**\n  * Get the style for features.  This returns whatever was passed to the `style`\n  * option at construction or to the `setStyle` method.\n  * @return {module:ol/style/Style|Array.<module:ol/style/Style>|module:ol/style/Style~StyleFunction}\n  *     Layer style.\n  * @api\n  */\n  getStyle() {\n    return this.style_;\n  }\n\n  /**\n  * Get the style function.\n  * @return {module:ol/style/Style~StyleFunction|undefined} Layer style function.\n  * @api\n  */\n  getStyleFunction() {\n    return this.styleFunction_;\n  }\n\n  /**\n  * @return {boolean} Whether the rendered layer should be updated while\n  *     animating.\n  */\n  getUpdateWhileAnimating() {\n    return this.updateWhileAnimating_;\n  }\n\n  /**\n  * @return {boolean} Whether the rendered layer should be updated while\n  *     interacting.\n  */\n  getUpdateWhileInteracting() {\n    return this.updateWhileInteracting_;\n  }\n\n  /**\n  * @param {module:ol/render~OrderFunction|null|undefined} renderOrder\n  *     Render order.\n  */\n  setRenderOrder(renderOrder) {\n    this.set(Property.RENDER_ORDER, renderOrder);\n  }\n\n  /**\n  * Set the style for features.  This can be a single style object, an array\n  * of styles, or a function that takes a feature and resolution and returns\n  * an array of styles. If it is `undefined` the default style is used. If\n  * it is `null` the layer has no style (a `null` style), so only features\n  * that have their own styles will be rendered in the layer. See\n  * {@link module:ol/style} for information on the default style.\n  * @param {module:ol/style/Style|Array.<module:ol/style/Style>|module:ol/style/Style~StyleFunction|null|undefined}\n  *     style Layer style.\n  * @api\n  */\n  setStyle(style) {\n    this.style_ = style !== undefined ? style : createDefaultStyle;\n    this.styleFunction_ = style === null ?\n      undefined : toStyleFunction(this.style_);\n    this.changed();\n  }\n\n  /**\n  * @return {module:ol/layer/VectorRenderType|string} The render mode.\n  */\n  getRenderMode() {\n    return this.renderMode_;\n  }\n}\n\n\n/**\n * Return the associated {@link module:ol/source/Vector vectorsource} of the layer.\n * @function\n * @return {module:ol/source/Vector} Source.\n * @api\n */\nVectorLayer.prototype.getSource;\n\n\nexport default VectorLayer;\n","/**\n * @module ol/format/FormatType\n */\n\n/**\n * @enum {string}\n */\nexport default {\n  ARRAY_BUFFER: 'arraybuffer',\n  JSON: 'json',\n  TEXT: 'text',\n  XML: 'xml'\n};\n","/**\n * @module ol/featureloader\n */\nimport {UNDEFINED} from './functions.js';\nimport FormatType from './format/FormatType.js';\n\n\n/**\n * {@link module:ol/source/Vector} sources use a function of this type to\n * load features.\n *\n * This function takes an {@link module:ol/extent~Extent} representing the area to be loaded,\n * a `{number}` representing the resolution (map units per pixel) and an\n * {@link module:ol/proj/Projection} for the projection  as\n * arguments. `this` within the function is bound to the\n * {@link module:ol/source/Vector} it's called from.\n *\n * The function is responsible for loading the features and adding them to the\n * source.\n * @typedef {function(this:module:ol/source/Vector, module:ol/extent~Extent, number,\n *                    module:ol/proj/Projection)} FeatureLoader\n * @api\n */\n\n\n/**\n * {@link module:ol/source/Vector} sources use a function of this type to\n * get the url to load features from.\n *\n * This function takes an {@link module:ol/extent~Extent} representing the area\n * to be loaded, a `{number}` representing the resolution (map units per pixel)\n * and an {@link module:ol/proj/Projection} for the projection  as\n * arguments and returns a `{string}` representing the URL.\n * @typedef {function(module:ol/extent~Extent, number, module:ol/proj/Projection): string} FeatureUrlFunction\n * @api\n */\n\n\n/**\n * @param {string|module:ol/featureloader~FeatureUrlFunction} url Feature URL service.\n * @param {module:ol/format/Feature} format Feature format.\n * @param {function(this:module:ol/VectorTile, Array.<module:ol/Feature>, module:ol/proj/Projection, module:ol/extent~Extent)|function(this:module:ol/source/Vector, Array.<module:ol/Feature>)} success\n *     Function called with the loaded features and optionally with the data\n *     projection. Called with the vector tile or source as `this`.\n * @param {function(this:module:ol/VectorTile)|function(this:module:ol/source/Vector)} failure\n *     Function called when loading failed. Called with the vector tile or\n *     source as `this`.\n * @return {module:ol/featureloader~FeatureLoader} The feature loader.\n */\nexport function loadFeaturesXhr(url, format, success, failure) {\n  return (\n    /**\n     * @param {module:ol/extent~Extent} extent Extent.\n     * @param {number} resolution Resolution.\n     * @param {module:ol/proj/Projection} projection Projection.\n     * @this {module:ol/source/Vector|module:ol/VectorTile}\n     */\n    function(extent, resolution, projection) {\n      const xhr = new XMLHttpRequest();\n      xhr.open('GET',\n        typeof url === 'function' ? url(extent, resolution, projection) : url,\n        true);\n      if (format.getType() == FormatType.ARRAY_BUFFER) {\n        xhr.responseType = 'arraybuffer';\n      }\n      /**\n       * @param {Event} event Event.\n       * @private\n       */\n      xhr.onload = function(event) {\n        // status will be 0 for file:// urls\n        if (!xhr.status || xhr.status >= 200 && xhr.status < 300) {\n          const type = format.getType();\n          /** @type {Document|Node|Object|string|undefined} */\n          let source;\n          if (type == FormatType.JSON || type == FormatType.TEXT) {\n            source = xhr.responseText;\n          } else if (type == FormatType.XML) {\n            source = xhr.responseXML;\n            if (!source) {\n              source = new DOMParser().parseFromString(xhr.responseText, 'application/xml');\n            }\n          } else if (type == FormatType.ARRAY_BUFFER) {\n            source = /** @type {ArrayBuffer} */ (xhr.response);\n          }\n          if (source) {\n            success.call(this, format.readFeatures(source,\n              {featureProjection: projection}),\n            format.readProjection(source), format.getLastExtent());\n          } else {\n            failure.call(this);\n          }\n        } else {\n          failure.call(this);\n        }\n      }.bind(this);\n      /**\n       * @private\n       */\n      xhr.onerror = function() {\n        failure.call(this);\n      }.bind(this);\n      xhr.send();\n    }\n  );\n}\n\n\n/**\n * Create an XHR feature loader for a `url` and `format`. The feature loader\n * loads features (with XHR), parses the features, and adds them to the\n * vector source.\n * @param {string|module:ol/featureloader~FeatureUrlFunction} url Feature URL service.\n * @param {module:ol/format/Feature} format Feature format.\n * @return {module:ol/featureloader~FeatureLoader} The feature loader.\n * @api\n */\nexport function xhr(url, format) {\n  return loadFeaturesXhr(url, format,\n    /**\n     * @param {Array.<module:ol/Feature>} features The loaded features.\n     * @param {module:ol/proj/Projection} dataProjection Data\n     * projection.\n     * @this {module:ol/source/Vector}\n     */\n    function(features, dataProjection) {\n      this.addFeatures(features);\n    }, /* FIXME handle error */ UNDEFINED);\n}\n","/**\n * @module ol/loadingstrategy\n */\n\n\n/**\n * Strategy function for loading all features with a single request.\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @return {Array.<module:ol/extent~Extent>} Extents.\n * @api\n */\nexport function all(extent, resolution) {\n  return [[-Infinity, -Infinity, Infinity, Infinity]];\n}\n\n\n/**\n * Strategy function for loading features based on the view's extent and\n * resolution.\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @return {Array.<module:ol/extent~Extent>} Extents.\n * @api\n */\nexport function bbox(extent, resolution) {\n  return [extent];\n}\n\n\n/**\n * Creates a strategy function for loading features based on a tile grid.\n * @param {module:ol/tilegrid/TileGrid} tileGrid Tile grid.\n * @return {function(module:ol/extent~Extent, number): Array.<module:ol/extent~Extent>} Loading strategy.\n * @api\n */\nexport function tile(tileGrid) {\n  return (\n    /**\n     * @param {module:ol/extent~Extent} extent Extent.\n     * @param {number} resolution Resolution.\n     * @return {Array.<module:ol/extent~Extent>} Extents.\n     */\n    function(extent, resolution) {\n      const z = tileGrid.getZForResolution(resolution);\n      const tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);\n      /** @type {Array.<module:ol/extent~Extent>} */\n      const extents = [];\n      /** @type {module:ol/tilecoord~TileCoord} */\n      const tileCoord = [z, 0, 0];\n      for (tileCoord[1] = tileRange.minX; tileCoord[1] <= tileRange.maxX; ++tileCoord[1]) {\n        for (tileCoord[2] = tileRange.minY; tileCoord[2] <= tileRange.maxY; ++tileCoord[2]) {\n          extents.push(tileGrid.getTileCoordExtent(tileCoord));\n        }\n      }\n      return extents;\n    }\n  );\n}\n","/**\n * @module ol/source/Source\n */\n\nimport {UNDEFINED} from '../functions.js';\nimport BaseObject from '../Object.js';\nimport {get as getProjection} from '../proj.js';\nimport SourceState from '../source/State.js';\n\n\n/**\n * A function that returns a string or an array of strings representing source\n * attributions.\n *\n * @typedef {function(module:ol/PluggableMap~FrameState): (string|Array.<string>)} Attribution\n */\n\n\n/**\n * A type that can be used to provide attribution information for data sources.\n *\n * It represents either\n * * a simple string (e.g. `'© Acme Inc.'`)\n * * an array of simple strings (e.g. `['© Acme Inc.', '© Bacme Inc.']`)\n * * a function that returns a string or array of strings (`{@link module:ol/source/Source~Attribution}`)\n *\n * @typedef {string|Array.<string>|module:ol/source/Source~Attribution} AttributionLike\n */\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/source/Source~AttributionLike} [attributions]\n * @property {module:ol/proj~ProjectionLike} projection\n * @property {module:ol/source/State} [state]\n * @property {boolean} [wrapX]\n */\n\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Base class for {@link module:ol/layer/Layer~Layer} sources.\n *\n * A generic `change` event is triggered when the state of the source changes.\n * @api\n */\nclass Source extends BaseObject {\n  /**\n   * @param {module:ol/source/Source~Options} options Source options.\n   */\n  constructor(options) {\n\n    super();\n\n    /**\n    * @private\n    * @type {module:ol/proj/Projection}\n    */\n    this.projection_ = getProjection(options.projection);\n\n    /**\n    * @private\n    * @type {?module:ol/source/Source~Attribution}\n    */\n    this.attributions_ = this.adaptAttributions_(options.attributions);\n\n    /**\n    * @private\n    * @type {module:ol/source/State}\n    */\n    this.state_ = options.state !== undefined ?\n      options.state : SourceState.READY;\n\n    /**\n    * @private\n    * @type {boolean}\n    */\n    this.wrapX_ = options.wrapX !== undefined ? options.wrapX : false;\n\n  }\n\n  /**\n  * Turns the attributions option into an attributions function.\n  * @param {module:ol/source/Source~AttributionLike|undefined} attributionLike The attribution option.\n  * @return {?module:ol/source/Source~Attribution} An attribution function (or null).\n  */\n  adaptAttributions_(attributionLike) {\n    if (!attributionLike) {\n      return null;\n    }\n    if (Array.isArray(attributionLike)) {\n      return function(frameState) {\n        return attributionLike;\n      };\n    }\n\n    if (typeof attributionLike === 'function') {\n      return attributionLike;\n    }\n\n    return function(frameState) {\n      return [attributionLike];\n    };\n  }\n\n  /**\n  * Get the attribution function for the source.\n  * @return {?module:ol/source/Source~Attribution} Attribution function.\n  */\n  getAttributions() {\n    return this.attributions_;\n  }\n\n  /**\n  * Get the projection of the source.\n  * @return {module:ol/proj/Projection} Projection.\n  * @api\n  */\n  getProjection() {\n    return this.projection_;\n  }\n\n  /**\n  * @abstract\n  * @return {Array.<number>|undefined} Resolutions.\n  */\n  getResolutions() {}\n\n  /**\n  * Get the state of the source, see {@link module:ol/source/State~State} for possible states.\n  * @return {module:ol/source/State} State.\n  * @api\n  */\n  getState() {\n    return this.state_;\n  }\n\n  /**\n  * @return {boolean|undefined} Wrap X.\n  */\n  getWrapX() {\n    return this.wrapX_;\n  }\n\n  /**\n  * Refreshes the source and finally dispatches a 'change' event.\n  * @api\n  */\n  refresh() {\n    this.changed();\n  }\n\n  /**\n  * Set the attributions of the source.\n  * @param {module:ol/source/Source~AttributionLike|undefined} attributions Attributions.\n  *     Can be passed as `string`, `Array<string>`, `{@link module:ol/source/Source~Attribution}`,\n  *     or `undefined`.\n  * @api\n  */\n  setAttributions(attributions) {\n    this.attributions_ = this.adaptAttributions_(attributions);\n    this.changed();\n  }\n\n  /**\n  * Set the state of the source.\n  * @param {module:ol/source/State} state State.\n  * @protected\n  */\n  setState(state) {\n    this.state_ = state;\n    this.changed();\n  }\n}\n\n/**\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {Object.<string, boolean>} skippedFeatureUids Skipped feature uids.\n * @param {function((module:ol/Feature|module:ol/render/Feature)): T} callback Feature callback.\n * @return {T|undefined} Callback result.\n * @template T\n */\nSource.prototype.forEachFeatureAtCoordinate = UNDEFINED;\n\n\nexport default Source;\n","/**\n * @module ol/source/VectorEventType\n */\n\n/**\n * @enum {string}\n */\nexport default {\n  /**\n   * Triggered when a feature is added to the source.\n   * @event ol/source/Vector~VectorSourceEvent#addfeature\n   * @api\n   */\n  ADDFEATURE: 'addfeature',\n\n  /**\n   * Triggered when a feature is updated.\n   * @event ol/source/Vector~VectorSourceEvent#changefeature\n   * @api\n   */\n  CHANGEFEATURE: 'changefeature',\n\n  /**\n   * Triggered when the clear method is called on the source.\n   * @event ol/source/Vector~VectorSourceEvent#clear\n   * @api\n   */\n  CLEAR: 'clear',\n\n  /**\n   * Triggered when a feature is removed from the source.\n   * See {@link module:ol/source/Vector#clear source.clear()} for exceptions.\n   * @event ol/source/Vector~VectorSourceEvent#removefeature\n   * @api\n   */\n  REMOVEFEATURE: 'removefeature'\n};\n","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n\ttypeof define === 'function' && define.amd ? define(factory) :\n\t(global.quickselect = factory());\n}(this, (function () { 'use strict';\n\nfunction quickselect(arr, k, left, right, compare) {\n    quickselectStep(arr, k, left || 0, right || (arr.length - 1), compare || defaultCompare);\n}\n\nfunction quickselectStep(arr, k, left, right, compare) {\n\n    while (right > left) {\n        if (right - left > 600) {\n            var n = right - left + 1;\n            var m = k - left + 1;\n            var z = Math.log(n);\n            var s = 0.5 * Math.exp(2 * z / 3);\n            var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);\n            var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));\n            var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));\n            quickselectStep(arr, k, newLeft, newRight, compare);\n        }\n\n        var t = arr[k];\n        var i = left;\n        var j = right;\n\n        swap(arr, left, k);\n        if (compare(arr[right], t) > 0) swap(arr, left, right);\n\n        while (i < j) {\n            swap(arr, i, j);\n            i++;\n            j--;\n            while (compare(arr[i], t) < 0) i++;\n            while (compare(arr[j], t) > 0) j--;\n        }\n\n        if (compare(arr[left], t) === 0) swap(arr, left, j);\n        else {\n            j++;\n            swap(arr, j, right);\n        }\n\n        if (j <= k) left = j + 1;\n        if (k <= j) right = j - 1;\n    }\n}\n\nfunction swap(arr, i, j) {\n    var tmp = arr[i];\n    arr[i] = arr[j];\n    arr[j] = tmp;\n}\n\nfunction defaultCompare(a, b) {\n    return a < b ? -1 : a > b ? 1 : 0;\n}\n\nreturn quickselect;\n\n})));\n","'use strict';\n\nmodule.exports = rbush;\nmodule.exports.default = rbush;\n\nvar quickselect = require('quickselect');\n\nfunction rbush(maxEntries, format) {\n    if (!(this instanceof rbush)) return new rbush(maxEntries, format);\n\n    // max entries in a node is 9 by default; min node fill is 40% for best performance\n    this._maxEntries = Math.max(4, maxEntries || 9);\n    this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));\n\n    if (format) {\n        this._initFormat(format);\n    }\n\n    this.clear();\n}\n\nrbush.prototype = {\n\n    all: function () {\n        return this._all(this.data, []);\n    },\n\n    search: function (bbox) {\n\n        var node = this.data,\n            result = [],\n            toBBox = this.toBBox;\n\n        if (!intersects(bbox, node)) return result;\n\n        var nodesToSearch = [],\n            i, len, child, childBBox;\n\n        while (node) {\n            for (i = 0, len = node.children.length; i < len; i++) {\n\n                child = node.children[i];\n                childBBox = node.leaf ? toBBox(child) : child;\n\n                if (intersects(bbox, childBBox)) {\n                    if (node.leaf) result.push(child);\n                    else if (contains(bbox, childBBox)) this._all(child, result);\n                    else nodesToSearch.push(child);\n                }\n            }\n            node = nodesToSearch.pop();\n        }\n\n        return result;\n    },\n\n    collides: function (bbox) {\n\n        var node = this.data,\n            toBBox = this.toBBox;\n\n        if (!intersects(bbox, node)) return false;\n\n        var nodesToSearch = [],\n            i, len, child, childBBox;\n\n        while (node) {\n            for (i = 0, len = node.children.length; i < len; i++) {\n\n                child = node.children[i];\n                childBBox = node.leaf ? toBBox(child) : child;\n\n                if (intersects(bbox, childBBox)) {\n                    if (node.leaf || contains(bbox, childBBox)) return true;\n                    nodesToSearch.push(child);\n                }\n            }\n            node = nodesToSearch.pop();\n        }\n\n        return false;\n    },\n\n    load: function (data) {\n        if (!(data && data.length)) return this;\n\n        if (data.length < this._minEntries) {\n            for (var i = 0, len = data.length; i < len; i++) {\n                this.insert(data[i]);\n            }\n            return this;\n        }\n\n        // recursively build the tree with the given data from scratch using OMT algorithm\n        var node = this._build(data.slice(), 0, data.length - 1, 0);\n\n        if (!this.data.children.length) {\n            // save as is if tree is empty\n            this.data = node;\n\n        } else if (this.data.height === node.height) {\n            // split root if trees have the same height\n            this._splitRoot(this.data, node);\n\n        } else {\n            if (this.data.height < node.height) {\n                // swap trees if inserted one is bigger\n                var tmpNode = this.data;\n                this.data = node;\n                node = tmpNode;\n            }\n\n            // insert the small tree into the large tree at appropriate level\n            this._insert(node, this.data.height - node.height - 1, true);\n        }\n\n        return this;\n    },\n\n    insert: function (item) {\n        if (item) this._insert(item, this.data.height - 1);\n        return this;\n    },\n\n    clear: function () {\n        this.data = createNode([]);\n        return this;\n    },\n\n    remove: function (item, equalsFn) {\n        if (!item) return this;\n\n        var node = this.data,\n            bbox = this.toBBox(item),\n            path = [],\n            indexes = [],\n            i, parent, index, goingUp;\n\n        // depth-first iterative tree traversal\n        while (node || path.length) {\n\n            if (!node) { // go up\n                node = path.pop();\n                parent = path[path.length - 1];\n                i = indexes.pop();\n                goingUp = true;\n            }\n\n            if (node.leaf) { // check current node\n                index = findItem(item, node.children, equalsFn);\n\n                if (index !== -1) {\n                    // item found, remove the item and condense tree upwards\n                    node.children.splice(index, 1);\n                    path.push(node);\n                    this._condense(path);\n                    return this;\n                }\n            }\n\n            if (!goingUp && !node.leaf && contains(node, bbox)) { // go down\n                path.push(node);\n                indexes.push(i);\n                i = 0;\n                parent = node;\n                node = node.children[0];\n\n            } else if (parent) { // go right\n                i++;\n                node = parent.children[i];\n                goingUp = false;\n\n            } else node = null; // nothing found\n        }\n\n        return this;\n    },\n\n    toBBox: function (item) { return item; },\n\n    compareMinX: compareNodeMinX,\n    compareMinY: compareNodeMinY,\n\n    toJSON: function () { return this.data; },\n\n    fromJSON: function (data) {\n        this.data = data;\n        return this;\n    },\n\n    _all: function (node, result) {\n        var nodesToSearch = [];\n        while (node) {\n            if (node.leaf) result.push.apply(result, node.children);\n            else nodesToSearch.push.apply(nodesToSearch, node.children);\n\n            node = nodesToSearch.pop();\n        }\n        return result;\n    },\n\n    _build: function (items, left, right, height) {\n\n        var N = right - left + 1,\n            M = this._maxEntries,\n            node;\n\n        if (N <= M) {\n            // reached leaf level; return leaf\n            node = createNode(items.slice(left, right + 1));\n            calcBBox(node, this.toBBox);\n            return node;\n        }\n\n        if (!height) {\n            // target height of the bulk-loaded tree\n            height = Math.ceil(Math.log(N) / Math.log(M));\n\n            // target number of root entries to maximize storage utilization\n            M = Math.ceil(N / Math.pow(M, height - 1));\n        }\n\n        node = createNode([]);\n        node.leaf = false;\n        node.height = height;\n\n        // split the items into M mostly square tiles\n\n        var N2 = Math.ceil(N / M),\n            N1 = N2 * Math.ceil(Math.sqrt(M)),\n            i, j, right2, right3;\n\n        multiSelect(items, left, right, N1, this.compareMinX);\n\n        for (i = left; i <= right; i += N1) {\n\n            right2 = Math.min(i + N1 - 1, right);\n\n            multiSelect(items, i, right2, N2, this.compareMinY);\n\n            for (j = i; j <= right2; j += N2) {\n\n                right3 = Math.min(j + N2 - 1, right2);\n\n                // pack each entry recursively\n                node.children.push(this._build(items, j, right3, height - 1));\n            }\n        }\n\n        calcBBox(node, this.toBBox);\n\n        return node;\n    },\n\n    _chooseSubtree: function (bbox, node, level, path) {\n\n        var i, len, child, targetNode, area, enlargement, minArea, minEnlargement;\n\n        while (true) {\n            path.push(node);\n\n            if (node.leaf || path.length - 1 === level) break;\n\n            minArea = minEnlargement = Infinity;\n\n            for (i = 0, len = node.children.length; i < len; i++) {\n                child = node.children[i];\n                area = bboxArea(child);\n                enlargement = enlargedArea(bbox, child) - area;\n\n                // choose entry with the least area enlargement\n                if (enlargement < minEnlargement) {\n                    minEnlargement = enlargement;\n                    minArea = area < minArea ? area : minArea;\n                    targetNode = child;\n\n                } else if (enlargement === minEnlargement) {\n                    // otherwise choose one with the smallest area\n                    if (area < minArea) {\n                        minArea = area;\n                        targetNode = child;\n                    }\n                }\n            }\n\n            node = targetNode || node.children[0];\n        }\n\n        return node;\n    },\n\n    _insert: function (item, level, isNode) {\n\n        var toBBox = this.toBBox,\n            bbox = isNode ? item : toBBox(item),\n            insertPath = [];\n\n        // find the best node for accommodating the item, saving all nodes along the path too\n        var node = this._chooseSubtree(bbox, this.data, level, insertPath);\n\n        // put the item into the node\n        node.children.push(item);\n        extend(node, bbox);\n\n        // split on node overflow; propagate upwards if necessary\n        while (level >= 0) {\n            if (insertPath[level].children.length > this._maxEntries) {\n                this._split(insertPath, level);\n                level--;\n            } else break;\n        }\n\n        // adjust bboxes along the insertion path\n        this._adjustParentBBoxes(bbox, insertPath, level);\n    },\n\n    // split overflowed node into two\n    _split: function (insertPath, level) {\n\n        var node = insertPath[level],\n            M = node.children.length,\n            m = this._minEntries;\n\n        this._chooseSplitAxis(node, m, M);\n\n        var splitIndex = this._chooseSplitIndex(node, m, M);\n\n        var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));\n        newNode.height = node.height;\n        newNode.leaf = node.leaf;\n\n        calcBBox(node, this.toBBox);\n        calcBBox(newNode, this.toBBox);\n\n        if (level) insertPath[level - 1].children.push(newNode);\n        else this._splitRoot(node, newNode);\n    },\n\n    _splitRoot: function (node, newNode) {\n        // split root node\n        this.data = createNode([node, newNode]);\n        this.data.height = node.height + 1;\n        this.data.leaf = false;\n        calcBBox(this.data, this.toBBox);\n    },\n\n    _chooseSplitIndex: function (node, m, M) {\n\n        var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index;\n\n        minOverlap = minArea = Infinity;\n\n        for (i = m; i <= M - m; i++) {\n            bbox1 = distBBox(node, 0, i, this.toBBox);\n            bbox2 = distBBox(node, i, M, this.toBBox);\n\n            overlap = intersectionArea(bbox1, bbox2);\n            area = bboxArea(bbox1) + bboxArea(bbox2);\n\n            // choose distribution with minimum overlap\n            if (overlap < minOverlap) {\n                minOverlap = overlap;\n                index = i;\n\n                minArea = area < minArea ? area : minArea;\n\n            } else if (overlap === minOverlap) {\n                // otherwise choose distribution with minimum area\n                if (area < minArea) {\n                    minArea = area;\n                    index = i;\n                }\n            }\n        }\n\n        return index;\n    },\n\n    // sorts node children by the best axis for split\n    _chooseSplitAxis: function (node, m, M) {\n\n        var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX,\n            compareMinY = node.leaf ? this.compareMinY : compareNodeMinY,\n            xMargin = this._allDistMargin(node, m, M, compareMinX),\n            yMargin = this._allDistMargin(node, m, M, compareMinY);\n\n        // if total distributions margin value is minimal for x, sort by minX,\n        // otherwise it's already sorted by minY\n        if (xMargin < yMargin) node.children.sort(compareMinX);\n    },\n\n    // total margin of all possible split distributions where each node is at least m full\n    _allDistMargin: function (node, m, M, compare) {\n\n        node.children.sort(compare);\n\n        var toBBox = this.toBBox,\n            leftBBox = distBBox(node, 0, m, toBBox),\n            rightBBox = distBBox(node, M - m, M, toBBox),\n            margin = bboxMargin(leftBBox) + bboxMargin(rightBBox),\n            i, child;\n\n        for (i = m; i < M - m; i++) {\n            child = node.children[i];\n            extend(leftBBox, node.leaf ? toBBox(child) : child);\n            margin += bboxMargin(leftBBox);\n        }\n\n        for (i = M - m - 1; i >= m; i--) {\n            child = node.children[i];\n            extend(rightBBox, node.leaf ? toBBox(child) : child);\n            margin += bboxMargin(rightBBox);\n        }\n\n        return margin;\n    },\n\n    _adjustParentBBoxes: function (bbox, path, level) {\n        // adjust bboxes along the given tree path\n        for (var i = level; i >= 0; i--) {\n            extend(path[i], bbox);\n        }\n    },\n\n    _condense: function (path) {\n        // go through the path, removing empty nodes and updating bboxes\n        for (var i = path.length - 1, siblings; i >= 0; i--) {\n            if (path[i].children.length === 0) {\n                if (i > 0) {\n                    siblings = path[i - 1].children;\n                    siblings.splice(siblings.indexOf(path[i]), 1);\n\n                } else this.clear();\n\n            } else calcBBox(path[i], this.toBBox);\n        }\n    },\n\n    _initFormat: function (format) {\n        // data format (minX, minY, maxX, maxY accessors)\n\n        // uses eval-type function compilation instead of just accepting a toBBox function\n        // because the algorithms are very sensitive to sorting functions performance,\n        // so they should be dead simple and without inner calls\n\n        var compareArr = ['return a', ' - b', ';'];\n\n        this.compareMinX = new Function('a', 'b', compareArr.join(format[0]));\n        this.compareMinY = new Function('a', 'b', compareArr.join(format[1]));\n\n        this.toBBox = new Function('a',\n            'return {minX: a' + format[0] +\n            ', minY: a' + format[1] +\n            ', maxX: a' + format[2] +\n            ', maxY: a' + format[3] + '};');\n    }\n};\n\nfunction findItem(item, items, equalsFn) {\n    if (!equalsFn) return items.indexOf(item);\n\n    for (var i = 0; i < items.length; i++) {\n        if (equalsFn(item, items[i])) return i;\n    }\n    return -1;\n}\n\n// calculate node's bbox from bboxes of its children\nfunction calcBBox(node, toBBox) {\n    distBBox(node, 0, node.children.length, toBBox, node);\n}\n\n// min bounding rectangle of node children from k to p-1\nfunction distBBox(node, k, p, toBBox, destNode) {\n    if (!destNode) destNode = createNode(null);\n    destNode.minX = Infinity;\n    destNode.minY = Infinity;\n    destNode.maxX = -Infinity;\n    destNode.maxY = -Infinity;\n\n    for (var i = k, child; i < p; i++) {\n        child = node.children[i];\n        extend(destNode, node.leaf ? toBBox(child) : child);\n    }\n\n    return destNode;\n}\n\nfunction extend(a, b) {\n    a.minX = Math.min(a.minX, b.minX);\n    a.minY = Math.min(a.minY, b.minY);\n    a.maxX = Math.max(a.maxX, b.maxX);\n    a.maxY = Math.max(a.maxY, b.maxY);\n    return a;\n}\n\nfunction compareNodeMinX(a, b) { return a.minX - b.minX; }\nfunction compareNodeMinY(a, b) { return a.minY - b.minY; }\n\nfunction bboxArea(a)   { return (a.maxX - a.minX) * (a.maxY - a.minY); }\nfunction bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); }\n\nfunction enlargedArea(a, b) {\n    return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *\n           (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY));\n}\n\nfunction intersectionArea(a, b) {\n    var minX = Math.max(a.minX, b.minX),\n        minY = Math.max(a.minY, b.minY),\n        maxX = Math.min(a.maxX, b.maxX),\n        maxY = Math.min(a.maxY, b.maxY);\n\n    return Math.max(0, maxX - minX) *\n           Math.max(0, maxY - minY);\n}\n\nfunction contains(a, b) {\n    return a.minX <= b.minX &&\n           a.minY <= b.minY &&\n           b.maxX <= a.maxX &&\n           b.maxY <= a.maxY;\n}\n\nfunction intersects(a, b) {\n    return b.minX <= a.maxX &&\n           b.minY <= a.maxY &&\n           b.maxX >= a.minX &&\n           b.maxY >= a.minY;\n}\n\nfunction createNode(children) {\n    return {\n        children: children,\n        height: 1,\n        leaf: true,\n        minX: Infinity,\n        minY: Infinity,\n        maxX: -Infinity,\n        maxY: -Infinity\n    };\n}\n\n// sort an array so that items come in groups of n unsorted items, with groups sorted between each other;\n// combines selection algorithm with binary divide & conquer approach\n\nfunction multiSelect(arr, left, right, n, compare) {\n    var stack = [left, right],\n        mid;\n\n    while (stack.length) {\n        right = stack.pop();\n        left = stack.pop();\n\n        if (right - left <= n) continue;\n\n        mid = left + Math.ceil((right - left) / n / 2) * n;\n        quickselect(arr, mid, left, right, compare);\n\n        stack.push(left, mid, mid, right);\n    }\n}\n","/**\n * @module ol/structs/RBush\n */\nimport {getUid} from '../util.js';\nimport rbush from 'rbush';\nimport {createOrUpdate, equals} from '../extent.js';\nimport {isEmpty} from '../obj.js';\n\n/**\n * @typedef {Object} Entry\n * @property {number} minX\n * @property {number} minY\n * @property {number} maxX\n * @property {number} maxY\n * @property {Object} [value]\n */\n\n/**\n * @classdesc\n * Wrapper around the RBush by Vladimir Agafonkin.\n * See https://github.com/mourner/rbush.\n *\n * @template T\n */\nclass RBush {\n  /**\n   * @param {number=} opt_maxEntries Max entries.\n   */\n  constructor(opt_maxEntries) {\n\n    /**\n     * @private\n     */\n    this.rbush_ = rbush(opt_maxEntries, undefined);\n\n    /**\n     * A mapping between the objects added to this rbush wrapper\n     * and the objects that are actually added to the internal rbush.\n     * @private\n     * @type {Object.<number, module:ol/structs/RBush~Entry>}\n     */\n    this.items_ = {};\n\n  }\n\n  /**\n   * Insert a value into the RBush.\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {T} value Value.\n   */\n  insert(extent, value) {\n    /** @type {module:ol/structs/RBush~Entry} */\n    const item = {\n      minX: extent[0],\n      minY: extent[1],\n      maxX: extent[2],\n      maxY: extent[3],\n      value: value\n    };\n\n    this.rbush_.insert(item);\n    this.items_[getUid(value)] = item;\n  }\n\n\n  /**\n   * Bulk-insert values into the RBush.\n   * @param {Array.<module:ol/extent~Extent>} extents Extents.\n   * @param {Array.<T>} values Values.\n   */\n  load(extents, values) {\n    const items = new Array(values.length);\n    for (let i = 0, l = values.length; i < l; i++) {\n      const extent = extents[i];\n      const value = values[i];\n\n      /** @type {module:ol/structs/RBush~Entry} */\n      const item = {\n        minX: extent[0],\n        minY: extent[1],\n        maxX: extent[2],\n        maxY: extent[3],\n        value: value\n      };\n      items[i] = item;\n      this.items_[getUid(value)] = item;\n    }\n    this.rbush_.load(items);\n  }\n\n\n  /**\n   * Remove a value from the RBush.\n   * @param {T} value Value.\n   * @return {boolean} Removed.\n   */\n  remove(value) {\n    const uid = getUid(value);\n\n    // get the object in which the value was wrapped when adding to the\n    // internal rbush. then use that object to do the removal.\n    const item = this.items_[uid];\n    delete this.items_[uid];\n    return this.rbush_.remove(item) !== null;\n  }\n\n\n  /**\n   * Update the extent of a value in the RBush.\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {T} value Value.\n   */\n  update(extent, value) {\n    const item = this.items_[getUid(value)];\n    const bbox = [item.minX, item.minY, item.maxX, item.maxY];\n    if (!equals(bbox, extent)) {\n      this.remove(value);\n      this.insert(extent, value);\n    }\n  }\n\n\n  /**\n   * Return all values in the RBush.\n   * @return {Array.<T>} All.\n   */\n  getAll() {\n    const items = this.rbush_.all();\n    return items.map(function(item) {\n      return item.value;\n    });\n  }\n\n\n  /**\n   * Return all values in the given extent.\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @return {Array.<T>} All in extent.\n   */\n  getInExtent(extent) {\n    /** @type {module:ol/structs/RBush~Entry} */\n    const bbox = {\n      minX: extent[0],\n      minY: extent[1],\n      maxX: extent[2],\n      maxY: extent[3]\n    };\n    const items = this.rbush_.search(bbox);\n    return items.map(function(item) {\n      return item.value;\n    });\n  }\n\n\n  /**\n   * Calls a callback function with each value in the tree.\n   * If the callback returns a truthy value, this value is returned without\n   * checking the rest of the tree.\n   * @param {function(this: S, T): *} callback Callback.\n   * @param {S=} opt_this The object to use as `this` in `callback`.\n   * @return {*} Callback return value.\n   * @template S\n   */\n  forEach(callback, opt_this) {\n    return this.forEach_(this.getAll(), callback, opt_this);\n  }\n\n\n  /**\n   * Calls a callback function with each value in the provided extent.\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {function(this: S, T): *} callback Callback.\n   * @param {S=} opt_this The object to use as `this` in `callback`.\n   * @return {*} Callback return value.\n   * @template S\n   */\n  forEachInExtent(extent, callback, opt_this) {\n    return this.forEach_(this.getInExtent(extent), callback, opt_this);\n  }\n\n\n  /**\n   * @param {Array.<T>} values Values.\n   * @param {function(this: S, T): *} callback Callback.\n   * @param {S=} opt_this The object to use as `this` in `callback`.\n   * @private\n   * @return {*} Callback return value.\n   * @template S\n   */\n  forEach_(values, callback, opt_this) {\n    let result;\n    for (let i = 0, l = values.length; i < l; i++) {\n      result = callback.call(opt_this, values[i]);\n      if (result) {\n        return result;\n      }\n    }\n    return result;\n  }\n\n\n  /**\n   * @return {boolean} Is empty.\n   */\n  isEmpty() {\n    return isEmpty(this.items_);\n  }\n\n\n  /**\n   * Remove all values from the RBush.\n   */\n  clear() {\n    this.rbush_.clear();\n    this.items_ = {};\n  }\n\n\n  /**\n   * @param {module:ol/extent~Extent=} opt_extent Extent.\n   * @return {module:ol/extent~Extent} Extent.\n   */\n  getExtent(opt_extent) {\n    // FIXME add getExtent() to rbush\n    const data = this.rbush_.data;\n    return createOrUpdate(data.minX, data.minY, data.maxX, data.maxY, opt_extent);\n  }\n\n\n  /**\n   * @param {module:ol/structs/RBush} rbush R-Tree.\n   */\n  concat(rbush) {\n    this.rbush_.load(rbush.rbush_.all());\n    for (const i in rbush.items_) {\n      this.items_[i | 0] = rbush.items_[i | 0];\n    }\n  }\n\n}\n\n\nexport default RBush;\n","/**\n * @module ol/source/Vector\n */\n\nimport {getUid} from '../util.js';\nimport Collection from '../Collection.js';\nimport CollectionEventType from '../CollectionEventType.js';\nimport ObjectEventType from '../ObjectEventType.js';\nimport {extend} from '../array.js';\nimport {assert} from '../asserts.js';\nimport {listen, unlistenByKey} from '../events.js';\nimport Event from '../events/Event.js';\nimport EventType from '../events/EventType.js';\nimport {containsExtent, equals} from '../extent.js';\nimport {xhr} from '../featureloader.js';\nimport {TRUE, UNDEFINED} from '../functions.js';\nimport {all as allStrategy} from '../loadingstrategy.js';\nimport {isEmpty, getValues} from '../obj.js';\nimport Source from '../source/Source.js';\nimport SourceState from '../source/State.js';\nimport VectorEventType from '../source/VectorEventType.js';\nimport RBush from '../structs/RBush.js';\n\n/**\n * A function that takes an {@link module:ol/extent~Extent} and a resolution as arguments, and\n * returns an array of {@link module:ol/extent~Extent} with the extents to load. Usually this\n * is one of the standard {@link module:ol/loadingstrategy} strategies.\n *\n * @typedef {function(module:ol/extent~Extent, number): Array.<module:ol/extent~Extent>} LoadingStrategy\n * @api\n */\n\n\n/**\n * @classdesc\n * Events emitted by {@link module:ol/source/Vector} instances are instances of this\n * type.\n */\nexport class VectorSourceEvent extends Event {\n\n  /**\n   * @param {string} type Type.\n   * @param {module:ol/Feature=} opt_feature Feature.\n   */\n  constructor(type, opt_feature) {\n\n    super(type);\n\n    /**\n     * The feature being added or removed.\n     * @type {module:ol/Feature|undefined}\n     * @api\n     */\n    this.feature = opt_feature;\n\n  }\n\n}\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/source/Source~AttributionLike} [attributions] Attributions.\n * @property {Array.<module:ol/Feature>|module:ol/Collection.<module:ol/Feature>} [features]\n * Features. If provided as {@link module:ol/Collection}, the features in the source\n * and the collection will stay in sync.\n * @property {module:ol/format/Feature} [format] The feature format used by the XHR\n * feature loader when `url` is set. Required if `url` is set, otherwise ignored.\n * @property {module:ol/featureloader~FeatureLoader} [loader]\n * The loader function used to load features, from a remote source for example.\n * If this is not set and `url` is set, the source will create and use an XHR\n * feature loader.\n *\n * Example:\n *\n * ```js\n * import {Vector} from 'ol/source';\n * import {GeoJSON} from 'ol/format';\n * import {bbox} from 'ol/loadingstrategy';\n *\n * var vectorSource = new Vector({\n *   format: new GeoJSON(),\n *   loader: function(extent, resolution, projection) {\n *      var proj = projection.getCode();\n *      var url = 'https://ahocevar.com/geoserver/wfs?service=WFS&' +\n *          'version=1.1.0&request=GetFeature&typename=osm:water_areas&' +\n *          'outputFormat=application/json&srsname=' + proj + '&' +\n *          'bbox=' + extent.join(',') + ',' + proj;\n *      var xhr = new XMLHttpRequest();\n *      xhr.open('GET', url);\n *      var onError = function() {\n *        vectorSource.removeLoadedExtent(extent);\n *      }\n *      xhr.onerror = onError;\n *      xhr.onload = function() {\n *        if (xhr.status == 200) {\n *          vectorSource.addFeatures(\n *              vectorSource.getFormat().readFeatures(xhr.responseText));\n *        } else {\n *          onError();\n *        }\n *      }\n *      xhr.send();\n *    },\n *    strategy: bbox\n *  });\n * ```\n * @property {boolean} [overlaps=true] This source may have overlapping geometries.\n * Setting this to `false` (e.g. for sources with polygons that represent administrative\n * boundaries or TopoJSON sources) allows the renderer to optimise fill and\n * stroke operations.\n * @property {module:ol/source/Vector~LoadingStrategy} [strategy] The loading strategy to use.\n * By default an {@link module:ol/loadingstrategy~all}\n * strategy is used, a one-off strategy which loads all features at once.\n * @property {string|module:ol/featureloader~FeatureUrlfunction} [url]\n * Setting this option instructs the source to load features using an XHR loader\n * (see {@link module:ol/featureloader~xhr}). Use a `string` and an\n * {@link module:ol/loadingstrategy~all} for a one-off download of all features from\n * the given URL. Use a {@link module:ol/featureloader~FeatureUrlfunction} to generate the url with\n * other loading strategies.\n * Requires `format` to be set as well.\n * When default XHR feature loader is provided, the features will\n * be transformed from the data projection to the view projection\n * during parsing. If your remote data source does not advertise its projection\n * properly, this transformation will be incorrect. For some formats, the\n * default projection (usually EPSG:4326) can be overridden by setting the\n * dataProjection constructor option on the format.\n * Note that if a source contains non-feature data, such as a GeoJSON geometry\n * or a KML NetworkLink, these will be ignored. Use a custom loader to load these.\n * @property {boolean} [useSpatialIndex=true]\n * By default, an RTree is used as spatial index. When features are removed and\n * added frequently, and the total number of features is low, setting this to\n * `false` may improve performance.\n *\n * Note that\n * {@link module:ol/source/Vector~VectorSource#getFeaturesInExtent},\n * {@link module:ol/source/Vector~VectorSource#getClosestFeatureToCoordinate} and\n * {@link module:ol/source/Vector~VectorSource#getExtent} cannot be used when `useSpatialIndex` is\n * set to `false`, and {@link module:ol/source/Vector~VectorSource#forEachFeatureInExtent} will loop\n * through all features.\n *\n * When set to `false`, the features will be maintained in an\n * {@link module:ol/Collection}, which can be retrieved through\n * {@link module:ol/source/Vector~VectorSource#getFeaturesCollection}.\n * @property {boolean} [wrapX=true] Wrap the world horizontally. For vector editing across the\n * -180° and 180° meridians to work properly, this should be set to `false`. The\n * resulting geometry coordinates will then exceed the world bounds.\n */\n\n\n/**\n * @classdesc\n * Provides a source of features for vector layers. Vector features provided\n * by this source are suitable for editing. See {@link module:ol/source/VectorTile~VectorTile} for\n * vector data that is optimized for rendering.\n *\n * @fires ol/source/Vector~VectorSourceEvent\n * @api\n */\nclass VectorSource extends Source {\n  /**\n   * @param {module:ol/source/Vector~Options=} opt_options Vector source options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options || {};\n\n    super({\n      attributions: options.attributions,\n      projection: undefined,\n      state: SourceState.READY,\n      wrapX: options.wrapX !== undefined ? options.wrapX : true\n    });\n\n    /**\n     * @private\n     * @type {module:ol/featureloader~FeatureLoader}\n     */\n    this.loader_ = UNDEFINED;\n\n    /**\n     * @private\n     * @type {module:ol/format/Feature|undefined}\n     */\n    this.format_ = options.format;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.overlaps_ = options.overlaps == undefined ? true : options.overlaps;\n\n    /**\n     * @private\n     * @type {string|module:ol/featureloader~FeatureUrlFunction|undefined}\n     */\n    this.url_ = options.url;\n\n    if (options.loader !== undefined) {\n      this.loader_ = options.loader;\n    } else if (this.url_ !== undefined) {\n      assert(this.format_, 7); // `format` must be set when `url` is set\n      // create a XHR feature loader for \"url\" and \"format\"\n      this.loader_ = xhr(this.url_, /** @type {module:ol/format/Feature} */ (this.format_));\n    }\n\n    /**\n     * @private\n     * @type {module:ol/source/Vector~LoadingStrategy}\n     */\n    this.strategy_ = options.strategy !== undefined ? options.strategy : allStrategy;\n\n    const useSpatialIndex =\n        options.useSpatialIndex !== undefined ? options.useSpatialIndex : true;\n\n    /**\n     * @private\n     * @type {module:ol/structs/RBush.<module:ol/Feature>}\n     */\n    this.featuresRtree_ = useSpatialIndex ? new RBush() : null;\n\n    /**\n     * @private\n     * @type {module:ol/structs/RBush.<{extent: module:ol/extent~Extent}>}\n     */\n    this.loadedExtentsRtree_ = new RBush();\n\n    /**\n     * @private\n     * @type {!Object.<string, module:ol/Feature>}\n     */\n    this.nullGeometryFeatures_ = {};\n\n    /**\n     * A lookup of features by id (the return from feature.getId()).\n     * @private\n     * @type {!Object.<string, module:ol/Feature>}\n     */\n    this.idIndex_ = {};\n\n    /**\n     * A lookup of features without id (keyed by getUid(feature)).\n     * @private\n     * @type {!Object.<string, module:ol/Feature>}\n     */\n    this.undefIdIndex_ = {};\n\n    /**\n     * @private\n     * @type {Object.<string, Array.<module:ol/events~EventsKey>>}\n     */\n    this.featureChangeKeys_ = {};\n\n    /**\n     * @private\n     * @type {module:ol/Collection.<module:ol/Feature>}\n     */\n    this.featuresCollection_ = null;\n\n    let collection, features;\n    if (options.features instanceof Collection) {\n      collection = options.features;\n      features = collection.getArray();\n    } else if (Array.isArray(options.features)) {\n      features = options.features;\n    }\n    if (!useSpatialIndex && collection === undefined) {\n      collection = new Collection(features);\n    }\n    if (features !== undefined) {\n      this.addFeaturesInternal(features);\n    }\n    if (collection !== undefined) {\n      this.bindFeaturesCollection_(collection);\n    }\n\n  }\n\n}\n\n\n/**\n * Add a single feature to the source.  If you want to add a batch of features\n * at once, call {@link module:ol/source/Vector~VectorSource#addFeatures #addFeatures()}\n * instead. A feature will not be added to the source if feature with\n * the same id is already there. The reason for this behavior is to avoid\n * feature duplication when using bbox or tile loading strategies.\n * @param {module:ol/Feature} feature Feature to add.\n * @api\n */\nVectorSource.prototype.addFeature = function(feature) {\n  this.addFeatureInternal(feature);\n  this.changed();\n};\n\n\n/**\n * Add a feature without firing a `change` event.\n * @param {module:ol/Feature} feature Feature.\n * @protected\n */\nVectorSource.prototype.addFeatureInternal = function(feature) {\n  const featureKey = getUid(feature).toString();\n\n  if (!this.addToIndex_(featureKey, feature)) {\n    return;\n  }\n\n  this.setupChangeEvents_(featureKey, feature);\n\n  const geometry = feature.getGeometry();\n  if (geometry) {\n    const extent = geometry.getExtent();\n    if (this.featuresRtree_) {\n      this.featuresRtree_.insert(extent, feature);\n    }\n  } else {\n    this.nullGeometryFeatures_[featureKey] = feature;\n  }\n\n  this.dispatchEvent(\n    new VectorSourceEvent(VectorEventType.ADDFEATURE, feature));\n};\n\n\n/**\n * @param {string} featureKey Unique identifier for the feature.\n * @param {module:ol/Feature} feature The feature.\n * @private\n */\nVectorSource.prototype.setupChangeEvents_ = function(featureKey, feature) {\n  this.featureChangeKeys_[featureKey] = [\n    listen(feature, EventType.CHANGE,\n      this.handleFeatureChange_, this),\n    listen(feature, ObjectEventType.PROPERTYCHANGE,\n      this.handleFeatureChange_, this)\n  ];\n};\n\n\n/**\n * @param {string} featureKey Unique identifier for the feature.\n * @param {module:ol/Feature} feature The feature.\n * @return {boolean} The feature is \"valid\", in the sense that it is also a\n *     candidate for insertion into the Rtree.\n * @private\n */\nVectorSource.prototype.addToIndex_ = function(featureKey, feature) {\n  let valid = true;\n  const id = feature.getId();\n  if (id !== undefined) {\n    if (!(id.toString() in this.idIndex_)) {\n      this.idIndex_[id.toString()] = feature;\n    } else {\n      valid = false;\n    }\n  } else {\n    assert(!(featureKey in this.undefIdIndex_),\n      30); // The passed `feature` was already added to the source\n    this.undefIdIndex_[featureKey] = feature;\n  }\n  return valid;\n};\n\n\n/**\n * Add a batch of features to the source.\n * @param {Array.<module:ol/Feature>} features Features to add.\n * @api\n */\nVectorSource.prototype.addFeatures = function(features) {\n  this.addFeaturesInternal(features);\n  this.changed();\n};\n\n\n/**\n * Add features without firing a `change` event.\n * @param {Array.<module:ol/Feature>} features Features.\n * @protected\n */\nVectorSource.prototype.addFeaturesInternal = function(features) {\n  const extents = [];\n  const newFeatures = [];\n  const geometryFeatures = [];\n\n  for (let i = 0, length = features.length; i < length; i++) {\n    const feature = features[i];\n    const featureKey = getUid(feature).toString();\n    if (this.addToIndex_(featureKey, feature)) {\n      newFeatures.push(feature);\n    }\n  }\n\n  for (let i = 0, length = newFeatures.length; i < length; i++) {\n    const feature = newFeatures[i];\n    const featureKey = getUid(feature).toString();\n    this.setupChangeEvents_(featureKey, feature);\n\n    const geometry = feature.getGeometry();\n    if (geometry) {\n      const extent = geometry.getExtent();\n      extents.push(extent);\n      geometryFeatures.push(feature);\n    } else {\n      this.nullGeometryFeatures_[featureKey] = feature;\n    }\n  }\n  if (this.featuresRtree_) {\n    this.featuresRtree_.load(extents, geometryFeatures);\n  }\n\n  for (let i = 0, length = newFeatures.length; i < length; i++) {\n    this.dispatchEvent(new VectorSourceEvent(VectorEventType.ADDFEATURE, newFeatures[i]));\n  }\n};\n\n\n/**\n * @param {!module:ol/Collection.<module:ol/Feature>} collection Collection.\n * @private\n */\nVectorSource.prototype.bindFeaturesCollection_ = function(collection) {\n  let modifyingCollection = false;\n  listen(this, VectorEventType.ADDFEATURE,\n    function(evt) {\n      if (!modifyingCollection) {\n        modifyingCollection = true;\n        collection.push(evt.feature);\n        modifyingCollection = false;\n      }\n    });\n  listen(this, VectorEventType.REMOVEFEATURE,\n    function(evt) {\n      if (!modifyingCollection) {\n        modifyingCollection = true;\n        collection.remove(evt.feature);\n        modifyingCollection = false;\n      }\n    });\n  listen(collection, CollectionEventType.ADD,\n    function(evt) {\n      if (!modifyingCollection) {\n        modifyingCollection = true;\n        this.addFeature(/** @type {module:ol/Feature} */ (evt.element));\n        modifyingCollection = false;\n      }\n    }, this);\n  listen(collection, CollectionEventType.REMOVE,\n    function(evt) {\n      if (!modifyingCollection) {\n        modifyingCollection = true;\n        this.removeFeature(/** @type {module:ol/Feature} */ (evt.element));\n        modifyingCollection = false;\n      }\n    }, this);\n  this.featuresCollection_ = collection;\n};\n\n\n/**\n * Remove all features from the source.\n * @param {boolean=} opt_fast Skip dispatching of {@link module:ol/source/Vector~VectorSourceEvent#removefeature} events.\n * @api\n */\nVectorSource.prototype.clear = function(opt_fast) {\n  if (opt_fast) {\n    for (const featureId in this.featureChangeKeys_) {\n      const keys = this.featureChangeKeys_[featureId];\n      keys.forEach(unlistenByKey);\n    }\n    if (!this.featuresCollection_) {\n      this.featureChangeKeys_ = {};\n      this.idIndex_ = {};\n      this.undefIdIndex_ = {};\n    }\n  } else {\n    if (this.featuresRtree_) {\n      this.featuresRtree_.forEach(this.removeFeatureInternal, this);\n      for (const id in this.nullGeometryFeatures_) {\n        this.removeFeatureInternal(this.nullGeometryFeatures_[id]);\n      }\n    }\n  }\n  if (this.featuresCollection_) {\n    this.featuresCollection_.clear();\n  }\n\n  if (this.featuresRtree_) {\n    this.featuresRtree_.clear();\n  }\n  this.loadedExtentsRtree_.clear();\n  this.nullGeometryFeatures_ = {};\n\n  const clearEvent = new VectorSourceEvent(VectorEventType.CLEAR);\n  this.dispatchEvent(clearEvent);\n  this.changed();\n};\n\n\n/**\n * Iterate through all features on the source, calling the provided callback\n * with each one.  If the callback returns any \"truthy\" value, iteration will\n * stop and the function will return the same value.\n * Note: this function only iterate through the feature that have a defined geometry.\n *\n * @param {function(module:ol/Feature): T} callback Called with each feature\n *     on the source.  Return a truthy value to stop iteration.\n * @return {T|undefined} The return value from the last call to the callback.\n * @template T\n * @api\n */\nVectorSource.prototype.forEachFeature = function(callback) {\n  if (this.featuresRtree_) {\n    return this.featuresRtree_.forEach(callback);\n  } else if (this.featuresCollection_) {\n    return this.featuresCollection_.forEach(callback);\n  }\n};\n\n\n/**\n * Iterate through all features whose geometries contain the provided\n * coordinate, calling the callback with each feature.  If the callback returns\n * a \"truthy\" value, iteration will stop and the function will return the same\n * value.\n *\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n * @param {function(module:ol/Feature): T} callback Called with each feature\n *     whose goemetry contains the provided coordinate.\n * @return {T|undefined} The return value from the last call to the callback.\n * @template T\n */\nVectorSource.prototype.forEachFeatureAtCoordinateDirect = function(coordinate, callback) {\n  const extent = [coordinate[0], coordinate[1], coordinate[0], coordinate[1]];\n  return this.forEachFeatureInExtent(extent, function(feature) {\n    const geometry = feature.getGeometry();\n    if (geometry.intersectsCoordinate(coordinate)) {\n      return callback(feature);\n    } else {\n      return undefined;\n    }\n  });\n};\n\n\n/**\n * Iterate through all features whose bounding box intersects the provided\n * extent (note that the feature's geometry may not intersect the extent),\n * calling the callback with each feature.  If the callback returns a \"truthy\"\n * value, iteration will stop and the function will return the same value.\n *\n * If you are interested in features whose geometry intersects an extent, call\n * the {@link module:ol/source/Vector~VectorSource#forEachFeatureIntersectingExtent #forEachFeatureIntersectingExtent()} method instead.\n *\n * When `useSpatialIndex` is set to false, this method will loop through all\n * features, equivalent to {@link module:ol/source/Vector~VectorSource#forEachFeature #forEachFeature()}.\n *\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {function(module:ol/Feature): T} callback Called with each feature\n *     whose bounding box intersects the provided extent.\n * @return {T|undefined} The return value from the last call to the callback.\n * @template T\n * @api\n */\nVectorSource.prototype.forEachFeatureInExtent = function(extent, callback) {\n  if (this.featuresRtree_) {\n    return this.featuresRtree_.forEachInExtent(extent, callback);\n  } else if (this.featuresCollection_) {\n    return this.featuresCollection_.forEach(callback);\n  }\n};\n\n\n/**\n * Iterate through all features whose geometry intersects the provided extent,\n * calling the callback with each feature.  If the callback returns a \"truthy\"\n * value, iteration will stop and the function will return the same value.\n *\n * If you only want to test for bounding box intersection, call the\n * {@link module:ol/source/Vector~VectorSource#forEachFeatureInExtent #forEachFeatureInExtent()} method instead.\n *\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {function(module:ol/Feature): T} callback Called with each feature\n *     whose geometry intersects the provided extent.\n * @return {T|undefined} The return value from the last call to the callback.\n * @template T\n * @api\n */\nVectorSource.prototype.forEachFeatureIntersectingExtent = function(extent, callback) {\n  return this.forEachFeatureInExtent(extent,\n    /**\n     * @param {module:ol/Feature} feature Feature.\n     * @return {T|undefined} The return value from the last call to the callback.\n     * @template T\n     */\n    function(feature) {\n      const geometry = feature.getGeometry();\n      if (geometry.intersectsExtent(extent)) {\n        const result = callback(feature);\n        if (result) {\n          return result;\n        }\n      }\n    });\n};\n\n\n/**\n * Get the features collection associated with this source. Will be `null`\n * unless the source was configured with `useSpatialIndex` set to `false`, or\n * with an {@link module:ol/Collection} as `features`.\n * @return {module:ol/Collection.<module:ol/Feature>} The collection of features.\n * @api\n */\nVectorSource.prototype.getFeaturesCollection = function() {\n  return this.featuresCollection_;\n};\n\n\n/**\n * Get all features on the source in random order.\n * @return {Array.<module:ol/Feature>} Features.\n * @api\n */\nVectorSource.prototype.getFeatures = function() {\n  let features;\n  if (this.featuresCollection_) {\n    features = this.featuresCollection_.getArray();\n  } else if (this.featuresRtree_) {\n    features = this.featuresRtree_.getAll();\n    if (!isEmpty(this.nullGeometryFeatures_)) {\n      extend(features, getValues(this.nullGeometryFeatures_));\n    }\n  }\n  return (\n    /** @type {Array.<module:ol/Feature>} */ (features)\n  );\n};\n\n\n/**\n * Get all features whose geometry intersects the provided coordinate.\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n * @return {Array.<module:ol/Feature>} Features.\n * @api\n */\nVectorSource.prototype.getFeaturesAtCoordinate = function(coordinate) {\n  const features = [];\n  this.forEachFeatureAtCoordinateDirect(coordinate, function(feature) {\n    features.push(feature);\n  });\n  return features;\n};\n\n\n/**\n * Get all features in the provided extent.  Note that this returns an array of\n * all features intersecting the given extent in random order (so it may include\n * features whose geometries do not intersect the extent).\n *\n * This method is not available when the source is configured with\n * `useSpatialIndex` set to `false`.\n * @param {module:ol/extent~Extent} extent Extent.\n * @return {Array.<module:ol/Feature>} Features.\n * @api\n */\nVectorSource.prototype.getFeaturesInExtent = function(extent) {\n  return this.featuresRtree_.getInExtent(extent);\n};\n\n\n/**\n * Get the closest feature to the provided coordinate.\n *\n * This method is not available when the source is configured with\n * `useSpatialIndex` set to `false`.\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n * @param {function(module:ol/Feature):boolean=} opt_filter Feature filter function.\n *     The filter function will receive one argument, the {@link module:ol/Feature feature}\n *     and it should return a boolean value. By default, no filtering is made.\n * @return {module:ol/Feature} Closest feature.\n * @api\n */\nVectorSource.prototype.getClosestFeatureToCoordinate = function(coordinate, opt_filter) {\n  // Find the closest feature using branch and bound.  We start searching an\n  // infinite extent, and find the distance from the first feature found.  This\n  // becomes the closest feature.  We then compute a smaller extent which any\n  // closer feature must intersect.  We continue searching with this smaller\n  // extent, trying to find a closer feature.  Every time we find a closer\n  // feature, we update the extent being searched so that any even closer\n  // feature must intersect it.  We continue until we run out of features.\n  const x = coordinate[0];\n  const y = coordinate[1];\n  let closestFeature = null;\n  const closestPoint = [NaN, NaN];\n  let minSquaredDistance = Infinity;\n  const extent = [-Infinity, -Infinity, Infinity, Infinity];\n  const filter = opt_filter ? opt_filter : TRUE;\n  this.featuresRtree_.forEachInExtent(extent,\n    /**\n     * @param {module:ol/Feature} feature Feature.\n     */\n    function(feature) {\n      if (filter(feature)) {\n        const geometry = feature.getGeometry();\n        const previousMinSquaredDistance = minSquaredDistance;\n        minSquaredDistance = geometry.closestPointXY(\n          x, y, closestPoint, minSquaredDistance);\n        if (minSquaredDistance < previousMinSquaredDistance) {\n          closestFeature = feature;\n          // This is sneaky.  Reduce the extent that it is currently being\n          // searched while the R-Tree traversal using this same extent object\n          // is still in progress.  This is safe because the new extent is\n          // strictly contained by the old extent.\n          const minDistance = Math.sqrt(minSquaredDistance);\n          extent[0] = x - minDistance;\n          extent[1] = y - minDistance;\n          extent[2] = x + minDistance;\n          extent[3] = y + minDistance;\n        }\n      }\n    });\n  return closestFeature;\n};\n\n\n/**\n * Get the extent of the features currently in the source.\n *\n * This method is not available when the source is configured with\n * `useSpatialIndex` set to `false`.\n * @param {module:ol/extent~Extent=} opt_extent Destination extent. If provided, no new extent\n *     will be created. Instead, that extent's coordinates will be overwritten.\n * @return {module:ol/extent~Extent} Extent.\n * @api\n */\nVectorSource.prototype.getExtent = function(opt_extent) {\n  return this.featuresRtree_.getExtent(opt_extent);\n};\n\n\n/**\n * Get a feature by its identifier (the value returned by feature.getId()).\n * Note that the index treats string and numeric identifiers as the same.  So\n * `source.getFeatureById(2)` will return a feature with id `'2'` or `2`.\n *\n * @param {string|number} id Feature identifier.\n * @return {module:ol/Feature} The feature (or `null` if not found).\n * @api\n */\nVectorSource.prototype.getFeatureById = function(id) {\n  const feature = this.idIndex_[id.toString()];\n  return feature !== undefined ? feature : null;\n};\n\n\n/**\n * Get the format associated with this source.\n *\n * @return {module:ol/format/Feature|undefined} The feature format.\n * @api\n */\nVectorSource.prototype.getFormat = function() {\n  return this.format_;\n};\n\n\n/**\n * @return {boolean} The source can have overlapping geometries.\n */\nVectorSource.prototype.getOverlaps = function() {\n  return this.overlaps_;\n};\n\n\n/**\n * @override\n */\nVectorSource.prototype.getResolutions = function() {};\n\n\n/**\n * Get the url associated with this source.\n *\n * @return {string|module:ol/featureloader~FeatureUrlFunction|undefined} The url.\n * @api\n */\nVectorSource.prototype.getUrl = function() {\n  return this.url_;\n};\n\n\n/**\n * @param {module:ol/events/Event} event Event.\n * @private\n */\nVectorSource.prototype.handleFeatureChange_ = function(event) {\n  const feature = /** @type {module:ol/Feature} */ (event.target);\n  const featureKey = getUid(feature).toString();\n  const geometry = feature.getGeometry();\n  if (!geometry) {\n    if (!(featureKey in this.nullGeometryFeatures_)) {\n      if (this.featuresRtree_) {\n        this.featuresRtree_.remove(feature);\n      }\n      this.nullGeometryFeatures_[featureKey] = feature;\n    }\n  } else {\n    const extent = geometry.getExtent();\n    if (featureKey in this.nullGeometryFeatures_) {\n      delete this.nullGeometryFeatures_[featureKey];\n      if (this.featuresRtree_) {\n        this.featuresRtree_.insert(extent, feature);\n      }\n    } else {\n      if (this.featuresRtree_) {\n        this.featuresRtree_.update(extent, feature);\n      }\n    }\n  }\n  const id = feature.getId();\n  if (id !== undefined) {\n    const sid = id.toString();\n    if (featureKey in this.undefIdIndex_) {\n      delete this.undefIdIndex_[featureKey];\n      this.idIndex_[sid] = feature;\n    } else {\n      if (this.idIndex_[sid] !== feature) {\n        this.removeFromIdIndex_(feature);\n        this.idIndex_[sid] = feature;\n      }\n    }\n  } else {\n    if (!(featureKey in this.undefIdIndex_)) {\n      this.removeFromIdIndex_(feature);\n      this.undefIdIndex_[featureKey] = feature;\n    }\n  }\n  this.changed();\n  this.dispatchEvent(new VectorSourceEvent(\n    VectorEventType.CHANGEFEATURE, feature));\n};\n\n/**\n * Returns true if the feature is contained within the source.\n * @param {module:ol/Feature} feature Feature.\n * @return {boolean} Has feature.\n * @api\n */\nVectorSource.prototype.hasFeature = function(feature) {\n  const id = feature.getId();\n  if (id !== undefined) {\n    return id in this.idIndex_;\n  } else {\n    const featureKey = getUid(feature).toString();\n    return featureKey in this.undefIdIndex_;\n  }\n};\n\n/**\n * @return {boolean} Is empty.\n */\nVectorSource.prototype.isEmpty = function() {\n  return this.featuresRtree_.isEmpty() && isEmpty(this.nullGeometryFeatures_);\n};\n\n\n/**\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @param {module:ol/proj/Projection} projection Projection.\n */\nVectorSource.prototype.loadFeatures = function(extent, resolution, projection) {\n  const loadedExtentsRtree = this.loadedExtentsRtree_;\n  const extentsToLoad = this.strategy_(extent, resolution);\n  for (let i = 0, ii = extentsToLoad.length; i < ii; ++i) {\n    const extentToLoad = extentsToLoad[i];\n    const alreadyLoaded = loadedExtentsRtree.forEachInExtent(extentToLoad,\n      /**\n       * @param {{extent: module:ol/extent~Extent}} object Object.\n       * @return {boolean} Contains.\n       */\n      function(object) {\n        return containsExtent(object.extent, extentToLoad);\n      });\n    if (!alreadyLoaded) {\n      this.loader_.call(this, extentToLoad, resolution, projection);\n      loadedExtentsRtree.insert(extentToLoad, {extent: extentToLoad.slice()});\n    }\n  }\n};\n\n\n/**\n * Remove an extent from the list of loaded extents.\n * @param {module:ol/extent~Extent} extent Extent.\n * @api\n */\nVectorSource.prototype.removeLoadedExtent = function(extent) {\n  const loadedExtentsRtree = this.loadedExtentsRtree_;\n  let obj;\n  loadedExtentsRtree.forEachInExtent(extent, function(object) {\n    if (equals(object.extent, extent)) {\n      obj = object;\n      return true;\n    }\n  });\n  if (obj) {\n    loadedExtentsRtree.remove(obj);\n  }\n};\n\n\n/**\n * Remove a single feature from the source.  If you want to remove all features\n * at once, use the {@link module:ol/source/Vector~VectorSource#clear #clear()} method\n * instead.\n * @param {module:ol/Feature} feature Feature to remove.\n * @api\n */\nVectorSource.prototype.removeFeature = function(feature) {\n  const featureKey = getUid(feature).toString();\n  if (featureKey in this.nullGeometryFeatures_) {\n    delete this.nullGeometryFeatures_[featureKey];\n  } else {\n    if (this.featuresRtree_) {\n      this.featuresRtree_.remove(feature);\n    }\n  }\n  this.removeFeatureInternal(feature);\n  this.changed();\n};\n\n\n/**\n * Remove feature without firing a `change` event.\n * @param {module:ol/Feature} feature Feature.\n * @protected\n */\nVectorSource.prototype.removeFeatureInternal = function(feature) {\n  const featureKey = getUid(feature).toString();\n  this.featureChangeKeys_[featureKey].forEach(unlistenByKey);\n  delete this.featureChangeKeys_[featureKey];\n  const id = feature.getId();\n  if (id !== undefined) {\n    delete this.idIndex_[id.toString()];\n  } else {\n    delete this.undefIdIndex_[featureKey];\n  }\n  this.dispatchEvent(new VectorSourceEvent(\n    VectorEventType.REMOVEFEATURE, feature));\n};\n\n\n/**\n * Remove a feature from the id index.  Called internally when the feature id\n * may have changed.\n * @param {module:ol/Feature} feature The feature.\n * @return {boolean} Removed the feature from the index.\n * @private\n */\nVectorSource.prototype.removeFromIdIndex_ = function(feature) {\n  let removed = false;\n  for (const id in this.idIndex_) {\n    if (this.idIndex_[id] === feature) {\n      delete this.idIndex_[id];\n      removed = true;\n      break;\n    }\n  }\n  return removed;\n};\n\n\n/**\n * Set the new loader of the source. The next loadFeatures call will use the\n * new loader.\n * @param {module:ol/featureloader~FeatureLoader} loader The loader to set.\n * @api\n */\nVectorSource.prototype.setLoader = function(loader) {\n  this.loader_ = loader;\n};\n\nexport default VectorSource;\n","/**\n * @module ol/interaction/Draw\n */\nimport EventType from '../events/EventType.js';\nimport Feature from '../Feature.js';\nimport MapBrowserEventType from '../MapBrowserEventType.js';\nimport MapBrowserPointerEvent from '../MapBrowserPointerEvent.js';\nimport {getChangeEventType} from '../Object.js';\nimport {squaredDistance as squaredCoordinateDistance} from '../coordinate.js';\nimport {listen} from '../events.js';\nimport Event from '../events/Event.js';\nimport {noModifierKeys, always, shiftKeyOnly} from '../events/condition.js';\nimport {boundingExtent, getBottomLeft, getBottomRight, getTopLeft, getTopRight} from '../extent.js';\nimport {TRUE, FALSE} from '../functions.js';\nimport Circle from '../geom/Circle.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport LineString from '../geom/LineString.js';\nimport MultiLineString from '../geom/MultiLineString.js';\nimport MultiPoint from '../geom/MultiPoint.js';\nimport MultiPolygon from '../geom/MultiPolygon.js';\nimport {POINTER_TYPE} from '../pointer/MouseSource.js';\nimport Point from '../geom/Point.js';\nimport Polygon, {fromCircle, makeRegular} from '../geom/Polygon.js';\nimport PointerInteraction, {handleEvent as handlePointerEvent} from '../interaction/Pointer.js';\nimport InteractionProperty from '../interaction/Property.js';\nimport VectorLayer from '../layer/Vector.js';\nimport VectorSource from '../source/Vector.js';\nimport {createEditingStyle} from '../style/Style.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/geom/GeometryType} type Geometry type of\n * the geometries being drawn with this instance.\n * @property {number} [clickTolerance=6] The maximum distance in pixels between\n * \"down\" and \"up\" for a \"up\" event to be considered a \"click\" event and\n * actually add a point/vertex to the geometry being drawn.  The default of `6`\n * was chosen for the draw interaction to behave correctly on mouse as well as\n * on touch devices.\n * @property {module:ol/Collection.<module:ol/Feature>} [features]\n * Destination collection for the drawn features.\n * @property {module:ol/source/Vector} [source] Destination source for\n * the drawn features.\n * @property {number} [dragVertexDelay=500] Delay in milliseconds after pointerdown\n * before the current vertex can be dragged to its exact position.\n * @property {number} [snapTolerance=12] Pixel distance for snapping to the\n * drawing finish.\n * @property {boolean} [stopClick=false] Stop click, singleclick, and\n * doubleclick events from firing during drawing.\n * @property {number} [maxPoints] The number of points that can be drawn before\n * a polygon ring or line string is finished. By default there is no\n * restriction.\n * @property {number} [minPoints] The number of points that must be drawn\n * before a polygon ring or line string can be finished. Default is `3` for\n * polygon rings and `2` for line strings.\n * @property {module:ol/events/condition~Condition} [finishCondition] A function\n * that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether the drawing can be finished.\n * @property {module:ol/style/Style|Array.<module:ol/style/Style>|module:ol/style/Style~StyleFunction} [style]\n * Style for sketch features.\n * @property {module:ol/interaction/Draw~GeometryFunction} [geometryFunction]\n * Function that is called when a geometry's coordinates are updated.\n * @property {string} [geometryName] Geometry name to use for features created\n * by the draw interaction.\n * @property {module:ol/events/condition~Condition} [condition] A function that\n * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled.\n * By default {@link module:ol/events/condition~noModifierKeys}, i.e. a click,\n * adds a vertex or deactivates freehand drawing.\n * @property {boolean} [freehand=false] Operate in freehand mode for lines,\n * polygons, and circles.  This makes the interaction always operate in freehand\n * mode and takes precedence over any `freehandCondition` option.\n * @property {module:ol/events/condition~Condition} [freehandCondition]\n * Condition that activates freehand drawing for lines and polygons. This\n * function takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and\n * returns a boolean to indicate whether that event should be handled. The\n * default is {@link module:ol/events/condition~shiftKeyOnly}, meaning that the\n * Shift key activates freehand drawing.\n * @property {boolean} [wrapX=false] Wrap the world horizontally on the sketch\n * overlay.\n */\n\n\n/**\n * Function that takes an array of coordinates and an optional existing geometry as\n * arguments, and returns a geometry. The optional existing geometry is the\n * geometry that is returned when the function is called without a second\n * argument.\n * @typedef {function(!Array.<module:ol/coordinate~Coordinate>, module:ol/geom/SimpleGeometry=):\n *     module:ol/geom/SimpleGeometry} GeometryFunction\n */\n\n\n/**\n * Draw mode.  This collapses multi-part geometry types with their single-part\n * cousins.\n * @enum {string}\n */\nconst Mode = {\n  POINT: 'Point',\n  LINE_STRING: 'LineString',\n  POLYGON: 'Polygon',\n  CIRCLE: 'Circle'\n};\n\n\n/**\n * @enum {string}\n */\nconst DrawEventType = {\n  /**\n   * Triggered upon feature draw start\n   * @event module:ol/interaction/Draw~DrawEvent#drawstart\n   * @api\n   */\n  DRAWSTART: 'drawstart',\n  /**\n   * Triggered upon feature draw end\n   * @event module:ol/interaction/Draw~DrawEvent#drawend\n   * @api\n   */\n  DRAWEND: 'drawend'\n};\n\n\n/**\n * @classdesc\n * Events emitted by {@link module:ol/interaction/Draw~Draw} instances are\n * instances of this type.\n */\nclass DrawEvent extends Event {\n  /**\n   * @param {module:ol/interaction/Draw~DrawEventType} type Type.\n   * @param {module:ol/Feature} feature The feature drawn.\n   */\n  constructor(type, feature) {\n\n    super(type);\n\n    /**\n     * The feature being drawn.\n     * @type {module:ol/Feature}\n     * @api\n     */\n    this.feature = feature;\n\n  }\n\n}\n\n\n/**\n * @classdesc\n * Interaction for drawing feature geometries.\n *\n * @fires module:ol/interaction/Draw~DrawEvent\n * @api\n */\nclass Draw extends PointerInteraction {\n  /**\n   * @param {module:ol/interaction/Draw~Options} options Options.\n   */\n  constructor(options) {\n\n    super({\n      handleDownEvent: handleDownEvent,\n      handleEvent: handleEvent,\n      handleUpEvent: handleUpEvent,\n      stopDown: FALSE\n    });\n\n    /**\n     * @type {boolean}\n     * @private\n     */\n    this.shouldHandle_ = false;\n\n    /**\n     * @type {module:ol/pixel~Pixel}\n     * @private\n     */\n    this.downPx_ = null;\n\n    /**\n     * @type {number|undefined}\n     * @private\n     */\n    this.downTimeout_;\n\n    /**\n     * @type {number|undefined}\n     * @private\n     */\n    this.lastDragTime_;\n\n    /**\n     * @type {boolean}\n     * @private\n     */\n    this.freehand_ = false;\n\n    /**\n     * Target source for drawn features.\n     * @type {module:ol/source/Vector}\n     * @private\n     */\n    this.source_ = options.source ? options.source : null;\n\n    /**\n     * Target collection for drawn features.\n     * @type {module:ol/Collection.<module:ol/Feature>}\n     * @private\n     */\n    this.features_ = options.features ? options.features : null;\n\n    /**\n     * Pixel distance for snapping.\n     * @type {number}\n     * @private\n     */\n    this.snapTolerance_ = options.snapTolerance ? options.snapTolerance : 12;\n\n    /**\n     * Geometry type.\n     * @type {module:ol/geom/GeometryType}\n     * @private\n     */\n    this.type_ = /** @type {module:ol/geom/GeometryType} */ (options.type);\n\n    /**\n     * Drawing mode (derived from geometry type.\n     * @type {module:ol/interaction/Draw~Mode}\n     * @private\n     */\n    this.mode_ = getMode(this.type_);\n\n    /**\n     * Stop click, singleclick, and doubleclick events from firing during drawing.\n     * Default is `false`.\n     * @type {boolean}\n     * @private\n     */\n    this.stopClick_ = !!options.stopClick;\n\n    /**\n     * The number of points that must be drawn before a polygon ring or line\n     * string can be finished.  The default is 3 for polygon rings and 2 for\n     * line strings.\n     * @type {number}\n     * @private\n     */\n    this.minPoints_ = options.minPoints ?\n      options.minPoints :\n      (this.mode_ === Mode.POLYGON ? 3 : 2);\n\n    /**\n     * The number of points that can be drawn before a polygon ring or line string\n     * is finished. The default is no restriction.\n     * @type {number}\n     * @private\n     */\n    this.maxPoints_ = options.maxPoints ? options.maxPoints : Infinity;\n\n    /**\n     * A function to decide if a potential finish coordinate is permissible\n     * @private\n     * @type {module:ol/events/condition~Condition}\n     */\n    this.finishCondition_ = options.finishCondition ? options.finishCondition : TRUE;\n\n    let geometryFunction = options.geometryFunction;\n    if (!geometryFunction) {\n      if (this.type_ === GeometryType.CIRCLE) {\n        /**\n         * @param {!Array.<module:ol/coordinate~Coordinate>} coordinates\n         *     The coordinates.\n         * @param {module:ol/geom/SimpleGeometry=} opt_geometry Optional geometry.\n         * @return {module:ol/geom/SimpleGeometry} A geometry.\n         */\n        geometryFunction = function(coordinates, opt_geometry) {\n          const circle = opt_geometry ? /** @type {module:ol/geom/Circle} */ (opt_geometry) :\n            new Circle([NaN, NaN]);\n          const squaredLength = squaredCoordinateDistance(\n            coordinates[0], coordinates[1]);\n          circle.setCenterAndRadius(coordinates[0], Math.sqrt(squaredLength));\n          return circle;\n        };\n      } else {\n        let Constructor;\n        const mode = this.mode_;\n        if (mode === Mode.POINT) {\n          Constructor = Point;\n        } else if (mode === Mode.LINE_STRING) {\n          Constructor = LineString;\n        } else if (mode === Mode.POLYGON) {\n          Constructor = Polygon;\n        }\n        /**\n         * @param {!Array.<module:ol/coordinate~Coordinate>} coordinates\n         *     The coordinates.\n         * @param {module:ol/geom/SimpleGeometry=} opt_geometry Optional geometry.\n         * @return {module:ol/geom/SimpleGeometry} A geometry.\n         */\n        geometryFunction = function(coordinates, opt_geometry) {\n          let geometry = opt_geometry;\n          if (geometry) {\n            if (mode === Mode.POLYGON) {\n              if (coordinates[0].length) {\n                // Add a closing coordinate to match the first\n                geometry.setCoordinates([coordinates[0].concat([coordinates[0][0]])]);\n              } else {\n                geometry.setCoordinates([]);\n              }\n            } else {\n              geometry.setCoordinates(coordinates);\n            }\n          } else {\n            geometry = new Constructor(coordinates);\n          }\n          return geometry;\n        };\n      }\n    }\n\n    /**\n     * @type {module:ol/interaction/Draw~GeometryFunction}\n     * @private\n     */\n    this.geometryFunction_ = geometryFunction;\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.dragVertexDelay_ = options.dragVertexDelay !== undefined ? options.dragVertexDelay : 500;\n\n    /**\n     * Finish coordinate for the feature (first point for polygons, last point for\n     * linestrings).\n     * @type {module:ol/coordinate~Coordinate}\n     * @private\n     */\n    this.finishCoordinate_ = null;\n\n    /**\n     * Sketch feature.\n     * @type {module:ol/Feature}\n     * @private\n     */\n    this.sketchFeature_ = null;\n\n    /**\n     * Sketch point.\n     * @type {module:ol/Feature}\n     * @private\n     */\n    this.sketchPoint_ = null;\n\n    /**\n     * Sketch coordinates. Used when drawing a line or polygon.\n     * @type {module:ol/coordinate~Coordinate|Array.<module:ol/coordinate~Coordinate>|Array.<Array.<module:ol/coordinate~Coordinate>>}\n     * @private\n     */\n    this.sketchCoords_ = null;\n\n    /**\n     * Sketch line. Used when drawing polygon.\n     * @type {module:ol/Feature}\n     * @private\n     */\n    this.sketchLine_ = null;\n\n    /**\n     * Sketch line coordinates. Used when drawing a polygon or circle.\n     * @type {Array.<module:ol/coordinate~Coordinate>}\n     * @private\n     */\n    this.sketchLineCoords_ = null;\n\n    /**\n     * Squared tolerance for handling up events.  If the squared distance\n     * between a down and up event is greater than this tolerance, up events\n     * will not be handled.\n     * @type {number}\n     * @private\n     */\n    this.squaredClickTolerance_ = options.clickTolerance ?\n      options.clickTolerance * options.clickTolerance : 36;\n\n    /**\n     * Draw overlay where our sketch features are drawn.\n     * @type {module:ol/layer/Vector}\n     * @private\n     */\n    this.overlay_ = new VectorLayer({\n      source: new VectorSource({\n        useSpatialIndex: false,\n        wrapX: options.wrapX ? options.wrapX : false\n      }),\n      style: options.style ? options.style :\n        getDefaultStyleFunction(),\n      updateWhileInteracting: true\n    });\n\n    /**\n     * Name of the geometry attribute for newly created features.\n     * @type {string|undefined}\n     * @private\n     */\n    this.geometryName_ = options.geometryName;\n\n    /**\n     * @private\n     * @type {module:ol/events/condition~Condition}\n     */\n    this.condition_ = options.condition ? options.condition : noModifierKeys;\n\n    /**\n     * @private\n     * @type {module:ol/events/condition~Condition}\n     */\n    this.freehandCondition_;\n    if (options.freehand) {\n      this.freehandCondition_ = always;\n    } else {\n      this.freehandCondition_ = options.freehandCondition ?\n        options.freehandCondition : shiftKeyOnly;\n    }\n\n    listen(this,\n      getChangeEventType(InteractionProperty.ACTIVE),\n      this.updateState_, this);\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setMap(map) {\n    super.setMap(map);\n    this.updateState_();\n  }\n\n  /**\n   * Handle move events.\n   * @param {module:ol/MapBrowserEvent} event A move event.\n   * @return {boolean} Pass the event to other interactions.\n   * @private\n   */\n  handlePointerMove_(event) {\n    if (this.downPx_ &&\n        ((!this.freehand_ && this.shouldHandle_) ||\n        (this.freehand_ && !this.shouldHandle_))) {\n      const downPx = this.downPx_;\n      const clickPx = event.pixel;\n      const dx = downPx[0] - clickPx[0];\n      const dy = downPx[1] - clickPx[1];\n      const squaredDistance = dx * dx + dy * dy;\n      this.shouldHandle_ = this.freehand_ ?\n        squaredDistance > this.squaredClickTolerance_ :\n        squaredDistance <= this.squaredClickTolerance_;\n      if (!this.shouldHandle_) {\n        return true;\n      }\n    }\n\n    if (this.finishCoordinate_) {\n      this.modifyDrawing_(event);\n    } else {\n      this.createOrUpdateSketchPoint_(event);\n    }\n    return true;\n  }\n\n  /**\n   * Determine if an event is within the snapping tolerance of the start coord.\n   * @param {module:ol/MapBrowserEvent} event Event.\n   * @return {boolean} The event is within the snapping tolerance of the start.\n   * @private\n   */\n  atFinish_(event) {\n    let at = false;\n    if (this.sketchFeature_) {\n      let potentiallyDone = false;\n      let potentiallyFinishCoordinates = [this.finishCoordinate_];\n      if (this.mode_ === Mode.LINE_STRING) {\n        potentiallyDone = this.sketchCoords_.length > this.minPoints_;\n      } else if (this.mode_ === Mode.POLYGON) {\n        potentiallyDone = this.sketchCoords_[0].length >\n            this.minPoints_;\n        potentiallyFinishCoordinates = [this.sketchCoords_[0][0],\n          this.sketchCoords_[0][this.sketchCoords_[0].length - 2]];\n      }\n      if (potentiallyDone) {\n        const map = event.map;\n        for (let i = 0, ii = potentiallyFinishCoordinates.length; i < ii; i++) {\n          const finishCoordinate = potentiallyFinishCoordinates[i];\n          const finishPixel = map.getPixelFromCoordinate(finishCoordinate);\n          const pixel = event.pixel;\n          const dx = pixel[0] - finishPixel[0];\n          const dy = pixel[1] - finishPixel[1];\n          const snapTolerance = this.freehand_ ? 1 : this.snapTolerance_;\n          at = Math.sqrt(dx * dx + dy * dy) <= snapTolerance;\n          if (at) {\n            this.finishCoordinate_ = finishCoordinate;\n            break;\n          }\n        }\n      }\n    }\n    return at;\n  }\n\n  /**\n   * @param {module:ol/MapBrowserEvent} event Event.\n   * @private\n   */\n  createOrUpdateSketchPoint_(event) {\n    const coordinates = event.coordinate.slice();\n    if (!this.sketchPoint_) {\n      this.sketchPoint_ = new Feature(new Point(coordinates));\n      this.updateSketchFeatures_();\n    } else {\n      const sketchPointGeom = /** @type {module:ol/geom/Point} */ (this.sketchPoint_.getGeometry());\n      sketchPointGeom.setCoordinates(coordinates);\n    }\n  }\n\n  /**\n   * Start the drawing.\n   * @param {module:ol/MapBrowserEvent} event Event.\n   * @private\n   */\n  startDrawing_(event) {\n    const start = event.coordinate;\n    this.finishCoordinate_ = start;\n    if (this.mode_ === Mode.POINT) {\n      this.sketchCoords_ = start.slice();\n    } else if (this.mode_ === Mode.POLYGON) {\n      this.sketchCoords_ = [[start.slice(), start.slice()]];\n      this.sketchLineCoords_ = this.sketchCoords_[0];\n    } else {\n      this.sketchCoords_ = [start.slice(), start.slice()];\n    }\n    if (this.sketchLineCoords_) {\n      this.sketchLine_ = new Feature(\n        new LineString(this.sketchLineCoords_));\n    }\n    const geometry = this.geometryFunction_(this.sketchCoords_);\n    this.sketchFeature_ = new Feature();\n    if (this.geometryName_) {\n      this.sketchFeature_.setGeometryName(this.geometryName_);\n    }\n    this.sketchFeature_.setGeometry(geometry);\n    this.updateSketchFeatures_();\n    this.dispatchEvent(new DrawEvent(DrawEventType.DRAWSTART, this.sketchFeature_));\n  }\n\n  /**\n   * Modify the drawing.\n   * @param {module:ol/MapBrowserEvent} event Event.\n   * @private\n   */\n  modifyDrawing_(event) {\n    let coordinate = event.coordinate;\n    const geometry = /** @type {module:ol/geom/SimpleGeometry} */ (this.sketchFeature_.getGeometry());\n    let coordinates, last;\n    if (this.mode_ === Mode.POINT) {\n      last = this.sketchCoords_;\n    } else if (this.mode_ === Mode.POLYGON) {\n      coordinates = this.sketchCoords_[0];\n      last = coordinates[coordinates.length - 1];\n      if (this.atFinish_(event)) {\n        // snap to finish\n        coordinate = this.finishCoordinate_.slice();\n      }\n    } else {\n      coordinates = this.sketchCoords_;\n      last = coordinates[coordinates.length - 1];\n    }\n    last[0] = coordinate[0];\n    last[1] = coordinate[1];\n    this.geometryFunction_(/** @type {!Array.<module:ol/coordinate~Coordinate>} */ (this.sketchCoords_), geometry);\n    if (this.sketchPoint_) {\n      const sketchPointGeom = /** @type {module:ol/geom/Point} */ (this.sketchPoint_.getGeometry());\n      sketchPointGeom.setCoordinates(coordinate);\n    }\n    let sketchLineGeom;\n    if (geometry instanceof Polygon &&\n        this.mode_ !== Mode.POLYGON) {\n      if (!this.sketchLine_) {\n        this.sketchLine_ = new Feature();\n      }\n      const ring = geometry.getLinearRing(0);\n      sketchLineGeom = /** @type {module:ol/geom/LineString} */ (this.sketchLine_.getGeometry());\n      if (!sketchLineGeom) {\n        sketchLineGeom = new LineString(ring.getFlatCoordinates(), ring.getLayout());\n        this.sketchLine_.setGeometry(sketchLineGeom);\n      } else {\n        sketchLineGeom.setFlatCoordinates(\n          ring.getLayout(), ring.getFlatCoordinates());\n        sketchLineGeom.changed();\n      }\n    } else if (this.sketchLineCoords_) {\n      sketchLineGeom = /** @type {module:ol/geom/LineString} */ (this.sketchLine_.getGeometry());\n      sketchLineGeom.setCoordinates(this.sketchLineCoords_);\n    }\n    this.updateSketchFeatures_();\n  }\n\n  /**\n   * Add a new coordinate to the drawing.\n   * @param {module:ol/MapBrowserEvent} event Event.\n   * @private\n   */\n  addToDrawing_(event) {\n    const coordinate = event.coordinate;\n    const geometry = /** @type {module:ol/geom/SimpleGeometry} */ (this.sketchFeature_.getGeometry());\n    let done;\n    let coordinates;\n    if (this.mode_ === Mode.LINE_STRING) {\n      this.finishCoordinate_ = coordinate.slice();\n      coordinates = this.sketchCoords_;\n      if (coordinates.length >= this.maxPoints_) {\n        if (this.freehand_) {\n          coordinates.pop();\n        } else {\n          done = true;\n        }\n      }\n      coordinates.push(coordinate.slice());\n      this.geometryFunction_(coordinates, geometry);\n    } else if (this.mode_ === Mode.POLYGON) {\n      coordinates = this.sketchCoords_[0];\n      if (coordinates.length >= this.maxPoints_) {\n        if (this.freehand_) {\n          coordinates.pop();\n        } else {\n          done = true;\n        }\n      }\n      coordinates.push(coordinate.slice());\n      if (done) {\n        this.finishCoordinate_ = coordinates[0];\n      }\n      this.geometryFunction_(this.sketchCoords_, geometry);\n    }\n    this.updateSketchFeatures_();\n    if (done) {\n      this.finishDrawing();\n    }\n  }\n\n  /**\n   * Remove last point of the feature currently being drawn.\n   * @api\n   */\n  removeLastPoint() {\n    if (!this.sketchFeature_) {\n      return;\n    }\n    const geometry = /** @type {module:ol/geom/SimpleGeometry} */ (this.sketchFeature_.getGeometry());\n    let coordinates, sketchLineGeom;\n    if (this.mode_ === Mode.LINE_STRING) {\n      coordinates = this.sketchCoords_;\n      coordinates.splice(-2, 1);\n      this.geometryFunction_(coordinates, geometry);\n      if (coordinates.length >= 2) {\n        this.finishCoordinate_ = coordinates[coordinates.length - 2].slice();\n      }\n    } else if (this.mode_ === Mode.POLYGON) {\n      coordinates = this.sketchCoords_[0];\n      coordinates.splice(-2, 1);\n      sketchLineGeom = /** @type {module:ol/geom/LineString} */ (this.sketchLine_.getGeometry());\n      sketchLineGeom.setCoordinates(coordinates);\n      this.geometryFunction_(this.sketchCoords_, geometry);\n    }\n\n    if (coordinates.length === 0) {\n      this.finishCoordinate_ = null;\n    }\n\n    this.updateSketchFeatures_();\n  }\n\n  /**\n   * Stop drawing and add the sketch feature to the target layer.\n   * The {@link module:ol/interaction/Draw~DrawEventType.DRAWEND} event is\n   * dispatched before inserting the feature.\n   * @api\n   */\n  finishDrawing() {\n    const sketchFeature = this.abortDrawing_();\n    if (!sketchFeature) {\n      return;\n    }\n    let coordinates = this.sketchCoords_;\n    const geometry = /** @type {module:ol/geom/SimpleGeometry} */ (sketchFeature.getGeometry());\n    if (this.mode_ === Mode.LINE_STRING) {\n      // remove the redundant last point\n      coordinates.pop();\n      this.geometryFunction_(coordinates, geometry);\n    } else if (this.mode_ === Mode.POLYGON) {\n      // remove the redundant last point in ring\n      coordinates[0].pop();\n      this.geometryFunction_(coordinates, geometry);\n      coordinates = geometry.getCoordinates();\n    }\n\n    // cast multi-part geometries\n    if (this.type_ === GeometryType.MULTI_POINT) {\n      sketchFeature.setGeometry(new MultiPoint([coordinates]));\n    } else if (this.type_ === GeometryType.MULTI_LINE_STRING) {\n      sketchFeature.setGeometry(new MultiLineString([coordinates]));\n    } else if (this.type_ === GeometryType.MULTI_POLYGON) {\n      sketchFeature.setGeometry(new MultiPolygon([coordinates]));\n    }\n\n    // First dispatch event to allow full set up of feature\n    this.dispatchEvent(new DrawEvent(DrawEventType.DRAWEND, sketchFeature));\n\n    // Then insert feature\n    if (this.features_) {\n      this.features_.push(sketchFeature);\n    }\n    if (this.source_) {\n      this.source_.addFeature(sketchFeature);\n    }\n  }\n\n  /**\n   * Stop drawing without adding the sketch feature to the target layer.\n   * @return {module:ol/Feature} The sketch feature (or null if none).\n   * @private\n   */\n  abortDrawing_() {\n    this.finishCoordinate_ = null;\n    const sketchFeature = this.sketchFeature_;\n    if (sketchFeature) {\n      this.sketchFeature_ = null;\n      this.sketchPoint_ = null;\n      this.sketchLine_ = null;\n      this.overlay_.getSource().clear(true);\n    }\n    return sketchFeature;\n  }\n\n  /**\n   * Extend an existing geometry by adding additional points. This only works\n   * on features with `LineString` geometries, where the interaction will\n   * extend lines by adding points to the end of the coordinates array.\n   * @param {!module:ol/Feature} feature Feature to be extended.\n   * @api\n   */\n  extend(feature) {\n    const geometry = feature.getGeometry();\n    const lineString = /** @type {module:ol/geom/LineString} */ (geometry);\n    this.sketchFeature_ = feature;\n    this.sketchCoords_ = lineString.getCoordinates();\n    const last = this.sketchCoords_[this.sketchCoords_.length - 1];\n    this.finishCoordinate_ = last.slice();\n    this.sketchCoords_.push(last.slice());\n    this.updateSketchFeatures_();\n    this.dispatchEvent(new DrawEvent(DrawEventType.DRAWSTART, this.sketchFeature_));\n  }\n\n  /**\n   * Redraw the sketch features.\n   * @private\n   */\n  updateSketchFeatures_() {\n    const sketchFeatures = [];\n    if (this.sketchFeature_) {\n      sketchFeatures.push(this.sketchFeature_);\n    }\n    if (this.sketchLine_) {\n      sketchFeatures.push(this.sketchLine_);\n    }\n    if (this.sketchPoint_) {\n      sketchFeatures.push(this.sketchPoint_);\n    }\n    const overlaySource = this.overlay_.getSource();\n    overlaySource.clear(true);\n    overlaySource.addFeatures(sketchFeatures);\n  }\n\n  /**\n   * @private\n   */\n  updateState_() {\n    const map = this.getMap();\n    const active = this.getActive();\n    if (!map || !active) {\n      this.abortDrawing_();\n    }\n    this.overlay_.setMap(active ? map : null);\n  }\n}\n\n\n/**\n * @return {module:ol/style/Style~StyleFunction} Styles.\n */\nfunction getDefaultStyleFunction() {\n  const styles = createEditingStyle();\n  return function(feature, resolution) {\n    return styles[feature.getGeometry().getType()];\n  };\n}\n\n\n/**\n * Handles the {@link module:ol/MapBrowserEvent map browser event} and may actually\n * draw or finish the drawing.\n * @param {module:ol/MapBrowserEvent} event Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @this {module:ol/interaction/Draw}\n * @api\n */\nexport function handleEvent(event) {\n  if (event.originalEvent.type === EventType.CONTEXTMENU) {\n    // Avoid context menu for long taps when drawing on mobile\n    event.preventDefault();\n  }\n  this.freehand_ = this.mode_ !== Mode.POINT && this.freehandCondition_(event);\n  let move = event.type === MapBrowserEventType.POINTERMOVE;\n  let pass = true;\n  if (this.lastDragTime_ && event.type === MapBrowserEventType.POINTERDRAG) {\n    const now = Date.now();\n    if (now - this.lastDragTime_ >= this.dragVertexDelay_) {\n      this.downPx_ = event.pixel;\n      this.shouldHandle_ = !this.freehand_;\n      move = true;\n    } else {\n      this.lastDragTime_ = undefined;\n    }\n    if (this.shouldHandle_ && this.downTimeout_) {\n      clearTimeout(this.downTimeout_);\n      this.downTimeout_ = undefined;\n    }\n  }\n  if (this.freehand_ &&\n      event.type === MapBrowserEventType.POINTERDRAG &&\n      this.sketchFeature_ !== null) {\n    this.addToDrawing_(event);\n    pass = false;\n  } else if (this.freehand_ &&\n      event.type === MapBrowserEventType.POINTERDOWN) {\n    pass = false;\n  } else if (move) {\n    pass = event.type === MapBrowserEventType.POINTERMOVE;\n    if (pass && this.freehand_) {\n      pass = this.handlePointerMove_(event);\n    } else if (event.pointerEvent.pointerType == POINTER_TYPE ||\n        (event.type === MapBrowserEventType.POINTERDRAG && !this.downTimeout_)) {\n      this.handlePointerMove_(event);\n    }\n  } else if (event.type === MapBrowserEventType.DBLCLICK) {\n    pass = false;\n  }\n\n  return handlePointerEvent.call(this, event) && pass;\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} event Event.\n * @return {boolean} Start drag sequence?\n * @this {module:ol/interaction/Draw}\n */\nfunction handleDownEvent(event) {\n  this.shouldHandle_ = !this.freehand_;\n\n  if (this.freehand_) {\n    this.downPx_ = event.pixel;\n    if (!this.finishCoordinate_) {\n      this.startDrawing_(event);\n    }\n    return true;\n  } else if (this.condition_(event)) {\n    this.lastDragTime_ = Date.now();\n    this.downTimeout_ = setTimeout(function() {\n      this.handlePointerMove_(new MapBrowserPointerEvent(\n        MapBrowserEventType.POINTERMOVE, event.map, event.pointerEvent, event.frameState));\n    }.bind(this), this.dragVertexDelay_);\n    this.downPx_ = event.pixel;\n    return true;\n  } else {\n    return false;\n  }\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} event Event.\n * @return {boolean} Stop drag sequence?\n * @this {module:ol/interaction/Draw}\n */\nfunction handleUpEvent(event) {\n  let pass = true;\n\n  if (this.downTimeout_) {\n    clearTimeout(this.downTimeout_);\n    this.downTimeout_ = undefined;\n  }\n\n  this.handlePointerMove_(event);\n\n  const circleMode = this.mode_ === Mode.CIRCLE;\n\n  if (this.shouldHandle_) {\n    if (!this.finishCoordinate_) {\n      this.startDrawing_(event);\n      if (this.mode_ === Mode.POINT) {\n        this.finishDrawing();\n      }\n    } else if (this.freehand_ || circleMode) {\n      this.finishDrawing();\n    } else if (this.atFinish_(event)) {\n      if (this.finishCondition_(event)) {\n        this.finishDrawing();\n      }\n    } else {\n      this.addToDrawing_(event);\n    }\n    pass = false;\n  } else if (this.freehand_) {\n    this.finishCoordinate_ = null;\n    this.abortDrawing_();\n  }\n  if (!pass && this.stopClick_) {\n    event.stopPropagation();\n  }\n  return pass;\n}\n\n\n/**\n * Create a `geometryFunction` for `type: 'Circle'` that will create a regular\n * polygon with a user specified number of sides and start angle instead of an\n * `module:ol/geom/Circle~Circle` geometry.\n * @param {number=} opt_sides Number of sides of the regular polygon. Default is\n *     32.\n * @param {number=} opt_angle Angle of the first point in radians. 0 means East.\n *     Default is the angle defined by the heading from the center of the\n *     regular polygon to the current pointer position.\n * @return {module:ol/interaction/Draw~GeometryFunction} Function that draws a\n *     polygon.\n * @api\n */\nexport function createRegularPolygon(opt_sides, opt_angle) {\n  return function(coordinates, opt_geometry) {\n    const center = coordinates[0];\n    const end = coordinates[1];\n    const radius = Math.sqrt(\n      squaredCoordinateDistance(center, end));\n    const geometry = opt_geometry ? /** @type {module:ol/geom/Polygon} */ (opt_geometry) :\n      fromCircle(new Circle(center), opt_sides);\n    const angle = opt_angle ? opt_angle :\n      Math.atan((end[1] - center[1]) / (end[0] - center[0]));\n    makeRegular(geometry, center, radius, angle);\n    return geometry;\n  };\n}\n\n\n/**\n * Create a `geometryFunction` that will create a box-shaped polygon (aligned\n * with the coordinate system axes).  Use this with the draw interaction and\n * `type: 'Circle'` to return a box instead of a circle geometry.\n * @return {module:ol/interaction/Draw~GeometryFunction} Function that draws a box-shaped polygon.\n * @api\n */\nexport function createBox() {\n  return (\n    function(coordinates, opt_geometry) {\n      const extent = boundingExtent(coordinates);\n      const boxCoordinates = [[\n        getBottomLeft(extent),\n        getBottomRight(extent),\n        getTopRight(extent),\n        getTopLeft(extent),\n        getBottomLeft(extent)\n      ]];\n      let geometry = opt_geometry;\n      if (geometry) {\n        geometry.setCoordinates(boxCoordinates);\n      } else {\n        geometry = new Polygon(boxCoordinates);\n      }\n      return geometry;\n    }\n  );\n}\n\n\n/**\n * Get the drawing mode.  The mode for mult-part geometries is the same as for\n * their single-part cousins.\n * @param {module:ol/geom/GeometryType} type Geometry type.\n * @return {module:ol/interaction/Draw~Mode} Drawing mode.\n */\nfunction getMode(type) {\n  let mode;\n  if (type === GeometryType.POINT ||\n      type === GeometryType.MULTI_POINT) {\n    mode = Mode.POINT;\n  } else if (type === GeometryType.LINE_STRING ||\n      type === GeometryType.MULTI_LINE_STRING) {\n    mode = Mode.LINE_STRING;\n  } else if (type === GeometryType.POLYGON ||\n      type === GeometryType.MULTI_POLYGON) {\n    mode = Mode.POLYGON;\n  } else if (type === GeometryType.CIRCLE) {\n    mode = Mode.CIRCLE;\n  }\n  return (\n    /** @type {!module:ol/interaction/Draw~Mode} */ (mode)\n  );\n}\n\n\nexport default Draw;\n","/**\n * @module ol/interaction/Extent\n */\nimport Feature from '../Feature.js';\nimport MapBrowserEventType from '../MapBrowserEventType.js';\nimport MapBrowserPointerEvent from '../MapBrowserPointerEvent.js';\nimport {squaredDistanceToSegment, closestOnSegment, distance as coordinateDistance, squaredDistance as squaredCoordinateDistance} from '../coordinate.js';\nimport Event from '../events/Event.js';\nimport {boundingExtent, getArea} from '../extent.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport Point from '../geom/Point.js';\nimport {fromExtent as polygonFromExtent} from '../geom/Polygon.js';\nimport PointerInteraction, {handleEvent as handlePointerEvent} from '../interaction/Pointer.js';\nimport VectorLayer from '../layer/Vector.js';\nimport VectorSource from '../source/Vector.js';\nimport {createEditingStyle} from '../style/Style.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/extent~Extent} [extent] Initial extent. Defaults to no\n * initial extent.\n * @property {module:ol/style/Style|Array.<module:ol/style/Style>|module:ol/style/Style~StyleFunction} [boxStyle]\n * Style for the drawn extent box. Defaults to\n * {@link module:ol/style/Style~createEditing()['Polygon']}\n * @property {number} [pixelTolerance=10] Pixel tolerance for considering the\n * pointer close enough to a segment or vertex for editing.\n * @property {module:ol/style/Style|Array.<module:ol/style/Style>|module:ol/style/Style~StyleFunction} [pointerStyle]\n * Style for the cursor used to draw the extent. Defaults to\n * {@link module:ol/style/Style~createEditing()['Point']}\n * @property {boolean} [wrapX=false] Wrap the drawn extent across multiple maps\n * in the X direction? Only affects visuals, not functionality.\n */\n\n\n/**\n * @enum {string}\n */\nconst ExtentEventType = {\n  /**\n   * Triggered after the extent is changed\n   * @event module:ol/interaction/Extent~ExtentEventType#extentchanged\n   * @api\n   */\n  EXTENTCHANGED: 'extentchanged'\n};\n\n\n/**\n * @classdesc\n * Events emitted by {@link module:ol/interaction/Extent~Extent} instances are\n * instances of this type.\n */\nclass ExtentInteractionEvent extends Event {\n\n  /**\n   * @param {module:ol/extent~Extent} extent the new extent\n   */\n  constructor(extent) {\n    super(ExtentEventType.EXTENTCHANGED);\n\n    /**\n     * The current extent.\n     * @type {module:ol/extent~Extent}\n     * @api\n     */\n    this.extent = extent;\n  }\n\n}\n\n\n/**\n * @classdesc\n * Allows the user to draw a vector box by clicking and dragging on the map.\n * Once drawn, the vector box can be modified by dragging its vertices or edges.\n * This interaction is only supported for mouse devices.\n *\n * @fires module:ol/interaction/Extent~Event\n * @api\n */\nclass ExtentInteraction extends PointerInteraction {\n  /**\n   * @param {module:ol/interaction/Extent~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    super({\n      handleDownEvent: handleDownEvent,\n      handleDragEvent: handleDragEvent,\n      handleEvent: handleEvent,\n      handleUpEvent: handleUpEvent\n    });\n\n    const options = opt_options || {};\n\n    /**\n     * Extent of the drawn box\n     * @type {module:ol/extent~Extent}\n     * @private\n     */\n    this.extent_ = null;\n\n    /**\n     * Handler for pointer move events\n     * @type {function (module:ol/coordinate~Coordinate): module:ol/extent~Extent|null}\n     * @private\n     */\n    this.pointerHandler_ = null;\n\n    /**\n     * Pixel threshold to snap to extent\n     * @type {number}\n     * @private\n     */\n    this.pixelTolerance_ = options.pixelTolerance !== undefined ?\n      options.pixelTolerance : 10;\n\n    /**\n     * Is the pointer snapped to an extent vertex\n     * @type {boolean}\n     * @private\n     */\n    this.snappedToVertex_ = false;\n\n    /**\n     * Feature for displaying the visible extent\n     * @type {module:ol/Feature}\n     * @private\n     */\n    this.extentFeature_ = null;\n\n    /**\n     * Feature for displaying the visible pointer\n     * @type {module:ol/Feature}\n     * @private\n     */\n    this.vertexFeature_ = null;\n\n    if (!opt_options) {\n      opt_options = {};\n    }\n\n    /**\n     * Layer for the extentFeature\n     * @type {module:ol/layer/Vector}\n     * @private\n     */\n    this.extentOverlay_ = new VectorLayer({\n      source: new VectorSource({\n        useSpatialIndex: false,\n        wrapX: !!opt_options.wrapX\n      }),\n      style: opt_options.boxStyle ? opt_options.boxStyle : getDefaultExtentStyleFunction(),\n      updateWhileAnimating: true,\n      updateWhileInteracting: true\n    });\n\n    /**\n     * Layer for the vertexFeature\n     * @type {module:ol/layer/Vector}\n     * @private\n     */\n    this.vertexOverlay_ = new VectorLayer({\n      source: new VectorSource({\n        useSpatialIndex: false,\n        wrapX: !!opt_options.wrapX\n      }),\n      style: opt_options.pointerStyle ? opt_options.pointerStyle : getDefaultPointerStyleFunction(),\n      updateWhileAnimating: true,\n      updateWhileInteracting: true\n    });\n\n    if (opt_options.extent) {\n      this.setExtent(opt_options.extent);\n    }\n  }\n\n  /**\n   * @param {module:ol/pixel~Pixel} pixel cursor location\n   * @param {module:ol/PluggableMap} map map\n   * @returns {module:ol/coordinate~Coordinate|null} snapped vertex on extent\n   * @private\n   */\n  snapToVertex_(pixel, map) {\n    const pixelCoordinate = map.getCoordinateFromPixel(pixel);\n    const sortByDistance = function(a, b) {\n      return squaredDistanceToSegment(pixelCoordinate, a) -\n          squaredDistanceToSegment(pixelCoordinate, b);\n    };\n    const extent = this.getExtent();\n    if (extent) {\n      //convert extents to line segments and find the segment closest to pixelCoordinate\n      const segments = getSegments(extent);\n      segments.sort(sortByDistance);\n      const closestSegment = segments[0];\n\n      let vertex = (closestOnSegment(pixelCoordinate,\n        closestSegment));\n      const vertexPixel = map.getPixelFromCoordinate(vertex);\n\n      //if the distance is within tolerance, snap to the segment\n      if (coordinateDistance(pixel, vertexPixel) <= this.pixelTolerance_) {\n        //test if we should further snap to a vertex\n        const pixel1 = map.getPixelFromCoordinate(closestSegment[0]);\n        const pixel2 = map.getPixelFromCoordinate(closestSegment[1]);\n        const squaredDist1 = squaredCoordinateDistance(vertexPixel, pixel1);\n        const squaredDist2 = squaredCoordinateDistance(vertexPixel, pixel2);\n        const dist = Math.sqrt(Math.min(squaredDist1, squaredDist2));\n        this.snappedToVertex_ = dist <= this.pixelTolerance_;\n        if (this.snappedToVertex_) {\n          vertex = squaredDist1 > squaredDist2 ?\n            closestSegment[1] : closestSegment[0];\n        }\n        return vertex;\n      }\n    }\n    return null;\n  }\n\n  /**\n   * @param {module:ol/MapBrowserEvent} mapBrowserEvent pointer move event\n   * @private\n   */\n  handlePointerMove_(mapBrowserEvent) {\n    const pixel = mapBrowserEvent.pixel;\n    const map = mapBrowserEvent.map;\n\n    let vertex = this.snapToVertex_(pixel, map);\n    if (!vertex) {\n      vertex = map.getCoordinateFromPixel(pixel);\n    }\n    this.createOrUpdatePointerFeature_(vertex);\n  }\n\n  /**\n   * @param {module:ol/extent~Extent} extent extent\n   * @returns {module:ol/Feature} extent as featrue\n   * @private\n   */\n  createOrUpdateExtentFeature_(extent) {\n    let extentFeature = this.extentFeature_;\n\n    if (!extentFeature) {\n      if (!extent) {\n        extentFeature = new Feature({});\n      } else {\n        extentFeature = new Feature(polygonFromExtent(extent));\n      }\n      this.extentFeature_ = extentFeature;\n      this.extentOverlay_.getSource().addFeature(extentFeature);\n    } else {\n      if (!extent) {\n        extentFeature.setGeometry(undefined);\n      } else {\n        extentFeature.setGeometry(polygonFromExtent(extent));\n      }\n    }\n    return extentFeature;\n  }\n\n  /**\n   * @param {module:ol/coordinate~Coordinate} vertex location of feature\n   * @returns {module:ol/Feature} vertex as feature\n   * @private\n   */\n  createOrUpdatePointerFeature_(vertex) {\n    let vertexFeature = this.vertexFeature_;\n    if (!vertexFeature) {\n      vertexFeature = new Feature(new Point(vertex));\n      this.vertexFeature_ = vertexFeature;\n      this.vertexOverlay_.getSource().addFeature(vertexFeature);\n    } else {\n      const geometry = /** @type {module:ol/geom/Point} */ (vertexFeature.getGeometry());\n      geometry.setCoordinates(vertex);\n    }\n    return vertexFeature;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setMap(map) {\n    this.extentOverlay_.setMap(map);\n    this.vertexOverlay_.setMap(map);\n    super.setMap(map);\n  }\n\n  /**\n   * Returns the current drawn extent in the view projection\n   *\n   * @return {module:ol/extent~Extent} Drawn extent in the view projection.\n   * @api\n   */\n  getExtent() {\n    return this.extent_;\n  }\n\n  /**\n   * Manually sets the drawn extent, using the view projection.\n   *\n   * @param {module:ol/extent~Extent} extent Extent\n   * @api\n   */\n  setExtent(extent) {\n    //Null extent means no bbox\n    this.extent_ = extent ? extent : null;\n    this.createOrUpdateExtentFeature_(extent);\n    this.dispatchEvent(new ExtentInteractionEvent(this.extent_));\n  }\n}\n\n/**\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Event.\n * @return {boolean} Propagate event?\n * @this {module:ol/interaction/Extent~Extent}\n */\nfunction handleEvent(mapBrowserEvent) {\n  if (!(mapBrowserEvent instanceof MapBrowserPointerEvent)) {\n    return true;\n  }\n  //display pointer (if not dragging)\n  if (mapBrowserEvent.type == MapBrowserEventType.POINTERMOVE && !this.handlingDownUpSequence) {\n    this.handlePointerMove_(mapBrowserEvent);\n  }\n  //call pointer to determine up/down/drag\n  handlePointerEvent.call(this, mapBrowserEvent);\n  //return false to stop propagation\n  return false;\n}\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @return {boolean} Event handled?\n * @this {module:ol/interaction/Extent~Extent}\n */\nfunction handleDownEvent(mapBrowserEvent) {\n  const pixel = mapBrowserEvent.pixel;\n  const map = mapBrowserEvent.map;\n\n  const extent = this.getExtent();\n  let vertex = this.snapToVertex_(pixel, map);\n\n  //find the extent corner opposite the passed corner\n  const getOpposingPoint = function(point) {\n    let x_ = null;\n    let y_ = null;\n    if (point[0] == extent[0]) {\n      x_ = extent[2];\n    } else if (point[0] == extent[2]) {\n      x_ = extent[0];\n    }\n    if (point[1] == extent[1]) {\n      y_ = extent[3];\n    } else if (point[1] == extent[3]) {\n      y_ = extent[1];\n    }\n    if (x_ !== null && y_ !== null) {\n      return [x_, y_];\n    }\n    return null;\n  };\n  if (vertex && extent) {\n    const x = (vertex[0] == extent[0] || vertex[0] == extent[2]) ? vertex[0] : null;\n    const y = (vertex[1] == extent[1] || vertex[1] == extent[3]) ? vertex[1] : null;\n\n    //snap to point\n    if (x !== null && y !== null) {\n      this.pointerHandler_ = getPointHandler(getOpposingPoint(vertex));\n    //snap to edge\n    } else if (x !== null) {\n      this.pointerHandler_ = getEdgeHandler(\n        getOpposingPoint([x, extent[1]]),\n        getOpposingPoint([x, extent[3]])\n      );\n    } else if (y !== null) {\n      this.pointerHandler_ = getEdgeHandler(\n        getOpposingPoint([extent[0], y]),\n        getOpposingPoint([extent[2], y])\n      );\n    }\n  //no snap - new bbox\n  } else {\n    vertex = map.getCoordinateFromPixel(pixel);\n    this.setExtent([vertex[0], vertex[1], vertex[0], vertex[1]]);\n    this.pointerHandler_ = getPointHandler(vertex);\n  }\n  return true; //event handled; start downup sequence\n}\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @return {boolean} Event handled?\n * @this {module:ol/interaction/Extent~Extent}\n */\nfunction handleDragEvent(mapBrowserEvent) {\n  if (this.pointerHandler_) {\n    const pixelCoordinate = mapBrowserEvent.coordinate;\n    this.setExtent(this.pointerHandler_(pixelCoordinate));\n    this.createOrUpdatePointerFeature_(pixelCoordinate);\n  }\n  return true;\n}\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} mapBrowserEvent Event.\n * @return {boolean} Stop drag sequence?\n * @this {module:ol/interaction/Extent~Extent}\n */\nfunction handleUpEvent(mapBrowserEvent) {\n  this.pointerHandler_ = null;\n  //If bbox is zero area, set to null;\n  const extent = this.getExtent();\n  if (!extent || getArea(extent) === 0) {\n    this.setExtent(null);\n  }\n  return false; //Stop handling downup sequence\n}\n\n/**\n * Returns the default style for the drawn bbox\n *\n * @return {module:ol/style/Style~StyleFunction} Default Extent style\n */\nfunction getDefaultExtentStyleFunction() {\n  const style = createEditingStyle();\n  return function(feature, resolution) {\n    return style[GeometryType.POLYGON];\n  };\n}\n\n/**\n * Returns the default style for the pointer\n *\n * @return {module:ol/style/Style~StyleFunction} Default pointer style\n */\nfunction getDefaultPointerStyleFunction() {\n  const style = createEditingStyle();\n  return function(feature, resolution) {\n    return style[GeometryType.POINT];\n  };\n}\n\n/**\n * @param {module:ol/coordinate~Coordinate} fixedPoint corner that will be unchanged in the new extent\n * @returns {function (module:ol/coordinate~Coordinate): module:ol/extent~Extent} event handler\n */\nfunction getPointHandler(fixedPoint) {\n  return function(point) {\n    return boundingExtent([fixedPoint, point]);\n  };\n}\n\n/**\n * @param {module:ol/coordinate~Coordinate} fixedP1 first corner that will be unchanged in the new extent\n * @param {module:ol/coordinate~Coordinate} fixedP2 second corner that will be unchanged in the new extent\n * @returns {function (module:ol/coordinate~Coordinate): module:ol/extent~Extent|null} event handler\n */\nfunction getEdgeHandler(fixedP1, fixedP2) {\n  if (fixedP1[0] == fixedP2[0]) {\n    return function(point) {\n      return boundingExtent([fixedP1, [point[0], fixedP2[1]]]);\n    };\n  } else if (fixedP1[1] == fixedP2[1]) {\n    return function(point) {\n      return boundingExtent([fixedP1, [fixedP2[0], point[1]]]);\n    };\n  } else {\n    return null;\n  }\n}\n\n/**\n * @param {module:ol/extent~Extent} extent extent\n * @returns {Array<Array<module:ol/coordinate~Coordinate>>} extent line segments\n */\nfunction getSegments(extent) {\n  return [\n    [[extent[0], extent[1]], [extent[0], extent[3]]],\n    [[extent[0], extent[3]], [extent[2], extent[3]]],\n    [[extent[2], extent[3]], [extent[2], extent[1]]],\n    [[extent[2], extent[1]], [extent[0], extent[1]]]\n  ];\n}\n\n\nexport default ExtentInteraction;\n","/**\n * @module ol/interaction/Modify\n */\nimport {getUid} from '../util.js';\nimport Collection from '../Collection.js';\nimport CollectionEventType from '../CollectionEventType.js';\nimport Feature from '../Feature.js';\nimport MapBrowserEventType from '../MapBrowserEventType.js';\nimport MapBrowserPointerEvent from '../MapBrowserPointerEvent.js';\nimport {equals} from '../array.js';\nimport {equals as coordinatesEqual, distance as coordinateDistance, squaredDistance as squaredCoordinateDistance, squaredDistanceToSegment, closestOnSegment} from '../coordinate.js';\nimport {listen, unlisten} from '../events.js';\nimport Event from '../events/Event.js';\nimport EventType from '../events/EventType.js';\nimport {always, primaryAction, altKeyOnly, singleClick} from '../events/condition.js';\nimport {boundingExtent, buffer, createOrUpdateFromCoordinate} from '../extent.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport Point from '../geom/Point.js';\nimport PointerInteraction, {handleEvent as handlePointerEvent} from '../interaction/Pointer.js';\nimport VectorLayer from '../layer/Vector.js';\nimport VectorSource from '../source/Vector.js';\nimport VectorEventType from '../source/VectorEventType.js';\nimport RBush from '../structs/RBush.js';\nimport {createEditingStyle} from '../style/Style.js';\n\n\n/**\n * The segment index assigned to a circle's center when\n * breaking up a circle into ModifySegmentDataType segments.\n * @type {number}\n */\nconst CIRCLE_CENTER_INDEX = 0;\n\n/**\n * The segment index assigned to a circle's circumference when\n * breaking up a circle into ModifySegmentDataType segments.\n * @type {number}\n */\nconst CIRCLE_CIRCUMFERENCE_INDEX = 1;\n\n\n/**\n * @enum {string}\n */\nconst ModifyEventType = {\n  /**\n   * Triggered upon feature modification start\n   * @event ModifyEvent#modifystart\n   * @api\n   */\n  MODIFYSTART: 'modifystart',\n  /**\n   * Triggered upon feature modification end\n   * @event ModifyEvent#modifyend\n   * @api\n   */\n  MODIFYEND: 'modifyend'\n};\n\n\n/**\n * @typedef {Object} SegmentData\n * @property {Array.<number>} [depth]\n * @property {module:ol/Feature} feature\n * @property {module:ol/geom/SimpleGeometry} geometry\n * @property {number} index\n * @property {Array.<module:ol/extent~Extent>} segment\n * @property {Array.<module:ol/interaction/Modify~SegmentData>} [featureSegments]\n */\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/events/condition~Condition} [condition] A function that\n * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event will be considered to add or move a\n * vertex to the sketch. Default is\n * {@link module:ol/events/condition~primaryAction}.\n * @property {module:ol/events/condition~Condition} [deleteCondition] A function\n * that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled. By default,\n * {@link module:ol/events/condition~singleClick} with\n * {@link module:ol/events/condition~altKeyOnly} results in a vertex deletion.\n * @property {module:ol/events/condition~Condition} [insertVertexCondition] A\n * function that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and\n * returns a boolean to indicate whether a new vertex can be added to the sketch\n * features. Default is {@link module:ol/events/condition~always}.\n * @property {number} [pixelTolerance=10] Pixel tolerance for considering the\n * pointer close enough to a segment or vertex for editing.\n * @property {module:ol/style/Style|Array.<module:ol/style/Style>|module:ol/style/Style~StyleFunction} [style]\n * Style used for the features being modified. By default the default edit\n * style is used (see {@link module:ol/style}).\n * @property {module:ol/source/Vector} [source] The vector source with\n * features to modify.  If a vector source is not provided, a feature collection\n * must be provided with the features option.\n * @property {module:ol/Collection.<module:ol/Feature>} [features]\n * The features the interaction works on.  If a feature collection is not\n * provided, a vector source must be provided with the source option.\n * @property {boolean} [wrapX=false] Wrap the world horizontally on the sketch\n * overlay.\n */\n\n\n/**\n * @classdesc\n * Events emitted by {@link module:ol/interaction/Modify~Modify} instances are\n * instances of this type.\n */\nexport class ModifyEvent extends Event {\n  /**\n   * @param {ModifyEventType} type Type.\n   * @param {module:ol/Collection.<module:ol/Feature>} features\n   * The features modified.\n   * @param {module:ol/MapBrowserPointerEvent} mapBrowserPointerEvent\n   * Associated {@link module:ol/MapBrowserPointerEvent}.\n   */\n  constructor(type, features, mapBrowserPointerEvent) {\n    super(type);\n\n    /**\n     * The features being modified.\n     * @type {module:ol/Collection.<module:ol/Feature>}\n     * @api\n     */\n    this.features = features;\n\n    /**\n     * Associated {@link module:ol/MapBrowserEvent}.\n     * @type {module:ol/MapBrowserEvent}\n     * @api\n     */\n    this.mapBrowserEvent = mapBrowserPointerEvent;\n\n  }\n\n}\n\n\n/**\n * @classdesc\n * Interaction for modifying feature geometries.  To modify features that have\n * been added to an existing source, construct the modify interaction with the\n * `source` option.  If you want to modify features in a collection (for example,\n * the collection used by a select interaction), construct the interaction with\n * the `features` option.  The interaction must be constructed with either a\n * `source` or `features` option.\n *\n * By default, the interaction will allow deletion of vertices when the `alt`\n * key is pressed.  To configure the interaction with a different condition\n * for deletion, use the `deleteCondition` option.\n * @fires module:ol/interaction/Modify~ModifyEvent\n * @api\n */\nclass Modify extends PointerInteraction {\n  /**\n   * @param {module:ol/interaction/Modify~Options} options Options.\n   */\n  constructor(options) {\n\n    super({\n      handleDownEvent: handleDownEvent,\n      handleDragEvent: handleDragEvent,\n      handleEvent: handleEvent,\n      handleUpEvent: handleUpEvent\n    });\n\n    /**\n     * @private\n     * @type {module:ol/events/condition~Condition}\n     */\n    this.condition_ = options.condition ? options.condition : primaryAction;\n\n\n    /**\n     * @private\n     * @param {module:ol/MapBrowserEvent} mapBrowserEvent Browser event.\n     * @return {boolean} Combined condition result.\n     */\n    this.defaultDeleteCondition_ = function(mapBrowserEvent) {\n      return altKeyOnly(mapBrowserEvent) && singleClick(mapBrowserEvent);\n    };\n\n    /**\n     * @type {module:ol/events/condition~Condition}\n     * @private\n     */\n    this.deleteCondition_ = options.deleteCondition ?\n      options.deleteCondition : this.defaultDeleteCondition_;\n\n    /**\n     * @type {module:ol/events/condition~Condition}\n     * @private\n     */\n    this.insertVertexCondition_ = options.insertVertexCondition ?\n      options.insertVertexCondition : always;\n\n    /**\n     * Editing vertex.\n     * @type {module:ol/Feature}\n     * @private\n     */\n    this.vertexFeature_ = null;\n\n    /**\n     * Segments intersecting {@link this.vertexFeature_} by segment uid.\n     * @type {Object.<string, boolean>}\n     * @private\n     */\n    this.vertexSegments_ = null;\n\n    /**\n     * @type {module:ol/pixel~Pixel}\n     * @private\n     */\n    this.lastPixel_ = [0, 0];\n\n    /**\n     * Tracks if the next `singleclick` event should be ignored to prevent\n     * accidental deletion right after vertex creation.\n     * @type {boolean}\n     * @private\n     */\n    this.ignoreNextSingleClick_ = false;\n\n    /**\n     * @type {boolean}\n     * @private\n     */\n    this.modified_ = false;\n\n    /**\n     * Segment RTree for each layer\n     * @type {module:ol/structs/RBush.<module:ol/interaction/Modify~SegmentData>}\n     * @private\n     */\n    this.rBush_ = new RBush();\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.pixelTolerance_ = options.pixelTolerance !== undefined ?\n      options.pixelTolerance : 10;\n\n    /**\n     * @type {boolean}\n     * @private\n     */\n    this.snappedToVertex_ = false;\n\n    /**\n     * Indicate whether the interaction is currently changing a feature's\n     * coordinates.\n     * @type {boolean}\n     * @private\n     */\n    this.changingFeature_ = false;\n\n    /**\n     * @type {Array}\n     * @private\n     */\n    this.dragSegments_ = [];\n\n    /**\n     * Draw overlay where sketch features are drawn.\n     * @type {module:ol/layer/Vector}\n     * @private\n     */\n    this.overlay_ = new VectorLayer({\n      source: new VectorSource({\n        useSpatialIndex: false,\n        wrapX: !!options.wrapX\n      }),\n      style: options.style ? options.style :\n        getDefaultStyleFunction(),\n      updateWhileAnimating: true,\n      updateWhileInteracting: true\n    });\n\n    /**\n     * @const\n     * @private\n     * @type {!Object.<string, function(module:ol/Feature, module:ol/geom/Geometry)>}\n     */\n    this.SEGMENT_WRITERS_ = {\n      'Point': this.writePointGeometry_,\n      'LineString': this.writeLineStringGeometry_,\n      'LinearRing': this.writeLineStringGeometry_,\n      'Polygon': this.writePolygonGeometry_,\n      'MultiPoint': this.writeMultiPointGeometry_,\n      'MultiLineString': this.writeMultiLineStringGeometry_,\n      'MultiPolygon': this.writeMultiPolygonGeometry_,\n      'Circle': this.writeCircleGeometry_,\n      'GeometryCollection': this.writeGeometryCollectionGeometry_\n    };\n\n\n    /**\n     * @type {module:ol/source/Vector}\n     * @private\n     */\n    this.source_ = null;\n\n    let features;\n    if (options.source) {\n      this.source_ = options.source;\n      features = new Collection(this.source_.getFeatures());\n      listen(this.source_, VectorEventType.ADDFEATURE,\n        this.handleSourceAdd_, this);\n      listen(this.source_, VectorEventType.REMOVEFEATURE,\n        this.handleSourceRemove_, this);\n    } else {\n      features = options.features;\n    }\n    if (!features) {\n      throw new Error('The modify interaction requires features or a source');\n    }\n\n    /**\n     * @type {module:ol/Collection.<module:ol/Feature>}\n     * @private\n     */\n    this.features_ = features;\n\n    this.features_.forEach(this.addFeature_.bind(this));\n    listen(this.features_, CollectionEventType.ADD,\n      this.handleFeatureAdd_, this);\n    listen(this.features_, CollectionEventType.REMOVE,\n      this.handleFeatureRemove_, this);\n\n    /**\n     * @type {module:ol/MapBrowserPointerEvent}\n     * @private\n     */\n    this.lastPointerEvent_ = null;\n\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature.\n   * @private\n   */\n  addFeature_(feature) {\n    const geometry = feature.getGeometry();\n    if (geometry && geometry.getType() in this.SEGMENT_WRITERS_) {\n      this.SEGMENT_WRITERS_[geometry.getType()].call(this, feature, geometry);\n    }\n    const map = this.getMap();\n    if (map && map.isRendered() && this.getActive()) {\n      this.handlePointerAtPixel_(this.lastPixel_, map);\n    }\n    listen(feature, EventType.CHANGE,\n      this.handleFeatureChange_, this);\n  }\n\n  /**\n   * @param {module:ol/MapBrowserPointerEvent} evt Map browser event\n   * @private\n   */\n  willModifyFeatures_(evt) {\n    if (!this.modified_) {\n      this.modified_ = true;\n      this.dispatchEvent(new ModifyEvent(\n        ModifyEventType.MODIFYSTART, this.features_, evt));\n    }\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature.\n   * @private\n   */\n  removeFeature_(feature) {\n    this.removeFeatureSegmentData_(feature);\n    // Remove the vertex feature if the collection of canditate features\n    // is empty.\n    if (this.vertexFeature_ && this.features_.getLength() === 0) {\n      this.overlay_.getSource().removeFeature(this.vertexFeature_);\n      this.vertexFeature_ = null;\n    }\n    unlisten(feature, EventType.CHANGE,\n      this.handleFeatureChange_, this);\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature.\n   * @private\n   */\n  removeFeatureSegmentData_(feature) {\n    const rBush = this.rBush_;\n    const /** @type {Array.<module:ol/interaction/Modify~SegmentData>} */ nodesToRemove = [];\n    rBush.forEach(\n      /**\n       * @param {module:ol/interaction/Modify~SegmentData} node RTree node.\n       */\n      function(node) {\n        if (feature === node.feature) {\n          nodesToRemove.push(node);\n        }\n      });\n    for (let i = nodesToRemove.length - 1; i >= 0; --i) {\n      rBush.remove(nodesToRemove[i]);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setActive(active) {\n    if (this.vertexFeature_ && !active) {\n      this.overlay_.getSource().removeFeature(this.vertexFeature_);\n      this.vertexFeature_ = null;\n    }\n    super.setActive(active);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setMap(map) {\n    this.overlay_.setMap(map);\n    super.setMap(map);\n  }\n\n  /**\n   * @param {module:ol/source/Vector~VectorSourceEvent} event Event.\n   * @private\n   */\n  handleSourceAdd_(event) {\n    if (event.feature) {\n      this.features_.push(event.feature);\n    }\n  }\n\n  /**\n   * @param {module:ol/source/Vector~VectorSourceEvent} event Event.\n   * @private\n   */\n  handleSourceRemove_(event) {\n    if (event.feature) {\n      this.features_.remove(event.feature);\n    }\n  }\n\n  /**\n   * @param {module:ol/Collection~CollectionEvent} evt Event.\n   * @private\n   */\n  handleFeatureAdd_(evt) {\n    this.addFeature_(/** @type {module:ol/Feature} */ (evt.element));\n  }\n\n  /**\n   * @param {module:ol/events/Event} evt Event.\n   * @private\n   */\n  handleFeatureChange_(evt) {\n    if (!this.changingFeature_) {\n      const feature = /** @type {module:ol/Feature} */ (evt.target);\n      this.removeFeature_(feature);\n      this.addFeature_(feature);\n    }\n  }\n\n  /**\n   * @param {module:ol/Collection~CollectionEvent} evt Event.\n   * @private\n   */\n  handleFeatureRemove_(evt) {\n    const feature = /** @type {module:ol/Feature} */ (evt.element);\n    this.removeFeature_(feature);\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature\n   * @param {module:ol/geom/Point} geometry Geometry.\n   * @private\n   */\n  writePointGeometry_(feature, geometry) {\n    const coordinates = geometry.getCoordinates();\n    const segmentData = /** @type {module:ol/interaction/Modify~SegmentData} */ ({\n      feature: feature,\n      geometry: geometry,\n      segment: [coordinates, coordinates]\n    });\n    this.rBush_.insert(geometry.getExtent(), segmentData);\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature\n   * @param {module:ol/geom/MultiPoint} geometry Geometry.\n   * @private\n   */\n  writeMultiPointGeometry_(feature, geometry) {\n    const points = geometry.getCoordinates();\n    for (let i = 0, ii = points.length; i < ii; ++i) {\n      const coordinates = points[i];\n      const segmentData = /** @type {module:ol/interaction/Modify~SegmentData} */ ({\n        feature: feature,\n        geometry: geometry,\n        depth: [i],\n        index: i,\n        segment: [coordinates, coordinates]\n      });\n      this.rBush_.insert(geometry.getExtent(), segmentData);\n    }\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature\n   * @param {module:ol/geom/LineString} geometry Geometry.\n   * @private\n   */\n  writeLineStringGeometry_(feature, geometry) {\n    const coordinates = geometry.getCoordinates();\n    for (let i = 0, ii = coordinates.length - 1; i < ii; ++i) {\n      const segment = coordinates.slice(i, i + 2);\n      const segmentData = /** @type {module:ol/interaction/Modify~SegmentData} */ ({\n        feature: feature,\n        geometry: geometry,\n        index: i,\n        segment: segment\n      });\n      this.rBush_.insert(boundingExtent(segment), segmentData);\n    }\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature\n   * @param {module:ol/geom/MultiLineString} geometry Geometry.\n   * @private\n   */\n  writeMultiLineStringGeometry_(feature, geometry) {\n    const lines = geometry.getCoordinates();\n    for (let j = 0, jj = lines.length; j < jj; ++j) {\n      const coordinates = lines[j];\n      for (let i = 0, ii = coordinates.length - 1; i < ii; ++i) {\n        const segment = coordinates.slice(i, i + 2);\n        const segmentData = /** @type {module:ol/interaction/Modify~SegmentData} */ ({\n          feature: feature,\n          geometry: geometry,\n          depth: [j],\n          index: i,\n          segment: segment\n        });\n        this.rBush_.insert(boundingExtent(segment), segmentData);\n      }\n    }\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature\n   * @param {module:ol/geom/Polygon} geometry Geometry.\n   * @private\n   */\n  writePolygonGeometry_(feature, geometry) {\n    const rings = geometry.getCoordinates();\n    for (let j = 0, jj = rings.length; j < jj; ++j) {\n      const coordinates = rings[j];\n      for (let i = 0, ii = coordinates.length - 1; i < ii; ++i) {\n        const segment = coordinates.slice(i, i + 2);\n        const segmentData = /** @type {module:ol/interaction/Modify~SegmentData} */ ({\n          feature: feature,\n          geometry: geometry,\n          depth: [j],\n          index: i,\n          segment: segment\n        });\n        this.rBush_.insert(boundingExtent(segment), segmentData);\n      }\n    }\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature\n   * @param {module:ol/geom/MultiPolygon} geometry Geometry.\n   * @private\n   */\n  writeMultiPolygonGeometry_(feature, geometry) {\n    const polygons = geometry.getCoordinates();\n    for (let k = 0, kk = polygons.length; k < kk; ++k) {\n      const rings = polygons[k];\n      for (let j = 0, jj = rings.length; j < jj; ++j) {\n        const coordinates = rings[j];\n        for (let i = 0, ii = coordinates.length - 1; i < ii; ++i) {\n          const segment = coordinates.slice(i, i + 2);\n          const segmentData = /** @type {module:ol/interaction/Modify~SegmentData} */ ({\n            feature: feature,\n            geometry: geometry,\n            depth: [j, k],\n            index: i,\n            segment: segment\n          });\n          this.rBush_.insert(boundingExtent(segment), segmentData);\n        }\n      }\n    }\n  }\n\n  /**\n   * We convert a circle into two segments.  The segment at index\n   * {@link CIRCLE_CENTER_INDEX} is the\n   * circle's center (a point).  The segment at index\n   * {@link CIRCLE_CIRCUMFERENCE_INDEX} is\n   * the circumference, and is not a line segment.\n   *\n   * @param {module:ol/Feature} feature Feature.\n   * @param {module:ol/geom/Circle} geometry Geometry.\n   * @private\n   */\n  writeCircleGeometry_(feature, geometry) {\n    const coordinates = geometry.getCenter();\n    const centerSegmentData = /** @type {module:ol/interaction/Modify~SegmentData} */ ({\n      feature: feature,\n      geometry: geometry,\n      index: CIRCLE_CENTER_INDEX,\n      segment: [coordinates, coordinates]\n    });\n    const circumferenceSegmentData = /** @type {module:ol/interaction/Modify~SegmentData} */ ({\n      feature: feature,\n      geometry: geometry,\n      index: CIRCLE_CIRCUMFERENCE_INDEX,\n      segment: [coordinates, coordinates]\n    });\n    const featureSegments = [centerSegmentData, circumferenceSegmentData];\n    centerSegmentData.featureSegments = circumferenceSegmentData.featureSegments = featureSegments;\n    this.rBush_.insert(createOrUpdateFromCoordinate(coordinates), centerSegmentData);\n    this.rBush_.insert(geometry.getExtent(), circumferenceSegmentData);\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature\n   * @param {module:ol/geom/GeometryCollection} geometry Geometry.\n   * @private\n   */\n  writeGeometryCollectionGeometry_(feature, geometry) {\n    const geometries = geometry.getGeometriesArray();\n    for (let i = 0; i < geometries.length; ++i) {\n      this.SEGMENT_WRITERS_[geometries[i].getType()].call(this, feature, geometries[i]);\n    }\n  }\n\n  /**\n   * @param {module:ol/coordinate~Coordinate} coordinates Coordinates.\n   * @return {module:ol/Feature} Vertex feature.\n   * @private\n   */\n  createOrUpdateVertexFeature_(coordinates) {\n    let vertexFeature = this.vertexFeature_;\n    if (!vertexFeature) {\n      vertexFeature = new Feature(new Point(coordinates));\n      this.vertexFeature_ = vertexFeature;\n      this.overlay_.getSource().addFeature(vertexFeature);\n    } else {\n      const geometry = /** @type {module:ol/geom/Point} */ (vertexFeature.getGeometry());\n      geometry.setCoordinates(coordinates);\n    }\n    return vertexFeature;\n  }\n\n  /**\n   * @param {module:ol/MapBrowserEvent} evt Event.\n   * @private\n   */\n  handlePointerMove_(evt) {\n    this.lastPixel_ = evt.pixel;\n    this.handlePointerAtPixel_(evt.pixel, evt.map);\n  }\n\n  /**\n   * @param {module:ol/pixel~Pixel} pixel Pixel\n   * @param {module:ol/PluggableMap} map Map.\n   * @private\n   */\n  handlePointerAtPixel_(pixel, map) {\n    const pixelCoordinate = map.getCoordinateFromPixel(pixel);\n    const sortByDistance = function(a, b) {\n      return pointDistanceToSegmentDataSquared(pixelCoordinate, a) -\n          pointDistanceToSegmentDataSquared(pixelCoordinate, b);\n    };\n\n    const box = buffer(createOrUpdateFromCoordinate(pixelCoordinate),\n      map.getView().getResolution() * this.pixelTolerance_);\n\n    const rBush = this.rBush_;\n    const nodes = rBush.getInExtent(box);\n    if (nodes.length > 0) {\n      nodes.sort(sortByDistance);\n      const node = nodes[0];\n      const closestSegment = node.segment;\n      let vertex = closestOnSegmentData(pixelCoordinate, node);\n      const vertexPixel = map.getPixelFromCoordinate(vertex);\n      let dist = coordinateDistance(pixel, vertexPixel);\n      if (dist <= this.pixelTolerance_) {\n        const vertexSegments = {};\n\n        if (node.geometry.getType() === GeometryType.CIRCLE &&\n        node.index === CIRCLE_CIRCUMFERENCE_INDEX) {\n\n          this.snappedToVertex_ = true;\n          this.createOrUpdateVertexFeature_(vertex);\n        } else {\n          const pixel1 = map.getPixelFromCoordinate(closestSegment[0]);\n          const pixel2 = map.getPixelFromCoordinate(closestSegment[1]);\n          const squaredDist1 = squaredCoordinateDistance(vertexPixel, pixel1);\n          const squaredDist2 = squaredCoordinateDistance(vertexPixel, pixel2);\n          dist = Math.sqrt(Math.min(squaredDist1, squaredDist2));\n          this.snappedToVertex_ = dist <= this.pixelTolerance_;\n          if (this.snappedToVertex_) {\n            vertex = squaredDist1 > squaredDist2 ? closestSegment[1] : closestSegment[0];\n          }\n          this.createOrUpdateVertexFeature_(vertex);\n          for (let i = 1, ii = nodes.length; i < ii; ++i) {\n            const segment = nodes[i].segment;\n            if ((coordinatesEqual(closestSegment[0], segment[0]) &&\n                coordinatesEqual(closestSegment[1], segment[1]) ||\n                (coordinatesEqual(closestSegment[0], segment[1]) &&\n                coordinatesEqual(closestSegment[1], segment[0])))) {\n              vertexSegments[getUid(segment)] = true;\n            } else {\n              break;\n            }\n          }\n        }\n\n        vertexSegments[getUid(closestSegment)] = true;\n        this.vertexSegments_ = vertexSegments;\n        return;\n      }\n    }\n    if (this.vertexFeature_) {\n      this.overlay_.getSource().removeFeature(this.vertexFeature_);\n      this.vertexFeature_ = null;\n    }\n  }\n\n  /**\n   * @param {module:ol/interaction/Modify~SegmentData} segmentData Segment data.\n   * @param {module:ol/coordinate~Coordinate} vertex Vertex.\n   * @private\n   */\n  insertVertex_(segmentData, vertex) {\n    const segment = segmentData.segment;\n    const feature = segmentData.feature;\n    const geometry = segmentData.geometry;\n    const depth = segmentData.depth;\n    const index = /** @type {number} */ (segmentData.index);\n    let coordinates;\n\n    while (vertex.length < geometry.getStride()) {\n      vertex.push(0);\n    }\n\n    switch (geometry.getType()) {\n      case GeometryType.MULTI_LINE_STRING:\n        coordinates = geometry.getCoordinates();\n        coordinates[depth[0]].splice(index + 1, 0, vertex);\n        break;\n      case GeometryType.POLYGON:\n        coordinates = geometry.getCoordinates();\n        coordinates[depth[0]].splice(index + 1, 0, vertex);\n        break;\n      case GeometryType.MULTI_POLYGON:\n        coordinates = geometry.getCoordinates();\n        coordinates[depth[1]][depth[0]].splice(index + 1, 0, vertex);\n        break;\n      case GeometryType.LINE_STRING:\n        coordinates = geometry.getCoordinates();\n        coordinates.splice(index + 1, 0, vertex);\n        break;\n      default:\n        return;\n    }\n\n    this.setGeometryCoordinates_(geometry, coordinates);\n    const rTree = this.rBush_;\n    rTree.remove(segmentData);\n    this.updateSegmentIndices_(geometry, index, depth, 1);\n    const newSegmentData = /** @type {module:ol/interaction/Modify~SegmentData} */ ({\n      segment: [segment[0], vertex],\n      feature: feature,\n      geometry: geometry,\n      depth: depth,\n      index: index\n    });\n    rTree.insert(boundingExtent(newSegmentData.segment),\n      newSegmentData);\n    this.dragSegments_.push([newSegmentData, 1]);\n\n    const newSegmentData2 = /** @type {module:ol/interaction/Modify~SegmentData} */ ({\n      segment: [vertex, segment[1]],\n      feature: feature,\n      geometry: geometry,\n      depth: depth,\n      index: index + 1\n    });\n    rTree.insert(boundingExtent(newSegmentData2.segment), newSegmentData2);\n    this.dragSegments_.push([newSegmentData2, 0]);\n    this.ignoreNextSingleClick_ = true;\n  }\n\n  /**\n   * Removes the vertex currently being pointed.\n   * @return {boolean} True when a vertex was removed.\n   * @api\n   */\n  removePoint() {\n    if (this.lastPointerEvent_ && this.lastPointerEvent_.type != MapBrowserEventType.POINTERDRAG) {\n      const evt = this.lastPointerEvent_;\n      this.willModifyFeatures_(evt);\n      this.removeVertex_();\n      this.dispatchEvent(new ModifyEvent(ModifyEventType.MODIFYEND, this.features_, evt));\n      this.modified_ = false;\n      return true;\n    }\n    return false;\n  }\n\n  /**\n   * Removes a vertex from all matching features.\n   * @return {boolean} True when a vertex was removed.\n   * @private\n   */\n  removeVertex_() {\n    const dragSegments = this.dragSegments_;\n    const segmentsByFeature = {};\n    let deleted = false;\n    let component, coordinates, dragSegment, geometry, i, index, left;\n    let newIndex, right, segmentData, uid;\n    for (i = dragSegments.length - 1; i >= 0; --i) {\n      dragSegment = dragSegments[i];\n      segmentData = dragSegment[0];\n      uid = getUid(segmentData.feature);\n      if (segmentData.depth) {\n        // separate feature components\n        uid += '-' + segmentData.depth.join('-');\n      }\n      if (!(uid in segmentsByFeature)) {\n        segmentsByFeature[uid] = {};\n      }\n      if (dragSegment[1] === 0) {\n        segmentsByFeature[uid].right = segmentData;\n        segmentsByFeature[uid].index = segmentData.index;\n      } else if (dragSegment[1] == 1) {\n        segmentsByFeature[uid].left = segmentData;\n        segmentsByFeature[uid].index = segmentData.index + 1;\n      }\n\n    }\n    for (uid in segmentsByFeature) {\n      right = segmentsByFeature[uid].right;\n      left = segmentsByFeature[uid].left;\n      index = segmentsByFeature[uid].index;\n      newIndex = index - 1;\n      if (left !== undefined) {\n        segmentData = left;\n      } else {\n        segmentData = right;\n      }\n      if (newIndex < 0) {\n        newIndex = 0;\n      }\n      geometry = segmentData.geometry;\n      coordinates = geometry.getCoordinates();\n      component = coordinates;\n      deleted = false;\n      switch (geometry.getType()) {\n        case GeometryType.MULTI_LINE_STRING:\n          if (coordinates[segmentData.depth[0]].length > 2) {\n            coordinates[segmentData.depth[0]].splice(index, 1);\n            deleted = true;\n          }\n          break;\n        case GeometryType.LINE_STRING:\n          if (coordinates.length > 2) {\n            coordinates.splice(index, 1);\n            deleted = true;\n          }\n          break;\n        case GeometryType.MULTI_POLYGON:\n          component = component[segmentData.depth[1]];\n          /* falls through */\n        case GeometryType.POLYGON:\n          component = component[segmentData.depth[0]];\n          if (component.length > 4) {\n            if (index == component.length - 1) {\n              index = 0;\n            }\n            component.splice(index, 1);\n            deleted = true;\n            if (index === 0) {\n              // close the ring again\n              component.pop();\n              component.push(component[0]);\n              newIndex = component.length - 1;\n            }\n          }\n          break;\n        default:\n          // pass\n      }\n\n      if (deleted) {\n        this.setGeometryCoordinates_(geometry, coordinates);\n        const segments = [];\n        if (left !== undefined) {\n          this.rBush_.remove(left);\n          segments.push(left.segment[0]);\n        }\n        if (right !== undefined) {\n          this.rBush_.remove(right);\n          segments.push(right.segment[1]);\n        }\n        if (left !== undefined && right !== undefined) {\n          const newSegmentData = /** @type {module:ol/interaction/Modify~SegmentData} */ ({\n            depth: segmentData.depth,\n            feature: segmentData.feature,\n            geometry: segmentData.geometry,\n            index: newIndex,\n            segment: segments\n          });\n          this.rBush_.insert(boundingExtent(newSegmentData.segment),\n            newSegmentData);\n        }\n        this.updateSegmentIndices_(geometry, index, segmentData.depth, -1);\n        if (this.vertexFeature_) {\n          this.overlay_.getSource().removeFeature(this.vertexFeature_);\n          this.vertexFeature_ = null;\n        }\n        dragSegments.length = 0;\n      }\n\n    }\n    return deleted;\n  }\n\n  /**\n   * @param {module:ol/geom/SimpleGeometry} geometry Geometry.\n   * @param {Array} coordinates Coordinates.\n   * @private\n   */\n  setGeometryCoordinates_(geometry, coordinates) {\n    this.changingFeature_ = true;\n    geometry.setCoordinates(coordinates);\n    this.changingFeature_ = false;\n  }\n\n  /**\n   * @param {module:ol/geom/SimpleGeometry} geometry Geometry.\n   * @param {number} index Index.\n   * @param {Array.<number>|undefined} depth Depth.\n   * @param {number} delta Delta (1 or -1).\n   * @private\n   */\n  updateSegmentIndices_(geometry, index, depth, delta) {\n    this.rBush_.forEachInExtent(geometry.getExtent(), function(segmentDataMatch) {\n      if (segmentDataMatch.geometry === geometry &&\n          (depth === undefined || segmentDataMatch.depth === undefined ||\n          equals(segmentDataMatch.depth, depth)) &&\n          segmentDataMatch.index > index) {\n        segmentDataMatch.index += delta;\n      }\n    });\n  }\n}\n\n\n/**\n * @param {module:ol/interaction/Modify~SegmentData} a The first segment data.\n * @param {module:ol/interaction/Modify~SegmentData} b The second segment data.\n * @return {number} The difference in indexes.\n */\nfunction compareIndexes(a, b) {\n  return a.index - b.index;\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} evt Event.\n * @return {boolean} Start drag sequence?\n * @this {module:ol/interaction/Modify}\n */\nfunction handleDownEvent(evt) {\n  if (!this.condition_(evt)) {\n    return false;\n  }\n  this.handlePointerAtPixel_(evt.pixel, evt.map);\n  const pixelCoordinate = evt.map.getCoordinateFromPixel(evt.pixel);\n  this.dragSegments_.length = 0;\n  this.modified_ = false;\n  const vertexFeature = this.vertexFeature_;\n  if (vertexFeature) {\n    const insertVertices = [];\n    const geometry = /** @type {module:ol/geom/Point} */ (vertexFeature.getGeometry());\n    const vertex = geometry.getCoordinates();\n    const vertexExtent = boundingExtent([vertex]);\n    const segmentDataMatches = this.rBush_.getInExtent(vertexExtent);\n    const componentSegments = {};\n    segmentDataMatches.sort(compareIndexes);\n    for (let i = 0, ii = segmentDataMatches.length; i < ii; ++i) {\n      const segmentDataMatch = segmentDataMatches[i];\n      const segment = segmentDataMatch.segment;\n      let uid = getUid(segmentDataMatch.feature);\n      const depth = segmentDataMatch.depth;\n      if (depth) {\n        uid += '-' + depth.join('-'); // separate feature components\n      }\n      if (!componentSegments[uid]) {\n        componentSegments[uid] = new Array(2);\n      }\n      if (segmentDataMatch.geometry.getType() === GeometryType.CIRCLE &&\n      segmentDataMatch.index === CIRCLE_CIRCUMFERENCE_INDEX) {\n\n        const closestVertex = closestOnSegmentData(pixelCoordinate, segmentDataMatch);\n        if (coordinatesEqual(closestVertex, vertex) && !componentSegments[uid][0]) {\n          this.dragSegments_.push([segmentDataMatch, 0]);\n          componentSegments[uid][0] = segmentDataMatch;\n        }\n      } else if (coordinatesEqual(segment[0], vertex) &&\n          !componentSegments[uid][0]) {\n        this.dragSegments_.push([segmentDataMatch, 0]);\n        componentSegments[uid][0] = segmentDataMatch;\n      } else if (coordinatesEqual(segment[1], vertex) &&\n          !componentSegments[uid][1]) {\n\n        // prevent dragging closed linestrings by the connecting node\n        if ((segmentDataMatch.geometry.getType() ===\n            GeometryType.LINE_STRING ||\n            segmentDataMatch.geometry.getType() ===\n            GeometryType.MULTI_LINE_STRING) &&\n            componentSegments[uid][0] &&\n            componentSegments[uid][0].index === 0) {\n          continue;\n        }\n\n        this.dragSegments_.push([segmentDataMatch, 1]);\n        componentSegments[uid][1] = segmentDataMatch;\n      } else if (this.insertVertexCondition_(evt) && getUid(segment) in this.vertexSegments_ &&\n          (!componentSegments[uid][0] && !componentSegments[uid][1])) {\n        insertVertices.push([segmentDataMatch, vertex]);\n      }\n    }\n    if (insertVertices.length) {\n      this.willModifyFeatures_(evt);\n    }\n    for (let j = insertVertices.length - 1; j >= 0; --j) {\n      this.insertVertex_.apply(this, insertVertices[j]);\n    }\n  }\n  return !!this.vertexFeature_;\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} evt Event.\n * @this {module:ol/interaction/Modify}\n */\nfunction handleDragEvent(evt) {\n  this.ignoreNextSingleClick_ = false;\n  this.willModifyFeatures_(evt);\n\n  const vertex = evt.coordinate;\n  for (let i = 0, ii = this.dragSegments_.length; i < ii; ++i) {\n    const dragSegment = this.dragSegments_[i];\n    const segmentData = dragSegment[0];\n    const depth = segmentData.depth;\n    const geometry = segmentData.geometry;\n    let coordinates;\n    const segment = segmentData.segment;\n    const index = dragSegment[1];\n\n    while (vertex.length < geometry.getStride()) {\n      vertex.push(segment[index][vertex.length]);\n    }\n\n    switch (geometry.getType()) {\n      case GeometryType.POINT:\n        coordinates = vertex;\n        segment[0] = segment[1] = vertex;\n        break;\n      case GeometryType.MULTI_POINT:\n        coordinates = geometry.getCoordinates();\n        coordinates[segmentData.index] = vertex;\n        segment[0] = segment[1] = vertex;\n        break;\n      case GeometryType.LINE_STRING:\n        coordinates = geometry.getCoordinates();\n        coordinates[segmentData.index + index] = vertex;\n        segment[index] = vertex;\n        break;\n      case GeometryType.MULTI_LINE_STRING:\n        coordinates = geometry.getCoordinates();\n        coordinates[depth[0]][segmentData.index + index] = vertex;\n        segment[index] = vertex;\n        break;\n      case GeometryType.POLYGON:\n        coordinates = geometry.getCoordinates();\n        coordinates[depth[0]][segmentData.index + index] = vertex;\n        segment[index] = vertex;\n        break;\n      case GeometryType.MULTI_POLYGON:\n        coordinates = geometry.getCoordinates();\n        coordinates[depth[1]][depth[0]][segmentData.index + index] = vertex;\n        segment[index] = vertex;\n        break;\n      case GeometryType.CIRCLE:\n        segment[0] = segment[1] = vertex;\n        if (segmentData.index === CIRCLE_CENTER_INDEX) {\n          this.changingFeature_ = true;\n          geometry.setCenter(vertex);\n          this.changingFeature_ = false;\n        } else { // We're dragging the circle's circumference:\n          this.changingFeature_ = true;\n          geometry.setRadius(coordinateDistance(geometry.getCenter(), vertex));\n          this.changingFeature_ = false;\n        }\n        break;\n      default:\n        // pass\n    }\n\n    if (coordinates) {\n      this.setGeometryCoordinates_(geometry, coordinates);\n    }\n  }\n  this.createOrUpdateVertexFeature_(vertex);\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} evt Event.\n * @return {boolean} Stop drag sequence?\n * @this {module:ol/interaction/Modify}\n */\nfunction handleUpEvent(evt) {\n  for (let i = this.dragSegments_.length - 1; i >= 0; --i) {\n    const segmentData = this.dragSegments_[i][0];\n    const geometry = segmentData.geometry;\n    if (geometry.getType() === GeometryType.CIRCLE) {\n      // Update a circle object in the R* bush:\n      const coordinates = geometry.getCenter();\n      const centerSegmentData = segmentData.featureSegments[0];\n      const circumferenceSegmentData = segmentData.featureSegments[1];\n      centerSegmentData.segment[0] = centerSegmentData.segment[1] = coordinates;\n      circumferenceSegmentData.segment[0] = circumferenceSegmentData.segment[1] = coordinates;\n      this.rBush_.update(createOrUpdateFromCoordinate(coordinates), centerSegmentData);\n      this.rBush_.update(geometry.getExtent(), circumferenceSegmentData);\n    } else {\n      this.rBush_.update(boundingExtent(segmentData.segment), segmentData);\n    }\n  }\n  if (this.modified_) {\n    this.dispatchEvent(new ModifyEvent(ModifyEventType.MODIFYEND, this.features_, evt));\n    this.modified_ = false;\n  }\n  return false;\n}\n\n\n/**\n * Handles the {@link module:ol/MapBrowserEvent map browser event} and may modify the\n * geometry.\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @this {module:ol/interaction/Modify}\n */\nfunction handleEvent(mapBrowserEvent) {\n  if (!(mapBrowserEvent instanceof MapBrowserPointerEvent)) {\n    return true;\n  }\n  this.lastPointerEvent_ = mapBrowserEvent;\n\n  let handled;\n  if (!mapBrowserEvent.map.getView().getInteracting() &&\n      mapBrowserEvent.type == MapBrowserEventType.POINTERMOVE &&\n      !this.handlingDownUpSequence) {\n    this.handlePointerMove_(mapBrowserEvent);\n  }\n  if (this.vertexFeature_ && this.deleteCondition_(mapBrowserEvent)) {\n    if (mapBrowserEvent.type != MapBrowserEventType.SINGLECLICK || !this.ignoreNextSingleClick_) {\n      handled = this.removePoint();\n    } else {\n      handled = true;\n    }\n  }\n\n  if (mapBrowserEvent.type == MapBrowserEventType.SINGLECLICK) {\n    this.ignoreNextSingleClick_ = false;\n  }\n\n  return handlePointerEvent.call(this, mapBrowserEvent) && !handled;\n}\n\n\n/**\n * Returns the distance from a point to a line segment.\n *\n * @param {module:ol/coordinate~Coordinate} pointCoordinates The coordinates of the point from\n *        which to calculate the distance.\n * @param {module:ol/interaction/Modify~SegmentData} segmentData The object describing the line\n *        segment we are calculating the distance to.\n * @return {number} The square of the distance between a point and a line segment.\n */\nfunction pointDistanceToSegmentDataSquared(pointCoordinates, segmentData) {\n  const geometry = segmentData.geometry;\n\n  if (geometry.getType() === GeometryType.CIRCLE) {\n    const circleGeometry = /** @type {module:ol/geom/Circle} */ (geometry);\n\n    if (segmentData.index === CIRCLE_CIRCUMFERENCE_INDEX) {\n      const distanceToCenterSquared =\n            squaredCoordinateDistance(circleGeometry.getCenter(), pointCoordinates);\n      const distanceToCircumference =\n            Math.sqrt(distanceToCenterSquared) - circleGeometry.getRadius();\n      return distanceToCircumference * distanceToCircumference;\n    }\n  }\n  return squaredDistanceToSegment(pointCoordinates, segmentData.segment);\n}\n\n/**\n * Returns the point closest to a given line segment.\n *\n * @param {module:ol/coordinate~Coordinate} pointCoordinates The point to which a closest point\n *        should be found.\n * @param {module:ol/interaction/Modify~SegmentData} segmentData The object describing the line\n *        segment which should contain the closest point.\n * @return {module:ol/coordinate~Coordinate} The point closest to the specified line segment.\n */\nfunction closestOnSegmentData(pointCoordinates, segmentData) {\n  const geometry = segmentData.geometry;\n\n  if (geometry.getType() === GeometryType.CIRCLE &&\n  segmentData.index === CIRCLE_CIRCUMFERENCE_INDEX) {\n    return geometry.getClosestPoint(pointCoordinates);\n  }\n  return closestOnSegment(pointCoordinates, segmentData.segment);\n}\n\n\n/**\n * @return {module:ol/style/Style~StyleFunction} Styles.\n */\nfunction getDefaultStyleFunction() {\n  const style = createEditingStyle();\n  return function(feature, resolution) {\n    return style[GeometryType.POINT];\n  };\n}\n\n\nexport default Modify;\n","/**\n * @module ol/interaction/Select\n */\nimport {getUid} from '../util.js';\nimport CollectionEventType from '../CollectionEventType.js';\nimport {extend, includes} from '../array.js';\nimport {listen} from '../events.js';\nimport Event from '../events/Event.js';\nimport {singleClick, never, shiftKeyOnly, pointerMove} from '../events/condition.js';\nimport {TRUE} from '../functions.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport Interaction from '../interaction/Interaction.js';\nimport VectorLayer from '../layer/Vector.js';\nimport {clear} from '../obj.js';\nimport VectorSource from '../source/Vector.js';\nimport {createEditingStyle} from '../style/Style.js';\n\n\n/**\n * @enum {string}\n */\nconst SelectEventType = {\n  /**\n   * Triggered when feature(s) has been (de)selected.\n   * @event SelectEvent#select\n   * @api\n   */\n  SELECT: 'select'\n};\n\n\n/**\n * A function that takes an {@link module:ol/Feature} or\n * {@link module:ol/render/Feature} and an\n * {@link module:ol/layer/Layer} and returns `true` if the feature may be\n * selected or `false` otherwise.\n * @typedef {function((module:ol/Feature|module:ol/render/Feature), module:ol/layer/Layer):\n *     boolean} FilterFunction\n */\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/events/condition~Condition} [addCondition] A function\n * that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled.\n * By default, this is {@link module:ol/events/condition~never}. Use this if you\n * want to use different events for add and remove instead of `toggle`.\n * @property {module:ol/events/condition~Condition} [condition] A function that\n * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled. This is the event\n * for the selected features as a whole. By default, this is\n * {@link module:ol/events/condition~singleClick}. Clicking on a feature selects that\n * feature and removes any that were in the selection. Clicking outside any\n * feature removes all from the selection.\n * See `toggle`, `add`, `remove` options for adding/removing extra features to/\n * from the selection.\n * @property {Array.<module:ol/layer/Layer>|function(module:ol/layer/Layer): boolean} [layers]\n * A list of layers from which features should be selected. Alternatively, a\n * filter function can be provided. The function will be called for each layer\n * in the map and should return `true` for layers that you want to be\n * selectable. If the option is absent, all visible layers will be considered\n * selectable.\n * @property {module:ol/style/Style|Array.<module:ol/style/Style>|module:ol/style/Style~StyleFunction} [style]\n * Style for the selected features. By default the default edit style is used\n * (see {@link module:ol/style}).\n * @property {module:ol/events/condition~Condition} [removeCondition] A function\n * that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled.\n * By default, this is {@link module:ol/events/condition~never}. Use this if you\n * want to use different events for add and remove instead of `toggle`.\n * @property {module:ol/events/condition~Condition} [toggleCondition] A function\n * that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled. This is in addition\n * to the `condition` event. By default,\n * {@link module:ol/events/condition~shiftKeyOnly}, i.e. pressing `shift` as\n * well as the `condition` event, adds that feature to the current selection if\n * it is not currently selected, and removes it if it is. See `add` and `remove`\n * if you want to use different events instead of a toggle.\n * @property {boolean} [multi=false] A boolean that determines if the default\n * behaviour should select only single features or all (overlapping) features at\n * the clicked map position. The default of `false` means single select.\n * @property {module:ol/Collection.<module:ol/Feature>} [features]\n * Collection where the interaction will place selected features. Optional. If\n * not set the interaction will create a collection. In any case the collection\n * used by the interaction is returned by\n * {@link module:ol/interaction/Select~Select#getFeatures}.\n * @property {module:ol/interaction/Select~FilterFunction} [filter] A function\n * that takes an {@link module:ol/Feature} and an\n * {@link module:ol/layer/Layer} and returns `true` if the feature may be\n * selected or `false` otherwise.\n * @property {boolean} [wrapX=true] Wrap the world horizontally on the selection\n * overlay.\n * @property {number} [hitTolerance=0] Hit-detection tolerance. Pixels inside\n * the radius around the given position will be checked for features. This only\n * works for the canvas renderer and not for WebGL.\n */\n\n\n/**\n * @classdesc\n * Events emitted by {@link module:ol/interaction/Select~Select} instances are instances of\n * this type.\n */\nclass SelectEvent extends Event {\n  /**\n   * @param {SelectEventType} type The event type.\n   * @param {Array.<module:ol/Feature>} selected Selected features.\n   * @param {Array.<module:ol/Feature>} deselected Deselected features.\n   * @param {module:ol/MapBrowserEvent} mapBrowserEvent Associated\n   *     {@link module:ol/MapBrowserEvent}.\n   */\n  constructor(type, selected, deselected, mapBrowserEvent) {\n    super(type);\n\n    /**\n     * Selected features array.\n     * @type {Array.<module:ol/Feature>}\n     * @api\n     */\n    this.selected = selected;\n\n    /**\n     * Deselected features array.\n     * @type {Array.<module:ol/Feature>}\n     * @api\n     */\n    this.deselected = deselected;\n\n    /**\n     * Associated {@link module:ol/MapBrowserEvent}.\n     * @type {module:ol/MapBrowserEvent}\n     * @api\n     */\n    this.mapBrowserEvent = mapBrowserEvent;\n\n  }\n\n}\n\n\n/**\n * @classdesc\n * Interaction for selecting vector features. By default, selected features are\n * styled differently, so this interaction can be used for visual highlighting,\n * as well as selecting features for other actions, such as modification or\n * output. There are three ways of controlling which features are selected:\n * using the browser event as defined by the `condition` and optionally the\n * `toggle`, `add`/`remove`, and `multi` options; a `layers` filter; and a\n * further feature filter using the `filter` option.\n *\n * Selected features are added to an internal unmanaged layer.\n *\n * @fires SelectEvent\n * @api\n */\nclass Select extends Interaction {\n  /**\n   * @param {module:ol/interaction/Select~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    super({\n      handleEvent: handleEvent\n    });\n\n    const options = opt_options ? opt_options : {};\n\n    /**\n     * @private\n     * @type {module:ol/events/condition~Condition}\n     */\n    this.condition_ = options.condition ? options.condition : singleClick;\n\n    /**\n     * @private\n     * @type {module:ol/events/condition~Condition}\n     */\n    this.addCondition_ = options.addCondition ? options.addCondition : never;\n\n    /**\n     * @private\n     * @type {module:ol/events/condition~Condition}\n     */\n    this.removeCondition_ = options.removeCondition ? options.removeCondition : never;\n\n    /**\n     * @private\n     * @type {module:ol/events/condition~Condition}\n     */\n    this.toggleCondition_ = options.toggleCondition ? options.toggleCondition : shiftKeyOnly;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.multi_ = options.multi ? options.multi : false;\n\n    /**\n     * @private\n     * @type {module:ol/interaction/Select~FilterFunction}\n     */\n    this.filter_ = options.filter ? options.filter : TRUE;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.hitTolerance_ = options.hitTolerance ? options.hitTolerance : 0;\n\n    const featureOverlay = new VectorLayer({\n      source: new VectorSource({\n        useSpatialIndex: false,\n        features: options.features,\n        wrapX: options.wrapX\n      }),\n      style: options.style ? options.style :\n        getDefaultStyleFunction(),\n      updateWhileAnimating: true,\n      updateWhileInteracting: true\n    });\n\n    /**\n     * @private\n     * @type {module:ol/layer/Vector}\n     */\n    this.featureOverlay_ = featureOverlay;\n\n    /** @type {function(module:ol/layer/Layer): boolean} */\n    let layerFilter;\n    if (options.layers) {\n      if (typeof options.layers === 'function') {\n        layerFilter = options.layers;\n      } else {\n        const layers = options.layers;\n        layerFilter = function(layer) {\n          return includes(layers, layer);\n        };\n      }\n    } else {\n      layerFilter = TRUE;\n    }\n\n    /**\n     * @private\n     * @type {function(module:ol/layer/Layer): boolean}\n     */\n    this.layerFilter_ = layerFilter;\n\n    /**\n     * An association between selected feature (key)\n     * and layer (value)\n     * @private\n     * @type {Object.<number, module:ol/layer/Layer>}\n     */\n    this.featureLayerAssociation_ = {};\n\n    const features = this.featureOverlay_.getSource().getFeaturesCollection();\n    listen(features, CollectionEventType.ADD,\n      this.addFeature_, this);\n    listen(features, CollectionEventType.REMOVE,\n      this.removeFeature_, this);\n\n  }\n\n  /**\n   * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n   * @param {module:ol/layer/Layer} layer Layer.\n   * @private\n   */\n  addFeatureLayerAssociation_(feature, layer) {\n    const key = getUid(feature);\n    this.featureLayerAssociation_[key] = layer;\n  }\n\n  /**\n   * Get the selected features.\n   * @return {module:ol/Collection.<module:ol/Feature>} Features collection.\n   * @api\n   */\n  getFeatures() {\n    return this.featureOverlay_.getSource().getFeaturesCollection();\n  }\n\n  /**\n   * Returns the Hit-detection tolerance.\n   * @returns {number} Hit tolerance in pixels.\n   * @api\n   */\n  getHitTolerance() {\n    return this.hitTolerance_;\n  }\n\n  /**\n   * Returns the associated {@link module:ol/layer/Vector~Vector vectorlayer} of\n   * the (last) selected feature. Note that this will not work with any\n   * programmatic method like pushing features to\n   * {@link module:ol/interaction/Select~Select#getFeatures collection}.\n   * @param {module:ol/Feature|module:ol/render/Feature} feature Feature\n   * @return {module:ol/layer/Vector} Layer.\n   * @api\n   */\n  getLayer(feature) {\n    const key = getUid(feature);\n    return (\n      /** @type {module:ol/layer/Vector} */ (this.featureLayerAssociation_[key])\n    );\n  }\n\n  /**\n   * Hit-detection tolerance. Pixels inside the radius around the given position\n   * will be checked for features. This only works for the canvas renderer and\n   * not for WebGL.\n   * @param {number} hitTolerance Hit tolerance in pixels.\n   * @api\n   */\n  setHitTolerance(hitTolerance) {\n    this.hitTolerance_ = hitTolerance;\n  }\n\n  /**\n   * Remove the interaction from its current map, if any,  and attach it to a new\n   * map, if any. Pass `null` to just remove the interaction from the current map.\n   * @param {module:ol/PluggableMap} map Map.\n   * @override\n   * @api\n   */\n  setMap(map) {\n    const currentMap = this.getMap();\n    const selectedFeatures =\n        this.featureOverlay_.getSource().getFeaturesCollection();\n    if (currentMap) {\n      selectedFeatures.forEach(currentMap.unskipFeature.bind(currentMap));\n    }\n    super.setMap(map);\n    this.featureOverlay_.setMap(map);\n    if (map) {\n      selectedFeatures.forEach(map.skipFeature.bind(map));\n    }\n  }\n\n  /**\n   * @param {module:ol/Collection~CollectionEvent} evt Event.\n   * @private\n   */\n  addFeature_(evt) {\n    const map = this.getMap();\n    if (map) {\n      map.skipFeature(/** @type {module:ol/Feature} */ (evt.element));\n    }\n  }\n\n  /**\n   * @param {module:ol/Collection~CollectionEvent} evt Event.\n   * @private\n   */\n  removeFeature_(evt) {\n    const map = this.getMap();\n    if (map) {\n      map.unskipFeature(/** @type {module:ol/Feature} */ (evt.element));\n    }\n  }\n\n  /**\n   * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n   * @private\n   */\n  removeFeatureLayerAssociation_(feature) {\n    const key = getUid(feature);\n    delete this.featureLayerAssociation_[key];\n  }\n}\n\n\n/**\n * Handles the {@link module:ol/MapBrowserEvent map browser event} and may change the\n * selected state of features.\n * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @this {module:ol/interaction/Select}\n */\nfunction handleEvent(mapBrowserEvent) {\n  if (!this.condition_(mapBrowserEvent)) {\n    return true;\n  }\n  const add = this.addCondition_(mapBrowserEvent);\n  const remove = this.removeCondition_(mapBrowserEvent);\n  const toggle = this.toggleCondition_(mapBrowserEvent);\n  const set = !add && !remove && !toggle;\n  const map = mapBrowserEvent.map;\n  const features = this.featureOverlay_.getSource().getFeaturesCollection();\n  const deselected = [];\n  const selected = [];\n  if (set) {\n    // Replace the currently selected feature(s) with the feature(s) at the\n    // pixel, or clear the selected feature(s) if there is no feature at\n    // the pixel.\n    clear(this.featureLayerAssociation_);\n    map.forEachFeatureAtPixel(mapBrowserEvent.pixel,\n      (\n        /**\n         * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n         * @param {module:ol/layer/Layer} layer Layer.\n         * @return {boolean|undefined} Continue to iterate over the features.\n         */\n        function(feature, layer) {\n          if (this.filter_(feature, layer)) {\n            selected.push(feature);\n            this.addFeatureLayerAssociation_(feature, layer);\n            return !this.multi_;\n          }\n        }).bind(this), {\n        layerFilter: this.layerFilter_,\n        hitTolerance: this.hitTolerance_\n      });\n    for (let i = features.getLength() - 1; i >= 0; --i) {\n      const feature = features.item(i);\n      const index = selected.indexOf(feature);\n      if (index > -1) {\n        // feature is already selected\n        selected.splice(index, 1);\n      } else {\n        features.remove(feature);\n        deselected.push(feature);\n      }\n    }\n    if (selected.length !== 0) {\n      features.extend(selected);\n    }\n  } else {\n    // Modify the currently selected feature(s).\n    map.forEachFeatureAtPixel(mapBrowserEvent.pixel,\n      (\n        /**\n         * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n         * @param {module:ol/layer/Layer} layer Layer.\n         * @return {boolean|undefined} Continue to iterate over the features.\n         */\n        function(feature, layer) {\n          if (this.filter_(feature, layer)) {\n            if ((add || toggle) && !includes(features.getArray(), feature)) {\n              selected.push(feature);\n              this.addFeatureLayerAssociation_(feature, layer);\n            } else if ((remove || toggle) && includes(features.getArray(), feature)) {\n              deselected.push(feature);\n              this.removeFeatureLayerAssociation_(feature);\n            }\n            return !this.multi_;\n          }\n        }).bind(this), {\n        layerFilter: this.layerFilter_,\n        hitTolerance: this.hitTolerance_\n      });\n    for (let j = deselected.length - 1; j >= 0; --j) {\n      features.remove(deselected[j]);\n    }\n    features.extend(selected);\n  }\n  if (selected.length > 0 || deselected.length > 0) {\n    this.dispatchEvent(\n      new SelectEvent(SelectEventType.SELECT,\n        selected, deselected, mapBrowserEvent));\n  }\n  return pointerMove(mapBrowserEvent);\n}\n\n\n/**\n * @return {module:ol/style/Style~StyleFunction} Styles.\n */\nfunction getDefaultStyleFunction() {\n  const styles = createEditingStyle();\n  extend(styles[GeometryType.POLYGON], styles[GeometryType.LINE_STRING]);\n  extend(styles[GeometryType.GEOMETRY_COLLECTION], styles[GeometryType.LINE_STRING]);\n\n  return function(feature, resolution) {\n    if (!feature.getGeometry()) {\n      return null;\n    }\n    return styles[feature.getGeometry().getType()];\n  };\n}\n\n\nexport default Select;\n","/**\n * @module ol/interaction/Snap\n */\nimport {getUid} from '../util.js';\nimport {CollectionEvent} from '../Collection.js';\nimport CollectionEventType from '../CollectionEventType.js';\nimport {distance as coordinateDistance, squaredDistance as squaredCoordinateDistance, closestOnCircle, closestOnSegment, squaredDistanceToSegment} from '../coordinate.js';\nimport {listen, unlistenByKey} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport {boundingExtent, createEmpty} from '../extent.js';\nimport {TRUE, FALSE} from '../functions.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport {fromCircle} from '../geom/Polygon.js';\nimport PointerInteraction, {handleEvent as handlePointerEvent} from '../interaction/Pointer.js';\nimport {getValues} from '../obj.js';\nimport {VectorSourceEvent} from '../source/Vector.js';\nimport VectorEventType from '../source/VectorEventType.js';\nimport RBush from '../structs/RBush.js';\n\n\n/**\n * @typedef {Object} Result\n * @property {boolean} snapped\n * @property {module:ol/coordinate~Coordinate|null} vertex\n * @property {module:ol/pixel~Pixel|null} vertexPixel\n */\n\n\n/**\n * @typedef {Object} SegmentData\n * @property {module:ol/Feature} feature\n * @property {Array.<module:ol/coordinate~Coordinate>} segment\n */\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/Collection.<module:ol/Feature>} [features] Snap to these features. Either this option or source should be provided.\n * @property {boolean} [edge=true] Snap to edges.\n * @property {boolean} [vertex=true] Snap to vertices.\n * @property {number} [pixelTolerance=10] Pixel tolerance for considering the pointer close enough to a segment or\n * vertex for snapping.\n * @property {module:ol/source/Vector} [source] Snap to features from this source. Either this option or features should be provided\n */\n\n\n/**\n * @classdesc\n * Handles snapping of vector features while modifying or drawing them.  The\n * features can come from a {@link module:ol/source/Vector} or {@link module:ol/Collection~Collection}\n * Any interaction object that allows the user to interact\n * with the features using the mouse can benefit from the snapping, as long\n * as it is added before.\n *\n * The snap interaction modifies map browser event `coordinate` and `pixel`\n * properties to force the snap to occur to any interaction that them.\n *\n * Example:\n *\n *     import Snap from 'ol/interaction/Snap';\n *\n *     var snap = new Snap({\n *       source: source\n *     });\n *\n * @api\n */\nclass Snap extends PointerInteraction {\n  /**\n   * @param {module:ol/interaction/Snap~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    super({\n      handleEvent: handleEvent,\n      handleDownEvent: TRUE,\n      handleUpEvent: handleUpEvent,\n      stopDown: FALSE\n    });\n\n    const options = opt_options ? opt_options : {};\n\n    /**\n     * @type {module:ol/source/Vector}\n     * @private\n     */\n    this.source_ = options.source ? options.source : null;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.vertex_ = options.vertex !== undefined ? options.vertex : true;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.edge_ = options.edge !== undefined ? options.edge : true;\n\n    /**\n     * @type {module:ol/Collection.<module:ol/Feature>}\n     * @private\n     */\n    this.features_ = options.features ? options.features : null;\n\n    /**\n     * @type {Array.<module:ol/events~EventsKey>}\n     * @private\n     */\n    this.featuresListenerKeys_ = [];\n\n    /**\n     * @type {Object.<number, module:ol/events~EventsKey>}\n     * @private\n     */\n    this.featureChangeListenerKeys_ = {};\n\n    /**\n     * Extents are preserved so indexed segment can be quickly removed\n     * when its feature geometry changes\n     * @type {Object.<number, module:ol/extent~Extent>}\n     * @private\n     */\n    this.indexedFeaturesExtents_ = {};\n\n    /**\n     * If a feature geometry changes while a pointer drag|move event occurs, the\n     * feature doesn't get updated right away.  It will be at the next 'pointerup'\n     * event fired.\n     * @type {!Object.<number, module:ol/Feature>}\n     * @private\n     */\n    this.pendingFeatures_ = {};\n\n    /**\n     * Used for distance sorting in sortByDistance_\n     * @type {module:ol/coordinate~Coordinate}\n     * @private\n     */\n    this.pixelCoordinate_ = null;\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.pixelTolerance_ = options.pixelTolerance !== undefined ?\n      options.pixelTolerance : 10;\n\n    /**\n     * @type {function(module:ol/interaction/Snap~SegmentData, module:ol/interaction/Snap~SegmentData): number}\n     * @private\n     */\n    this.sortByDistance_ = sortByDistance.bind(this);\n\n\n    /**\n    * Segment RTree for each layer\n    * @type {module:ol/structs/RBush.<module:ol/interaction/Snap~SegmentData>}\n    * @private\n    */\n    this.rBush_ = new RBush();\n\n\n    /**\n    * @const\n    * @private\n    * @type {Object.<string, function(module:ol/Feature, module:ol/geom/Geometry)>}\n    */\n    this.SEGMENT_WRITERS_ = {\n      'Point': this.writePointGeometry_,\n      'LineString': this.writeLineStringGeometry_,\n      'LinearRing': this.writeLineStringGeometry_,\n      'Polygon': this.writePolygonGeometry_,\n      'MultiPoint': this.writeMultiPointGeometry_,\n      'MultiLineString': this.writeMultiLineStringGeometry_,\n      'MultiPolygon': this.writeMultiPolygonGeometry_,\n      'GeometryCollection': this.writeGeometryCollectionGeometry_,\n      'Circle': this.writeCircleGeometry_\n    };\n  }\n\n  /**\n   * Add a feature to the collection of features that we may snap to.\n   * @param {module:ol/Feature} feature Feature.\n   * @param {boolean=} opt_listen Whether to listen to the feature change or not\n   *     Defaults to `true`.\n   * @api\n   */\n  addFeature(feature, opt_listen) {\n    const register = opt_listen !== undefined ? opt_listen : true;\n    const feature_uid = getUid(feature);\n    const geometry = feature.getGeometry();\n    if (geometry) {\n      const segmentWriter = this.SEGMENT_WRITERS_[geometry.getType()];\n      if (segmentWriter) {\n        this.indexedFeaturesExtents_[feature_uid] = geometry.getExtent(createEmpty());\n        segmentWriter.call(this, feature, geometry);\n      }\n    }\n\n    if (register) {\n      this.featureChangeListenerKeys_[feature_uid] = listen(\n        feature,\n        EventType.CHANGE,\n        this.handleFeatureChange_, this);\n    }\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature.\n   * @private\n   */\n  forEachFeatureAdd_(feature) {\n    this.addFeature(feature);\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature.\n   * @private\n   */\n  forEachFeatureRemove_(feature) {\n    this.removeFeature(feature);\n  }\n\n  /**\n   * @return {module:ol/Collection.<module:ol/Feature>|Array.<module:ol/Feature>} Features.\n   * @private\n   */\n  getFeatures_() {\n    let features;\n    if (this.features_) {\n      features = this.features_;\n    } else if (this.source_) {\n      features = this.source_.getFeatures();\n    }\n    return (\n      /** @type {!Array.<module:ol/Feature>|!module:ol/Collection.<module:ol/Feature>} */ (features)\n    );\n  }\n\n  /**\n   * @param {module:ol/source/Vector|module:ol/Collection~CollectionEvent} evt Event.\n   * @private\n   */\n  handleFeatureAdd_(evt) {\n    let feature;\n    if (evt instanceof VectorSourceEvent) {\n      feature = evt.feature;\n    } else if (evt instanceof CollectionEvent) {\n      feature = evt.element;\n    }\n    this.addFeature(/** @type {module:ol/Feature} */ (feature));\n  }\n\n  /**\n   * @param {module:ol/source/Vector|module:ol/Collection~CollectionEvent} evt Event.\n   * @private\n   */\n  handleFeatureRemove_(evt) {\n    let feature;\n    if (evt instanceof VectorSourceEvent) {\n      feature = evt.feature;\n    } else if (evt instanceof CollectionEvent) {\n      feature = evt.element;\n    }\n    this.removeFeature(/** @type {module:ol/Feature} */ (feature));\n  }\n\n  /**\n   * @param {module:ol/events/Event} evt Event.\n   * @private\n   */\n  handleFeatureChange_(evt) {\n    const feature = /** @type {module:ol/Feature} */ (evt.target);\n    if (this.handlingDownUpSequence) {\n      const uid = getUid(feature);\n      if (!(uid in this.pendingFeatures_)) {\n        this.pendingFeatures_[uid] = feature;\n      }\n    } else {\n      this.updateFeature_(feature);\n    }\n  }\n\n  /**\n   * Remove a feature from the collection of features that we may snap to.\n   * @param {module:ol/Feature} feature Feature\n   * @param {boolean=} opt_unlisten Whether to unlisten to the feature change\n   *     or not. Defaults to `true`.\n   * @api\n   */\n  removeFeature(feature, opt_unlisten) {\n    const unregister = opt_unlisten !== undefined ? opt_unlisten : true;\n    const feature_uid = getUid(feature);\n    const extent = this.indexedFeaturesExtents_[feature_uid];\n    if (extent) {\n      const rBush = this.rBush_;\n      const nodesToRemove = [];\n      rBush.forEachInExtent(extent, function(node) {\n        if (feature === node.feature) {\n          nodesToRemove.push(node);\n        }\n      });\n      for (let i = nodesToRemove.length - 1; i >= 0; --i) {\n        rBush.remove(nodesToRemove[i]);\n      }\n    }\n\n    if (unregister) {\n      unlistenByKey(this.featureChangeListenerKeys_[feature_uid]);\n      delete this.featureChangeListenerKeys_[feature_uid];\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setMap(map) {\n    const currentMap = this.getMap();\n    const keys = this.featuresListenerKeys_;\n    const features = this.getFeatures_();\n\n    if (currentMap) {\n      keys.forEach(unlistenByKey);\n      keys.length = 0;\n      features.forEach(this.forEachFeatureRemove_.bind(this));\n    }\n    super.setMap(map);\n\n    if (map) {\n      if (this.features_) {\n        keys.push(\n          listen(this.features_, CollectionEventType.ADD,\n            this.handleFeatureAdd_, this),\n          listen(this.features_, CollectionEventType.REMOVE,\n            this.handleFeatureRemove_, this)\n        );\n      } else if (this.source_) {\n        keys.push(\n          listen(this.source_, VectorEventType.ADDFEATURE,\n            this.handleFeatureAdd_, this),\n          listen(this.source_, VectorEventType.REMOVEFEATURE,\n            this.handleFeatureRemove_, this)\n        );\n      }\n      features.forEach(this.forEachFeatureAdd_.bind(this));\n    }\n  }\n\n  /**\n   * @param {module:ol/pixel~Pixel} pixel Pixel\n   * @param {module:ol/coordinate~Coordinate} pixelCoordinate Coordinate\n   * @param {module:ol/PluggableMap} map Map.\n   * @return {module:ol/interaction/Snap~Result} Snap result\n   */\n  snapTo(pixel, pixelCoordinate, map) {\n\n    const lowerLeft = map.getCoordinateFromPixel(\n      [pixel[0] - this.pixelTolerance_, pixel[1] + this.pixelTolerance_]);\n    const upperRight = map.getCoordinateFromPixel(\n      [pixel[0] + this.pixelTolerance_, pixel[1] - this.pixelTolerance_]);\n    const box = boundingExtent([lowerLeft, upperRight]);\n\n    let segments = this.rBush_.getInExtent(box);\n\n    // If snapping on vertices only, don't consider circles\n    if (this.vertex_ && !this.edge_) {\n      segments = segments.filter(function(segment) {\n        return segment.feature.getGeometry().getType() !==\n            GeometryType.CIRCLE;\n      });\n    }\n\n    let snappedToVertex = false;\n    let snapped = false;\n    let vertex = null;\n    let vertexPixel = null;\n    let dist, pixel1, pixel2, squaredDist1, squaredDist2;\n    if (segments.length > 0) {\n      this.pixelCoordinate_ = pixelCoordinate;\n      segments.sort(this.sortByDistance_);\n      const closestSegment = segments[0].segment;\n      const isCircle = segments[0].feature.getGeometry().getType() ===\n          GeometryType.CIRCLE;\n      if (this.vertex_ && !this.edge_) {\n        pixel1 = map.getPixelFromCoordinate(closestSegment[0]);\n        pixel2 = map.getPixelFromCoordinate(closestSegment[1]);\n        squaredDist1 = squaredCoordinateDistance(pixel, pixel1);\n        squaredDist2 = squaredCoordinateDistance(pixel, pixel2);\n        dist = Math.sqrt(Math.min(squaredDist1, squaredDist2));\n        snappedToVertex = dist <= this.pixelTolerance_;\n        if (snappedToVertex) {\n          snapped = true;\n          vertex = squaredDist1 > squaredDist2 ? closestSegment[1] : closestSegment[0];\n          vertexPixel = map.getPixelFromCoordinate(vertex);\n        }\n      } else if (this.edge_) {\n        if (isCircle) {\n          vertex = closestOnCircle(pixelCoordinate,\n            /** @type {module:ol/geom/Circle} */ (segments[0].feature.getGeometry()));\n        } else {\n          vertex = closestOnSegment(pixelCoordinate, closestSegment);\n        }\n        vertexPixel = map.getPixelFromCoordinate(vertex);\n        if (coordinateDistance(pixel, vertexPixel) <= this.pixelTolerance_) {\n          snapped = true;\n          if (this.vertex_ && !isCircle) {\n            pixel1 = map.getPixelFromCoordinate(closestSegment[0]);\n            pixel2 = map.getPixelFromCoordinate(closestSegment[1]);\n            squaredDist1 = squaredCoordinateDistance(vertexPixel, pixel1);\n            squaredDist2 = squaredCoordinateDistance(vertexPixel, pixel2);\n            dist = Math.sqrt(Math.min(squaredDist1, squaredDist2));\n            snappedToVertex = dist <= this.pixelTolerance_;\n            if (snappedToVertex) {\n              vertex = squaredDist1 > squaredDist2 ? closestSegment[1] : closestSegment[0];\n              vertexPixel = map.getPixelFromCoordinate(vertex);\n            }\n          }\n        }\n      }\n      if (snapped) {\n        vertexPixel = [Math.round(vertexPixel[0]), Math.round(vertexPixel[1])];\n      }\n    }\n    return (\n      /** @type {module:ol/interaction/Snap~Result} */ ({\n        snapped: snapped,\n        vertex: vertex,\n        vertexPixel: vertexPixel\n      })\n    );\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature\n   * @private\n   */\n  updateFeature_(feature) {\n    this.removeFeature(feature, false);\n    this.addFeature(feature, false);\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature\n   * @param {module:ol/geom/Circle} geometry Geometry.\n   * @private\n   */\n  writeCircleGeometry_(feature, geometry) {\n    const polygon = fromCircle(geometry);\n    const coordinates = polygon.getCoordinates()[0];\n    for (let i = 0, ii = coordinates.length - 1; i < ii; ++i) {\n      const segment = coordinates.slice(i, i + 2);\n      const segmentData = /** @type {module:ol/interaction/Snap~SegmentData} */ ({\n        feature: feature,\n        segment: segment\n      });\n      this.rBush_.insert(boundingExtent(segment), segmentData);\n    }\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature\n   * @param {module:ol/geom/GeometryCollection} geometry Geometry.\n   * @private\n   */\n  writeGeometryCollectionGeometry_(feature, geometry) {\n    const geometries = geometry.getGeometriesArray();\n    for (let i = 0; i < geometries.length; ++i) {\n      const segmentWriter = this.SEGMENT_WRITERS_[geometries[i].getType()];\n      if (segmentWriter) {\n        segmentWriter.call(this, feature, geometries[i]);\n      }\n    }\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature\n   * @param {module:ol/geom/LineString} geometry Geometry.\n   * @private\n   */\n  writeLineStringGeometry_(feature, geometry) {\n    const coordinates = geometry.getCoordinates();\n    for (let i = 0, ii = coordinates.length - 1; i < ii; ++i) {\n      const segment = coordinates.slice(i, i + 2);\n      const segmentData = /** @type {module:ol/interaction/Snap~SegmentData} */ ({\n        feature: feature,\n        segment: segment\n      });\n      this.rBush_.insert(boundingExtent(segment), segmentData);\n    }\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature\n   * @param {module:ol/geom/MultiLineString} geometry Geometry.\n   * @private\n   */\n  writeMultiLineStringGeometry_(feature, geometry) {\n    const lines = geometry.getCoordinates();\n    for (let j = 0, jj = lines.length; j < jj; ++j) {\n      const coordinates = lines[j];\n      for (let i = 0, ii = coordinates.length - 1; i < ii; ++i) {\n        const segment = coordinates.slice(i, i + 2);\n        const segmentData = /** @type {module:ol/interaction/Snap~SegmentData} */ ({\n          feature: feature,\n          segment: segment\n        });\n        this.rBush_.insert(boundingExtent(segment), segmentData);\n      }\n    }\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature\n   * @param {module:ol/geom/MultiPoint} geometry Geometry.\n   * @private\n   */\n  writeMultiPointGeometry_(feature, geometry) {\n    const points = geometry.getCoordinates();\n    for (let i = 0, ii = points.length; i < ii; ++i) {\n      const coordinates = points[i];\n      const segmentData = /** @type {module:ol/interaction/Snap~SegmentData} */ ({\n        feature: feature,\n        segment: [coordinates, coordinates]\n      });\n      this.rBush_.insert(geometry.getExtent(), segmentData);\n    }\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature\n   * @param {module:ol/geom/MultiPolygon} geometry Geometry.\n   * @private\n   */\n  writeMultiPolygonGeometry_(feature, geometry) {\n    const polygons = geometry.getCoordinates();\n    for (let k = 0, kk = polygons.length; k < kk; ++k) {\n      const rings = polygons[k];\n      for (let j = 0, jj = rings.length; j < jj; ++j) {\n        const coordinates = rings[j];\n        for (let i = 0, ii = coordinates.length - 1; i < ii; ++i) {\n          const segment = coordinates.slice(i, i + 2);\n          const segmentData = /** @type {module:ol/interaction/Snap~SegmentData} */ ({\n            feature: feature,\n            segment: segment\n          });\n          this.rBush_.insert(boundingExtent(segment), segmentData);\n        }\n      }\n    }\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature\n   * @param {module:ol/geom/Point} geometry Geometry.\n   * @private\n   */\n  writePointGeometry_(feature, geometry) {\n    const coordinates = geometry.getCoordinates();\n    const segmentData = /** @type {module:ol/interaction/Snap~SegmentData} */ ({\n      feature: feature,\n      segment: [coordinates, coordinates]\n    });\n    this.rBush_.insert(geometry.getExtent(), segmentData);\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature\n   * @param {module:ol/geom/Polygon} geometry Geometry.\n   * @private\n   */\n  writePolygonGeometry_(feature, geometry) {\n    const rings = geometry.getCoordinates();\n    for (let j = 0, jj = rings.length; j < jj; ++j) {\n      const coordinates = rings[j];\n      for (let i = 0, ii = coordinates.length - 1; i < ii; ++i) {\n        const segment = coordinates.slice(i, i + 2);\n        const segmentData = /** @type {module:ol/interaction/Snap~SegmentData} */ ({\n          feature: feature,\n          segment: segment\n        });\n        this.rBush_.insert(boundingExtent(segment), segmentData);\n      }\n    }\n  }\n}\n\n\n/**\n * Handle all pointer events events.\n * @param {module:ol/MapBrowserEvent} evt A move event.\n * @return {boolean} Pass the event to other interactions.\n * @this {module:ol/interaction/Snap}\n */\nexport function handleEvent(evt) {\n  const result = this.snapTo(evt.pixel, evt.coordinate, evt.map);\n  if (result.snapped) {\n    evt.coordinate = result.vertex.slice(0, 2);\n    evt.pixel = result.vertexPixel;\n  }\n  return handlePointerEvent.call(this, evt);\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} evt Event.\n * @return {boolean} Stop drag sequence?\n * @this {module:ol/interaction/Snap}\n */\nfunction handleUpEvent(evt) {\n  const featuresToUpdate = getValues(this.pendingFeatures_);\n  if (featuresToUpdate.length) {\n    featuresToUpdate.forEach(this.updateFeature_.bind(this));\n    this.pendingFeatures_ = {};\n  }\n  return false;\n}\n\n\n/**\n * Sort segments by distance, helper function\n * @param {module:ol/interaction/Snap~SegmentData} a The first segment data.\n * @param {module:ol/interaction/Snap~SegmentData} b The second segment data.\n * @return {number} The difference in distance.\n * @this {module:ol/interaction/Snap}\n */\nfunction sortByDistance(a, b) {\n  const deltaA = squaredDistanceToSegment(this.pixelCoordinate_, a.segment);\n  const deltaB = squaredDistanceToSegment(this.pixelCoordinate_, b.segment);\n  return deltaA - deltaB;\n}\n\nexport default Snap;\n","/**\n * @module ol/interaction/Translate\n */\nimport Collection from '../Collection.js';\nimport {getChangeEventType} from '../Object.js';\nimport {listen} from '../events.js';\nimport Event from '../events/Event.js';\nimport {TRUE} from '../functions.js';\nimport {includes} from '../array.js';\nimport PointerInteraction from '../interaction/Pointer.js';\nimport InteractionProperty from '../interaction/Property.js';\n\n\n/**\n * @enum {string}\n */\nconst TranslateEventType = {\n  /**\n   * Triggered upon feature translation start.\n   * @event TranslateEvent#translatestart\n   * @api\n   */\n  TRANSLATESTART: 'translatestart',\n  /**\n   * Triggered upon feature translation.\n   * @event TranslateEvent#translating\n   * @api\n   */\n  TRANSLATING: 'translating',\n  /**\n   * Triggered upon feature translation end.\n   * @event TranslateEvent#translateend\n   * @api\n   */\n  TRANSLATEEND: 'translateend'\n};\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/Collection.<module:ol/Feature>} [features] Only features contained in this collection will be able to be translated. If\n * not specified, all features on the map will be able to be translated.\n * @property {Array.<module:ol/layer/Layer>|function(module:ol/layer/Layer): boolean} [layers] A list of layers from which features should be\n * translated. Alternatively, a filter function can be provided. The\n * function will be called for each layer in the map and should return\n * `true` for layers that you want to be translatable. If the option is\n * absent, all visible layers will be considered translatable.\n * @property {number} [hitTolerance=0] Hit-detection tolerance. Pixels inside the radius around the given position\n * will be checked for features. This only works for the canvas renderer and\n * not for WebGL.\n */\n\n\n/**\n * @classdesc\n * Events emitted by {@link module:ol/interaction/Translate~Translate} instances\n * are instances of this type.\n */\nexport class TranslateEvent extends Event {\n  /**\n   * @param {module:ol/interaction/Translate~TranslateEventType} type Type.\n   * @param {module:ol/Collection.<module:ol/Feature>} features The features translated.\n   * @param {module:ol/coordinate~Coordinate} coordinate The event coordinate.\n   */\n  constructor(type, features, coordinate) {\n\n    super(type);\n\n    /**\n     * The features being translated.\n     * @type {module:ol/Collection.<module:ol/Feature>}\n     * @api\n     */\n    this.features = features;\n\n    /**\n     * The coordinate of the drag event.\n     * @const\n     * @type {module:ol/coordinate~Coordinate}\n     * @api\n     */\n    this.coordinate = coordinate;\n\n  }\n\n}\n\n\n/**\n * @classdesc\n * Interaction for translating (moving) features.\n *\n * @fires module:ol/interaction/Translate~TranslateEvent\n * @api\n */\nclass Translate extends PointerInteraction {\n  /**\n   * @param {module:ol/interaction/Translate~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n    super({\n      handleDownEvent: handleDownEvent,\n      handleDragEvent: handleDragEvent,\n      handleMoveEvent: handleMoveEvent,\n      handleUpEvent: handleUpEvent\n    });\n\n    const options = opt_options ? opt_options : {};\n\n    /**\n     * The last position we translated to.\n     * @type {module:ol/coordinate~Coordinate}\n     * @private\n     */\n    this.lastCoordinate_ = null;\n\n\n    /**\n     * @type {module:ol/Collection.<module:ol/Feature>}\n     * @private\n     */\n    this.features_ = options.features !== undefined ? options.features : null;\n\n    /** @type {function(module:ol/layer/Layer): boolean} */\n    let layerFilter;\n    if (options.layers) {\n      if (typeof options.layers === 'function') {\n        layerFilter = options.layers;\n      } else {\n        const layers = options.layers;\n        layerFilter = function(layer) {\n          return includes(layers, layer);\n        };\n      }\n    } else {\n      layerFilter = TRUE;\n    }\n\n    /**\n     * @private\n     * @type {function(module:ol/layer/Layer): boolean}\n     */\n    this.layerFilter_ = layerFilter;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.hitTolerance_ = options.hitTolerance ? options.hitTolerance : 0;\n\n    /**\n     * @type {module:ol/Feature}\n     * @private\n     */\n    this.lastFeature_ = null;\n\n    listen(this,\n      getChangeEventType(InteractionProperty.ACTIVE),\n      this.handleActiveChanged_, this);\n\n  }\n\n  /**\n   * Tests to see if the given coordinates intersects any of our selected\n   * features.\n   * @param {module:ol/pixel~Pixel} pixel Pixel coordinate to test for intersection.\n   * @param {module:ol/PluggableMap} map Map to test the intersection on.\n   * @return {module:ol/Feature} Returns the feature found at the specified pixel\n   * coordinates.\n   * @private\n   */\n  featuresAtPixel_(pixel, map) {\n    return map.forEachFeatureAtPixel(pixel,\n      function(feature) {\n        if (!this.features_ || includes(this.features_.getArray(), feature)) {\n          return feature;\n        }\n      }.bind(this), {\n        layerFilter: this.layerFilter_,\n        hitTolerance: this.hitTolerance_\n      });\n  }\n\n  /**\n   * Returns the Hit-detection tolerance.\n   * @returns {number} Hit tolerance in pixels.\n   * @api\n   */\n  getHitTolerance() {\n    return this.hitTolerance_;\n  }\n\n  /**\n   * Hit-detection tolerance. Pixels inside the radius around the given position\n   * will be checked for features. This only works for the canvas renderer and\n   * not for WebGL.\n   * @param {number} hitTolerance Hit tolerance in pixels.\n   * @api\n   */\n  setHitTolerance(hitTolerance) {\n    this.hitTolerance_ = hitTolerance;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setMap(map) {\n    const oldMap = this.getMap();\n    super.setMap(map);\n    this.updateState_(oldMap);\n  }\n\n  /**\n   * @private\n   */\n  handleActiveChanged_() {\n    this.updateState_(null);\n  }\n\n  /**\n   * @param {module:ol/PluggableMap} oldMap Old map.\n   * @private\n   */\n  updateState_(oldMap) {\n    let map = this.getMap();\n    const active = this.getActive();\n    if (!map || !active) {\n      map = map || oldMap;\n      if (map) {\n        const elem = map.getViewport();\n        elem.classList.remove('ol-grab', 'ol-grabbing');\n      }\n    }\n  }\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} event Event.\n * @return {boolean} Start drag sequence?\n * @this {module:ol/interaction/Translate}\n */\nfunction handleDownEvent(event) {\n  this.lastFeature_ = this.featuresAtPixel_(event.pixel, event.map);\n  if (!this.lastCoordinate_ && this.lastFeature_) {\n    this.lastCoordinate_ = event.coordinate;\n    handleMoveEvent.call(this, event);\n\n    const features = this.features_ || new Collection([this.lastFeature_]);\n\n    this.dispatchEvent(\n      new TranslateEvent(\n        TranslateEventType.TRANSLATESTART, features,\n        event.coordinate));\n    return true;\n  }\n  return false;\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} event Event.\n * @return {boolean} Stop drag sequence?\n * @this {module:ol/interaction/Translate}\n */\nfunction handleUpEvent(event) {\n  if (this.lastCoordinate_) {\n    this.lastCoordinate_ = null;\n    handleMoveEvent.call(this, event);\n\n    const features = this.features_ || new Collection([this.lastFeature_]);\n\n    this.dispatchEvent(\n      new TranslateEvent(\n        TranslateEventType.TRANSLATEEND, features,\n        event.coordinate));\n    return true;\n  }\n  return false;\n}\n\n\n/**\n * @param {module:ol/MapBrowserPointerEvent} event Event.\n * @this {module:ol/interaction/Translate}\n */\nfunction handleDragEvent(event) {\n  if (this.lastCoordinate_) {\n    const newCoordinate = event.coordinate;\n    const deltaX = newCoordinate[0] - this.lastCoordinate_[0];\n    const deltaY = newCoordinate[1] - this.lastCoordinate_[1];\n\n    const features = this.features_ || new Collection([this.lastFeature_]);\n\n    features.forEach(function(feature) {\n      const geom = feature.getGeometry();\n      geom.translate(deltaX, deltaY);\n      feature.setGeometry(geom);\n    });\n\n    this.lastCoordinate_ = newCoordinate;\n    this.dispatchEvent(\n      new TranslateEvent(\n        TranslateEventType.TRANSLATING, features,\n        newCoordinate));\n  }\n}\n\n\n/**\n * @param {module:ol/MapBrowserEvent} event Event.\n * @this {module:ol/interaction/Translate}\n */\nfunction handleMoveEvent(event) {\n  const elem = event.map.getViewport();\n\n  // Change the cursor to grab/grabbing if hovering any of the features managed\n  // by the interaction\n  if (this.featuresAtPixel_(event.pixel, event.map)) {\n    elem.classList.remove(this.lastCoordinate_ ? 'ol-grab' : 'ol-grabbing');\n    elem.classList.add(this.lastCoordinate_ ? 'ol-grabbing' : 'ol-grab');\n  } else {\n    elem.classList.remove('ol-grab', 'ol-grabbing');\n  }\n}\n\n\nexport default Translate;\n","/**\n * @module ol/interaction\n */\nimport Collection from './Collection.js';\nimport Kinetic from './Kinetic.js';\nimport DoubleClickZoom from './interaction/DoubleClickZoom.js';\nimport DragPan from './interaction/DragPan.js';\nimport DragRotate from './interaction/DragRotate.js';\nimport DragZoom from './interaction/DragZoom.js';\nimport KeyboardPan from './interaction/KeyboardPan.js';\nimport KeyboardZoom from './interaction/KeyboardZoom.js';\nimport MouseWheelZoom from './interaction/MouseWheelZoom.js';\nimport PinchRotate from './interaction/PinchRotate.js';\nimport PinchZoom from './interaction/PinchZoom.js';\n\nexport {default as DoubleClickZoom} from './interaction/DoubleClickZoom.js';\nexport {default as DragAndDrop} from './interaction/DragAndDrop.js';\nexport {default as DragBox} from './interaction/DragBox.js';\nexport {default as DragPan} from './interaction/DragPan.js';\nexport {default as DragRotate} from './interaction/DragRotate.js';\nexport {default as DragRotateAndZoom} from './interaction/DragRotateAndZoom.js';\nexport {default as DragZoom} from './interaction/DragZoom.js';\nexport {default as Draw} from './interaction/Draw.js';\nexport {default as Extent} from './interaction/Extent.js';\nexport {default as Interaction} from './interaction/Interaction.js';\nexport {default as KeyboardPan} from './interaction/KeyboardPan.js';\nexport {default as KeyboardZoom} from './interaction/KeyboardZoom.js';\nexport {default as Modify} from './interaction/Modify.js';\nexport {default as MouseWheelZoom} from './interaction/MouseWheelZoom.js';\nexport {default as PinchRotate} from './interaction/PinchRotate.js';\nexport {default as PinchZoom} from './interaction/PinchZoom.js';\nexport {default as Pointer} from './interaction/Pointer.js';\nexport {default as Select} from './interaction/Select.js';\nexport {default as Snap} from './interaction/Snap.js';\nexport {default as Translate} from './interaction/Translate.js';\n\n\n/**\n * @typedef {Object} DefaultsOptions\n * @property {boolean} [altShiftDragRotate=true] Whether Alt-Shift-drag rotate is\n * desired.\n * @property {boolean} [constrainResolution=false] Zoom to the closest integer\n * zoom level after the wheel/trackpad or pinch gesture ends.\n * @property {boolean} [doubleClickZoom=true] Whether double click zoom is\n * desired.\n * @property {boolean} [keyboard=true] Whether keyboard interaction is desired.\n * @property {boolean} [mouseWheelZoom=true] Whether mousewheel zoom is desired.\n * @property {boolean} [shiftDragZoom=true] Whether Shift-drag zoom is desired.\n * @property {boolean} [dragPan=true] Whether drag pan is desired.\n * @property {boolean} [pinchRotate=true] Whether pinch rotate is desired.\n * @property {boolean} [pinchZoom=true] Whether pinch zoom is desired.\n * @property {number} [zoomDelta] Zoom level delta when using keyboard or\n * mousewheel zoom.\n * @property {number} [zoomDuration] Duration of the zoom animation in\n * milliseconds.\n */\n\n\n/**\n * Set of interactions included in maps by default. Specific interactions can be\n * excluded by setting the appropriate option to false in the constructor\n * options, but the order of the interactions is fixed.  If you want to specify\n * a different order for interactions, you will need to create your own\n * {@link module:ol/interaction/Interaction} instances and insert\n * them into a {@link module:ol/Collection} in the order you want\n * before creating your {@link module:ol/Map~Map} instance. The default set of\n * interactions, in sequence, is:\n * * {@link module:ol/interaction/DragRotate~DragRotate}\n * * {@link module:ol/interaction/DoubleClickZoom~DoubleClickZoom}\n * * {@link module:ol/interaction/DragPan~DragPan}\n * * {@link module:ol/interaction/PinchRotate~PinchRotate}\n * * {@link module:ol/interaction/PinchZoom~PinchZoom}\n * * {@link module:ol/interaction/KeyboardPan~KeyboardPan}\n * * {@link module:ol/interaction/KeyboardZoom~KeyboardZoom}\n * * {@link module:ol/interaction/MouseWheelZoom~MouseWheelZoom}\n * * {@link module:ol/interaction/DragZoom~DragZoom}\n *\n * @param {module:ol/interaction/Interaction~DefaultsOptions=} opt_options\n * Defaults options.\n * @return {module:ol/Collection.<module:ol/interaction/Interaction>}\n * A collection of interactions to be used with the {@link module:ol/Map~Map}\n * constructor's `interactions` option.\n * @api\n */\nexport function defaults(opt_options) {\n\n  const options = opt_options ? opt_options : {};\n\n  const interactions = new Collection();\n\n  const kinetic = new Kinetic(-0.005, 0.05, 100);\n\n  const altShiftDragRotate = options.altShiftDragRotate !== undefined ?\n    options.altShiftDragRotate : true;\n  if (altShiftDragRotate) {\n    interactions.push(new DragRotate());\n  }\n\n  const doubleClickZoom = options.doubleClickZoom !== undefined ?\n    options.doubleClickZoom : true;\n  if (doubleClickZoom) {\n    interactions.push(new DoubleClickZoom({\n      delta: options.zoomDelta,\n      duration: options.zoomDuration\n    }));\n  }\n\n  const dragPan = options.dragPan !== undefined ? options.dragPan : true;\n  if (dragPan) {\n    interactions.push(new DragPan({\n      kinetic: kinetic\n    }));\n  }\n\n  const pinchRotate = options.pinchRotate !== undefined ? options.pinchRotate :\n    true;\n  if (pinchRotate) {\n    interactions.push(new PinchRotate());\n  }\n\n  const pinchZoom = options.pinchZoom !== undefined ? options.pinchZoom : true;\n  if (pinchZoom) {\n    interactions.push(new PinchZoom({\n      constrainResolution: options.constrainResolution,\n      duration: options.zoomDuration\n    }));\n  }\n\n  const keyboard = options.keyboard !== undefined ? options.keyboard : true;\n  if (keyboard) {\n    interactions.push(new KeyboardPan());\n    interactions.push(new KeyboardZoom({\n      delta: options.zoomDelta,\n      duration: options.zoomDuration\n    }));\n  }\n\n  const mouseWheelZoom = options.mouseWheelZoom !== undefined ?\n    options.mouseWheelZoom : true;\n  if (mouseWheelZoom) {\n    interactions.push(new MouseWheelZoom({\n      constrainResolution: options.constrainResolution,\n      duration: options.zoomDuration\n    }));\n  }\n\n  const shiftDragZoom = options.shiftDragZoom !== undefined ?\n    options.shiftDragZoom : true;\n  if (shiftDragZoom) {\n    interactions.push(new DragZoom({\n      duration: options.zoomDuration\n    }));\n  }\n\n  return interactions;\n\n}\n","/**\n * Default maximum allowed threshold  (in pixels) for reprojection\n * triangulation.\n * @type {number}\n */\nexport const ERROR_THRESHOLD = 0.5;\n\n/**\n * Enable automatic reprojection of raster sources. Default is `true`.\n * TODO: decide if we want to expose this as a build flag or remove it\n * @type {boolean}\n */\nexport const ENABLE_RASTER_REPROJECTION = true;\n","/**\n * @module ol/ImageCanvas\n */\nimport ImageBase from './ImageBase.js';\nimport ImageState from './ImageState.js';\n\n\n/**\n * A function that is called to trigger asynchronous canvas drawing.  It is\n * called with a \"done\" callback that should be called when drawing is done.\n * If any error occurs during drawing, the \"done\" callback should be called with\n * that error.\n *\n * @typedef {function(function(Error))} Loader\n */\n\n\nclass ImageCanvas extends ImageBase {\n\n  /**\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {number} resolution Resolution.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {HTMLCanvasElement} canvas Canvas.\n   * @param {module:ol/ImageCanvas~Loader=} opt_loader Optional loader function to\n   *     support asynchronous canvas drawing.\n   */\n  constructor(extent, resolution, pixelRatio, canvas, opt_loader) {\n\n    const state = opt_loader !== undefined ? ImageState.IDLE : ImageState.LOADED;\n\n    super(extent, resolution, pixelRatio, state);\n\n    /**\n     * Optional canvas loader function.\n     * @type {?module:ol/ImageCanvas~Loader}\n     * @private\n     */\n    this.loader_ = opt_loader !== undefined ? opt_loader : null;\n\n    /**\n     * @private\n     * @type {HTMLCanvasElement}\n     */\n    this.canvas_ = canvas;\n\n    /**\n     * @private\n     * @type {Error}\n     */\n    this.error_ = null;\n\n  }\n\n  /**\n   * Get any error associated with asynchronous rendering.\n   * @return {Error} Any error that occurred during rendering.\n   */\n  getError() {\n    return this.error_;\n  }\n\n  /**\n   * Handle async drawing complete.\n   * @param {Error} err Any error during drawing.\n   * @private\n   */\n  handleLoad_(err) {\n    if (err) {\n      this.error_ = err;\n      this.state = ImageState.ERROR;\n    } else {\n      this.state = ImageState.LOADED;\n    }\n    this.changed();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  load() {\n    if (this.state == ImageState.IDLE) {\n      this.state = ImageState.LOADING;\n      this.changed();\n      this.loader_(this.handleLoad_.bind(this));\n    }\n  }\n\n  /**\n   * @return {HTMLCanvasElement} Canvas element.\n   */\n  getImage() {\n    return this.canvas_;\n  }\n}\n\n\nexport default ImageCanvas;\n","/**\n * @module ol/render/Event\n */\n\nimport Event from '../events/Event.js';\n\nclass RenderEvent extends Event {\n\n  /**\n   * @param {module:ol/render/EventType} type Type.\n   * @param {module:ol/render/VectorContext=} opt_vectorContext Vector context.\n   * @param {module:ol/PluggableMap~FrameState=} opt_frameState Frame state.\n   * @param {?CanvasRenderingContext2D=} opt_context Context.\n   * @param {?module:ol/webgl/Context=} opt_glContext WebGL Context.\n   */\n  constructor(type, opt_vectorContext, opt_frameState, opt_context, opt_glContext) {\n\n    super(type);\n\n    /**\n     * For canvas, this is an instance of {@link module:ol/render/canvas/Immediate}.\n     * @type {module:ol/render/VectorContext|undefined}\n     * @api\n     */\n    this.vectorContext = opt_vectorContext;\n\n    /**\n     * An object representing the current render frame state.\n     * @type {module:ol/PluggableMap~FrameState|undefined}\n     * @api\n     */\n    this.frameState = opt_frameState;\n\n    /**\n     * Canvas context. Only available when a Canvas renderer is used, null\n     * otherwise.\n     * @type {CanvasRenderingContext2D|null|undefined}\n     * @api\n     */\n    this.context = opt_context;\n\n    /**\n     * WebGL context. Only available when a WebGL renderer is used, null\n     * otherwise.\n     * @type {module:ol/webgl/Context|null|undefined}\n     * @api\n     */\n    this.glContext = opt_glContext;\n\n  }\n\n}\n\nexport default RenderEvent;\n","/**\n * @module ol/render/VectorContext\n */\n\n/**\n * @classdesc\n * Context for drawing geometries.  A vector context is available on render\n * events and does not need to be constructed directly.\n * @api\n */\nclass VectorContext {\n  /**\n   * Render a geometry with a custom renderer.\n   *\n   * @param {module:ol/geom/SimpleGeometry} geometry Geometry.\n   * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n   * @param {Function} renderer Renderer.\n   */\n  drawCustom(geometry, feature, renderer) {}\n\n  /**\n   * Render a geometry.\n   *\n   * @param {module:ol/geom/Geometry} geometry The geometry to render.\n   */\n  drawGeometry(geometry) {}\n\n  /**\n   * Set the rendering style.\n   *\n   * @param {module:ol/style/Style} style The rendering style.\n   */\n  setStyle(style) {}\n\n  /**\n   * @param {module:ol/geom/Circle} circleGeometry Circle geometry.\n   * @param {module:ol/Feature} feature Feature.\n   */\n  drawCircle(circleGeometry, feature) {}\n\n  /**\n   * @param {module:ol/Feature} feature Feature.\n   * @param {module:ol/style/Style} style Style.\n   */\n  drawFeature(feature, style) {}\n\n  /**\n   * @param {module:ol/geom/GeometryCollection} geometryCollectionGeometry Geometry collection.\n   * @param {module:ol/Feature} feature Feature.\n   */\n  drawGeometryCollection(geometryCollectionGeometry, feature) {}\n\n  /**\n   * @param {module:ol/geom/LineString|module:ol/render/Feature} lineStringGeometry Line string geometry.\n   * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n   */\n  drawLineString(lineStringGeometry, feature) {}\n\n  /**\n   * @param {module:ol/geom/MultiLineString|module:ol/render/Feature} multiLineStringGeometry MultiLineString geometry.\n   * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n   */\n  drawMultiLineString(multiLineStringGeometry, feature) {}\n\n  /**\n   * @param {module:ol/geom/MultiPoint|module:ol/render/Feature} multiPointGeometry MultiPoint geometry.\n   * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n   */\n  drawMultiPoint(multiPointGeometry, feature) {}\n\n  /**\n   * @param {module:ol/geom/MultiPolygon} multiPolygonGeometry MultiPolygon geometry.\n   * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n   */\n  drawMultiPolygon(multiPolygonGeometry, feature) {}\n\n  /**\n   * @param {module:ol/geom/Point|module:ol/render/Feature} pointGeometry Point geometry.\n   * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n   */\n  drawPoint(pointGeometry, feature) {}\n\n  /**\n   * @param {module:ol/geom/Polygon|module:ol/render/Feature} polygonGeometry Polygon geometry.\n   * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n   */\n  drawPolygon(polygonGeometry, feature) {}\n\n  /**\n   * @param {module:ol/geom/Geometry|module:ol/render/Feature} geometry Geometry.\n   * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n   */\n  drawText(geometry, feature) {}\n\n  /**\n   * @param {module:ol/style/Fill} fillStyle Fill style.\n   * @param {module:ol/style/Stroke} strokeStyle Stroke style.\n   */\n  setFillStrokeStyle(fillStyle, strokeStyle) {}\n\n  /**\n   * @param {module:ol/style/Image} imageStyle Image style.\n   * @param {module:ol/render/canvas~DeclutterGroup=} opt_declutterGroup Declutter.\n   */\n  setImageStyle(imageStyle, opt_declutterGroup) {}\n\n  /**\n   * @param {module:ol/style/Text} textStyle Text style.\n   * @param {module:ol/render/canvas~DeclutterGroup=} opt_declutterGroup Declutter.\n   */\n  setTextStyle(textStyle, opt_declutterGroup) {}\n}\n\nexport default VectorContext;\n","/**\n * @module ol/render/canvas/Immediate\n */\n// FIXME test, especially polygons with holes and multipolygons\n// FIXME need to handle large thick features (where pixel size matters)\n// FIXME add offset and end to ol/geom/flat/transform~transform2D?\n\nimport {equals} from '../../array.js';\nimport {asColorLike} from '../../colorlike.js';\nimport {intersects} from '../../extent.js';\nimport GeometryType from '../../geom/GeometryType.js';\nimport {transformGeom2D} from '../../geom/SimpleGeometry.js';\nimport {transform2D} from '../../geom/flat/transform.js';\nimport {CANVAS_LINE_DASH} from '../../has.js';\nimport VectorContext from '../VectorContext.js';\nimport {defaultTextAlign, defaultFillStyle, defaultLineCap, defaultLineDash, defaultLineDashOffset, defaultLineJoin, defaultLineWidth, defaultMiterLimit, defaultStrokeStyle, defaultTextBaseline, defaultFont} from '../canvas.js';\nimport {create as createTransform, compose as composeTransform} from '../../transform.js';\n\n/**\n * @classdesc\n * A concrete subclass of {@link module:ol/render/VectorContext} that implements\n * direct rendering of features and geometries to an HTML5 Canvas context.\n * Instances of this class are created internally by the library and\n * provided to application code as vectorContext member of the\n * {@link module:ol/render/Event~RenderEvent} object associated with postcompose, precompose and\n * render events emitted by layers and maps.\n */\nclass CanvasImmediateRenderer extends VectorContext {\n  /**\n   * @param {CanvasRenderingContext2D} context Context.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {module:ol/transform~Transform} transform Transform.\n   * @param {number} viewRotation View rotation.\n   */\n  constructor(context, pixelRatio, extent, transform, viewRotation) {\n    super();\n\n    /**\n     * @private\n     * @type {CanvasRenderingContext2D}\n     */\n    this.context_ = context;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.pixelRatio_ = pixelRatio;\n\n    /**\n     * @private\n     * @type {module:ol/extent~Extent}\n     */\n    this.extent_ = extent;\n\n    /**\n     * @private\n     * @type {module:ol/transform~Transform}\n     */\n    this.transform_ = transform;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.viewRotation_ = viewRotation;\n\n    /**\n     * @private\n     * @type {?module:ol/render/canvas~FillState}\n     */\n    this.contextFillState_ = null;\n\n    /**\n     * @private\n     * @type {?module:ol/render/canvas~StrokeState}\n     */\n    this.contextStrokeState_ = null;\n\n    /**\n     * @private\n     * @type {?module:ol/render/canvas~TextState}\n     */\n    this.contextTextState_ = null;\n\n    /**\n     * @private\n     * @type {?module:ol/render/canvas~FillState}\n     */\n    this.fillState_ = null;\n\n    /**\n     * @private\n     * @type {?module:ol/render/canvas~StrokeState}\n     */\n    this.strokeState_ = null;\n\n    /**\n     * @private\n     * @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement}\n     */\n    this.image_ = null;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.imageAnchorX_ = 0;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.imageAnchorY_ = 0;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.imageHeight_ = 0;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.imageOpacity_ = 0;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.imageOriginX_ = 0;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.imageOriginY_ = 0;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.imageRotateWithView_ = false;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.imageRotation_ = 0;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.imageScale_ = 0;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.imageSnapToPixel_ = false;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.imageWidth_ = 0;\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.text_ = '';\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.textOffsetX_ = 0;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.textOffsetY_ = 0;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.textRotateWithView_ = false;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.textRotation_ = 0;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.textScale_ = 0;\n\n    /**\n     * @private\n     * @type {?module:ol/render/canvas~FillState}\n     */\n    this.textFillState_ = null;\n\n    /**\n     * @private\n     * @type {?module:ol/render/canvas~StrokeState}\n     */\n    this.textStrokeState_ = null;\n\n    /**\n     * @private\n     * @type {?module:ol/render/canvas~TextState}\n     */\n    this.textState_ = null;\n\n    /**\n     * @private\n     * @type {Array.<number>}\n     */\n    this.pixelCoordinates_ = [];\n\n    /**\n     * @private\n     * @type {module:ol/transform~Transform}\n     */\n    this.tmpLocalTransform_ = createTransform();\n\n  }\n\n  /**\n   * @param {Array.<number>} flatCoordinates Flat coordinates.\n   * @param {number} offset Offset.\n   * @param {number} end End.\n   * @param {number} stride Stride.\n   * @private\n   */\n  drawImages_(flatCoordinates, offset, end, stride) {\n    if (!this.image_) {\n      return;\n    }\n    const pixelCoordinates = transform2D(\n      flatCoordinates, offset, end, 2, this.transform_,\n      this.pixelCoordinates_);\n    const context = this.context_;\n    const localTransform = this.tmpLocalTransform_;\n    const alpha = context.globalAlpha;\n    if (this.imageOpacity_ != 1) {\n      context.globalAlpha = alpha * this.imageOpacity_;\n    }\n    let rotation = this.imageRotation_;\n    if (this.imageRotateWithView_) {\n      rotation += this.viewRotation_;\n    }\n    for (let i = 0, ii = pixelCoordinates.length; i < ii; i += 2) {\n      let x = pixelCoordinates[i] - this.imageAnchorX_;\n      let y = pixelCoordinates[i + 1] - this.imageAnchorY_;\n      if (this.imageSnapToPixel_) {\n        x = Math.round(x);\n        y = Math.round(y);\n      }\n      if (rotation !== 0 || this.imageScale_ != 1) {\n        const centerX = x + this.imageAnchorX_;\n        const centerY = y + this.imageAnchorY_;\n        composeTransform(localTransform,\n          centerX, centerY,\n          this.imageScale_, this.imageScale_,\n          rotation,\n          -centerX, -centerY);\n        context.setTransform.apply(context, localTransform);\n      }\n      context.drawImage(this.image_, this.imageOriginX_, this.imageOriginY_,\n        this.imageWidth_, this.imageHeight_, x, y,\n        this.imageWidth_, this.imageHeight_);\n    }\n    if (rotation !== 0 || this.imageScale_ != 1) {\n      context.setTransform(1, 0, 0, 1, 0, 0);\n    }\n    if (this.imageOpacity_ != 1) {\n      context.globalAlpha = alpha;\n    }\n  }\n\n  /**\n   * @param {Array.<number>} flatCoordinates Flat coordinates.\n   * @param {number} offset Offset.\n   * @param {number} end End.\n   * @param {number} stride Stride.\n   * @private\n   */\n  drawText_(flatCoordinates, offset, end, stride) {\n    if (!this.textState_ || this.text_ === '') {\n      return;\n    }\n    if (this.textFillState_) {\n      this.setContextFillState_(this.textFillState_);\n    }\n    if (this.textStrokeState_) {\n      this.setContextStrokeState_(this.textStrokeState_);\n    }\n    this.setContextTextState_(this.textState_);\n    const pixelCoordinates = transform2D(\n      flatCoordinates, offset, end, stride, this.transform_,\n      this.pixelCoordinates_);\n    const context = this.context_;\n    let rotation = this.textRotation_;\n    if (this.textRotateWithView_) {\n      rotation += this.viewRotation_;\n    }\n    for (; offset < end; offset += stride) {\n      const x = pixelCoordinates[offset] + this.textOffsetX_;\n      const y = pixelCoordinates[offset + 1] + this.textOffsetY_;\n      if (rotation !== 0 || this.textScale_ != 1) {\n        const localTransform = composeTransform(this.tmpLocalTransform_,\n          x, y,\n          this.textScale_, this.textScale_,\n          rotation,\n          -x, -y);\n        context.setTransform.apply(context, localTransform);\n      }\n      if (this.textStrokeState_) {\n        context.strokeText(this.text_, x, y);\n      }\n      if (this.textFillState_) {\n        context.fillText(this.text_, x, y);\n      }\n    }\n    if (rotation !== 0 || this.textScale_ != 1) {\n      context.setTransform(1, 0, 0, 1, 0, 0);\n    }\n  }\n\n  /**\n   * @param {Array.<number>} flatCoordinates Flat coordinates.\n   * @param {number} offset Offset.\n   * @param {number} end End.\n   * @param {number} stride Stride.\n   * @param {boolean} close Close.\n   * @private\n   * @return {number} end End.\n   */\n  moveToLineTo_(flatCoordinates, offset, end, stride, close) {\n    const context = this.context_;\n    const pixelCoordinates = transform2D(\n      flatCoordinates, offset, end, stride, this.transform_,\n      this.pixelCoordinates_);\n    context.moveTo(pixelCoordinates[0], pixelCoordinates[1]);\n    let length = pixelCoordinates.length;\n    if (close) {\n      length -= 2;\n    }\n    for (let i = 2; i < length; i += 2) {\n      context.lineTo(pixelCoordinates[i], pixelCoordinates[i + 1]);\n    }\n    if (close) {\n      context.closePath();\n    }\n    return end;\n  }\n\n  /**\n   * @param {Array.<number>} flatCoordinates Flat coordinates.\n   * @param {number} offset Offset.\n   * @param {Array.<number>} ends Ends.\n   * @param {number} stride Stride.\n   * @private\n   * @return {number} End.\n   */\n  drawRings_(flatCoordinates, offset, ends, stride) {\n    for (let i = 0, ii = ends.length; i < ii; ++i) {\n      offset = this.moveToLineTo_(flatCoordinates, offset, ends[i], stride, true);\n    }\n    return offset;\n  }\n\n  /**\n   * Render a circle geometry into the canvas.  Rendering is immediate and uses\n   * the current fill and stroke styles.\n   *\n   * @param {module:ol/geom/Circle} geometry Circle geometry.\n   * @override\n   * @api\n   */\n  drawCircle(geometry) {\n    if (!intersects(this.extent_, geometry.getExtent())) {\n      return;\n    }\n    if (this.fillState_ || this.strokeState_) {\n      if (this.fillState_) {\n        this.setContextFillState_(this.fillState_);\n      }\n      if (this.strokeState_) {\n        this.setContextStrokeState_(this.strokeState_);\n      }\n      const pixelCoordinates = transformGeom2D(\n        geometry, this.transform_, this.pixelCoordinates_);\n      const dx = pixelCoordinates[2] - pixelCoordinates[0];\n      const dy = pixelCoordinates[3] - pixelCoordinates[1];\n      const radius = Math.sqrt(dx * dx + dy * dy);\n      const context = this.context_;\n      context.beginPath();\n      context.arc(\n        pixelCoordinates[0], pixelCoordinates[1], radius, 0, 2 * Math.PI);\n      if (this.fillState_) {\n        context.fill();\n      }\n      if (this.strokeState_) {\n        context.stroke();\n      }\n    }\n    if (this.text_ !== '') {\n      this.drawText_(geometry.getCenter(), 0, 2, 2);\n    }\n  }\n\n  /**\n   * Set the rendering style.  Note that since this is an immediate rendering API,\n   * any `zIndex` on the provided style will be ignored.\n   *\n   * @param {module:ol/style/Style} style The rendering style.\n   * @override\n   * @api\n   */\n  setStyle(style) {\n    this.setFillStrokeStyle(style.getFill(), style.getStroke());\n    this.setImageStyle(style.getImage());\n    this.setTextStyle(style.getText());\n  }\n\n  /**\n   * Render a geometry into the canvas.  Call\n   * {@link module:ol/render/canvas/Immediate#setStyle} first to set the rendering style.\n   *\n   * @param {module:ol/geom/Geometry|module:ol/render/Feature} geometry The geometry to render.\n   * @override\n   * @api\n   */\n  drawGeometry(geometry) {\n    const type = geometry.getType();\n    switch (type) {\n      case GeometryType.POINT:\n        this.drawPoint(/** @type {module:ol/geom/Point} */ (geometry));\n        break;\n      case GeometryType.LINE_STRING:\n        this.drawLineString(/** @type {module:ol/geom/LineString} */ (geometry));\n        break;\n      case GeometryType.POLYGON:\n        this.drawPolygon(/** @type {module:ol/geom/Polygon} */ (geometry));\n        break;\n      case GeometryType.MULTI_POINT:\n        this.drawMultiPoint(/** @type {module:ol/geom/MultiPoint} */ (geometry));\n        break;\n      case GeometryType.MULTI_LINE_STRING:\n        this.drawMultiLineString(/** @type {module:ol/geom/MultiLineString} */ (geometry));\n        break;\n      case GeometryType.MULTI_POLYGON:\n        this.drawMultiPolygon(/** @type {module:ol/geom/MultiPolygon} */ (geometry));\n        break;\n      case GeometryType.GEOMETRY_COLLECTION:\n        this.drawGeometryCollection(/** @type {module:ol/geom/GeometryCollection} */ (geometry));\n        break;\n      case GeometryType.CIRCLE:\n        this.drawCircle(/** @type {module:ol/geom/Circle} */ (geometry));\n        break;\n      default:\n    }\n  }\n\n  /**\n   * Render a feature into the canvas.  Note that any `zIndex` on the provided\n   * style will be ignored - features are rendered immediately in the order that\n   * this method is called.  If you need `zIndex` support, you should be using an\n   * {@link module:ol/layer/Vector~VectorLayer} instead.\n   *\n   * @param {module:ol/Feature} feature Feature.\n   * @param {module:ol/style/Style} style Style.\n   * @override\n   * @api\n   */\n  drawFeature(feature, style) {\n    const geometry = style.getGeometryFunction()(feature);\n    if (!geometry || !intersects(this.extent_, geometry.getExtent())) {\n      return;\n    }\n    this.setStyle(style);\n    this.drawGeometry(geometry);\n  }\n\n  /**\n   * Render a GeometryCollection to the canvas.  Rendering is immediate and\n   * uses the current styles appropriate for each geometry in the collection.\n   *\n   * @param {module:ol/geom/GeometryCollection} geometry Geometry collection.\n   * @override\n   */\n  drawGeometryCollection(geometry) {\n    const geometries = geometry.getGeometriesArray();\n    for (let i = 0, ii = geometries.length; i < ii; ++i) {\n      this.drawGeometry(geometries[i]);\n    }\n  }\n\n  /**\n   * Render a Point geometry into the canvas.  Rendering is immediate and uses\n   * the current style.\n   *\n   * @param {module:ol/geom/Point|module:ol/render/Feature} geometry Point geometry.\n   * @override\n   */\n  drawPoint(geometry) {\n    const flatCoordinates = geometry.getFlatCoordinates();\n    const stride = geometry.getStride();\n    if (this.image_) {\n      this.drawImages_(flatCoordinates, 0, flatCoordinates.length, stride);\n    }\n    if (this.text_ !== '') {\n      this.drawText_(flatCoordinates, 0, flatCoordinates.length, stride);\n    }\n  }\n\n  /**\n   * Render a MultiPoint geometry  into the canvas.  Rendering is immediate and\n   * uses the current style.\n   *\n   * @param {module:ol/geom/MultiPoint|module:ol/render/Feature} geometry MultiPoint geometry.\n   * @override\n   */\n  drawMultiPoint(geometry) {\n    const flatCoordinates = geometry.getFlatCoordinates();\n    const stride = geometry.getStride();\n    if (this.image_) {\n      this.drawImages_(flatCoordinates, 0, flatCoordinates.length, stride);\n    }\n    if (this.text_ !== '') {\n      this.drawText_(flatCoordinates, 0, flatCoordinates.length, stride);\n    }\n  }\n\n  /**\n   * Render a LineString into the canvas.  Rendering is immediate and uses\n   * the current style.\n   *\n   * @param {module:ol/geom/LineString|module:ol/render/Feature} geometry LineString geometry.\n   * @override\n   */\n  drawLineString(geometry) {\n    if (!intersects(this.extent_, geometry.getExtent())) {\n      return;\n    }\n    if (this.strokeState_) {\n      this.setContextStrokeState_(this.strokeState_);\n      const context = this.context_;\n      const flatCoordinates = geometry.getFlatCoordinates();\n      context.beginPath();\n      this.moveToLineTo_(flatCoordinates, 0, flatCoordinates.length,\n        geometry.getStride(), false);\n      context.stroke();\n    }\n    if (this.text_ !== '') {\n      const flatMidpoint = geometry.getFlatMidpoint();\n      this.drawText_(flatMidpoint, 0, 2, 2);\n    }\n  }\n\n  /**\n   * Render a MultiLineString geometry into the canvas.  Rendering is immediate\n   * and uses the current style.\n   *\n   * @param {module:ol/geom/MultiLineString|module:ol/render/Feature} geometry MultiLineString geometry.\n   * @override\n   */\n  drawMultiLineString(geometry) {\n    const geometryExtent = geometry.getExtent();\n    if (!intersects(this.extent_, geometryExtent)) {\n      return;\n    }\n    if (this.strokeState_) {\n      this.setContextStrokeState_(this.strokeState_);\n      const context = this.context_;\n      const flatCoordinates = geometry.getFlatCoordinates();\n      let offset = 0;\n      const ends = geometry.getEnds();\n      const stride = geometry.getStride();\n      context.beginPath();\n      for (let i = 0, ii = ends.length; i < ii; ++i) {\n        offset = this.moveToLineTo_(flatCoordinates, offset, ends[i], stride, false);\n      }\n      context.stroke();\n    }\n    if (this.text_ !== '') {\n      const flatMidpoints = geometry.getFlatMidpoints();\n      this.drawText_(flatMidpoints, 0, flatMidpoints.length, 2);\n    }\n  }\n\n  /**\n   * Render a Polygon geometry into the canvas.  Rendering is immediate and uses\n   * the current style.\n   *\n   * @param {module:ol/geom/Polygon|module:ol/render/Feature} geometry Polygon geometry.\n   * @override\n   */\n  drawPolygon(geometry) {\n    if (!intersects(this.extent_, geometry.getExtent())) {\n      return;\n    }\n    if (this.strokeState_ || this.fillState_) {\n      if (this.fillState_) {\n        this.setContextFillState_(this.fillState_);\n      }\n      if (this.strokeState_) {\n        this.setContextStrokeState_(this.strokeState_);\n      }\n      const context = this.context_;\n      context.beginPath();\n      this.drawRings_(geometry.getOrientedFlatCoordinates(),\n        0, geometry.getEnds(), geometry.getStride());\n      if (this.fillState_) {\n        context.fill();\n      }\n      if (this.strokeState_) {\n        context.stroke();\n      }\n    }\n    if (this.text_ !== '') {\n      const flatInteriorPoint = geometry.getFlatInteriorPoint();\n      this.drawText_(flatInteriorPoint, 0, 2, 2);\n    }\n  }\n\n  /**\n   * Render MultiPolygon geometry into the canvas.  Rendering is immediate and\n   * uses the current style.\n   * @param {module:ol/geom/MultiPolygon} geometry MultiPolygon geometry.\n   * @override\n   */\n  drawMultiPolygon(geometry) {\n    if (!intersects(this.extent_, geometry.getExtent())) {\n      return;\n    }\n    if (this.strokeState_ || this.fillState_) {\n      if (this.fillState_) {\n        this.setContextFillState_(this.fillState_);\n      }\n      if (this.strokeState_) {\n        this.setContextStrokeState_(this.strokeState_);\n      }\n      const context = this.context_;\n      const flatCoordinates = geometry.getOrientedFlatCoordinates();\n      let offset = 0;\n      const endss = geometry.getEndss();\n      const stride = geometry.getStride();\n      context.beginPath();\n      for (let i = 0, ii = endss.length; i < ii; ++i) {\n        const ends = endss[i];\n        offset = this.drawRings_(flatCoordinates, offset, ends, stride);\n      }\n      if (this.fillState_) {\n        context.fill();\n      }\n      if (this.strokeState_) {\n        context.stroke();\n      }\n    }\n    if (this.text_ !== '') {\n      const flatInteriorPoints = geometry.getFlatInteriorPoints();\n      this.drawText_(flatInteriorPoints, 0, flatInteriorPoints.length, 2);\n    }\n  }\n\n  /**\n   * @param {module:ol/render/canvas~FillState} fillState Fill state.\n   * @private\n   */\n  setContextFillState_(fillState) {\n    const context = this.context_;\n    const contextFillState = this.contextFillState_;\n    if (!contextFillState) {\n      context.fillStyle = fillState.fillStyle;\n      this.contextFillState_ = {\n        fillStyle: fillState.fillStyle\n      };\n    } else {\n      if (contextFillState.fillStyle != fillState.fillStyle) {\n        contextFillState.fillStyle = context.fillStyle = fillState.fillStyle;\n      }\n    }\n  }\n\n  /**\n   * @param {module:ol/render/canvas~StrokeState} strokeState Stroke state.\n   * @private\n   */\n  setContextStrokeState_(strokeState) {\n    const context = this.context_;\n    const contextStrokeState = this.contextStrokeState_;\n    if (!contextStrokeState) {\n      context.lineCap = strokeState.lineCap;\n      if (CANVAS_LINE_DASH) {\n        context.setLineDash(strokeState.lineDash);\n        context.lineDashOffset = strokeState.lineDashOffset;\n      }\n      context.lineJoin = strokeState.lineJoin;\n      context.lineWidth = strokeState.lineWidth;\n      context.miterLimit = strokeState.miterLimit;\n      context.strokeStyle = strokeState.strokeStyle;\n      this.contextStrokeState_ = {\n        lineCap: strokeState.lineCap,\n        lineDash: strokeState.lineDash,\n        lineDashOffset: strokeState.lineDashOffset,\n        lineJoin: strokeState.lineJoin,\n        lineWidth: strokeState.lineWidth,\n        miterLimit: strokeState.miterLimit,\n        strokeStyle: strokeState.strokeStyle\n      };\n    } else {\n      if (contextStrokeState.lineCap != strokeState.lineCap) {\n        contextStrokeState.lineCap = context.lineCap = strokeState.lineCap;\n      }\n      if (CANVAS_LINE_DASH) {\n        if (!equals(contextStrokeState.lineDash, strokeState.lineDash)) {\n          context.setLineDash(contextStrokeState.lineDash = strokeState.lineDash);\n        }\n        if (contextStrokeState.lineDashOffset != strokeState.lineDashOffset) {\n          contextStrokeState.lineDashOffset = context.lineDashOffset =\n              strokeState.lineDashOffset;\n        }\n      }\n      if (contextStrokeState.lineJoin != strokeState.lineJoin) {\n        contextStrokeState.lineJoin = context.lineJoin = strokeState.lineJoin;\n      }\n      if (contextStrokeState.lineWidth != strokeState.lineWidth) {\n        contextStrokeState.lineWidth = context.lineWidth = strokeState.lineWidth;\n      }\n      if (contextStrokeState.miterLimit != strokeState.miterLimit) {\n        contextStrokeState.miterLimit = context.miterLimit =\n            strokeState.miterLimit;\n      }\n      if (contextStrokeState.strokeStyle != strokeState.strokeStyle) {\n        contextStrokeState.strokeStyle = context.strokeStyle =\n            strokeState.strokeStyle;\n      }\n    }\n  }\n\n  /**\n   * @param {module:ol/render/canvas~TextState} textState Text state.\n   * @private\n   */\n  setContextTextState_(textState) {\n    const context = this.context_;\n    const contextTextState = this.contextTextState_;\n    const textAlign = textState.textAlign ?\n      textState.textAlign : defaultTextAlign;\n    if (!contextTextState) {\n      context.font = textState.font;\n      context.textAlign = textAlign;\n      context.textBaseline = textState.textBaseline;\n      this.contextTextState_ = {\n        font: textState.font,\n        textAlign: textAlign,\n        textBaseline: textState.textBaseline\n      };\n    } else {\n      if (contextTextState.font != textState.font) {\n        contextTextState.font = context.font = textState.font;\n      }\n      if (contextTextState.textAlign != textAlign) {\n        contextTextState.textAlign = context.textAlign = textAlign;\n      }\n      if (contextTextState.textBaseline != textState.textBaseline) {\n        contextTextState.textBaseline = context.textBaseline =\n            textState.textBaseline;\n      }\n    }\n  }\n\n  /**\n   * Set the fill and stroke style for subsequent draw operations.  To clear\n   * either fill or stroke styles, pass null for the appropriate parameter.\n   *\n   * @param {module:ol/style/Fill} fillStyle Fill style.\n   * @param {module:ol/style/Stroke} strokeStyle Stroke style.\n   * @override\n   */\n  setFillStrokeStyle(fillStyle, strokeStyle) {\n    if (!fillStyle) {\n      this.fillState_ = null;\n    } else {\n      const fillStyleColor = fillStyle.getColor();\n      this.fillState_ = {\n        fillStyle: asColorLike(fillStyleColor ?\n          fillStyleColor : defaultFillStyle)\n      };\n    }\n    if (!strokeStyle) {\n      this.strokeState_ = null;\n    } else {\n      const strokeStyleColor = strokeStyle.getColor();\n      const strokeStyleLineCap = strokeStyle.getLineCap();\n      const strokeStyleLineDash = strokeStyle.getLineDash();\n      const strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();\n      const strokeStyleLineJoin = strokeStyle.getLineJoin();\n      const strokeStyleWidth = strokeStyle.getWidth();\n      const strokeStyleMiterLimit = strokeStyle.getMiterLimit();\n      this.strokeState_ = {\n        lineCap: strokeStyleLineCap !== undefined ?\n          strokeStyleLineCap : defaultLineCap,\n        lineDash: strokeStyleLineDash ?\n          strokeStyleLineDash : defaultLineDash,\n        lineDashOffset: strokeStyleLineDashOffset ?\n          strokeStyleLineDashOffset : defaultLineDashOffset,\n        lineJoin: strokeStyleLineJoin !== undefined ?\n          strokeStyleLineJoin : defaultLineJoin,\n        lineWidth: this.pixelRatio_ * (strokeStyleWidth !== undefined ?\n          strokeStyleWidth : defaultLineWidth),\n        miterLimit: strokeStyleMiterLimit !== undefined ?\n          strokeStyleMiterLimit : defaultMiterLimit,\n        strokeStyle: asColorLike(strokeStyleColor ?\n          strokeStyleColor : defaultStrokeStyle)\n      };\n    }\n  }\n\n  /**\n   * Set the image style for subsequent draw operations.  Pass null to remove\n   * the image style.\n   *\n   * @param {module:ol/style/Image} imageStyle Image style.\n   * @override\n   */\n  setImageStyle(imageStyle) {\n    if (!imageStyle) {\n      this.image_ = null;\n    } else {\n      const imageAnchor = imageStyle.getAnchor();\n      // FIXME pixel ratio\n      const imageImage = imageStyle.getImage(1);\n      const imageOrigin = imageStyle.getOrigin();\n      const imageSize = imageStyle.getSize();\n      this.imageAnchorX_ = imageAnchor[0];\n      this.imageAnchorY_ = imageAnchor[1];\n      this.imageHeight_ = imageSize[1];\n      this.image_ = imageImage;\n      this.imageOpacity_ = imageStyle.getOpacity();\n      this.imageOriginX_ = imageOrigin[0];\n      this.imageOriginY_ = imageOrigin[1];\n      this.imageRotateWithView_ = imageStyle.getRotateWithView();\n      this.imageRotation_ = imageStyle.getRotation();\n      this.imageScale_ = imageStyle.getScale() * this.pixelRatio_;\n      this.imageSnapToPixel_ = imageStyle.getSnapToPixel();\n      this.imageWidth_ = imageSize[0];\n    }\n  }\n\n  /**\n   * Set the text style for subsequent draw operations.  Pass null to\n   * remove the text style.\n   *\n   * @param {module:ol/style/Text} textStyle Text style.\n   * @override\n   */\n  setTextStyle(textStyle) {\n    if (!textStyle) {\n      this.text_ = '';\n    } else {\n      const textFillStyle = textStyle.getFill();\n      if (!textFillStyle) {\n        this.textFillState_ = null;\n      } else {\n        const textFillStyleColor = textFillStyle.getColor();\n        this.textFillState_ = {\n          fillStyle: asColorLike(textFillStyleColor ?\n            textFillStyleColor : defaultFillStyle)\n        };\n      }\n      const textStrokeStyle = textStyle.getStroke();\n      if (!textStrokeStyle) {\n        this.textStrokeState_ = null;\n      } else {\n        const textStrokeStyleColor = textStrokeStyle.getColor();\n        const textStrokeStyleLineCap = textStrokeStyle.getLineCap();\n        const textStrokeStyleLineDash = textStrokeStyle.getLineDash();\n        const textStrokeStyleLineDashOffset = textStrokeStyle.getLineDashOffset();\n        const textStrokeStyleLineJoin = textStrokeStyle.getLineJoin();\n        const textStrokeStyleWidth = textStrokeStyle.getWidth();\n        const textStrokeStyleMiterLimit = textStrokeStyle.getMiterLimit();\n        this.textStrokeState_ = {\n          lineCap: textStrokeStyleLineCap !== undefined ?\n            textStrokeStyleLineCap : defaultLineCap,\n          lineDash: textStrokeStyleLineDash ?\n            textStrokeStyleLineDash : defaultLineDash,\n          lineDashOffset: textStrokeStyleLineDashOffset ?\n            textStrokeStyleLineDashOffset : defaultLineDashOffset,\n          lineJoin: textStrokeStyleLineJoin !== undefined ?\n            textStrokeStyleLineJoin : defaultLineJoin,\n          lineWidth: textStrokeStyleWidth !== undefined ?\n            textStrokeStyleWidth : defaultLineWidth,\n          miterLimit: textStrokeStyleMiterLimit !== undefined ?\n            textStrokeStyleMiterLimit : defaultMiterLimit,\n          strokeStyle: asColorLike(textStrokeStyleColor ?\n            textStrokeStyleColor : defaultStrokeStyle)\n        };\n      }\n      const textFont = textStyle.getFont();\n      const textOffsetX = textStyle.getOffsetX();\n      const textOffsetY = textStyle.getOffsetY();\n      const textRotateWithView = textStyle.getRotateWithView();\n      const textRotation = textStyle.getRotation();\n      const textScale = textStyle.getScale();\n      const textText = textStyle.getText();\n      const textTextAlign = textStyle.getTextAlign();\n      const textTextBaseline = textStyle.getTextBaseline();\n      this.textState_ = {\n        font: textFont !== undefined ?\n          textFont : defaultFont,\n        textAlign: textTextAlign !== undefined ?\n          textTextAlign : defaultTextAlign,\n        textBaseline: textTextBaseline !== undefined ?\n          textTextBaseline : defaultTextBaseline\n      };\n      this.text_ = textText !== undefined ? textText : '';\n      this.textOffsetX_ =\n          textOffsetX !== undefined ? (this.pixelRatio_ * textOffsetX) : 0;\n      this.textOffsetY_ =\n          textOffsetY !== undefined ? (this.pixelRatio_ * textOffsetY) : 0;\n      this.textRotateWithView_ = textRotateWithView !== undefined ? textRotateWithView : false;\n      this.textRotation_ = textRotation !== undefined ? textRotation : 0;\n      this.textScale_ = this.pixelRatio_ * (textScale !== undefined ?\n        textScale : 1);\n    }\n  }\n}\n\n\nexport default CanvasImmediateRenderer;\n","/**\n * @module ol/style/IconImageCache\n */\nimport {asString} from '../color.js';\n\n/**\n * @classdesc\n * Singleton class. Available through {@link module:ol/style/IconImageCache~shared}.\n */\nclass IconImageCache {\n  constructor() {\n\n    /**\n    * @type {!Object.<string, module:ol/style/IconImage>}\n    * @private\n    */\n    this.cache_ = {};\n\n    /**\n    * @type {number}\n    * @private\n    */\n    this.cacheSize_ = 0;\n\n    /**\n    * @type {number}\n    * @private\n    */\n    this.maxCacheSize_ = 32;\n  }\n\n  /**\n  * FIXME empty description for jsdoc\n  */\n  clear() {\n    this.cache_ = {};\n    this.cacheSize_ = 0;\n  }\n\n  /**\n  * FIXME empty description for jsdoc\n  */\n  expire() {\n    if (this.cacheSize_ > this.maxCacheSize_) {\n      let i = 0;\n      for (const key in this.cache_) {\n        const iconImage = this.cache_[key];\n        if ((i++ & 3) === 0 && !iconImage.hasListener()) {\n          delete this.cache_[key];\n          --this.cacheSize_;\n        }\n      }\n    }\n  }\n\n  /**\n  * @param {string} src Src.\n  * @param {?string} crossOrigin Cross origin.\n  * @param {module:ol/color~Color} color Color.\n  * @return {module:ol/style/IconImage} Icon image.\n  */\n  get(src, crossOrigin, color) {\n    const key = getKey(src, crossOrigin, color);\n    return key in this.cache_ ? this.cache_[key] : null;\n  }\n\n  /**\n  * @param {string} src Src.\n  * @param {?string} crossOrigin Cross origin.\n  * @param {module:ol/color~Color} color Color.\n  * @param {module:ol/style/IconImage} iconImage Icon image.\n  */\n  set(src, crossOrigin, color, iconImage) {\n    const key = getKey(src, crossOrigin, color);\n    this.cache_[key] = iconImage;\n    ++this.cacheSize_;\n  }\n\n  /**\n  * Set the cache size of the icon cache. Default is `32`. Change this value when\n  * your map uses more than 32 different icon images and you are not caching icon\n  * styles on the application level.\n  * @param {number} maxCacheSize Cache max size.\n  * @api\n  */\n  setSize(maxCacheSize) {\n    this.maxCacheSize_ = maxCacheSize;\n    this.expire();\n  }\n}\n\n\n/**\n * @param {string} src Src.\n * @param {?string} crossOrigin Cross origin.\n * @param {module:ol/color~Color} color Color.\n * @return {string} Cache key.\n */\nfunction getKey(src, crossOrigin, color) {\n  const colorString = color ? asString(color) : 'null';\n  return crossOrigin + ':' + src + ':' + colorString;\n}\n\n\nexport default IconImageCache;\n\n\n/**\n * The {@link module:ol/style/IconImageCache~IconImageCache} for\n * {@link module:ol/style/Icon~Icon} images.\n * @api\n */\nexport const shared = new IconImageCache();\n","/**\n * @module ol/renderer/Map\n */\nimport {getUid} from '../util.js';\nimport Disposable from '../Disposable.js';\nimport {listen, unlistenByKey} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport {getWidth} from '../extent.js';\nimport {TRUE, UNDEFINED} from '../functions.js';\nimport {visibleAtResolution} from '../layer/Layer.js';\nimport {shared as iconImageCache} from '../style/IconImageCache.js';\nimport {compose as composeTransform, invert as invertTransform, setFromArray as transformSetFromArray} from '../transform.js';\n\n\nclass MapRenderer extends Disposable {\n\n  /**\n   * @param {module:ol/PluggableMap} map Map.\n   */\n  constructor(map) {\n    super();\n\n    /**\n     * @private\n     * @type {module:ol/PluggableMap}\n     */\n    this.map_ = map;\n\n    /**\n     * @private\n     * @type {!Object.<string, module:ol/renderer/Layer>}\n     */\n    this.layerRenderers_ = {};\n\n    /**\n     * @private\n     * @type {Object.<string, module:ol/events~EventsKey>}\n     */\n    this.layerRendererListeners_ = {};\n\n    /**\n     * @private\n     * @type {Array.<module:ol/renderer/Layer>}\n     */\n    this.layerRendererConstructors_ = [];\n\n  }\n\n  /**\n   * Register layer renderer constructors.\n   * @param {Array.<module:ol/renderer/Layer>} constructors Layer renderers.\n   */\n  registerLayerRenderers(constructors) {\n    this.layerRendererConstructors_.push.apply(this.layerRendererConstructors_, constructors);\n  }\n\n  /**\n   * Get the registered layer renderer constructors.\n   * @return {Array.<module:ol/renderer/Layer>} Registered layer renderers.\n   */\n  getLayerRendererConstructors() {\n    return this.layerRendererConstructors_;\n  }\n\n  /**\n   * @param {module:ol/PluggableMap~FrameState} frameState FrameState.\n   * @protected\n   */\n  calculateMatrices2D(frameState) {\n    const viewState = frameState.viewState;\n    const coordinateToPixelTransform = frameState.coordinateToPixelTransform;\n    const pixelToCoordinateTransform = frameState.pixelToCoordinateTransform;\n\n    composeTransform(coordinateToPixelTransform,\n      frameState.size[0] / 2, frameState.size[1] / 2,\n      1 / viewState.resolution, -1 / viewState.resolution,\n      -viewState.rotation,\n      -viewState.center[0], -viewState.center[1]);\n\n    invertTransform(\n      transformSetFromArray(pixelToCoordinateTransform, coordinateToPixelTransform));\n  }\n\n  /**\n   * Removes all layer renderers.\n   */\n  removeLayerRenderers() {\n    for (const key in this.layerRenderers_) {\n      this.removeLayerRendererByKey_(key).dispose();\n    }\n  }\n\n  /**\n   * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n   * @param {module:ol/PluggableMap~FrameState} frameState FrameState.\n   * @param {number} hitTolerance Hit tolerance in pixels.\n   * @param {function(this: S, (module:ol/Feature|module:ol/render/Feature),\n   *     module:ol/layer/Layer): T} callback Feature callback.\n   * @param {S} thisArg Value to use as `this` when executing `callback`.\n   * @param {function(this: U, module:ol/layer/Layer): boolean} layerFilter Layer filter\n   *     function, only layers which are visible and for which this function\n   *     returns `true` will be tested for features.  By default, all visible\n   *     layers will be tested.\n   * @param {U} thisArg2 Value to use as `this` when executing `layerFilter`.\n   * @return {T|undefined} Callback result.\n   * @template S,T,U\n   */\n  forEachFeatureAtCoordinate(\n    coordinate,\n    frameState,\n    hitTolerance,\n    callback,\n    thisArg,\n    layerFilter,\n    thisArg2\n  ) {\n    let result;\n    const viewState = frameState.viewState;\n    const viewResolution = viewState.resolution;\n\n    /**\n     * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n     * @param {module:ol/layer/Layer} layer Layer.\n     * @return {?} Callback result.\n     */\n    function forEachFeatureAtCoordinate(feature, layer) {\n      const key = getUid(feature).toString();\n      const managed = frameState.layerStates[getUid(layer)].managed;\n      if (!(key in frameState.skippedFeatureUids && !managed)) {\n        return callback.call(thisArg, feature, managed ? layer : null);\n      }\n    }\n\n    const projection = viewState.projection;\n\n    let translatedCoordinate = coordinate;\n    if (projection.canWrapX()) {\n      const projectionExtent = projection.getExtent();\n      const worldWidth = getWidth(projectionExtent);\n      const x = coordinate[0];\n      if (x < projectionExtent[0] || x > projectionExtent[2]) {\n        const worldsAway = Math.ceil((projectionExtent[0] - x) / worldWidth);\n        translatedCoordinate = [x + worldWidth * worldsAway, coordinate[1]];\n      }\n    }\n\n    const layerStates = frameState.layerStatesArray;\n    const numLayers = layerStates.length;\n    let i;\n    for (i = numLayers - 1; i >= 0; --i) {\n      const layerState = layerStates[i];\n      const layer = layerState.layer;\n      if (visibleAtResolution(layerState, viewResolution) && layerFilter.call(thisArg2, layer)) {\n        const layerRenderer = this.getLayerRenderer(layer);\n        if (layer.getSource()) {\n          result = layerRenderer.forEachFeatureAtCoordinate(\n            layer.getSource().getWrapX() ? translatedCoordinate : coordinate,\n            frameState, hitTolerance, forEachFeatureAtCoordinate, thisArg);\n        }\n        if (result) {\n          return result;\n        }\n      }\n    }\n    return undefined;\n  }\n\n  /**\n   * @abstract\n   * @param {module:ol/pixel~Pixel} pixel Pixel.\n   * @param {module:ol/PluggableMap~FrameState} frameState FrameState.\n   * @param {number} hitTolerance Hit tolerance in pixels.\n   * @param {function(this: S, module:ol/layer/Layer, (Uint8ClampedArray|Uint8Array)): T} callback Layer\n   *     callback.\n   * @param {S} thisArg Value to use as `this` when executing `callback`.\n   * @param {function(this: U, module:ol/layer/Layer): boolean} layerFilter Layer filter\n   *     function, only layers which are visible and for which this function\n   *     returns `true` will be tested for features.  By default, all visible\n   *     layers will be tested.\n   * @param {U} thisArg2 Value to use as `this` when executing `layerFilter`.\n   * @return {T|undefined} Callback result.\n   * @template S,T,U\n   */\n  forEachLayerAtPixel(pixel, frameState, hitTolerance, callback, thisArg, layerFilter, thisArg2) {}\n\n  /**\n   * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n   * @param {module:ol/PluggableMap~FrameState} frameState FrameState.\n   * @param {number} hitTolerance Hit tolerance in pixels.\n   * @param {function(this: U, module:ol/layer/Layer): boolean} layerFilter Layer filter\n   *     function, only layers which are visible and for which this function\n   *     returns `true` will be tested for features.  By default, all visible\n   *     layers will be tested.\n   * @param {U} thisArg Value to use as `this` when executing `layerFilter`.\n   * @return {boolean} Is there a feature at the given coordinate?\n   * @template U\n   */\n  hasFeatureAtCoordinate(coordinate, frameState, hitTolerance, layerFilter, thisArg) {\n    const hasFeature = this.forEachFeatureAtCoordinate(\n      coordinate, frameState, hitTolerance, TRUE, this, layerFilter, thisArg);\n\n    return hasFeature !== undefined;\n  }\n\n  /**\n   * @param {module:ol/layer/Layer} layer Layer.\n   * @protected\n   * @return {module:ol/renderer/Layer} Layer renderer.\n   */\n  getLayerRenderer(layer) {\n    const layerKey = getUid(layer).toString();\n    if (layerKey in this.layerRenderers_) {\n      return this.layerRenderers_[layerKey];\n    } else {\n      let renderer;\n      for (let i = 0, ii = this.layerRendererConstructors_.length; i < ii; ++i) {\n        const candidate = this.layerRendererConstructors_[i];\n        if (candidate['handles'](layer)) {\n          renderer = candidate['create'](this, layer);\n          break;\n        }\n      }\n      if (renderer) {\n        this.layerRenderers_[layerKey] = renderer;\n        this.layerRendererListeners_[layerKey] = listen(renderer,\n          EventType.CHANGE, this.handleLayerRendererChange_, this);\n      } else {\n        throw new Error('Unable to create renderer for layer: ' + layer.getType());\n      }\n      return renderer;\n    }\n  }\n\n  /**\n   * @param {string} layerKey Layer key.\n   * @protected\n   * @return {module:ol/renderer/Layer} Layer renderer.\n   */\n  getLayerRendererByKey(layerKey) {\n    return this.layerRenderers_[layerKey];\n  }\n\n  /**\n   * @protected\n   * @return {Object.<string, module:ol/renderer/Layer>} Layer renderers.\n   */\n  getLayerRenderers() {\n    return this.layerRenderers_;\n  }\n\n  /**\n   * @return {module:ol/PluggableMap} Map.\n   */\n  getMap() {\n    return this.map_;\n  }\n\n  /**\n   * Handle changes in a layer renderer.\n   * @private\n   */\n  handleLayerRendererChange_() {\n    this.map_.render();\n  }\n\n  /**\n   * @param {string} layerKey Layer key.\n   * @return {module:ol/renderer/Layer} Layer renderer.\n   * @private\n   */\n  removeLayerRendererByKey_(layerKey) {\n    const layerRenderer = this.layerRenderers_[layerKey];\n    delete this.layerRenderers_[layerKey];\n\n    unlistenByKey(this.layerRendererListeners_[layerKey]);\n    delete this.layerRendererListeners_[layerKey];\n\n    return layerRenderer;\n  }\n\n  /**\n   * @param {module:ol/PluggableMap} map Map.\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @private\n   */\n  removeUnusedLayerRenderers_(map, frameState) {\n    for (const layerKey in this.layerRenderers_) {\n      if (!frameState || !(layerKey in frameState.layerStates)) {\n        this.removeLayerRendererByKey_(layerKey).dispose();\n      }\n    }\n  }\n\n  /**\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @protected\n   */\n  scheduleExpireIconCache(frameState) {\n    frameState.postRenderFunctions.push(/** @type {module:ol/PluggableMap~PostRenderFunction} */ (expireIconCache));\n  }\n\n  /**\n   * @param {!module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @protected\n   */\n  scheduleRemoveUnusedLayerRenderers(frameState) {\n    for (const layerKey in this.layerRenderers_) {\n      if (!(layerKey in frameState.layerStates)) {\n        frameState.postRenderFunctions.push(\n          /** @type {module:ol/PluggableMap~PostRenderFunction} */ (this.removeUnusedLayerRenderers_.bind(this))\n        );\n        return;\n      }\n    }\n  }\n}\n\n\n/**\n * @param {module:ol/PluggableMap} map Map.\n * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n */\nfunction expireIconCache(map, frameState) {\n  iconImageCache.expire();\n}\n\n\n/**\n * Render.\n * @param {?module:ol/PluggableMap~FrameState} frameState Frame state.\n */\nMapRenderer.prototype.renderFrame = UNDEFINED;\n\n\n/**\n * @param {module:ol/layer/Layer~State} state1 First layer state.\n * @param {module:ol/layer/Layer~State} state2 Second layer state.\n * @return {number} The zIndex difference.\n */\nexport function sortByZIndex(state1, state2) {\n  return state1.zIndex - state2.zIndex;\n}\nexport default MapRenderer;\n","/**\n * @module ol/renderer/canvas/Map\n */\nimport {create as createTransform, apply as applyTransform, compose as composeTransform} from '../../transform.js';\nimport {includes, stableSort} from '../../array.js';\nimport {CLASS_UNSELECTABLE} from '../../css.js';\nimport {createCanvasContext2D} from '../../dom.js';\nimport {visibleAtResolution} from '../../layer/Layer.js';\nimport RenderEvent from '../../render/Event.js';\nimport RenderEventType from '../../render/EventType.js';\nimport {rotateAtOffset} from '../../render/canvas.js';\nimport CanvasImmediateRenderer from '../../render/canvas/Immediate.js';\nimport MapRenderer, {sortByZIndex} from '../Map.js';\nimport SourceState from '../../source/State.js';\n\n\n/**\n * @type {Array.<module:ol/renderer/Layer>}\n */\nexport const layerRendererConstructors = [];\n\n/**\n * @classdesc\n * Canvas map renderer.\n * @api\n */\nclass CanvasMapRenderer extends MapRenderer {\n\n  /**\n   * @param {module:ol/PluggableMap} map Map.\n   */\n  constructor(map) {\n    super(map);\n\n    const container = map.getViewport();\n\n    /**\n     * @private\n     * @type {CanvasRenderingContext2D}\n     */\n    this.context_ = createCanvasContext2D();\n\n    /**\n     * @private\n     * @type {HTMLCanvasElement}\n     */\n    this.canvas_ = this.context_.canvas;\n\n    this.canvas_.style.width = '100%';\n    this.canvas_.style.height = '100%';\n    this.canvas_.style.display = 'block';\n    this.canvas_.className = CLASS_UNSELECTABLE;\n    container.insertBefore(this.canvas_, container.childNodes[0] || null);\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.renderedVisible_ = true;\n\n    /**\n     * @private\n     * @type {module:ol/transform~Transform}\n     */\n    this.transform_ = createTransform();\n\n  }\n\n  /**\n   * @param {module:ol/render/EventType} type Event type.\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @private\n   */\n  dispatchComposeEvent_(type, frameState) {\n    const map = this.getMap();\n    const context = this.context_;\n    if (map.hasListener(type)) {\n      const extent = frameState.extent;\n      const pixelRatio = frameState.pixelRatio;\n      const viewState = frameState.viewState;\n      const rotation = viewState.rotation;\n\n      const transform = this.getTransform(frameState);\n\n      const vectorContext = new CanvasImmediateRenderer(context, pixelRatio,\n        extent, transform, rotation);\n      const composeEvent = new RenderEvent(type, vectorContext,\n        frameState, context, null);\n      map.dispatchEvent(composeEvent);\n    }\n  }\n\n  /**\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @protected\n   * @return {!module:ol/transform~Transform} Transform.\n   */\n  getTransform(frameState) {\n    const viewState = frameState.viewState;\n    const dx1 = this.canvas_.width / 2;\n    const dy1 = this.canvas_.height / 2;\n    const sx = frameState.pixelRatio / viewState.resolution;\n    const sy = -sx;\n    const angle = -viewState.rotation;\n    const dx2 = -viewState.center[0];\n    const dy2 = -viewState.center[1];\n    return composeTransform(this.transform_, dx1, dy1, sx, sy, angle, dx2, dy2);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  renderFrame(frameState) {\n\n    if (!frameState) {\n      if (this.renderedVisible_) {\n        this.canvas_.style.display = 'none';\n        this.renderedVisible_ = false;\n      }\n      return;\n    }\n\n    const context = this.context_;\n    const pixelRatio = frameState.pixelRatio;\n    const width = Math.round(frameState.size[0] * pixelRatio);\n    const height = Math.round(frameState.size[1] * pixelRatio);\n    if (this.canvas_.width != width || this.canvas_.height != height) {\n      this.canvas_.width = width;\n      this.canvas_.height = height;\n    } else {\n      context.clearRect(0, 0, width, height);\n    }\n\n    const rotation = frameState.viewState.rotation;\n\n    this.calculateMatrices2D(frameState);\n\n    this.dispatchComposeEvent_(RenderEventType.PRECOMPOSE, frameState);\n\n    const layerStatesArray = frameState.layerStatesArray;\n    stableSort(layerStatesArray, sortByZIndex);\n\n    if (rotation) {\n      context.save();\n      rotateAtOffset(context, rotation, width / 2, height / 2);\n    }\n\n    const viewResolution = frameState.viewState.resolution;\n    let i, ii, layer, layerRenderer, layerState;\n    for (i = 0, ii = layerStatesArray.length; i < ii; ++i) {\n      layerState = layerStatesArray[i];\n      layer = layerState.layer;\n      layerRenderer = /** @type {module:ol/renderer/canvas/Layer} */ (this.getLayerRenderer(layer));\n      if (!visibleAtResolution(layerState, viewResolution) ||\n          layerState.sourceState != SourceState.READY) {\n        continue;\n      }\n      if (layerRenderer.prepareFrame(frameState, layerState)) {\n        layerRenderer.composeFrame(frameState, layerState, context);\n      }\n    }\n\n    if (rotation) {\n      context.restore();\n    }\n\n    this.dispatchComposeEvent_(RenderEventType.POSTCOMPOSE, frameState);\n\n    if (!this.renderedVisible_) {\n      this.canvas_.style.display = '';\n      this.renderedVisible_ = true;\n    }\n\n    this.scheduleRemoveUnusedLayerRenderers(frameState);\n    this.scheduleExpireIconCache(frameState);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  forEachLayerAtPixel(pixel, frameState, hitTolerance, callback, thisArg, layerFilter, thisArg2) {\n    let result;\n    const viewState = frameState.viewState;\n    const viewResolution = viewState.resolution;\n\n    const layerStates = frameState.layerStatesArray;\n    const numLayers = layerStates.length;\n\n    const coordinate = applyTransform(\n      frameState.pixelToCoordinateTransform, pixel.slice());\n\n    let i;\n    for (i = numLayers - 1; i >= 0; --i) {\n      const layerState = layerStates[i];\n      const layer = layerState.layer;\n      if (visibleAtResolution(layerState, viewResolution) && layerFilter.call(thisArg2, layer)) {\n        const layerRenderer = /** @type {module:ol/renderer/canvas/Layer} */ (this.getLayerRenderer(layer));\n        result = layerRenderer.forEachLayerAtCoordinate(\n          coordinate, frameState, hitTolerance, callback, thisArg);\n        if (result) {\n          return result;\n        }\n      }\n    }\n    return undefined;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  registerLayerRenderers(constructors) {\n    MapRenderer.prototype.registerLayerRenderers.call(this, constructors);\n    for (let i = 0, ii = constructors.length; i < ii; ++i) {\n      const ctor = constructors[i];\n      if (!includes(layerRendererConstructors, ctor)) {\n        layerRendererConstructors.push(ctor);\n      }\n    }\n  }\n}\n\n\nexport default CanvasMapRenderer;\n","/**\n * @module ol/renderer/Layer\n */\nimport {getUid} from '../util.js';\nimport ImageState from '../ImageState.js';\nimport Observable from '../Observable.js';\nimport TileState from '../TileState.js';\nimport {listen} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport {FALSE, UNDEFINED} from '../functions.js';\nimport SourceState from '../source/State.js';\n\nclass LayerRenderer extends Observable {\n\n  /**\n   * @param {module:ol/layer/Layer} layer Layer.\n   */\n  constructor(layer) {\n\n    super();\n\n    /**\n     * @private\n     * @type {module:ol/layer/Layer}\n     */\n    this.layer_ = layer;\n\n  }\n\n  /**\n   * Create a function that adds loaded tiles to the tile lookup.\n   * @param {module:ol/source/Tile} source Tile source.\n   * @param {module:ol/proj/Projection} projection Projection of the tiles.\n   * @param {Object.<number, Object.<string, module:ol/Tile>>} tiles Lookup of loaded tiles by zoom level.\n   * @return {function(number, module:ol/TileRange):boolean} A function that can be\n   *     called with a zoom level and a tile range to add loaded tiles to the lookup.\n   * @protected\n   */\n  createLoadedTileFinder(source, projection, tiles) {\n    return (\n      /**\n       * @param {number} zoom Zoom level.\n       * @param {module:ol/TileRange} tileRange Tile range.\n       * @return {boolean} The tile range is fully loaded.\n       */\n      function(zoom, tileRange) {\n        function callback(tile) {\n          if (!tiles[zoom]) {\n            tiles[zoom] = {};\n          }\n          tiles[zoom][tile.tileCoord.toString()] = tile;\n        }\n        return source.forEachLoadedTile(projection, zoom, tileRange, callback);\n      }\n    );\n  }\n\n  /**\n   * @return {module:ol/layer/Layer} Layer.\n   */\n  getLayer() {\n    return this.layer_;\n  }\n\n  /**\n   * Handle changes in image state.\n   * @param {module:ol/events/Event} event Image change event.\n   * @private\n   */\n  handleImageChange_(event) {\n    const image = /** @type {module:ol/Image} */ (event.target);\n    if (image.getState() === ImageState.LOADED) {\n      this.renderIfReadyAndVisible();\n    }\n  }\n\n  /**\n   * Load the image if not already loaded, and register the image change\n   * listener if needed.\n   * @param {module:ol/ImageBase} image Image.\n   * @return {boolean} `true` if the image is already loaded, `false` otherwise.\n   * @protected\n   */\n  loadImage(image) {\n    let imageState = image.getState();\n    if (imageState != ImageState.LOADED && imageState != ImageState.ERROR) {\n      listen(image, EventType.CHANGE, this.handleImageChange_, this);\n    }\n    if (imageState == ImageState.IDLE) {\n      image.load();\n      imageState = image.getState();\n    }\n    return imageState == ImageState.LOADED;\n  }\n\n  /**\n   * @protected\n   */\n  renderIfReadyAndVisible() {\n    const layer = this.getLayer();\n    if (layer.getVisible() && layer.getSourceState() == SourceState.READY) {\n      this.changed();\n    }\n  }\n\n  /**\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @param {module:ol/source/Tile} tileSource Tile source.\n   * @protected\n   */\n  scheduleExpireCache(frameState, tileSource) {\n    if (tileSource.canExpireCache()) {\n      /**\n       * @param {module:ol/source/Tile} tileSource Tile source.\n       * @param {module:ol/PluggableMap} map Map.\n       * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n       */\n      const postRenderFunction = function(tileSource, map, frameState) {\n        const tileSourceKey = getUid(tileSource).toString();\n        if (tileSourceKey in frameState.usedTiles) {\n          tileSource.expireCache(frameState.viewState.projection,\n            frameState.usedTiles[tileSourceKey]);\n        }\n      }.bind(null, tileSource);\n\n      frameState.postRenderFunctions.push(\n        /** @type {module:ol/PluggableMap~PostRenderFunction} */ (postRenderFunction)\n      );\n    }\n  }\n\n  /**\n   * @param {!Object.<string, !Object.<string, module:ol/TileRange>>} usedTiles Used tiles.\n   * @param {module:ol/source/Tile} tileSource Tile source.\n   * @param {number} z Z.\n   * @param {module:ol/TileRange} tileRange Tile range.\n   * @protected\n   */\n  updateUsedTiles(usedTiles, tileSource, z, tileRange) {\n    // FIXME should we use tilesToDrawByZ instead?\n    const tileSourceKey = getUid(tileSource).toString();\n    const zKey = z.toString();\n    if (tileSourceKey in usedTiles) {\n      if (zKey in usedTiles[tileSourceKey]) {\n        usedTiles[tileSourceKey][zKey].extend(tileRange);\n      } else {\n        usedTiles[tileSourceKey][zKey] = tileRange;\n      }\n    } else {\n      usedTiles[tileSourceKey] = {};\n      usedTiles[tileSourceKey][zKey] = tileRange;\n    }\n  }\n\n  /**\n   * Manage tile pyramid.\n   * This function performs a number of functions related to the tiles at the\n   * current zoom and lower zoom levels:\n   * - registers idle tiles in frameState.wantedTiles so that they are not\n   *   discarded by the tile queue\n   * - enqueues missing tiles\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @param {module:ol/source/Tile} tileSource Tile source.\n   * @param {module:ol/tilegrid/TileGrid} tileGrid Tile grid.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {number} currentZ Current Z.\n   * @param {number} preload Load low resolution tiles up to 'preload' levels.\n   * @param {function(this: T, module:ol/Tile)=} opt_tileCallback Tile callback.\n   * @param {T=} opt_this Object to use as `this` in `opt_tileCallback`.\n   * @protected\n   * @template T\n   */\n  manageTilePyramid(\n    frameState,\n    tileSource,\n    tileGrid,\n    pixelRatio,\n    projection,\n    extent,\n    currentZ,\n    preload,\n    opt_tileCallback,\n    opt_this\n  ) {\n    const tileSourceKey = getUid(tileSource).toString();\n    if (!(tileSourceKey in frameState.wantedTiles)) {\n      frameState.wantedTiles[tileSourceKey] = {};\n    }\n    const wantedTiles = frameState.wantedTiles[tileSourceKey];\n    const tileQueue = frameState.tileQueue;\n    const minZoom = tileGrid.getMinZoom();\n    let tile, tileRange, tileResolution, x, y, z;\n    for (z = minZoom; z <= currentZ; ++z) {\n      tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z, tileRange);\n      tileResolution = tileGrid.getResolution(z);\n      for (x = tileRange.minX; x <= tileRange.maxX; ++x) {\n        for (y = tileRange.minY; y <= tileRange.maxY; ++y) {\n          if (currentZ - z <= preload) {\n            tile = tileSource.getTile(z, x, y, pixelRatio, projection);\n            if (tile.getState() == TileState.IDLE) {\n              wantedTiles[tile.getKey()] = true;\n              if (!tileQueue.isKeyQueued(tile.getKey())) {\n                tileQueue.enqueue([tile, tileSourceKey,\n                  tileGrid.getTileCoordCenter(tile.tileCoord), tileResolution]);\n              }\n            }\n            if (opt_tileCallback !== undefined) {\n              opt_tileCallback.call(opt_this, tile);\n            }\n          } else {\n            tileSource.useTile(z, x, y, projection);\n          }\n        }\n      }\n    }\n  }\n}\n\n\n/**\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {function(this: S, (module:ol/Feature|module:ol/render/Feature), module:ol/layer/Layer): T}\n *     callback Feature callback.\n * @param {S} thisArg Value to use as `this` when executing `callback`.\n * @return {T|undefined} Callback result.\n * @template S,T\n */\nLayerRenderer.prototype.forEachFeatureAtCoordinate = UNDEFINED;\n\n\n/**\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n * @return {boolean} Is there a feature at the given coordinate?\n */\nLayerRenderer.prototype.hasFeatureAtCoordinate = FALSE;\n\n\nexport default LayerRenderer;\n","/**\n * @module ol/renderer/canvas/Layer\n */\nimport {getBottomLeft, getBottomRight, getTopLeft, getTopRight} from '../../extent.js';\nimport {TRUE} from '../../functions.js';\nimport RenderEvent from '../../render/Event.js';\nimport RenderEventType from '../../render/EventType.js';\nimport {rotateAtOffset} from '../../render/canvas.js';\nimport CanvasImmediateRenderer from '../../render/canvas/Immediate.js';\nimport LayerRenderer from '../Layer.js';\nimport {create as createTransform, apply as applyTransform, compose as composeTransform} from '../../transform.js';\n\nclass CanvasLayerRenderer extends LayerRenderer {\n\n  /**\n   * @param {module:ol/layer/Layer} layer Layer.\n   */\n  constructor(layer) {\n\n    super(layer);\n\n    /**\n     * @protected\n     * @type {number}\n     */\n    this.renderedResolution;\n\n    /**\n     * @private\n     * @type {module:ol/transform~Transform}\n     */\n    this.transform_ = createTransform();\n\n  }\n\n  /**\n   * @param {CanvasRenderingContext2D} context Context.\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @param {module:ol/extent~Extent} extent Clip extent.\n   * @protected\n   */\n  clip(context, frameState, extent) {\n    const pixelRatio = frameState.pixelRatio;\n    const width = frameState.size[0] * pixelRatio;\n    const height = frameState.size[1] * pixelRatio;\n    const rotation = frameState.viewState.rotation;\n    const topLeft = getTopLeft(/** @type {module:ol/extent~Extent} */ (extent));\n    const topRight = getTopRight(/** @type {module:ol/extent~Extent} */ (extent));\n    const bottomRight = getBottomRight(/** @type {module:ol/extent~Extent} */ (extent));\n    const bottomLeft = getBottomLeft(/** @type {module:ol/extent~Extent} */ (extent));\n\n    applyTransform(frameState.coordinateToPixelTransform, topLeft);\n    applyTransform(frameState.coordinateToPixelTransform, topRight);\n    applyTransform(frameState.coordinateToPixelTransform, bottomRight);\n    applyTransform(frameState.coordinateToPixelTransform, bottomLeft);\n\n    context.save();\n    rotateAtOffset(context, -rotation, width / 2, height / 2);\n    context.beginPath();\n    context.moveTo(topLeft[0] * pixelRatio, topLeft[1] * pixelRatio);\n    context.lineTo(topRight[0] * pixelRatio, topRight[1] * pixelRatio);\n    context.lineTo(bottomRight[0] * pixelRatio, bottomRight[1] * pixelRatio);\n    context.lineTo(bottomLeft[0] * pixelRatio, bottomLeft[1] * pixelRatio);\n    context.clip();\n    rotateAtOffset(context, rotation, width / 2, height / 2);\n  }\n\n  /**\n   * @param {module:ol/render/EventType} type Event type.\n   * @param {CanvasRenderingContext2D} context Context.\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @param {module:ol/transform~Transform=} opt_transform Transform.\n   * @private\n   */\n  dispatchComposeEvent_(type, context, frameState, opt_transform) {\n    const layer = this.getLayer();\n    if (layer.hasListener(type)) {\n      const width = frameState.size[0] * frameState.pixelRatio;\n      const height = frameState.size[1] * frameState.pixelRatio;\n      const rotation = frameState.viewState.rotation;\n      rotateAtOffset(context, -rotation, width / 2, height / 2);\n      const transform = opt_transform !== undefined ?\n        opt_transform : this.getTransform(frameState, 0);\n      const render = new CanvasImmediateRenderer(\n        context, frameState.pixelRatio, frameState.extent, transform,\n        frameState.viewState.rotation);\n      const composeEvent = new RenderEvent(type, render, frameState,\n        context, null);\n      layer.dispatchEvent(composeEvent);\n      rotateAtOffset(context, rotation, width / 2, height / 2);\n    }\n  }\n\n  /**\n   * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n   * @param {module:ol/PluggableMap~FrameState} frameState FrameState.\n   * @param {number} hitTolerance Hit tolerance in pixels.\n   * @param {function(this: S, module:ol/layer/Layer, (Uint8ClampedArray|Uint8Array)): T} callback Layer\n   *     callback.\n   * @param {S} thisArg Value to use as `this` when executing `callback`.\n   * @return {T|undefined} Callback result.\n   * @template S,T,U\n   */\n  forEachLayerAtCoordinate(coordinate, frameState, hitTolerance, callback, thisArg) {\n    const hasFeature = this.forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, TRUE, this);\n\n    if (hasFeature) {\n      return callback.call(thisArg, this.getLayer(), null);\n    } else {\n      return undefined;\n    }\n  }\n\n  /**\n   * @param {CanvasRenderingContext2D} context Context.\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @param {module:ol/layer/Layer~State} layerState Layer state.\n   * @param {module:ol/transform~Transform=} opt_transform Transform.\n   * @protected\n   */\n  postCompose(context, frameState, layerState, opt_transform) {\n    this.dispatchComposeEvent_(RenderEventType.POSTCOMPOSE, context, frameState, opt_transform);\n  }\n\n  /**\n   * @param {CanvasRenderingContext2D} context Context.\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @param {module:ol/transform~Transform=} opt_transform Transform.\n   * @protected\n   */\n  preCompose(context, frameState, opt_transform) {\n    this.dispatchComposeEvent_(RenderEventType.PRECOMPOSE, context, frameState, opt_transform);\n  }\n\n  /**\n   * @param {CanvasRenderingContext2D} context Context.\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @param {module:ol/transform~Transform=} opt_transform Transform.\n   * @protected\n   */\n  dispatchRenderEvent(context, frameState, opt_transform) {\n    this.dispatchComposeEvent_(RenderEventType.RENDER, context, frameState, opt_transform);\n  }\n\n  /**\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @param {number} offsetX Offset on the x-axis in view coordinates.\n   * @protected\n   * @return {!module:ol/transform~Transform} Transform.\n   */\n  getTransform(frameState, offsetX) {\n    const viewState = frameState.viewState;\n    const pixelRatio = frameState.pixelRatio;\n    const dx1 = pixelRatio * frameState.size[0] / 2;\n    const dy1 = pixelRatio * frameState.size[1] / 2;\n    const sx = pixelRatio / viewState.resolution;\n    const sy = -sx;\n    const angle = -viewState.rotation;\n    const dx2 = -viewState.center[0] + offsetX;\n    const dy2 = -viewState.center[1];\n    return composeTransform(this.transform_, dx1, dy1, sx, sy, angle, dx2, dy2);\n  }\n\n  /**\n   * @abstract\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @param {module:ol/layer/Layer~State} layerState Layer state.\n   * @param {CanvasRenderingContext2D} context Context.\n   */\n  composeFrame(frameState, layerState, context) {}\n\n  /**\n   * @abstract\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @param {module:ol/layer/Layer~State} layerState Layer state.\n   * @return {boolean} whether composeFrame should be called.\n   */\n  prepareFrame(frameState, layerState) {}\n}\n\nexport default CanvasLayerRenderer;\n","/**\n * @module ol/renderer/canvas/IntermediateCanvas\n */\nimport {scale as scaleCoordinate} from '../../coordinate.js';\nimport {createCanvasContext2D} from '../../dom.js';\nimport {containsExtent, intersects} from '../../extent.js';\nimport {UNDEFINED} from '../../functions.js';\nimport CanvasLayerRenderer from '../canvas/Layer.js';\nimport {create as createTransform, apply as applyTransform} from '../../transform.js';\n\nclass IntermediateCanvasRenderer extends CanvasLayerRenderer {\n\n  /**\n   * @param {module:ol/layer/Layer} layer Layer.\n   */\n  constructor(layer) {\n\n    super(layer);\n\n    /**\n     * @protected\n     * @type {module:ol/transform~Transform}\n     */\n    this.coordinateToCanvasPixelTransform = createTransform();\n\n    /**\n     * @private\n     * @type {CanvasRenderingContext2D}\n     */\n    this.hitCanvasContext_ = null;\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  composeFrame(frameState, layerState, context) {\n\n    this.preCompose(context, frameState);\n\n    const image = this.getImage();\n    if (image) {\n\n      // clipped rendering if layer extent is set\n      const extent = layerState.extent;\n      const clipped = extent !== undefined &&\n          !containsExtent(extent, frameState.extent) &&\n          intersects(extent, frameState.extent);\n      if (clipped) {\n        this.clip(context, frameState, /** @type {module:ol/extent~Extent} */ (extent));\n      }\n\n      const imageTransform = this.getImageTransform();\n      // for performance reasons, context.save / context.restore is not used\n      // to save and restore the transformation matrix and the opacity.\n      // see http://jsperf.com/context-save-restore-versus-variable\n      const alpha = context.globalAlpha;\n      context.globalAlpha = layerState.opacity;\n\n      // for performance reasons, context.setTransform is only used\n      // when the view is rotated. see http://jsperf.com/canvas-transform\n      const dx = imageTransform[4];\n      const dy = imageTransform[5];\n      const dw = image.width * imageTransform[0];\n      const dh = image.height * imageTransform[3];\n      context.drawImage(image, 0, 0, +image.width, +image.height,\n        Math.round(dx), Math.round(dy), Math.round(dw), Math.round(dh));\n      context.globalAlpha = alpha;\n\n      if (clipped) {\n        context.restore();\n      }\n    }\n\n    this.postCompose(context, frameState, layerState);\n  }\n\n  /**\n   * @abstract\n   * @return {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} Canvas.\n   */\n  getImage() {}\n\n  /**\n   * @abstract\n   * @return {!module:ol/transform~Transform} Image transform.\n   */\n  getImageTransform() {}\n\n  /**\n   * @inheritDoc\n   */\n  forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback, thisArg) {\n    const layer = this.getLayer();\n    const source = layer.getSource();\n    const resolution = frameState.viewState.resolution;\n    const rotation = frameState.viewState.rotation;\n    const skippedFeatureUids = frameState.skippedFeatureUids;\n    return source.forEachFeatureAtCoordinate(\n      coordinate, resolution, rotation, hitTolerance, skippedFeatureUids,\n      /**\n       * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n       * @return {?} Callback result.\n       */\n      function(feature) {\n        return callback.call(thisArg, feature, layer);\n      });\n  }\n\n  /**\n   * @inheritDoc\n   */\n  forEachLayerAtCoordinate(coordinate, frameState, hitTolerance, callback, thisArg) {\n    if (!this.getImage()) {\n      return undefined;\n    }\n\n    if (this.getLayer().getSource().forEachFeatureAtCoordinate !== UNDEFINED) {\n      // for ImageCanvas sources use the original hit-detection logic,\n      // so that for example also transparent polygons are detected\n      return CanvasLayerRenderer.prototype.forEachLayerAtCoordinate.apply(this, arguments);\n    } else {\n      const pixel = applyTransform(this.coordinateToCanvasPixelTransform, coordinate.slice());\n      scaleCoordinate(pixel, frameState.viewState.resolution / this.renderedResolution);\n\n      if (!this.hitCanvasContext_) {\n        this.hitCanvasContext_ = createCanvasContext2D(1, 1);\n      }\n\n      this.hitCanvasContext_.clearRect(0, 0, 1, 1);\n      this.hitCanvasContext_.drawImage(this.getImage(), pixel[0], pixel[1], 1, 1, 0, 0, 1, 1);\n\n      const imageData = this.hitCanvasContext_.getImageData(0, 0, 1, 1).data;\n      if (imageData[3] > 0) {\n        return callback.call(thisArg, this.getLayer(), imageData);\n      } else {\n        return undefined;\n      }\n    }\n  }\n}\n\n\nexport default IntermediateCanvasRenderer;\n","/**\n * @module ol/renderer/canvas/ImageLayer\n */\nimport {ENABLE_RASTER_REPROJECTION} from '../../reproj/common.js';\nimport ImageCanvas from '../../ImageCanvas.js';\nimport LayerType from '../../LayerType.js';\nimport ViewHint from '../../ViewHint.js';\nimport {equals} from '../../array.js';\nimport {getHeight, getIntersection, getWidth, isEmpty} from '../../extent.js';\nimport VectorRenderType from '../../layer/VectorRenderType.js';\nimport {assign} from '../../obj.js';\nimport {layerRendererConstructors} from './Map.js';\nimport IntermediateCanvasRenderer from './IntermediateCanvas.js';\nimport {create as createTransform, compose as composeTransform} from '../../transform.js';\n\n/**\n * @classdesc\n * Canvas renderer for image layers.\n * @api\n */\nclass CanvasImageLayerRenderer extends IntermediateCanvasRenderer {\n\n  /**\n   * @param {module:ol/layer/Image|module:ol/layer/Vector} imageLayer Image or vector layer.\n   */\n  constructor(imageLayer) {\n\n    super(imageLayer);\n\n    /**\n     * @private\n     * @type {?module:ol/ImageBase}\n     */\n    this.image_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/transform~Transform}\n     */\n    this.imageTransform_ = createTransform();\n\n    /**\n     * @type {!Array.<string>}\n     */\n    this.skippedFeatures_ = [];\n\n    /**\n     * @private\n     * @type {module:ol/renderer/canvas/VectorLayer}\n     */\n    this.vectorRenderer_ = null;\n\n    if (imageLayer.getType() === LayerType.VECTOR) {\n      for (let i = 0, ii = layerRendererConstructors.length; i < ii; ++i) {\n        const ctor = layerRendererConstructors[i];\n        if (ctor !== CanvasImageLayerRenderer && ctor['handles'](imageLayer)) {\n          this.vectorRenderer_ = new ctor(imageLayer);\n          break;\n        }\n      }\n    }\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  disposeInternal() {\n    if (this.vectorRenderer_) {\n      this.vectorRenderer_.dispose();\n    }\n    IntermediateCanvasRenderer.prototype.disposeInternal.call(this);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getImage() {\n    return !this.image_ ? null : this.image_.getImage();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getImageTransform() {\n    return this.imageTransform_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  prepareFrame(frameState, layerState) {\n\n    const pixelRatio = frameState.pixelRatio;\n    const size = frameState.size;\n    const viewState = frameState.viewState;\n    const viewCenter = viewState.center;\n    const viewResolution = viewState.resolution;\n\n    let image;\n    const imageLayer = /** @type {module:ol/layer/Image} */ (this.getLayer());\n    const imageSource = imageLayer.getSource();\n\n    const hints = frameState.viewHints;\n\n    const vectorRenderer = this.vectorRenderer_;\n    let renderedExtent = frameState.extent;\n    if (!vectorRenderer && layerState.extent !== undefined) {\n      renderedExtent = getIntersection(renderedExtent, layerState.extent);\n    }\n\n    if (!hints[ViewHint.ANIMATING] && !hints[ViewHint.INTERACTING] &&\n        !isEmpty(renderedExtent)) {\n      let projection = viewState.projection;\n      if (!ENABLE_RASTER_REPROJECTION) {\n        const sourceProjection = imageSource.getProjection();\n        if (sourceProjection) {\n          projection = sourceProjection;\n        }\n      }\n      let skippedFeatures = this.skippedFeatures_;\n      if (vectorRenderer) {\n        const context = vectorRenderer.context;\n        const imageFrameState = /** @type {module:ol/PluggableMap~FrameState} */ (assign({}, frameState, {\n          size: [\n            getWidth(renderedExtent) / viewResolution,\n            getHeight(renderedExtent) / viewResolution\n          ],\n          viewState: /** @type {module:ol/View~State} */ (assign({}, frameState.viewState, {\n            rotation: 0\n          }))\n        }));\n        const newSkippedFeatures = Object.keys(imageFrameState.skippedFeatureUids).sort();\n        image = new ImageCanvas(renderedExtent, viewResolution, pixelRatio, context.canvas, function(callback) {\n          if (vectorRenderer.prepareFrame(imageFrameState, layerState) &&\n              (vectorRenderer.replayGroupChanged ||\n              !equals(skippedFeatures, newSkippedFeatures))) {\n            context.canvas.width = imageFrameState.size[0] * pixelRatio;\n            context.canvas.height = imageFrameState.size[1] * pixelRatio;\n            vectorRenderer.compose(context, imageFrameState, layerState);\n            skippedFeatures = newSkippedFeatures;\n            callback();\n          }\n        });\n      } else {\n        image = imageSource.getImage(\n          renderedExtent, viewResolution, pixelRatio, projection);\n      }\n      if (image && this.loadImage(image)) {\n        this.image_ = image;\n        this.skippedFeatures_ = skippedFeatures;\n      }\n    }\n\n    if (this.image_) {\n      image = this.image_;\n      const imageExtent = image.getExtent();\n      const imageResolution = image.getResolution();\n      const imagePixelRatio = image.getPixelRatio();\n      const scale = pixelRatio * imageResolution /\n          (viewResolution * imagePixelRatio);\n      const transform = composeTransform(this.imageTransform_,\n        pixelRatio * size[0] / 2, pixelRatio * size[1] / 2,\n        scale, scale,\n        0,\n        imagePixelRatio * (imageExtent[0] - viewCenter[0]) / imageResolution,\n        imagePixelRatio * (viewCenter[1] - imageExtent[3]) / imageResolution);\n      composeTransform(this.coordinateToCanvasPixelTransform,\n        pixelRatio * size[0] / 2 - transform[4], pixelRatio * size[1] / 2 - transform[5],\n        pixelRatio / viewResolution, -pixelRatio / viewResolution,\n        0,\n        -viewCenter[0], -viewCenter[1]);\n\n      this.renderedResolution = imageResolution * pixelRatio / imagePixelRatio;\n    }\n\n    return !!this.image_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback, thisArg) {\n    if (this.vectorRenderer_) {\n      return this.vectorRenderer_.forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback, thisArg);\n    } else {\n      return IntermediateCanvasRenderer.prototype.forEachFeatureAtCoordinate.call(this, coordinate, frameState, hitTolerance, callback, thisArg);\n    }\n  }\n}\n\n\n/**\n * Determine if this renderer handles the provided layer.\n * @param {module:ol/layer/Layer} layer The candidate layer.\n * @return {boolean} The renderer can render the layer.\n */\nCanvasImageLayerRenderer['handles'] = function(layer) {\n  return layer.getType() === LayerType.IMAGE ||\n    layer.getType() === LayerType.VECTOR &&\n    /** @type {module:ol/layer/Vector} */ (layer).getRenderMode() === VectorRenderType.IMAGE;\n};\n\n\n/**\n * Create a layer renderer.\n * @param {module:ol/renderer/Map} mapRenderer The map renderer.\n * @param {module:ol/layer/Layer} layer The layer to be rendererd.\n * @return {module:ol/renderer/canvas/ImageLayer} The layer renderer.\n */\nCanvasImageLayerRenderer['create'] = function(mapRenderer, layer) {\n  return new CanvasImageLayerRenderer(/** @type {module:ol/layer/Image} */ (layer));\n};\n\n\nexport default CanvasImageLayerRenderer;\n","/**\n * @module ol/TileRange\n */\n\n/**\n * A representation of a contiguous block of tiles.  A tile range is specified\n * by its min/max tile coordinates and is inclusive of coordinates.\n */\nclass TileRange {\n\n  /**\n   * @param {number} minX Minimum X.\n   * @param {number} maxX Maximum X.\n   * @param {number} minY Minimum Y.\n   * @param {number} maxY Maximum Y.\n   */\n  constructor(minX, maxX, minY, maxY) {\n\n    /**\n     * @type {number}\n     */\n    this.minX = minX;\n\n    /**\n     * @type {number}\n     */\n    this.maxX = maxX;\n\n    /**\n     * @type {number}\n     */\n    this.minY = minY;\n\n    /**\n     * @type {number}\n     */\n    this.maxY = maxY;\n\n  }\n\n  /**\n   * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n   * @return {boolean} Contains tile coordinate.\n   */\n  contains(tileCoord) {\n    return this.containsXY(tileCoord[1], tileCoord[2]);\n  }\n\n  /**\n   * @param {module:ol/TileRange} tileRange Tile range.\n   * @return {boolean} Contains.\n   */\n  containsTileRange(tileRange) {\n    return this.minX <= tileRange.minX && tileRange.maxX <= this.maxX &&\n       this.minY <= tileRange.minY && tileRange.maxY <= this.maxY;\n  }\n\n  /**\n   * @param {number} x Tile coordinate x.\n   * @param {number} y Tile coordinate y.\n   * @return {boolean} Contains coordinate.\n   */\n  containsXY(x, y) {\n    return this.minX <= x && x <= this.maxX && this.minY <= y && y <= this.maxY;\n  }\n\n  /**\n   * @param {module:ol/TileRange} tileRange Tile range.\n   * @return {boolean} Equals.\n   */\n  equals(tileRange) {\n    return this.minX == tileRange.minX && this.minY == tileRange.minY &&\n       this.maxX == tileRange.maxX && this.maxY == tileRange.maxY;\n  }\n\n  /**\n   * @param {module:ol/TileRange} tileRange Tile range.\n   */\n  extend(tileRange) {\n    if (tileRange.minX < this.minX) {\n      this.minX = tileRange.minX;\n    }\n    if (tileRange.maxX > this.maxX) {\n      this.maxX = tileRange.maxX;\n    }\n    if (tileRange.minY < this.minY) {\n      this.minY = tileRange.minY;\n    }\n    if (tileRange.maxY > this.maxY) {\n      this.maxY = tileRange.maxY;\n    }\n  }\n\n  /**\n  * @return {number} Height.\n  */\n  getHeight() {\n    return this.maxY - this.minY + 1;\n  }\n\n  /**\n  * @return {module:ol/size~Size} Size.\n  */\n  getSize() {\n    return [this.getWidth(), this.getHeight()];\n  }\n\n  /**\n  * @return {number} Width.\n  */\n  getWidth() {\n    return this.maxX - this.minX + 1;\n  }\n\n  /**\n  * @param {module:ol/TileRange} tileRange Tile range.\n  * @return {boolean} Intersects.\n  */\n  intersects(tileRange) {\n    return this.minX <= tileRange.maxX &&\n       this.maxX >= tileRange.minX &&\n       this.minY <= tileRange.maxY &&\n       this.maxY >= tileRange.minY;\n  }\n}\n\n\n/**\n * @param {number} minX Minimum X.\n * @param {number} maxX Maximum X.\n * @param {number} minY Minimum Y.\n * @param {number} maxY Maximum Y.\n * @param {module:ol/TileRange=} tileRange TileRange.\n * @return {module:ol/TileRange} Tile range.\n */\nexport function createOrUpdate(minX, maxX, minY, maxY, tileRange) {\n  if (tileRange !== undefined) {\n    tileRange.minX = minX;\n    tileRange.maxX = maxX;\n    tileRange.minY = minY;\n    tileRange.maxY = maxY;\n    return tileRange;\n  } else {\n    return new TileRange(minX, maxX, minY, maxY);\n  }\n}\n\n\nexport default TileRange;\n","/**\n * @module ol/renderer/canvas/TileLayer\n */\nimport {getUid} from '../../util.js';\nimport LayerType from '../../LayerType.js';\nimport TileRange from '../../TileRange.js';\nimport TileState from '../../TileState.js';\nimport ViewHint from '../../ViewHint.js';\nimport {createCanvasContext2D} from '../../dom.js';\nimport {containsExtent, createEmpty, equals, getIntersection, isEmpty} from '../../extent.js';\nimport IntermediateCanvasRenderer from '../canvas/IntermediateCanvas.js';\nimport {create as createTransform, compose as composeTransform} from '../../transform.js';\n\n/**\n * @classdesc\n * Canvas renderer for tile layers.\n * @api\n */\nclass CanvasTileLayerRenderer extends IntermediateCanvasRenderer {\n\n  /**\n   * @param {module:ol/layer/Tile|module:ol/layer/VectorTile} tileLayer Tile layer.\n   * @param {boolean=} opt_noContext Skip the context creation.\n   */\n  constructor(tileLayer, opt_noContext) {\n\n    super(tileLayer);\n\n    /**\n     * @protected\n     * @type {CanvasRenderingContext2D}\n     */\n    this.context = opt_noContext ? null : createCanvasContext2D();\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.oversampling_;\n\n    /**\n     * @private\n     * @type {module:ol/extent~Extent}\n     */\n    this.renderedExtent_ = null;\n\n    /**\n     * @protected\n     * @type {number}\n     */\n    this.renderedRevision;\n\n    /**\n     * @protected\n     * @type {!Array.<module:ol/Tile>}\n     */\n    this.renderedTiles = [];\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.newTiles_ = false;\n\n    /**\n     * @protected\n     * @type {module:ol/extent~Extent}\n     */\n    this.tmpExtent = createEmpty();\n\n    /**\n     * @private\n     * @type {module:ol/TileRange}\n     */\n    this.tmpTileRange_ = new TileRange(0, 0, 0, 0);\n\n    /**\n     * @private\n     * @type {module:ol/transform~Transform}\n     */\n    this.imageTransform_ = createTransform();\n\n    /**\n     * @protected\n     * @type {number}\n     */\n    this.zDirection = 0;\n\n  }\n\n  /**\n   * @private\n   * @param {module:ol/Tile} tile Tile.\n   * @return {boolean} Tile is drawable.\n   */\n  isDrawableTile_(tile) {\n    const tileState = tile.getState();\n    const useInterimTilesOnError = this.getLayer().getUseInterimTilesOnError();\n    return tileState == TileState.LOADED ||\n        tileState == TileState.EMPTY ||\n        tileState == TileState.ERROR && !useInterimTilesOnError;\n  }\n\n  /**\n   * @param {number} z Tile coordinate z.\n   * @param {number} x Tile coordinate x.\n   * @param {number} y Tile coordinate y.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @return {!module:ol/Tile} Tile.\n   */\n  getTile(z, x, y, pixelRatio, projection) {\n    const layer = this.getLayer();\n    const source = /** @type {module:ol/source/Tile} */ (layer.getSource());\n    let tile = source.getTile(z, x, y, pixelRatio, projection);\n    if (tile.getState() == TileState.ERROR) {\n      if (!layer.getUseInterimTilesOnError()) {\n        // When useInterimTilesOnError is false, we consider the error tile as loaded.\n        tile.setState(TileState.LOADED);\n      } else if (layer.getPreload() > 0) {\n        // Preloaded tiles for lower resolutions might have finished loading.\n        this.newTiles_ = true;\n      }\n    }\n    if (!this.isDrawableTile_(tile)) {\n      tile = tile.getInterimTile();\n    }\n    return tile;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  prepareFrame(frameState, layerState) {\n\n    const pixelRatio = frameState.pixelRatio;\n    const size = frameState.size;\n    const viewState = frameState.viewState;\n    const projection = viewState.projection;\n    const viewResolution = viewState.resolution;\n    const viewCenter = viewState.center;\n\n    const tileLayer = this.getLayer();\n    const tileSource = /** @type {module:ol/source/Tile} */ (tileLayer.getSource());\n    const sourceRevision = tileSource.getRevision();\n    const tileGrid = tileSource.getTileGridForProjection(projection);\n    const z = tileGrid.getZForResolution(viewResolution, this.zDirection);\n    const tileResolution = tileGrid.getResolution(z);\n    let oversampling = Math.round(viewResolution / tileResolution) || 1;\n    let extent = frameState.extent;\n\n    if (layerState.extent !== undefined) {\n      extent = getIntersection(extent, layerState.extent);\n    }\n    if (isEmpty(extent)) {\n      // Return false to prevent the rendering of the layer.\n      return false;\n    }\n\n    const tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);\n    const imageExtent = tileGrid.getTileRangeExtent(z, tileRange);\n\n    const tilePixelRatio = tileSource.getTilePixelRatio(pixelRatio);\n\n    /**\n     * @type {Object.<number, Object.<string, module:ol/Tile>>}\n     */\n    const tilesToDrawByZ = {};\n    tilesToDrawByZ[z] = {};\n\n    const findLoadedTiles = this.createLoadedTileFinder(\n      tileSource, projection, tilesToDrawByZ);\n\n    const hints = frameState.viewHints;\n    const animatingOrInteracting = hints[ViewHint.ANIMATING] || hints[ViewHint.INTERACTING];\n\n    const tmpExtent = this.tmpExtent;\n    const tmpTileRange = this.tmpTileRange_;\n    this.newTiles_ = false;\n    let tile, x, y;\n    for (x = tileRange.minX; x <= tileRange.maxX; ++x) {\n      for (y = tileRange.minY; y <= tileRange.maxY; ++y) {\n        if (Date.now() - frameState.time > 16 && animatingOrInteracting) {\n          continue;\n        }\n        tile = this.getTile(z, x, y, pixelRatio, projection);\n        if (this.isDrawableTile_(tile)) {\n          const uid = getUid(this);\n          if (tile.getState() == TileState.LOADED) {\n            tilesToDrawByZ[z][tile.tileCoord.toString()] = tile;\n            const inTransition = tile.inTransition(uid);\n            if (!this.newTiles_ && (inTransition || this.renderedTiles.indexOf(tile) === -1)) {\n              this.newTiles_ = true;\n            }\n          }\n          if (tile.getAlpha(uid, frameState.time) === 1) {\n            // don't look for alt tiles if alpha is 1\n            continue;\n          }\n        }\n\n        const childTileRange = tileGrid.getTileCoordChildTileRange(\n          tile.tileCoord, tmpTileRange, tmpExtent);\n        let covered = false;\n        if (childTileRange) {\n          covered = findLoadedTiles(z + 1, childTileRange);\n        }\n        if (!covered) {\n          tileGrid.forEachTileCoordParentTileRange(\n            tile.tileCoord, findLoadedTiles, null, tmpTileRange, tmpExtent);\n        }\n\n      }\n    }\n\n    const renderedResolution = tileResolution * pixelRatio / tilePixelRatio * oversampling;\n    if (!(this.renderedResolution && Date.now() - frameState.time > 16 && animatingOrInteracting) && (\n      this.newTiles_ ||\n          !(this.renderedExtent_ && containsExtent(this.renderedExtent_, extent)) ||\n          this.renderedRevision != sourceRevision ||\n          oversampling != this.oversampling_ ||\n          !animatingOrInteracting && renderedResolution != this.renderedResolution\n    )) {\n\n      const context = this.context;\n      if (context) {\n        const tilePixelSize = tileSource.getTilePixelSize(z, pixelRatio, projection);\n        const width = Math.round(tileRange.getWidth() * tilePixelSize[0] / oversampling);\n        const height = Math.round(tileRange.getHeight() * tilePixelSize[1] / oversampling);\n        const canvas = context.canvas;\n        if (canvas.width != width || canvas.height != height) {\n          this.oversampling_ = oversampling;\n          canvas.width = width;\n          canvas.height = height;\n        } else {\n          if (this.renderedExtent_ && !equals(imageExtent, this.renderedExtent_)) {\n            context.clearRect(0, 0, width, height);\n          }\n          oversampling = this.oversampling_;\n        }\n      }\n\n      this.renderedTiles.length = 0;\n      /** @type {Array.<number>} */\n      const zs = Object.keys(tilesToDrawByZ).map(Number);\n      zs.sort(function(a, b) {\n        if (a === z) {\n          return 1;\n        } else if (b === z) {\n          return -1;\n        } else {\n          return a > b ? 1 : a < b ? -1 : 0;\n        }\n      });\n      let currentResolution, currentScale, currentTilePixelSize, currentZ, i, ii;\n      let tileExtent, tileGutter, tilesToDraw, w, h;\n      for (i = 0, ii = zs.length; i < ii; ++i) {\n        currentZ = zs[i];\n        currentTilePixelSize = tileSource.getTilePixelSize(currentZ, pixelRatio, projection);\n        currentResolution = tileGrid.getResolution(currentZ);\n        currentScale = currentResolution / tileResolution;\n        tileGutter = tilePixelRatio * tileSource.getGutter(projection);\n        tilesToDraw = tilesToDrawByZ[currentZ];\n        for (const tileCoordKey in tilesToDraw) {\n          tile = tilesToDraw[tileCoordKey];\n          tileExtent = tileGrid.getTileCoordExtent(tile.getTileCoord(), tmpExtent);\n          x = (tileExtent[0] - imageExtent[0]) / tileResolution * tilePixelRatio / oversampling;\n          y = (imageExtent[3] - tileExtent[3]) / tileResolution * tilePixelRatio / oversampling;\n          w = currentTilePixelSize[0] * currentScale / oversampling;\n          h = currentTilePixelSize[1] * currentScale / oversampling;\n          this.drawTileImage(tile, frameState, layerState, x, y, w, h, tileGutter, z === currentZ);\n          this.renderedTiles.push(tile);\n        }\n      }\n\n      this.renderedRevision = sourceRevision;\n      this.renderedResolution = tileResolution * pixelRatio / tilePixelRatio * oversampling;\n      this.renderedExtent_ = imageExtent;\n    }\n\n    const scale = this.renderedResolution / viewResolution;\n    const transform = composeTransform(this.imageTransform_,\n      pixelRatio * size[0] / 2, pixelRatio * size[1] / 2,\n      scale, scale,\n      0,\n      (this.renderedExtent_[0] - viewCenter[0]) / this.renderedResolution * pixelRatio,\n      (viewCenter[1] - this.renderedExtent_[3]) / this.renderedResolution * pixelRatio);\n    composeTransform(this.coordinateToCanvasPixelTransform,\n      pixelRatio * size[0] / 2 - transform[4], pixelRatio * size[1] / 2 - transform[5],\n      pixelRatio / viewResolution, -pixelRatio / viewResolution,\n      0,\n      -viewCenter[0], -viewCenter[1]);\n\n\n    this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);\n    this.manageTilePyramid(frameState, tileSource, tileGrid, pixelRatio,\n      projection, extent, z, tileLayer.getPreload());\n    this.scheduleExpireCache(frameState, tileSource);\n\n    return this.renderedTiles.length > 0;\n  }\n\n  /**\n   * @param {module:ol/Tile} tile Tile.\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @param {module:ol/layer/Layer~State} layerState Layer state.\n   * @param {number} x Left of the tile.\n   * @param {number} y Top of the tile.\n   * @param {number} w Width of the tile.\n   * @param {number} h Height of the tile.\n   * @param {number} gutter Tile gutter.\n   * @param {boolean} transition Apply an alpha transition.\n   */\n  drawTileImage(tile, frameState, layerState, x, y, w, h, gutter, transition) {\n    const image = tile.getImage(this.getLayer());\n    if (!image) {\n      return;\n    }\n    const uid = getUid(this);\n    const alpha = transition ? tile.getAlpha(uid, frameState.time) : 1;\n    if (alpha === 1 && !this.getLayer().getSource().getOpaque(frameState.viewState.projection)) {\n      this.context.clearRect(x, y, w, h);\n    }\n    const alphaChanged = alpha !== this.context.globalAlpha;\n    if (alphaChanged) {\n      this.context.save();\n      this.context.globalAlpha = alpha;\n    }\n    this.context.drawImage(image, gutter, gutter,\n      image.width - 2 * gutter, image.height - 2 * gutter, x, y, w, h);\n\n    if (alphaChanged) {\n      this.context.restore();\n    }\n    if (alpha !== 1) {\n      frameState.animate = true;\n    } else if (transition) {\n      tile.endTransition(uid);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getImage() {\n    const context = this.context;\n    return context ? context.canvas : null;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getImageTransform() {\n    return this.imageTransform_;\n  }\n}\n\n\n/**\n * Determine if this renderer handles the provided layer.\n * @param {module:ol/layer/Layer} layer The candidate layer.\n * @return {boolean} The renderer can render the layer.\n */\nCanvasTileLayerRenderer['handles'] = function(layer) {\n  return layer.getType() === LayerType.TILE;\n};\n\n\n/**\n * Create a layer renderer.\n * @param {module:ol/renderer/Map} mapRenderer The map renderer.\n * @param {module:ol/layer/Layer} layer The layer to be rendererd.\n * @return {module:ol/renderer/canvas/TileLayer} The layer renderer.\n */\nCanvasTileLayerRenderer['create'] = function(mapRenderer, layer) {\n  return new CanvasTileLayerRenderer(/** @type {module:ol/layer/Tile} */ (layer));\n};\n\n\n/**\n * @function\n * @return {module:ol/layer/Tile|module:ol/layer/VectorTile}\n */\nCanvasTileLayerRenderer.prototype.getLayer;\n\n\nexport default CanvasTileLayerRenderer;\n","/**\n * @module ol/render/ReplayGroup\n */\n/**\n * Base class for replay groups.\n */\nclass ReplayGroup {\n  /**\n   * @abstract\n   * @param {number|undefined} zIndex Z index.\n   * @param {module:ol/render/ReplayType} replayType Replay type.\n   * @return {module:ol/render/VectorContext} Replay.\n   */\n  getReplay(zIndex, replayType) {}\n\n  /**\n   * @abstract\n   * @return {boolean} Is empty.\n   */\n  isEmpty() {}\n}\n\nexport default ReplayGroup;\n","/**\n * @module ol/render/ReplayType\n */\n\n/**\n * @enum {string}\n */\nexport default {\n  CIRCLE: 'Circle',\n  DEFAULT: 'Default',\n  IMAGE: 'Image',\n  LINE_STRING: 'LineString',\n  POLYGON: 'Polygon',\n  TEXT: 'Text'\n};\n","/**\n * @module ol/geom/flat/textpath\n */\nimport {lerp} from '../../math.js';\n\n\n/**\n * @param {Array.<number>} flatCoordinates Path to put text on.\n * @param {number} offset Start offset of the `flatCoordinates`.\n * @param {number} end End offset of the `flatCoordinates`.\n * @param {number} stride Stride.\n * @param {string} text Text to place on the path.\n * @param {function(string):number} measure Measure function returning the\n * width of the character passed as 1st argument.\n * @param {number} startM m along the path where the text starts.\n * @param {number} maxAngle Max angle between adjacent chars in radians.\n * @return {Array.<Array.<*>>} The result array of null if `maxAngle` was\n * exceeded. Entries of the array are x, y, anchorX, angle, chunk.\n */\nexport function drawTextOnPath(\n  flatCoordinates, offset, end, stride, text, measure, startM, maxAngle) {\n  const result = [];\n\n  // Keep text upright\n  const reverse = flatCoordinates[offset] > flatCoordinates[end - stride];\n\n  const numChars = text.length;\n\n  let x1 = flatCoordinates[offset];\n  let y1 = flatCoordinates[offset + 1];\n  offset += stride;\n  let x2 = flatCoordinates[offset];\n  let y2 = flatCoordinates[offset + 1];\n  let segmentM = 0;\n  let segmentLength = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));\n\n  let chunk = '';\n  let chunkLength = 0;\n  let data, index, previousAngle;\n  for (let i = 0; i < numChars; ++i) {\n    index = reverse ? numChars - i - 1 : i;\n    const char = text.charAt(index);\n    chunk = reverse ? char + chunk : chunk + char;\n    const charLength = measure(chunk) - chunkLength;\n    chunkLength += charLength;\n    const charM = startM + charLength / 2;\n    while (offset < end - stride && segmentM + segmentLength < charM) {\n      x1 = x2;\n      y1 = y2;\n      offset += stride;\n      x2 = flatCoordinates[offset];\n      y2 = flatCoordinates[offset + 1];\n      segmentM += segmentLength;\n      segmentLength = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));\n    }\n    const segmentPos = charM - segmentM;\n    let angle = Math.atan2(y2 - y1, x2 - x1);\n    if (reverse) {\n      angle += angle > 0 ? -Math.PI : Math.PI;\n    }\n    if (previousAngle !== undefined) {\n      let delta = angle - previousAngle;\n      delta += (delta > Math.PI) ? -2 * Math.PI : (delta < -Math.PI) ? 2 * Math.PI : 0;\n      if (Math.abs(delta) > maxAngle) {\n        return null;\n      }\n    }\n    const interpolate = segmentPos / segmentLength;\n    const x = lerp(x1, x2, interpolate);\n    const y = lerp(y1, y2, interpolate);\n    if (previousAngle == angle) {\n      if (reverse) {\n        data[0] = x;\n        data[1] = y;\n        data[2] = charLength / 2;\n      }\n      data[4] = chunk;\n    } else {\n      chunk = char;\n      chunkLength = charLength;\n      data = [x, y, charLength / 2, angle, chunk];\n      if (reverse) {\n        result.unshift(data);\n      } else {\n        result.push(data);\n      }\n      previousAngle = angle;\n    }\n    startM += charLength;\n  }\n  return result;\n}\n","/**\n * @module ol/render/canvas/Instruction\n */\n\n/**\n * @enum {number}\n */\nconst Instruction = {\n  BEGIN_GEOMETRY: 0,\n  BEGIN_PATH: 1,\n  CIRCLE: 2,\n  CLOSE_PATH: 3,\n  CUSTOM: 4,\n  DRAW_CHARS: 5,\n  DRAW_IMAGE: 6,\n  END_GEOMETRY: 7,\n  FILL: 8,\n  MOVE_TO_LINE_TO: 9,\n  SET_FILL_STYLE: 10,\n  SET_STROKE_STYLE: 11,\n  STROKE: 12\n};\n\n\n/**\n * @type {Array.<Instruction>}\n */\nexport const fillInstruction = [Instruction.FILL];\n\n\n/**\n * @type {Array.<Instruction>}\n */\nexport const strokeInstruction = [Instruction.STROKE];\n\n\n/**\n * @type {Array.<Instruction>}\n */\nexport const beginPathInstruction = [Instruction.BEGIN_PATH];\n\n\n/**\n * @type {Array.<Instruction>}\n */\nexport const closePathInstruction = [Instruction.CLOSE_PATH];\n\n\nexport default Instruction;\n","/**\n * @module ol/render/replay\n */\nimport ReplayType from '../render/ReplayType.js';\n\n\n/**\n * @const\n * @type {Array.<module:ol/render/ReplayType>}\n */\nexport const ORDER = [\n  ReplayType.POLYGON,\n  ReplayType.CIRCLE,\n  ReplayType.LINE_STRING,\n  ReplayType.IMAGE,\n  ReplayType.TEXT,\n  ReplayType.DEFAULT\n];\n\n/**\n * @const\n * @enum {number}\n */\nexport const TEXT_ALIGN = {};\nTEXT_ALIGN['left'] = 0;\nTEXT_ALIGN['end'] = 0;\nTEXT_ALIGN['center'] = 0.5;\nTEXT_ALIGN['right'] = 1;\nTEXT_ALIGN['start'] = 1;\nTEXT_ALIGN['top'] = 0;\nTEXT_ALIGN['middle'] = 0.5;\nTEXT_ALIGN['hanging'] = 0.2;\nTEXT_ALIGN['alphabetic'] = 0.8;\nTEXT_ALIGN['ideographic'] = 0.8;\nTEXT_ALIGN['bottom'] = 1;\n","/**\n * @module ol/render/canvas/Replay\n */\nimport {getUid} from '../../util.js';\nimport {UNDEFINED} from '../../functions.js';\nimport {equals, reverseSubArray} from '../../array.js';\nimport {asColorLike} from '../../colorlike.js';\nimport {buffer, clone, coordinateRelationship, createEmpty, createOrUpdate,\n  createOrUpdateEmpty, extend, extendCoordinate, intersects} from '../../extent.js';\nimport Relationship from '../../extent/Relationship.js';\nimport GeometryType from '../../geom/GeometryType.js';\nimport {inflateCoordinates, inflateCoordinatesArray, inflateMultiCoordinatesArray} from '../../geom/flat/inflate.js';\nimport {lineStringLength} from '../../geom/flat/length.js';\nimport {drawTextOnPath} from '../../geom/flat/textpath.js';\nimport {transform2D} from '../../geom/flat/transform.js';\nimport {CANVAS_LINE_DASH} from '../../has.js';\nimport {isEmpty} from '../../obj.js';\nimport VectorContext from '../VectorContext.js';\nimport {drawImage, resetTransform, defaultPadding, defaultFillStyle, defaultStrokeStyle,\n  defaultMiterLimit, defaultLineWidth, defaultLineJoin, defaultLineDashOffset,\n  defaultLineDash, defaultLineCap} from '../canvas.js';\nimport CanvasInstruction from '../canvas/Instruction.js';\nimport {TEXT_ALIGN} from '../replay.js';\nimport {\n  create as createTransform,\n  compose as composeTransform,\n  apply as applyTransform,\n  setFromArray as transformSetFromArray\n} from '../../transform.js';\n\n\n/**\n * @type {module:ol/extent~Extent}\n */\nconst tmpExtent = createEmpty();\n\n\n/**\n * @type {!module:ol/transform~Transform}\n */\nconst tmpTransform = createTransform();\n\n\nclass CanvasReplay extends VectorContext {\n  /**\n   * @param {number} tolerance Tolerance.\n   * @param {module:ol/extent~Extent} maxExtent Maximum extent.\n   * @param {number} resolution Resolution.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {boolean} overlaps The replay can have overlapping geometries.\n   * @param {?} declutterTree Declutter tree.\n   */\n  constructor(tolerance, maxExtent, resolution, pixelRatio, overlaps, declutterTree) {\n    super();\n\n    /**\n     * @type {?}\n     */\n    this.declutterTree = declutterTree;\n\n    /**\n     * @protected\n     * @type {number}\n     */\n    this.tolerance = tolerance;\n\n    /**\n     * @protected\n     * @const\n     * @type {module:ol/extent~Extent}\n     */\n    this.maxExtent = maxExtent;\n\n    /**\n     * @protected\n     * @type {boolean}\n     */\n    this.overlaps = overlaps;\n\n    /**\n     * @protected\n     * @type {number}\n     */\n    this.pixelRatio = pixelRatio;\n\n    /**\n     * @protected\n     * @type {number}\n     */\n    this.maxLineWidth = 0;\n\n    /**\n     * @protected\n     * @const\n     * @type {number}\n     */\n    this.resolution = resolution;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.alignFill_;\n\n    /**\n     * @private\n     * @type {Array.<*>}\n     */\n    this.beginGeometryInstruction1_ = null;\n\n    /**\n     * @private\n     * @type {Array.<*>}\n     */\n    this.beginGeometryInstruction2_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/extent~Extent}\n     */\n    this.bufferedMaxExtent_ = null;\n\n    /**\n     * @protected\n     * @type {Array.<*>}\n     */\n    this.instructions = [];\n\n    /**\n     * @protected\n     * @type {Array.<number>}\n     */\n    this.coordinates = [];\n\n    /**\n     * @private\n     * @type {!Object.<number,module:ol/coordinate~Coordinate|Array.<module:ol/coordinate~Coordinate>|Array.<Array.<module:ol/coordinate~Coordinate>>>}\n     */\n    this.coordinateCache_ = {};\n\n    /**\n     * @private\n     * @type {!module:ol/transform~Transform}\n     */\n    this.renderedTransform_ = createTransform();\n\n    /**\n     * @protected\n     * @type {Array.<*>}\n     */\n    this.hitDetectionInstructions = [];\n\n    /**\n     * @private\n     * @type {Array.<number>}\n     */\n    this.pixelCoordinates_ = null;\n\n    /**\n     * @protected\n     * @type {module:ol/render/canvas~FillStrokeState}\n     */\n    this.state = /** @type {module:ol/render/canvas~FillStrokeState} */ ({});\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.viewRotation_ = 0;\n\n  }\n\n  /**\n   * @param {CanvasRenderingContext2D} context Context.\n   * @param {module:ol/coordinate~Coordinate} p1 1st point of the background box.\n   * @param {module:ol/coordinate~Coordinate} p2 2nd point of the background box.\n   * @param {module:ol/coordinate~Coordinate} p3 3rd point of the background box.\n   * @param {module:ol/coordinate~Coordinate} p4 4th point of the background box.\n   * @param {Array.<*>} fillInstruction Fill instruction.\n   * @param {Array.<*>} strokeInstruction Stroke instruction.\n   */\n  replayTextBackground_(context, p1, p2, p3, p4, fillInstruction, strokeInstruction) {\n    context.beginPath();\n    context.moveTo.apply(context, p1);\n    context.lineTo.apply(context, p2);\n    context.lineTo.apply(context, p3);\n    context.lineTo.apply(context, p4);\n    context.lineTo.apply(context, p1);\n    if (fillInstruction) {\n      this.alignFill_ = /** @type {boolean} */ (fillInstruction[2]);\n      this.fill_(context);\n    }\n    if (strokeInstruction) {\n      this.setStrokeStyle_(context, /** @type {Array.<*>} */ (strokeInstruction));\n      context.stroke();\n    }\n  }\n\n  /**\n   * @param {CanvasRenderingContext2D} context Context.\n   * @param {number} x X.\n   * @param {number} y Y.\n   * @param {HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} image Image.\n   * @param {number} anchorX Anchor X.\n   * @param {number} anchorY Anchor Y.\n   * @param {module:ol/render/canvas~DeclutterGroup} declutterGroup Declutter group.\n   * @param {number} height Height.\n   * @param {number} opacity Opacity.\n   * @param {number} originX Origin X.\n   * @param {number} originY Origin Y.\n   * @param {number} rotation Rotation.\n   * @param {number} scale Scale.\n   * @param {boolean} snapToPixel Snap to pixel.\n   * @param {number} width Width.\n   * @param {Array.<number>} padding Padding.\n   * @param {Array.<*>} fillInstruction Fill instruction.\n   * @param {Array.<*>} strokeInstruction Stroke instruction.\n   */\n  replayImage_(\n    context,\n    x,\n    y,\n    image,\n    anchorX,\n    anchorY,\n    declutterGroup,\n    height,\n    opacity,\n    originX,\n    originY,\n    rotation,\n    scale,\n    snapToPixel,\n    width,\n    padding,\n    fillInstruction,\n    strokeInstruction\n  ) {\n    const fillStroke = fillInstruction || strokeInstruction;\n    anchorX *= scale;\n    anchorY *= scale;\n    x -= anchorX;\n    y -= anchorY;\n\n    const w = (width + originX > image.width) ? image.width - originX : width;\n    const h = (height + originY > image.height) ? image.height - originY : height;\n    const boxW = padding[3] + w * scale + padding[1];\n    const boxH = padding[0] + h * scale + padding[2];\n    const boxX = x - padding[3];\n    const boxY = y - padding[0];\n\n    /** @type {module:ol/coordinate~Coordinate} */\n    let p1;\n    /** @type {module:ol/coordinate~Coordinate} */\n    let p2;\n    /** @type {module:ol/coordinate~Coordinate} */\n    let p3;\n    /** @type {module:ol/coordinate~Coordinate} */\n    let p4;\n    if (fillStroke || rotation !== 0) {\n      p1 = [boxX, boxY];\n      p2 = [boxX + boxW, boxY];\n      p3 = [boxX + boxW, boxY + boxH];\n      p4 = [boxX, boxY + boxH];\n    }\n\n    let transform = null;\n    if (rotation !== 0) {\n      const centerX = x + anchorX;\n      const centerY = y + anchorY;\n      transform = composeTransform(tmpTransform, centerX, centerY, 1, 1, rotation, -centerX, -centerY);\n\n      createOrUpdateEmpty(tmpExtent);\n      extendCoordinate(tmpExtent, applyTransform(tmpTransform, p1));\n      extendCoordinate(tmpExtent, applyTransform(tmpTransform, p2));\n      extendCoordinate(tmpExtent, applyTransform(tmpTransform, p3));\n      extendCoordinate(tmpExtent, applyTransform(tmpTransform, p4));\n    } else {\n      createOrUpdate(boxX, boxY, boxX + boxW, boxY + boxH, tmpExtent);\n    }\n    const canvas = context.canvas;\n    const strokePadding = strokeInstruction ? (strokeInstruction[2] * scale / 2) : 0;\n    const intersects =\n        tmpExtent[0] - strokePadding <= canvas.width && tmpExtent[2] + strokePadding >= 0 &&\n        tmpExtent[1] - strokePadding <= canvas.height && tmpExtent[3] + strokePadding >= 0;\n\n    if (snapToPixel) {\n      x = Math.round(x);\n      y = Math.round(y);\n    }\n\n    if (declutterGroup) {\n      if (!intersects && declutterGroup[4] == 1) {\n        return;\n      }\n      extend(declutterGroup, tmpExtent);\n      const declutterArgs = intersects ?\n        [context, transform ? transform.slice(0) : null, opacity, image, originX, originY, w, h, x, y, scale] :\n        null;\n      if (declutterArgs && fillStroke) {\n        declutterArgs.push(fillInstruction, strokeInstruction, p1, p2, p3, p4);\n      }\n      declutterGroup.push(declutterArgs);\n    } else if (intersects) {\n      if (fillStroke) {\n        this.replayTextBackground_(context, p1, p2, p3, p4,\n          /** @type {Array.<*>} */ (fillInstruction),\n          /** @type {Array.<*>} */ (strokeInstruction));\n      }\n      drawImage(context, transform, opacity, image, originX, originY, w, h, x, y, scale);\n    }\n  }\n\n  /**\n   * @protected\n   * @param {Array.<number>} dashArray Dash array.\n   * @return {Array.<number>} Dash array with pixel ratio applied\n   */\n  applyPixelRatio(dashArray) {\n    const pixelRatio = this.pixelRatio;\n    return pixelRatio == 1 ? dashArray : dashArray.map(function(dash) {\n      return dash * pixelRatio;\n    });\n  }\n\n  /**\n   * @param {Array.<number>} flatCoordinates Flat coordinates.\n   * @param {number} offset Offset.\n   * @param {number} end End.\n   * @param {number} stride Stride.\n   * @param {boolean} closed Last input coordinate equals first.\n   * @param {boolean} skipFirst Skip first coordinate.\n   * @protected\n   * @return {number} My end.\n   */\n  appendFlatCoordinates(flatCoordinates, offset, end, stride, closed, skipFirst) {\n\n    let myEnd = this.coordinates.length;\n    const extent = this.getBufferedMaxExtent();\n    if (skipFirst) {\n      offset += stride;\n    }\n    const lastCoord = [flatCoordinates[offset], flatCoordinates[offset + 1]];\n    const nextCoord = [NaN, NaN];\n    let skipped = true;\n\n    let i, lastRel, nextRel;\n    for (i = offset + stride; i < end; i += stride) {\n      nextCoord[0] = flatCoordinates[i];\n      nextCoord[1] = flatCoordinates[i + 1];\n      nextRel = coordinateRelationship(extent, nextCoord);\n      if (nextRel !== lastRel) {\n        if (skipped) {\n          this.coordinates[myEnd++] = lastCoord[0];\n          this.coordinates[myEnd++] = lastCoord[1];\n        }\n        this.coordinates[myEnd++] = nextCoord[0];\n        this.coordinates[myEnd++] = nextCoord[1];\n        skipped = false;\n      } else if (nextRel === Relationship.INTERSECTING) {\n        this.coordinates[myEnd++] = nextCoord[0];\n        this.coordinates[myEnd++] = nextCoord[1];\n        skipped = false;\n      } else {\n        skipped = true;\n      }\n      lastCoord[0] = nextCoord[0];\n      lastCoord[1] = nextCoord[1];\n      lastRel = nextRel;\n    }\n\n    // Last coordinate equals first or only one point to append:\n    if ((closed && skipped) || i === offset + stride) {\n      this.coordinates[myEnd++] = lastCoord[0];\n      this.coordinates[myEnd++] = lastCoord[1];\n    }\n    return myEnd;\n  }\n\n  /**\n   * @param {Array.<number>} flatCoordinates Flat coordinates.\n   * @param {number} offset Offset.\n   * @param {Array.<number>} ends Ends.\n   * @param {number} stride Stride.\n   * @param {Array.<number>} replayEnds Replay ends.\n   * @return {number} Offset.\n   */\n  drawCustomCoordinates_(flatCoordinates, offset, ends, stride, replayEnds) {\n    for (let i = 0, ii = ends.length; i < ii; ++i) {\n      const end = ends[i];\n      const replayEnd = this.appendFlatCoordinates(flatCoordinates, offset, end, stride, false, false);\n      replayEnds.push(replayEnd);\n      offset = end;\n    }\n    return offset;\n  }\n\n  /**\n   * @inheritDoc.\n   */\n  drawCustom(geometry, feature, renderer) {\n    this.beginGeometry(geometry, feature);\n    const type = geometry.getType();\n    const stride = geometry.getStride();\n    const replayBegin = this.coordinates.length;\n    let flatCoordinates, replayEnd, replayEnds, replayEndss;\n    let offset;\n    if (type == GeometryType.MULTI_POLYGON) {\n      geometry = /** @type {module:ol/geom/MultiPolygon} */ (geometry);\n      flatCoordinates = geometry.getOrientedFlatCoordinates();\n      replayEndss = [];\n      const endss = geometry.getEndss();\n      offset = 0;\n      for (let i = 0, ii = endss.length; i < ii; ++i) {\n        const myEnds = [];\n        offset = this.drawCustomCoordinates_(flatCoordinates, offset, endss[i], stride, myEnds);\n        replayEndss.push(myEnds);\n      }\n      this.instructions.push([CanvasInstruction.CUSTOM,\n        replayBegin, replayEndss, geometry, renderer, inflateMultiCoordinatesArray]);\n    } else if (type == GeometryType.POLYGON || type == GeometryType.MULTI_LINE_STRING) {\n      replayEnds = [];\n      flatCoordinates = (type == GeometryType.POLYGON) ?\n        /** @type {module:ol/geom/Polygon} */ (geometry).getOrientedFlatCoordinates() :\n        geometry.getFlatCoordinates();\n      offset = this.drawCustomCoordinates_(flatCoordinates, 0,\n        /** @type {module:ol/geom/Polygon|module:ol/geom/MultiLineString} */ (geometry).getEnds(),\n        stride, replayEnds);\n      this.instructions.push([CanvasInstruction.CUSTOM,\n        replayBegin, replayEnds, geometry, renderer, inflateCoordinatesArray]);\n    } else if (type == GeometryType.LINE_STRING || type == GeometryType.MULTI_POINT) {\n      flatCoordinates = geometry.getFlatCoordinates();\n      replayEnd = this.appendFlatCoordinates(\n        flatCoordinates, 0, flatCoordinates.length, stride, false, false);\n      this.instructions.push([CanvasInstruction.CUSTOM,\n        replayBegin, replayEnd, geometry, renderer, inflateCoordinates]);\n    } else if (type == GeometryType.POINT) {\n      flatCoordinates = geometry.getFlatCoordinates();\n      this.coordinates.push(flatCoordinates[0], flatCoordinates[1]);\n      replayEnd = this.coordinates.length;\n      this.instructions.push([CanvasInstruction.CUSTOM,\n        replayBegin, replayEnd, geometry, renderer]);\n    }\n    this.endGeometry(geometry, feature);\n  }\n\n  /**\n   * @protected\n   * @param {module:ol/geom/Geometry|module:ol/render/Feature} geometry Geometry.\n   * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n   */\n  beginGeometry(geometry, feature) {\n    this.beginGeometryInstruction1_ = [CanvasInstruction.BEGIN_GEOMETRY, feature, 0];\n    this.instructions.push(this.beginGeometryInstruction1_);\n    this.beginGeometryInstruction2_ = [CanvasInstruction.BEGIN_GEOMETRY, feature, 0];\n    this.hitDetectionInstructions.push(this.beginGeometryInstruction2_);\n  }\n\n  /**\n   * @private\n   * @param {CanvasRenderingContext2D} context Context.\n   */\n  fill_(context) {\n    if (this.alignFill_) {\n      const origin = applyTransform(this.renderedTransform_, [0, 0]);\n      const repeatSize = 512 * this.pixelRatio;\n      context.translate(origin[0] % repeatSize, origin[1] % repeatSize);\n      context.rotate(this.viewRotation_);\n    }\n    context.fill();\n    if (this.alignFill_) {\n      context.setTransform.apply(context, resetTransform);\n    }\n  }\n\n  /**\n   * @private\n   * @param {CanvasRenderingContext2D} context Context.\n   * @param {Array.<*>} instruction Instruction.\n   */\n  setStrokeStyle_(context, instruction) {\n    context.strokeStyle = /** @type {module:ol/colorlike~ColorLike} */ (instruction[1]);\n    context.lineWidth = /** @type {number} */ (instruction[2]);\n    context.lineCap = /** @type {string} */ (instruction[3]);\n    context.lineJoin = /** @type {string} */ (instruction[4]);\n    context.miterLimit = /** @type {number} */ (instruction[5]);\n    if (CANVAS_LINE_DASH) {\n      context.lineDashOffset = /** @type {number} */ (instruction[7]);\n      context.setLineDash(/** @type {Array.<number>} */ (instruction[6]));\n    }\n  }\n\n  /**\n   * @param {module:ol/render/canvas~DeclutterGroup} declutterGroup Declutter group.\n   * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n   */\n  renderDeclutter_(declutterGroup, feature) {\n    if (declutterGroup && declutterGroup.length > 5) {\n      const groupCount = declutterGroup[4];\n      if (groupCount == 1 || groupCount == declutterGroup.length - 5) {\n        /** @type {module:ol/structs/RBush~Entry} */\n        const box = {\n          minX: /** @type {number} */ (declutterGroup[0]),\n          minY: /** @type {number} */ (declutterGroup[1]),\n          maxX: /** @type {number} */ (declutterGroup[2]),\n          maxY: /** @type {number} */ (declutterGroup[3]),\n          value: feature\n        };\n        if (!this.declutterTree.collides(box)) {\n          this.declutterTree.insert(box);\n          for (let j = 5, jj = declutterGroup.length; j < jj; ++j) {\n            const declutterData = /** @type {Array} */ (declutterGroup[j]);\n            if (declutterData) {\n              if (declutterData.length > 11) {\n                this.replayTextBackground_(declutterData[0],\n                  declutterData[13], declutterData[14], declutterData[15], declutterData[16],\n                  declutterData[11], declutterData[12]);\n              }\n              drawImage.apply(undefined, declutterData);\n            }\n          }\n        }\n        declutterGroup.length = 5;\n        createOrUpdateEmpty(declutterGroup);\n      }\n    }\n  }\n\n  /**\n   * @private\n   * @param {CanvasRenderingContext2D} context Context.\n   * @param {module:ol/transform~Transform} transform Transform.\n   * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features\n   *     to skip.\n   * @param {Array.<*>} instructions Instructions array.\n   * @param {function((module:ol/Feature|module:ol/render/Feature)): T|undefined}\n   *     featureCallback Feature callback.\n   * @param {module:ol/extent~Extent=} opt_hitExtent Only check features that intersect this\n   *     extent.\n   * @return {T|undefined} Callback result.\n   * @template T\n   */\n  replay_(\n    context,\n    transform,\n    skippedFeaturesHash,\n    instructions,\n    featureCallback,\n    opt_hitExtent\n  ) {\n    /** @type {Array.<number>} */\n    let pixelCoordinates;\n    if (this.pixelCoordinates_ && equals(transform, this.renderedTransform_)) {\n      pixelCoordinates = this.pixelCoordinates_;\n    } else {\n      if (!this.pixelCoordinates_) {\n        this.pixelCoordinates_ = [];\n      }\n      pixelCoordinates = transform2D(\n        this.coordinates, 0, this.coordinates.length, 2,\n        transform, this.pixelCoordinates_);\n      transformSetFromArray(this.renderedTransform_, transform);\n    }\n    const skipFeatures = !isEmpty(skippedFeaturesHash);\n    let i = 0; // instruction index\n    const ii = instructions.length; // end of instructions\n    let d = 0; // data index\n    let dd; // end of per-instruction data\n    let anchorX, anchorY, prevX, prevY, roundX, roundY, declutterGroup, image;\n    let pendingFill = 0;\n    let pendingStroke = 0;\n    let lastFillInstruction = null;\n    let lastStrokeInstruction = null;\n    const coordinateCache = this.coordinateCache_;\n    const viewRotation = this.viewRotation_;\n\n    const state = /** @type {module:ol/render~State} */ ({\n      context: context,\n      pixelRatio: this.pixelRatio,\n      resolution: this.resolution,\n      rotation: viewRotation\n    });\n\n    // When the batch size gets too big, performance decreases. 200 is a good\n    // balance between batch size and number of fill/stroke instructions.\n    const batchSize = this.instructions != instructions || this.overlaps ? 0 : 200;\n    let /** @type {module:ol/Feature|module:ol/render/Feature} */ feature;\n    let x, y;\n    while (i < ii) {\n      const instruction = instructions[i];\n      const type = /** @type {module:ol/render/canvas/Instruction} */ (instruction[0]);\n      switch (type) {\n        case CanvasInstruction.BEGIN_GEOMETRY:\n          feature = /** @type {module:ol/Feature|module:ol/render/Feature} */ (instruction[1]);\n          if ((skipFeatures &&\n              skippedFeaturesHash[getUid(feature).toString()]) ||\n              !feature.getGeometry()) {\n            i = /** @type {number} */ (instruction[2]);\n          } else if (opt_hitExtent !== undefined && !intersects(\n            opt_hitExtent, feature.getGeometry().getExtent())) {\n            i = /** @type {number} */ (instruction[2]) + 1;\n          } else {\n            ++i;\n          }\n          break;\n        case CanvasInstruction.BEGIN_PATH:\n          if (pendingFill > batchSize) {\n            this.fill_(context);\n            pendingFill = 0;\n          }\n          if (pendingStroke > batchSize) {\n            context.stroke();\n            pendingStroke = 0;\n          }\n          if (!pendingFill && !pendingStroke) {\n            context.beginPath();\n            prevX = prevY = NaN;\n          }\n          ++i;\n          break;\n        case CanvasInstruction.CIRCLE:\n          d = /** @type {number} */ (instruction[1]);\n          const x1 = pixelCoordinates[d];\n          const y1 = pixelCoordinates[d + 1];\n          const x2 = pixelCoordinates[d + 2];\n          const y2 = pixelCoordinates[d + 3];\n          const dx = x2 - x1;\n          const dy = y2 - y1;\n          const r = Math.sqrt(dx * dx + dy * dy);\n          context.moveTo(x1 + r, y1);\n          context.arc(x1, y1, r, 0, 2 * Math.PI, true);\n          ++i;\n          break;\n        case CanvasInstruction.CLOSE_PATH:\n          context.closePath();\n          ++i;\n          break;\n        case CanvasInstruction.CUSTOM:\n          d = /** @type {number} */ (instruction[1]);\n          dd = instruction[2];\n          const geometry = /** @type {module:ol/geom/SimpleGeometry} */ (instruction[3]);\n          const renderer = instruction[4];\n          const fn = instruction.length == 6 ? instruction[5] : undefined;\n          state.geometry = geometry;\n          state.feature = feature;\n          if (!(i in coordinateCache)) {\n            coordinateCache[i] = [];\n          }\n          const coords = coordinateCache[i];\n          if (fn) {\n            fn(pixelCoordinates, d, dd, 2, coords);\n          } else {\n            coords[0] = pixelCoordinates[d];\n            coords[1] = pixelCoordinates[d + 1];\n            coords.length = 2;\n          }\n          renderer(coords, state);\n          ++i;\n          break;\n        case CanvasInstruction.DRAW_IMAGE:\n          d = /** @type {number} */ (instruction[1]);\n          dd = /** @type {number} */ (instruction[2]);\n          image = /** @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} */\n              (instruction[3]);\n          // Remaining arguments in DRAW_IMAGE are in alphabetical order\n          anchorX = /** @type {number} */ (instruction[4]);\n          anchorY = /** @type {number} */ (instruction[5]);\n          declutterGroup = featureCallback ? null : /** @type {module:ol/render/canvas~DeclutterGroup} */ (instruction[6]);\n          const height = /** @type {number} */ (instruction[7]);\n          const opacity = /** @type {number} */ (instruction[8]);\n          const originX = /** @type {number} */ (instruction[9]);\n          const originY = /** @type {number} */ (instruction[10]);\n          const rotateWithView = /** @type {boolean} */ (instruction[11]);\n          let rotation = /** @type {number} */ (instruction[12]);\n          const scale = /** @type {number} */ (instruction[13]);\n          const snapToPixel = /** @type {boolean} */ (instruction[14]);\n          const width = /** @type {number} */ (instruction[15]);\n\n          let padding, backgroundFill, backgroundStroke;\n          if (instruction.length > 16) {\n            padding = /** @type {Array.<number>} */ (instruction[16]);\n            backgroundFill = /** @type {boolean} */ (instruction[17]);\n            backgroundStroke = /** @type {boolean} */ (instruction[18]);\n          } else {\n            padding = defaultPadding;\n            backgroundFill = backgroundStroke = false;\n          }\n\n          if (rotateWithView) {\n            rotation += viewRotation;\n          }\n          for (; d < dd; d += 2) {\n            this.replayImage_(context,\n              pixelCoordinates[d], pixelCoordinates[d + 1], image, anchorX, anchorY,\n              declutterGroup, height, opacity, originX, originY, rotation, scale,\n              snapToPixel, width, padding,\n              backgroundFill ? /** @type {Array.<*>} */ (lastFillInstruction) : null,\n              backgroundStroke ? /** @type {Array.<*>} */ (lastStrokeInstruction) : null);\n          }\n          this.renderDeclutter_(declutterGroup, feature);\n          ++i;\n          break;\n        case CanvasInstruction.DRAW_CHARS:\n          const begin = /** @type {number} */ (instruction[1]);\n          const end = /** @type {number} */ (instruction[2]);\n          const baseline = /** @type {number} */ (instruction[3]);\n          declutterGroup = featureCallback ? null : /** @type {module:ol/render/canvas~DeclutterGroup} */ (instruction[4]);\n          const overflow = /** @type {number} */ (instruction[5]);\n          const fillKey = /** @type {string} */ (instruction[6]);\n          const maxAngle = /** @type {number} */ (instruction[7]);\n          const measure = /** @type {function(string):number} */ (instruction[8]);\n          const offsetY = /** @type {number} */ (instruction[9]);\n          const strokeKey = /** @type {string} */ (instruction[10]);\n          const strokeWidth = /** @type {number} */ (instruction[11]);\n          const text = /** @type {string} */ (instruction[12]);\n          const textKey = /** @type {string} */ (instruction[13]);\n          const textScale = /** @type {number} */ (instruction[14]);\n\n          const pathLength = lineStringLength(pixelCoordinates, begin, end, 2);\n          const textLength = measure(text);\n          if (overflow || textLength <= pathLength) {\n            const textAlign = /** @type {module:ol~render} */ (this).textStates[textKey].textAlign;\n            const startM = (pathLength - textLength) * TEXT_ALIGN[textAlign];\n            const parts = drawTextOnPath(\n              pixelCoordinates, begin, end, 2, text, measure, startM, maxAngle);\n            if (parts) {\n              let c, cc, chars, label, part;\n              if (strokeKey) {\n                for (c = 0, cc = parts.length; c < cc; ++c) {\n                  part = parts[c]; // x, y, anchorX, rotation, chunk\n                  chars = /** @type {string} */ (part[4]);\n                  label = /** @type {module:ol~render} */ (this).getImage(chars, textKey, '', strokeKey);\n                  anchorX = /** @type {number} */ (part[2]) + strokeWidth;\n                  anchorY = baseline * label.height + (0.5 - baseline) * 2 * strokeWidth - offsetY;\n                  this.replayImage_(context,\n                    /** @type {number} */ (part[0]), /** @type {number} */ (part[1]), label,\n                    anchorX, anchorY, declutterGroup, label.height, 1, 0, 0,\n                    /** @type {number} */ (part[3]), textScale, false, label.width,\n                    defaultPadding, null, null);\n                }\n              }\n              if (fillKey) {\n                for (c = 0, cc = parts.length; c < cc; ++c) {\n                  part = parts[c]; // x, y, anchorX, rotation, chunk\n                  chars = /** @type {string} */ (part[4]);\n                  label = /** @type {module:ol~render} */ (this).getImage(chars, textKey, fillKey, '');\n                  anchorX = /** @type {number} */ (part[2]);\n                  anchorY = baseline * label.height - offsetY;\n                  this.replayImage_(context,\n                    /** @type {number} */ (part[0]), /** @type {number} */ (part[1]), label,\n                    anchorX, anchorY, declutterGroup, label.height, 1, 0, 0,\n                    /** @type {number} */ (part[3]), textScale, false, label.width,\n                    defaultPadding, null, null);\n                }\n              }\n            }\n          }\n          this.renderDeclutter_(declutterGroup, feature);\n          ++i;\n          break;\n        case CanvasInstruction.END_GEOMETRY:\n          if (featureCallback !== undefined) {\n            feature = /** @type {module:ol/Feature|module:ol/render/Feature} */ (instruction[1]);\n            const result = featureCallback(feature);\n            if (result) {\n              return result;\n            }\n          }\n          ++i;\n          break;\n        case CanvasInstruction.FILL:\n          if (batchSize) {\n            pendingFill++;\n          } else {\n            this.fill_(context);\n          }\n          ++i;\n          break;\n        case CanvasInstruction.MOVE_TO_LINE_TO:\n          d = /** @type {number} */ (instruction[1]);\n          dd = /** @type {number} */ (instruction[2]);\n          x = pixelCoordinates[d];\n          y = pixelCoordinates[d + 1];\n          roundX = (x + 0.5) | 0;\n          roundY = (y + 0.5) | 0;\n          if (roundX !== prevX || roundY !== prevY) {\n            context.moveTo(x, y);\n            prevX = roundX;\n            prevY = roundY;\n          }\n          for (d += 2; d < dd; d += 2) {\n            x = pixelCoordinates[d];\n            y = pixelCoordinates[d + 1];\n            roundX = (x + 0.5) | 0;\n            roundY = (y + 0.5) | 0;\n            if (d == dd - 2 || roundX !== prevX || roundY !== prevY) {\n              context.lineTo(x, y);\n              prevX = roundX;\n              prevY = roundY;\n            }\n          }\n          ++i;\n          break;\n        case CanvasInstruction.SET_FILL_STYLE:\n          lastFillInstruction = instruction;\n          this.alignFill_ = instruction[2];\n\n          if (pendingFill) {\n            this.fill_(context);\n            pendingFill = 0;\n            if (pendingStroke) {\n              context.stroke();\n              pendingStroke = 0;\n            }\n          }\n\n          context.fillStyle = /** @type {module:ol/colorlike~ColorLike} */ (instruction[1]);\n          ++i;\n          break;\n        case CanvasInstruction.SET_STROKE_STYLE:\n          lastStrokeInstruction = instruction;\n          if (pendingStroke) {\n            context.stroke();\n            pendingStroke = 0;\n          }\n          this.setStrokeStyle_(context, /** @type {Array.<*>} */ (instruction));\n          ++i;\n          break;\n        case CanvasInstruction.STROKE:\n          if (batchSize) {\n            pendingStroke++;\n          } else {\n            context.stroke();\n          }\n          ++i;\n          break;\n        default:\n          ++i; // consume the instruction anyway, to avoid an infinite loop\n          break;\n      }\n    }\n    if (pendingFill) {\n      this.fill_(context);\n    }\n    if (pendingStroke) {\n      context.stroke();\n    }\n    return undefined;\n  }\n\n  /**\n   * @param {CanvasRenderingContext2D} context Context.\n   * @param {module:ol/transform~Transform} transform Transform.\n   * @param {number} viewRotation View rotation.\n   * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features\n   *     to skip.\n   */\n  replay(context, transform, viewRotation, skippedFeaturesHash) {\n    this.viewRotation_ = viewRotation;\n    this.replay_(context, transform,\n      skippedFeaturesHash, this.instructions, undefined, undefined);\n  }\n\n  /**\n   * @param {CanvasRenderingContext2D} context Context.\n   * @param {module:ol/transform~Transform} transform Transform.\n   * @param {number} viewRotation View rotation.\n   * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features\n   *     to skip.\n   * @param {function((module:ol/Feature|module:ol/render/Feature)): T=} opt_featureCallback\n   *     Feature callback.\n   * @param {module:ol/extent~Extent=} opt_hitExtent Only check features that intersect this\n   *     extent.\n   * @return {T|undefined} Callback result.\n   * @template T\n   */\n  replayHitDetection(\n    context,\n    transform,\n    viewRotation,\n    skippedFeaturesHash,\n    opt_featureCallback,\n    opt_hitExtent\n  ) {\n    this.viewRotation_ = viewRotation;\n    return this.replay_(context, transform, skippedFeaturesHash,\n      this.hitDetectionInstructions, opt_featureCallback, opt_hitExtent);\n  }\n\n  /**\n   * Reverse the hit detection instructions.\n   */\n  reverseHitDetectionInstructions() {\n    const hitDetectionInstructions = this.hitDetectionInstructions;\n    // step 1 - reverse array\n    hitDetectionInstructions.reverse();\n    // step 2 - reverse instructions within geometry blocks\n    let i;\n    const n = hitDetectionInstructions.length;\n    let instruction;\n    let type;\n    let begin = -1;\n    for (i = 0; i < n; ++i) {\n      instruction = hitDetectionInstructions[i];\n      type = /** @type {module:ol/render/canvas/Instruction} */ (instruction[0]);\n      if (type == CanvasInstruction.END_GEOMETRY) {\n        begin = i;\n      } else if (type == CanvasInstruction.BEGIN_GEOMETRY) {\n        instruction[2] = i;\n        reverseSubArray(this.hitDetectionInstructions, begin, i);\n        begin = -1;\n      }\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setFillStrokeStyle(fillStyle, strokeStyle) {\n    const state = this.state;\n    if (fillStyle) {\n      const fillStyleColor = fillStyle.getColor();\n      state.fillStyle = asColorLike(fillStyleColor ?\n        fillStyleColor : defaultFillStyle);\n    } else {\n      state.fillStyle = undefined;\n    }\n    if (strokeStyle) {\n      const strokeStyleColor = strokeStyle.getColor();\n      state.strokeStyle = asColorLike(strokeStyleColor ?\n        strokeStyleColor : defaultStrokeStyle);\n      const strokeStyleLineCap = strokeStyle.getLineCap();\n      state.lineCap = strokeStyleLineCap !== undefined ?\n        strokeStyleLineCap : defaultLineCap;\n      const strokeStyleLineDash = strokeStyle.getLineDash();\n      state.lineDash = strokeStyleLineDash ?\n        strokeStyleLineDash.slice() : defaultLineDash;\n      const strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();\n      state.lineDashOffset = strokeStyleLineDashOffset ?\n        strokeStyleLineDashOffset : defaultLineDashOffset;\n      const strokeStyleLineJoin = strokeStyle.getLineJoin();\n      state.lineJoin = strokeStyleLineJoin !== undefined ?\n        strokeStyleLineJoin : defaultLineJoin;\n      const strokeStyleWidth = strokeStyle.getWidth();\n      state.lineWidth = strokeStyleWidth !== undefined ?\n        strokeStyleWidth : defaultLineWidth;\n      const strokeStyleMiterLimit = strokeStyle.getMiterLimit();\n      state.miterLimit = strokeStyleMiterLimit !== undefined ?\n        strokeStyleMiterLimit : defaultMiterLimit;\n\n      if (state.lineWidth > this.maxLineWidth) {\n        this.maxLineWidth = state.lineWidth;\n        // invalidate the buffered max extent cache\n        this.bufferedMaxExtent_ = null;\n      }\n    } else {\n      state.strokeStyle = undefined;\n      state.lineCap = undefined;\n      state.lineDash = null;\n      state.lineDashOffset = undefined;\n      state.lineJoin = undefined;\n      state.lineWidth = undefined;\n      state.miterLimit = undefined;\n    }\n  }\n\n  /**\n   * @param {module:ol/render/canvas~FillStrokeState} state State.\n   * @param {module:ol/geom/Geometry|module:ol/render/Feature} geometry Geometry.\n   * @return {Array.<*>} Fill instruction.\n   */\n  createFill(state, geometry) {\n    const fillStyle = state.fillStyle;\n    const fillInstruction = [CanvasInstruction.SET_FILL_STYLE, fillStyle];\n    if (typeof fillStyle !== 'string') {\n      // Fill is a pattern or gradient - align it!\n      fillInstruction.push(true);\n    }\n    return fillInstruction;\n  }\n\n  /**\n   * @param {module:ol/render/canvas~FillStrokeState} state State.\n   */\n  applyStroke(state) {\n    this.instructions.push(this.createStroke(state));\n  }\n\n  /**\n   * @param {module:ol/render/canvas~FillStrokeState} state State.\n   * @return {Array.<*>} Stroke instruction.\n   */\n  createStroke(state) {\n    return [\n      CanvasInstruction.SET_STROKE_STYLE,\n      state.strokeStyle, state.lineWidth * this.pixelRatio, state.lineCap,\n      state.lineJoin, state.miterLimit,\n      this.applyPixelRatio(state.lineDash), state.lineDashOffset * this.pixelRatio\n    ];\n  }\n\n  /**\n   * @param {module:ol/render/canvas~FillStrokeState} state State.\n   * @param {function(this:module:ol/render/canvas/Replay, module:ol/render/canvas~FillStrokeState, (module:ol/geom/Geometry|module:ol/render/Feature)):Array.<*>} createFill Create fill.\n   * @param {module:ol/geom/Geometry|module:ol/render/Feature} geometry Geometry.\n   */\n  updateFillStyle(state, createFill, geometry) {\n    const fillStyle = state.fillStyle;\n    if (typeof fillStyle !== 'string' || state.currentFillStyle != fillStyle) {\n      if (fillStyle !== undefined) {\n        this.instructions.push(createFill.call(this, state, geometry));\n      }\n      state.currentFillStyle = fillStyle;\n    }\n  }\n\n  /**\n   * @param {module:ol/render/canvas~FillStrokeState} state State.\n   * @param {function(this:module:ol/render/canvas/Replay, module:ol/render/canvas~FillStrokeState)} applyStroke Apply stroke.\n   */\n  updateStrokeStyle(state, applyStroke) {\n    const strokeStyle = state.strokeStyle;\n    const lineCap = state.lineCap;\n    const lineDash = state.lineDash;\n    const lineDashOffset = state.lineDashOffset;\n    const lineJoin = state.lineJoin;\n    const lineWidth = state.lineWidth;\n    const miterLimit = state.miterLimit;\n    if (state.currentStrokeStyle != strokeStyle ||\n        state.currentLineCap != lineCap ||\n        (lineDash != state.currentLineDash && !equals(state.currentLineDash, lineDash)) ||\n        state.currentLineDashOffset != lineDashOffset ||\n        state.currentLineJoin != lineJoin ||\n        state.currentLineWidth != lineWidth ||\n        state.currentMiterLimit != miterLimit) {\n      if (strokeStyle !== undefined) {\n        applyStroke.call(this, state);\n      }\n      state.currentStrokeStyle = strokeStyle;\n      state.currentLineCap = lineCap;\n      state.currentLineDash = lineDash;\n      state.currentLineDashOffset = lineDashOffset;\n      state.currentLineJoin = lineJoin;\n      state.currentLineWidth = lineWidth;\n      state.currentMiterLimit = miterLimit;\n    }\n  }\n\n  /**\n   * @param {module:ol/geom/Geometry|module:ol/render/Feature} geometry Geometry.\n   * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n   */\n  endGeometry(geometry, feature) {\n    this.beginGeometryInstruction1_[2] = this.instructions.length;\n    this.beginGeometryInstruction1_ = null;\n    this.beginGeometryInstruction2_[2] = this.hitDetectionInstructions.length;\n    this.beginGeometryInstruction2_ = null;\n    const endGeometryInstruction = [CanvasInstruction.END_GEOMETRY, feature];\n    this.instructions.push(endGeometryInstruction);\n    this.hitDetectionInstructions.push(endGeometryInstruction);\n  }\n\n  /**\n   * Get the buffered rendering extent.  Rendering will be clipped to the extent\n   * provided to the constructor.  To account for symbolizers that may intersect\n   * this extent, we calculate a buffered extent (e.g. based on stroke width).\n   * @return {module:ol/extent~Extent} The buffered rendering extent.\n   * @protected\n   */\n  getBufferedMaxExtent() {\n    if (!this.bufferedMaxExtent_) {\n      this.bufferedMaxExtent_ = clone(this.maxExtent);\n      if (this.maxLineWidth > 0) {\n        const width = this.resolution * (this.maxLineWidth + 1) / 2;\n        buffer(this.bufferedMaxExtent_, width, this.bufferedMaxExtent_);\n      }\n    }\n    return this.bufferedMaxExtent_;\n  }\n}\n\n\n/**\n * FIXME empty description for jsdoc\n */\nCanvasReplay.prototype.finish = UNDEFINED;\n\n\nexport default CanvasReplay;\n","/**\n * @module ol/render/canvas/ImageReplay\n */\nimport CanvasInstruction from '../canvas/Instruction.js';\nimport CanvasReplay from '../canvas/Replay.js';\n\nclass CanvasImageReplay extends CanvasReplay {\n  /**\n   * @param {number} tolerance Tolerance.\n   * @param {module:ol/extent~Extent} maxExtent Maximum extent.\n   * @param {number} resolution Resolution.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {boolean} overlaps The replay can have overlapping geometries.\n   * @param {?} declutterTree Declutter tree.\n   */\n  constructor(tolerance, maxExtent, resolution, pixelRatio, overlaps, declutterTree) {\n    super(tolerance, maxExtent, resolution, pixelRatio, overlaps, declutterTree);\n\n    /**\n     * @private\n     * @type {module:ol/render/canvas~DeclutterGroup}\n     */\n    this.declutterGroup_ = null;\n\n    /**\n     * @private\n     * @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement}\n     */\n    this.hitDetectionImage_ = null;\n\n    /**\n     * @private\n     * @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement}\n     */\n    this.image_ = null;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.anchorX_ = undefined;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.anchorY_ = undefined;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.height_ = undefined;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.opacity_ = undefined;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.originX_ = undefined;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.originY_ = undefined;\n\n    /**\n     * @private\n     * @type {boolean|undefined}\n     */\n    this.rotateWithView_ = undefined;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.rotation_ = undefined;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.scale_ = undefined;\n\n    /**\n     * @private\n     * @type {boolean|undefined}\n     */\n    this.snapToPixel_ = undefined;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.width_ = undefined;\n\n  }\n\n  /**\n   * @param {Array.<number>} flatCoordinates Flat coordinates.\n   * @param {number} offset Offset.\n   * @param {number} end End.\n   * @param {number} stride Stride.\n   * @private\n   * @return {number} My end.\n   */\n  drawCoordinates_(flatCoordinates, offset, end, stride) {\n    return this.appendFlatCoordinates(flatCoordinates, offset, end, stride, false, false);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawPoint(pointGeometry, feature) {\n    if (!this.image_) {\n      return;\n    }\n    this.beginGeometry(pointGeometry, feature);\n    const flatCoordinates = pointGeometry.getFlatCoordinates();\n    const stride = pointGeometry.getStride();\n    const myBegin = this.coordinates.length;\n    const myEnd = this.drawCoordinates_(flatCoordinates, 0, flatCoordinates.length, stride);\n    this.instructions.push([\n      CanvasInstruction.DRAW_IMAGE, myBegin, myEnd, this.image_,\n      // Remaining arguments to DRAW_IMAGE are in alphabetical order\n      this.anchorX_, this.anchorY_, this.declutterGroup_, this.height_, this.opacity_,\n      this.originX_, this.originY_, this.rotateWithView_, this.rotation_,\n      this.scale_ * this.pixelRatio, this.snapToPixel_, this.width_\n    ]);\n    this.hitDetectionInstructions.push([\n      CanvasInstruction.DRAW_IMAGE, myBegin, myEnd, this.hitDetectionImage_,\n      // Remaining arguments to DRAW_IMAGE are in alphabetical order\n      this.anchorX_, this.anchorY_, this.declutterGroup_, this.height_, this.opacity_,\n      this.originX_, this.originY_, this.rotateWithView_, this.rotation_,\n      this.scale_, this.snapToPixel_, this.width_\n    ]);\n    this.endGeometry(pointGeometry, feature);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawMultiPoint(multiPointGeometry, feature) {\n    if (!this.image_) {\n      return;\n    }\n    this.beginGeometry(multiPointGeometry, feature);\n    const flatCoordinates = multiPointGeometry.getFlatCoordinates();\n    const stride = multiPointGeometry.getStride();\n    const myBegin = this.coordinates.length;\n    const myEnd = this.drawCoordinates_(\n      flatCoordinates, 0, flatCoordinates.length, stride);\n    this.instructions.push([\n      CanvasInstruction.DRAW_IMAGE, myBegin, myEnd, this.image_,\n      // Remaining arguments to DRAW_IMAGE are in alphabetical order\n      this.anchorX_, this.anchorY_, this.declutterGroup_, this.height_, this.opacity_,\n      this.originX_, this.originY_, this.rotateWithView_, this.rotation_,\n      this.scale_ * this.pixelRatio, this.snapToPixel_, this.width_\n    ]);\n    this.hitDetectionInstructions.push([\n      CanvasInstruction.DRAW_IMAGE, myBegin, myEnd, this.hitDetectionImage_,\n      // Remaining arguments to DRAW_IMAGE are in alphabetical order\n      this.anchorX_, this.anchorY_, this.declutterGroup_, this.height_, this.opacity_,\n      this.originX_, this.originY_, this.rotateWithView_, this.rotation_,\n      this.scale_, this.snapToPixel_, this.width_\n    ]);\n    this.endGeometry(multiPointGeometry, feature);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  finish() {\n    this.reverseHitDetectionInstructions();\n    // FIXME this doesn't really protect us against further calls to draw*Geometry\n    this.anchorX_ = undefined;\n    this.anchorY_ = undefined;\n    this.hitDetectionImage_ = null;\n    this.image_ = null;\n    this.height_ = undefined;\n    this.scale_ = undefined;\n    this.opacity_ = undefined;\n    this.originX_ = undefined;\n    this.originY_ = undefined;\n    this.rotateWithView_ = undefined;\n    this.rotation_ = undefined;\n    this.snapToPixel_ = undefined;\n    this.width_ = undefined;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setImageStyle(imageStyle, declutterGroup) {\n    const anchor = imageStyle.getAnchor();\n    const size = imageStyle.getSize();\n    const hitDetectionImage = imageStyle.getHitDetectionImage(1);\n    const image = imageStyle.getImage(1);\n    const origin = imageStyle.getOrigin();\n    this.anchorX_ = anchor[0];\n    this.anchorY_ = anchor[1];\n    this.declutterGroup_ = /** @type {module:ol/render/canvas~DeclutterGroup} */ (declutterGroup);\n    this.hitDetectionImage_ = hitDetectionImage;\n    this.image_ = image;\n    this.height_ = size[1];\n    this.opacity_ = imageStyle.getOpacity();\n    this.originX_ = origin[0];\n    this.originY_ = origin[1];\n    this.rotateWithView_ = imageStyle.getRotateWithView();\n    this.rotation_ = imageStyle.getRotation();\n    this.scale_ = imageStyle.getScale();\n    this.snapToPixel_ = imageStyle.getSnapToPixel();\n    this.width_ = size[0];\n  }\n}\n\n\nexport default CanvasImageReplay;\n","/**\n * @module ol/render/canvas/LineStringReplay\n */\nimport CanvasInstruction, {strokeInstruction, beginPathInstruction} from '../canvas/Instruction.js';\nimport CanvasReplay from '../canvas/Replay.js';\n\nclass CanvasLineStringReplay extends CanvasReplay {\n  /**\n   * @param {number} tolerance Tolerance.\n   * @param {module:ol/extent~Extent} maxExtent Maximum extent.\n   * @param {number} resolution Resolution.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {boolean} overlaps The replay can have overlapping geometries.\n   * @param {?} declutterTree Declutter tree.\n   */\n  constructor(tolerance, maxExtent, resolution, pixelRatio, overlaps, declutterTree) {\n    super(tolerance, maxExtent, resolution, pixelRatio, overlaps, declutterTree);\n  }\n\n  /**\n   * @param {Array.<number>} flatCoordinates Flat coordinates.\n   * @param {number} offset Offset.\n   * @param {number} end End.\n   * @param {number} stride Stride.\n   * @private\n   * @return {number} end.\n   */\n  drawFlatCoordinates_(flatCoordinates, offset, end, stride) {\n    const myBegin = this.coordinates.length;\n    const myEnd = this.appendFlatCoordinates(\n      flatCoordinates, offset, end, stride, false, false);\n    const moveToLineToInstruction = [CanvasInstruction.MOVE_TO_LINE_TO, myBegin, myEnd];\n    this.instructions.push(moveToLineToInstruction);\n    this.hitDetectionInstructions.push(moveToLineToInstruction);\n    return end;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawLineString(lineStringGeometry, feature) {\n    const state = this.state;\n    const strokeStyle = state.strokeStyle;\n    const lineWidth = state.lineWidth;\n    if (strokeStyle === undefined || lineWidth === undefined) {\n      return;\n    }\n    this.updateStrokeStyle(state, this.applyStroke);\n    this.beginGeometry(lineStringGeometry, feature);\n    this.hitDetectionInstructions.push([\n      CanvasInstruction.SET_STROKE_STYLE,\n      state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,\n      state.miterLimit, state.lineDash, state.lineDashOffset\n    ], beginPathInstruction);\n    const flatCoordinates = lineStringGeometry.getFlatCoordinates();\n    const stride = lineStringGeometry.getStride();\n    this.drawFlatCoordinates_(flatCoordinates, 0, flatCoordinates.length, stride);\n    this.hitDetectionInstructions.push(strokeInstruction);\n    this.endGeometry(lineStringGeometry, feature);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawMultiLineString(multiLineStringGeometry, feature) {\n    const state = this.state;\n    const strokeStyle = state.strokeStyle;\n    const lineWidth = state.lineWidth;\n    if (strokeStyle === undefined || lineWidth === undefined) {\n      return;\n    }\n    this.updateStrokeStyle(state, this.applyStroke);\n    this.beginGeometry(multiLineStringGeometry, feature);\n    this.hitDetectionInstructions.push([\n      CanvasInstruction.SET_STROKE_STYLE,\n      state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,\n      state.miterLimit, state.lineDash, state.lineDashOffset\n    ], beginPathInstruction);\n    const ends = multiLineStringGeometry.getEnds();\n    const flatCoordinates = multiLineStringGeometry.getFlatCoordinates();\n    const stride = multiLineStringGeometry.getStride();\n    let offset = 0;\n    for (let i = 0, ii = ends.length; i < ii; ++i) {\n      offset = this.drawFlatCoordinates_(flatCoordinates, offset, ends[i], stride);\n    }\n    this.hitDetectionInstructions.push(strokeInstruction);\n    this.endGeometry(multiLineStringGeometry, feature);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  finish() {\n    const state = this.state;\n    if (state.lastStroke != undefined && state.lastStroke != this.coordinates.length) {\n      this.instructions.push(strokeInstruction);\n    }\n    this.reverseHitDetectionInstructions();\n    this.state = null;\n  }\n\n  /**\n   * @inheritDoc.\n   */\n  applyStroke(state) {\n    if (state.lastStroke != undefined && state.lastStroke != this.coordinates.length) {\n      this.instructions.push(strokeInstruction);\n      state.lastStroke = this.coordinates.length;\n    }\n    state.lastStroke = 0;\n    CanvasReplay.prototype.applyStroke.call(this, state);\n    this.instructions.push(beginPathInstruction);\n  }\n}\n\n\nexport default CanvasLineStringReplay;\n","/**\n * @module ol/render/canvas/PolygonReplay\n */\nimport {asString} from '../../color.js';\nimport {snap} from '../../geom/flat/simplify.js';\nimport {defaultFillStyle} from '../canvas.js';\nimport CanvasInstruction, {\n  fillInstruction, strokeInstruction, beginPathInstruction, closePathInstruction\n} from '../canvas/Instruction.js';\nimport CanvasReplay from '../canvas/Replay.js';\n\n\nclass CanvasPolygonReplay extends CanvasReplay {\n  /**\n   * @param {number} tolerance Tolerance.\n   * @param {module:ol/extent~Extent} maxExtent Maximum extent.\n   * @param {number} resolution Resolution.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {boolean} overlaps The replay can have overlapping geometries.\n   * @param {?} declutterTree Declutter tree.\n   */\n  constructor(tolerance, maxExtent, resolution, pixelRatio, overlaps, declutterTree) {\n    super(tolerance, maxExtent, resolution, pixelRatio, overlaps, declutterTree);\n  }\n\n  /**\n   * @param {Array.<number>} flatCoordinates Flat coordinates.\n   * @param {number} offset Offset.\n   * @param {Array.<number>} ends Ends.\n   * @param {number} stride Stride.\n   * @private\n   * @return {number} End.\n   */\n  drawFlatCoordinatess_(flatCoordinates, offset, ends, stride) {\n    const state = this.state;\n    const fill = state.fillStyle !== undefined;\n    const stroke = state.strokeStyle != undefined;\n    const numEnds = ends.length;\n    this.instructions.push(beginPathInstruction);\n    this.hitDetectionInstructions.push(beginPathInstruction);\n    for (let i = 0; i < numEnds; ++i) {\n      const end = ends[i];\n      const myBegin = this.coordinates.length;\n      const myEnd = this.appendFlatCoordinates(flatCoordinates, offset, end, stride, true, !stroke);\n      const moveToLineToInstruction = [CanvasInstruction.MOVE_TO_LINE_TO, myBegin, myEnd];\n      this.instructions.push(moveToLineToInstruction);\n      this.hitDetectionInstructions.push(moveToLineToInstruction);\n      if (stroke) {\n        // Performance optimization: only call closePath() when we have a stroke.\n        // Otherwise the ring is closed already (see appendFlatCoordinates above).\n        this.instructions.push(closePathInstruction);\n        this.hitDetectionInstructions.push(closePathInstruction);\n      }\n      offset = end;\n    }\n    if (fill) {\n      this.instructions.push(fillInstruction);\n      this.hitDetectionInstructions.push(fillInstruction);\n    }\n    if (stroke) {\n      this.instructions.push(strokeInstruction);\n      this.hitDetectionInstructions.push(strokeInstruction);\n    }\n    return offset;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawCircle(circleGeometry, feature) {\n    const state = this.state;\n    const fillStyle = state.fillStyle;\n    const strokeStyle = state.strokeStyle;\n    if (fillStyle === undefined && strokeStyle === undefined) {\n      return;\n    }\n    this.setFillStrokeStyles_(circleGeometry);\n    this.beginGeometry(circleGeometry, feature);\n    if (state.fillStyle !== undefined) {\n      this.hitDetectionInstructions.push([\n        CanvasInstruction.SET_FILL_STYLE,\n        asString(defaultFillStyle)\n      ]);\n    }\n    if (state.strokeStyle !== undefined) {\n      this.hitDetectionInstructions.push([\n        CanvasInstruction.SET_STROKE_STYLE,\n        state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,\n        state.miterLimit, state.lineDash, state.lineDashOffset\n      ]);\n    }\n    const flatCoordinates = circleGeometry.getFlatCoordinates();\n    const stride = circleGeometry.getStride();\n    const myBegin = this.coordinates.length;\n    this.appendFlatCoordinates(\n      flatCoordinates, 0, flatCoordinates.length, stride, false, false);\n    const circleInstruction = [CanvasInstruction.CIRCLE, myBegin];\n    this.instructions.push(beginPathInstruction, circleInstruction);\n    this.hitDetectionInstructions.push(beginPathInstruction, circleInstruction);\n    this.hitDetectionInstructions.push(fillInstruction);\n    if (state.fillStyle !== undefined) {\n      this.instructions.push(fillInstruction);\n    }\n    if (state.strokeStyle !== undefined) {\n      this.instructions.push(strokeInstruction);\n      this.hitDetectionInstructions.push(strokeInstruction);\n    }\n    this.endGeometry(circleGeometry, feature);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawPolygon(polygonGeometry, feature) {\n    const state = this.state;\n    const fillStyle = state.fillStyle;\n    const strokeStyle = state.strokeStyle;\n    if (fillStyle === undefined && strokeStyle === undefined) {\n      return;\n    }\n    this.setFillStrokeStyles_(polygonGeometry);\n    this.beginGeometry(polygonGeometry, feature);\n    if (state.fillStyle !== undefined) {\n      this.hitDetectionInstructions.push([\n        CanvasInstruction.SET_FILL_STYLE,\n        asString(defaultFillStyle)\n      ]);\n    }\n    if (state.strokeStyle !== undefined) {\n      this.hitDetectionInstructions.push([\n        CanvasInstruction.SET_STROKE_STYLE,\n        state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,\n        state.miterLimit, state.lineDash, state.lineDashOffset\n      ]);\n    }\n    const ends = polygonGeometry.getEnds();\n    const flatCoordinates = polygonGeometry.getOrientedFlatCoordinates();\n    const stride = polygonGeometry.getStride();\n    this.drawFlatCoordinatess_(flatCoordinates, 0, ends, stride);\n    this.endGeometry(polygonGeometry, feature);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawMultiPolygon(multiPolygonGeometry, feature) {\n    const state = this.state;\n    const fillStyle = state.fillStyle;\n    const strokeStyle = state.strokeStyle;\n    if (fillStyle === undefined && strokeStyle === undefined) {\n      return;\n    }\n    this.setFillStrokeStyles_(multiPolygonGeometry);\n    this.beginGeometry(multiPolygonGeometry, feature);\n    if (state.fillStyle !== undefined) {\n      this.hitDetectionInstructions.push([\n        CanvasInstruction.SET_FILL_STYLE,\n        asString(defaultFillStyle)\n      ]);\n    }\n    if (state.strokeStyle !== undefined) {\n      this.hitDetectionInstructions.push([\n        CanvasInstruction.SET_STROKE_STYLE,\n        state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,\n        state.miterLimit, state.lineDash, state.lineDashOffset\n      ]);\n    }\n    const endss = multiPolygonGeometry.getEndss();\n    const flatCoordinates = multiPolygonGeometry.getOrientedFlatCoordinates();\n    const stride = multiPolygonGeometry.getStride();\n    let offset = 0;\n    for (let i = 0, ii = endss.length; i < ii; ++i) {\n      offset = this.drawFlatCoordinatess_(flatCoordinates, offset, endss[i], stride);\n    }\n    this.endGeometry(multiPolygonGeometry, feature);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  finish() {\n    this.reverseHitDetectionInstructions();\n    this.state = null;\n    // We want to preserve topology when drawing polygons.  Polygons are\n    // simplified using quantization and point elimination. However, we might\n    // have received a mix of quantized and non-quantized geometries, so ensure\n    // that all are quantized by quantizing all coordinates in the batch.\n    const tolerance = this.tolerance;\n    if (tolerance !== 0) {\n      const coordinates = this.coordinates;\n      for (let i = 0, ii = coordinates.length; i < ii; ++i) {\n        coordinates[i] = snap(coordinates[i], tolerance);\n      }\n    }\n  }\n\n  /**\n   * @private\n   * @param {module:ol/geom/Geometry|module:ol/render/Feature} geometry Geometry.\n   */\n  setFillStrokeStyles_(geometry) {\n    const state = this.state;\n    const fillStyle = state.fillStyle;\n    if (fillStyle !== undefined) {\n      this.updateFillStyle(state, this.createFill, geometry);\n    }\n    if (state.strokeStyle !== undefined) {\n      this.updateStrokeStyle(state, this.applyStroke);\n    }\n  }\n}\n\n\nexport default CanvasPolygonReplay;\n","/**\n * @module ol/geom/flat/straightchunk\n */\n\n\n/**\n * @param {number} maxAngle Maximum acceptable angle delta between segments.\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {Array.<number>} Start and end of the first suitable chunk of the\n * given `flatCoordinates`.\n */\nexport function matchingChunk(maxAngle, flatCoordinates, offset, end, stride) {\n  let chunkStart = offset;\n  let chunkEnd = offset;\n  let chunkM = 0;\n  let m = 0;\n  let start = offset;\n  let acos, i, m12, m23, x1, y1, x12, y12, x23, y23;\n  for (i = offset; i < end; i += stride) {\n    const x2 = flatCoordinates[i];\n    const y2 = flatCoordinates[i + 1];\n    if (x1 !== undefined) {\n      x23 = x2 - x1;\n      y23 = y2 - y1;\n      m23 = Math.sqrt(x23 * x23 + y23 * y23);\n      if (x12 !== undefined) {\n        m += m12;\n        acos = Math.acos((x12 * x23 + y12 * y23) / (m12 * m23));\n        if (acos > maxAngle) {\n          if (m > chunkM) {\n            chunkM = m;\n            chunkStart = start;\n            chunkEnd = i;\n          }\n          m = 0;\n          start = i - stride;\n        }\n      }\n      m12 = m23;\n      x12 = x23;\n      y12 = y23;\n    }\n    x1 = x2;\n    y1 = y2;\n  }\n  m += m23;\n  return m > chunkM ? [start, i] : [chunkStart, chunkEnd];\n}\n","/**\n * @module ol/render/canvas/ReplayGroup\n */\n\nimport {numberSafeCompareFunction} from '../../array.js';\nimport {createCanvasContext2D} from '../../dom.js';\nimport {buffer, createEmpty, extendCoordinate} from '../../extent.js';\nimport {transform2D} from '../../geom/flat/transform.js';\nimport {isEmpty} from '../../obj.js';\nimport ReplayGroup from '../ReplayGroup.js';\nimport ReplayType from '../ReplayType.js';\nimport CanvasReplay from '../canvas/Replay.js';\nimport CanvasImageReplay from '../canvas/ImageReplay.js';\nimport CanvasLineStringReplay from '../canvas/LineStringReplay.js';\nimport CanvasPolygonReplay from '../canvas/PolygonReplay.js';\nimport CanvasTextReplay from '../canvas/TextReplay.js';\nimport {ORDER} from '../replay.js';\nimport {create as createTransform, compose as composeTransform} from '../../transform.js';\n\n\n/**\n * @type {Object.<module:ol/render/ReplayType,\n *                function(new: module:ol/render/canvas/Replay, number, module:ol/extent~Extent,\n *                number, number, boolean, Array.<module:ol/render/canvas~DeclutterGroup>)>}\n */\nconst BATCH_CONSTRUCTORS = {\n  'Circle': CanvasPolygonReplay,\n  'Default': CanvasReplay,\n  'Image': CanvasImageReplay,\n  'LineString': CanvasLineStringReplay,\n  'Polygon': CanvasPolygonReplay,\n  'Text': CanvasTextReplay\n};\n\n\nclass CanvasReplayGroup extends ReplayGroup {\n  /**\n   * @param {number} tolerance Tolerance.\n   * @param {module:ol/extent~Extent} maxExtent Max extent.\n   * @param {number} resolution Resolution.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {boolean} overlaps The replay group can have overlapping geometries.\n   * @param {?} declutterTree Declutter tree for declutter processing in postrender.\n   * @param {number=} opt_renderBuffer Optional rendering buffer.\n   */\n  constructor(\n    tolerance,\n    maxExtent,\n    resolution,\n    pixelRatio,\n    overlaps,\n    declutterTree,\n    opt_renderBuffer\n  ) {\n    super();\n\n    /**\n     * Declutter tree.\n     * @private\n     */\n    this.declutterTree_ = declutterTree;\n\n    /**\n     * @type {module:ol/render/canvas~DeclutterGroup}\n     * @private\n     */\n    this.declutterGroup_ = null;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.tolerance_ = tolerance;\n\n    /**\n     * @private\n     * @type {module:ol/extent~Extent}\n     */\n    this.maxExtent_ = maxExtent;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.overlaps_ = overlaps;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.pixelRatio_ = pixelRatio;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.resolution_ = resolution;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.renderBuffer_ = opt_renderBuffer;\n\n    /**\n     * @private\n     * @type {!Object.<string, !Object.<module:ol/render/ReplayType, module:ol/render/canvas/Replay>>}\n     */\n    this.replaysByZIndex_ = {};\n\n    /**\n     * @private\n     * @type {CanvasRenderingContext2D}\n     */\n    this.hitDetectionContext_ = createCanvasContext2D(1, 1);\n\n    /**\n     * @private\n     * @type {module:ol/transform~Transform}\n     */\n    this.hitDetectionTransform_ = createTransform();\n  }\n\n  /**\n   * @param {boolean} group Group with previous replay.\n   * @return {module:ol/render/canvas~DeclutterGroup} Declutter instruction group.\n   */\n  addDeclutter(group) {\n    let declutter = null;\n    if (this.declutterTree_) {\n      if (group) {\n        declutter = this.declutterGroup_;\n        /** @type {number} */ (declutter[4])++;\n      } else {\n        declutter = this.declutterGroup_ = createEmpty();\n        declutter.push(1);\n      }\n    }\n    return declutter;\n  }\n\n  /**\n   * @param {CanvasRenderingContext2D} context Context.\n   * @param {module:ol/transform~Transform} transform Transform.\n   */\n  clip(context, transform) {\n    const flatClipCoords = this.getClipCoords(transform);\n    context.beginPath();\n    context.moveTo(flatClipCoords[0], flatClipCoords[1]);\n    context.lineTo(flatClipCoords[2], flatClipCoords[3]);\n    context.lineTo(flatClipCoords[4], flatClipCoords[5]);\n    context.lineTo(flatClipCoords[6], flatClipCoords[7]);\n    context.clip();\n  }\n\n  /**\n   * @param {Array.<module:ol/render/ReplayType>} replays Replays.\n   * @return {boolean} Has replays of the provided types.\n   */\n  hasReplays(replays) {\n    for (const zIndex in this.replaysByZIndex_) {\n      const candidates = this.replaysByZIndex_[zIndex];\n      for (let i = 0, ii = replays.length; i < ii; ++i) {\n        if (replays[i] in candidates) {\n          return true;\n        }\n      }\n    }\n    return false;\n  }\n\n  /**\n   * FIXME empty description for jsdoc\n   */\n  finish() {\n    for (const zKey in this.replaysByZIndex_) {\n      const replays = this.replaysByZIndex_[zKey];\n      for (const replayKey in replays) {\n        replays[replayKey].finish();\n      }\n    }\n  }\n\n  /**\n   * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n   * @param {number} resolution Resolution.\n   * @param {number} rotation Rotation.\n   * @param {number} hitTolerance Hit tolerance in pixels.\n   * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features to skip.\n   * @param {function((module:ol/Feature|module:ol/render/Feature)): T} callback Feature callback.\n   * @param {Object.<string, module:ol/render/canvas~DeclutterGroup>} declutterReplays Declutter replays.\n   * @return {T|undefined} Callback result.\n   * @template T\n   */\n  forEachFeatureAtCoordinate(\n    coordinate,\n    resolution,\n    rotation,\n    hitTolerance,\n    skippedFeaturesHash,\n    callback,\n    declutterReplays\n  ) {\n\n    hitTolerance = Math.round(hitTolerance);\n    const contextSize = hitTolerance * 2 + 1;\n    const transform = composeTransform(this.hitDetectionTransform_,\n      hitTolerance + 0.5, hitTolerance + 0.5,\n      1 / resolution, -1 / resolution,\n      -rotation,\n      -coordinate[0], -coordinate[1]);\n    const context = this.hitDetectionContext_;\n\n    if (context.canvas.width !== contextSize || context.canvas.height !== contextSize) {\n      context.canvas.width = contextSize;\n      context.canvas.height = contextSize;\n    } else {\n      context.clearRect(0, 0, contextSize, contextSize);\n    }\n\n    /**\n     * @type {module:ol/extent~Extent}\n     */\n    let hitExtent;\n    if (this.renderBuffer_ !== undefined) {\n      hitExtent = createEmpty();\n      extendCoordinate(hitExtent, coordinate);\n      buffer(hitExtent, resolution * (this.renderBuffer_ + hitTolerance), hitExtent);\n    }\n\n    const mask = getCircleArray(hitTolerance);\n    let declutteredFeatures;\n    if (this.declutterTree_) {\n      declutteredFeatures = this.declutterTree_.all().map(function(entry) {\n        return entry.value;\n      });\n    }\n\n    let replayType;\n\n    /**\n     * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n     * @return {?} Callback result.\n     */\n    function featureCallback(feature) {\n      const imageData = context.getImageData(0, 0, contextSize, contextSize).data;\n      for (let i = 0; i < contextSize; i++) {\n        for (let j = 0; j < contextSize; j++) {\n          if (mask[i][j]) {\n            if (imageData[(j * contextSize + i) * 4 + 3] > 0) {\n              let result;\n              if (!(declutteredFeatures && (replayType == ReplayType.IMAGE || replayType == ReplayType.TEXT)) ||\n                  declutteredFeatures.indexOf(feature) !== -1) {\n                result = callback(feature);\n              }\n              if (result) {\n                return result;\n              } else {\n                context.clearRect(0, 0, contextSize, contextSize);\n                return undefined;\n              }\n            }\n          }\n        }\n      }\n    }\n\n    /** @type {Array.<number>} */\n    const zs = Object.keys(this.replaysByZIndex_).map(Number);\n    zs.sort(numberSafeCompareFunction);\n\n    let i, j, replays, replay, result;\n    for (i = zs.length - 1; i >= 0; --i) {\n      const zIndexKey = zs[i].toString();\n      replays = this.replaysByZIndex_[zIndexKey];\n      for (j = ORDER.length - 1; j >= 0; --j) {\n        replayType = ORDER[j];\n        replay = replays[replayType];\n        if (replay !== undefined) {\n          if (declutterReplays &&\n              (replayType == ReplayType.IMAGE || replayType == ReplayType.TEXT)) {\n            const declutter = declutterReplays[zIndexKey];\n            if (!declutter) {\n              declutterReplays[zIndexKey] = [replay, transform.slice(0)];\n            } else {\n              declutter.push(replay, transform.slice(0));\n            }\n          } else {\n            result = replay.replayHitDetection(context, transform, rotation,\n              skippedFeaturesHash, featureCallback, hitExtent);\n            if (result) {\n              return result;\n            }\n          }\n        }\n      }\n    }\n    return undefined;\n  }\n\n  /**\n   * @param {module:ol/transform~Transform} transform Transform.\n   * @return {Array.<number>} Clip coordinates.\n   */\n  getClipCoords(transform) {\n    const maxExtent = this.maxExtent_;\n    const minX = maxExtent[0];\n    const minY = maxExtent[1];\n    const maxX = maxExtent[2];\n    const maxY = maxExtent[3];\n    const flatClipCoords = [minX, minY, minX, maxY, maxX, maxY, maxX, minY];\n    transform2D(\n      flatClipCoords, 0, 8, 2, transform, flatClipCoords);\n    return flatClipCoords;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getReplay(zIndex, replayType) {\n    const zIndexKey = zIndex !== undefined ? zIndex.toString() : '0';\n    let replays = this.replaysByZIndex_[zIndexKey];\n    if (replays === undefined) {\n      replays = {};\n      this.replaysByZIndex_[zIndexKey] = replays;\n    }\n    let replay = replays[replayType];\n    if (replay === undefined) {\n      const Constructor = BATCH_CONSTRUCTORS[replayType];\n      replay = new Constructor(this.tolerance_, this.maxExtent_,\n        this.resolution_, this.pixelRatio_, this.overlaps_, this.declutterTree_);\n      replays[replayType] = replay;\n    }\n    return replay;\n  }\n\n  /**\n   * @return {Object.<string, Object.<module:ol/render/ReplayType, module:ol/render/canvas/Replay>>} Replays.\n   */\n  getReplays() {\n    return this.replaysByZIndex_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  isEmpty() {\n    return isEmpty(this.replaysByZIndex_);\n  }\n\n  /**\n   * @param {CanvasRenderingContext2D} context Context.\n   * @param {module:ol/transform~Transform} transform Transform.\n   * @param {number} viewRotation View rotation.\n   * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features to skip.\n   * @param {Array.<module:ol/render/ReplayType>=} opt_replayTypes Ordered replay types to replay.\n   *     Default is {@link module:ol/render/replay~ORDER}\n   * @param {Object.<string, module:ol/render/canvas~DeclutterGroup>=} opt_declutterReplays Declutter replays.\n   */\n  replay(\n    context,\n    transform,\n    viewRotation,\n    skippedFeaturesHash,\n    opt_replayTypes,\n    opt_declutterReplays\n  ) {\n\n    /** @type {Array.<number>} */\n    const zs = Object.keys(this.replaysByZIndex_).map(Number);\n    zs.sort(numberSafeCompareFunction);\n\n    // setup clipping so that the parts of over-simplified geometries are not\n    // visible outside the current extent when panning\n    context.save();\n    this.clip(context, transform);\n\n    const replayTypes = opt_replayTypes ? opt_replayTypes : ORDER;\n    let i, ii, j, jj, replays, replay;\n    for (i = 0, ii = zs.length; i < ii; ++i) {\n      const zIndexKey = zs[i].toString();\n      replays = this.replaysByZIndex_[zIndexKey];\n      for (j = 0, jj = replayTypes.length; j < jj; ++j) {\n        const replayType = replayTypes[j];\n        replay = replays[replayType];\n        if (replay !== undefined) {\n          if (opt_declutterReplays &&\n              (replayType == ReplayType.IMAGE || replayType == ReplayType.TEXT)) {\n            const declutter = opt_declutterReplays[zIndexKey];\n            if (!declutter) {\n              opt_declutterReplays[zIndexKey] = [replay, transform.slice(0)];\n            } else {\n              declutter.push(replay, transform.slice(0));\n            }\n          } else {\n            replay.replay(context, transform, viewRotation, skippedFeaturesHash);\n          }\n        }\n      }\n    }\n\n    context.restore();\n  }\n}\n\n\n/**\n * This cache is used for storing calculated pixel circles for increasing performance.\n * It is a static property to allow each Replaygroup to access it.\n * @type {Object.<number, Array.<Array.<(boolean|undefined)>>>}\n */\nconst circleArrayCache = {\n  0: [[true]]\n};\n\n\n/**\n * This method fills a row in the array from the given coordinate to the\n * middle with `true`.\n * @param {Array.<Array.<(boolean|undefined)>>} array The array that will be altered.\n * @param {number} x X coordinate.\n * @param {number} y Y coordinate.\n */\nfunction fillCircleArrayRowToMiddle(array, x, y) {\n  let i;\n  const radius = Math.floor(array.length / 2);\n  if (x >= radius) {\n    for (i = radius; i < x; i++) {\n      array[i][y] = true;\n    }\n  } else if (x < radius) {\n    for (i = x + 1; i < radius; i++) {\n      array[i][y] = true;\n    }\n  }\n}\n\n\n/**\n * This methods creates a circle inside a fitting array. Points inside the\n * circle are marked by true, points on the outside are undefined.\n * It uses the midpoint circle algorithm.\n * A cache is used to increase performance.\n * @param {number} radius Radius.\n * @returns {Array.<Array.<(boolean|undefined)>>} An array with marked circle points.\n */\nexport function getCircleArray(radius) {\n  if (circleArrayCache[radius] !== undefined) {\n    return circleArrayCache[radius];\n  }\n\n  const arraySize = radius * 2 + 1;\n  const arr = new Array(arraySize);\n  for (let i = 0; i < arraySize; i++) {\n    arr[i] = new Array(arraySize);\n  }\n\n  let x = radius;\n  let y = 0;\n  let error = 0;\n\n  while (x >= y) {\n    fillCircleArrayRowToMiddle(arr, radius + x, radius + y);\n    fillCircleArrayRowToMiddle(arr, radius + y, radius + x);\n    fillCircleArrayRowToMiddle(arr, radius - y, radius + x);\n    fillCircleArrayRowToMiddle(arr, radius - x, radius + y);\n    fillCircleArrayRowToMiddle(arr, radius - x, radius - y);\n    fillCircleArrayRowToMiddle(arr, radius - y, radius - x);\n    fillCircleArrayRowToMiddle(arr, radius + y, radius - x);\n    fillCircleArrayRowToMiddle(arr, radius + x, radius - y);\n\n    y++;\n    error += 1 + 2 * y;\n    if (2 * (error - x) + 1 > 0) {\n      x -= 1;\n      error += 1 - 2 * x;\n    }\n  }\n\n  circleArrayCache[radius] = arr;\n  return arr;\n}\n\n\n/**\n * @param {!Object.<string, Array.<*>>} declutterReplays Declutter replays.\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} rotation Rotation.\n */\nexport function replayDeclutter(declutterReplays, context, rotation) {\n  const zs = Object.keys(declutterReplays).map(Number).sort(numberSafeCompareFunction);\n  const skippedFeatureUids = {};\n  for (let z = 0, zz = zs.length; z < zz; ++z) {\n    const replayData = declutterReplays[zs[z].toString()];\n    for (let i = 0, ii = replayData.length; i < ii;) {\n      const replay = replayData[i++];\n      const transform = replayData[i++];\n      replay.replay(context, transform, rotation, skippedFeatureUids);\n    }\n  }\n}\n\n\nexport default CanvasReplayGroup;\n","/**\n * @module ol/render/canvas/TextReplay\n */\nimport {getUid} from '../../util.js';\nimport {asColorLike} from '../../colorlike.js';\nimport {createCanvasContext2D} from '../../dom.js';\nimport {intersects} from '../../extent.js';\nimport {matchingChunk} from '../../geom/flat/straightchunk.js';\nimport GeometryType from '../../geom/GeometryType.js';\nimport {CANVAS_LINE_DASH} from '../../has.js';\nimport {labelCache, measureTextWidth, defaultTextAlign, measureTextHeight, defaultPadding, defaultLineCap, defaultLineDashOffset, defaultLineDash, defaultLineJoin, defaultFillStyle, checkFont, defaultFont, defaultLineWidth, defaultMiterLimit, defaultStrokeStyle, defaultTextBaseline} from '../canvas.js';\nimport CanvasInstruction from '../canvas/Instruction.js';\nimport CanvasReplay from '../canvas/Replay.js';\nimport {TEXT_ALIGN} from '../replay.js';\nimport TextPlacement from '../../style/TextPlacement.js';\n\nclass CanvasTextReplay extends CanvasReplay {\n  /**\n   * @param {number} tolerance Tolerance.\n   * @param {module:ol/extent~Extent} maxExtent Maximum extent.\n   * @param {number} resolution Resolution.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {boolean} overlaps The replay can have overlapping geometries.\n   * @param {?} declutterTree Declutter tree.\n   */\n  constructor(tolerance, maxExtent, resolution, pixelRatio, overlaps, declutterTree) {\n    super(tolerance, maxExtent, resolution, pixelRatio, overlaps, declutterTree);\n\n    /**\n     * @private\n     * @type {module:ol/render/canvas~DeclutterGroup}\n     */\n    this.declutterGroup_;\n\n    /**\n     * @private\n     * @type {Array.<HTMLCanvasElement>}\n     */\n    this.labels_ = null;\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.text_ = '';\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.textOffsetX_ = 0;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.textOffsetY_ = 0;\n\n    /**\n     * @private\n     * @type {boolean|undefined}\n     */\n    this.textRotateWithView_ = undefined;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.textRotation_ = 0;\n\n    /**\n     * @private\n     * @type {?module:ol/render/canvas~FillState}\n     */\n    this.textFillState_ = null;\n\n    /**\n     * @type {!Object.<string, module:ol/render/canvas~FillState>}\n     */\n    this.fillStates = {};\n\n    /**\n     * @private\n     * @type {?module:ol/render/canvas~StrokeState}\n     */\n    this.textStrokeState_ = null;\n\n    /**\n     * @type {!Object.<string, module:ol/render/canvas~StrokeState>}\n     */\n    this.strokeStates = {};\n\n    /**\n     * @private\n     * @type {module:ol/render/canvas~TextState}\n     */\n    this.textState_ = /** @type {module:ol/render/canvas~TextState} */ ({});\n\n    /**\n     * @type {!Object.<string, module:ol/render/canvas~TextState>}\n     */\n    this.textStates = {};\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.textKey_ = '';\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.fillKey_ = '';\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.strokeKey_ = '';\n\n    /**\n     * @private\n     * @type {Object.<string, Object.<string, number>>}\n     */\n    this.widths_ = {};\n\n    labelCache.prune();\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawText(geometry, feature) {\n    const fillState = this.textFillState_;\n    const strokeState = this.textStrokeState_;\n    const textState = this.textState_;\n    if (this.text_ === '' || !textState || (!fillState && !strokeState)) {\n      return;\n    }\n\n    let begin = this.coordinates.length;\n\n    const geometryType = geometry.getType();\n    let flatCoordinates = null;\n    let end = 2;\n    let stride = 2;\n    let i, ii;\n\n    if (textState.placement === TextPlacement.LINE) {\n      if (!intersects(this.getBufferedMaxExtent(), geometry.getExtent())) {\n        return;\n      }\n      let ends;\n      flatCoordinates = geometry.getFlatCoordinates();\n      stride = geometry.getStride();\n      if (geometryType == GeometryType.LINE_STRING) {\n        ends = [flatCoordinates.length];\n      } else if (geometryType == GeometryType.MULTI_LINE_STRING) {\n        ends = geometry.getEnds();\n      } else if (geometryType == GeometryType.POLYGON) {\n        ends = geometry.getEnds().slice(0, 1);\n      } else if (geometryType == GeometryType.MULTI_POLYGON) {\n        const endss = geometry.getEndss();\n        ends = [];\n        for (i = 0, ii = endss.length; i < ii; ++i) {\n          ends.push(endss[i][0]);\n        }\n      }\n      this.beginGeometry(geometry, feature);\n      const textAlign = textState.textAlign;\n      let flatOffset = 0;\n      let flatEnd;\n      for (let o = 0, oo = ends.length; o < oo; ++o) {\n        if (textAlign == undefined) {\n          const range = matchingChunk(textState.maxAngle, flatCoordinates, flatOffset, ends[o], stride);\n          flatOffset = range[0];\n          flatEnd = range[1];\n        } else {\n          flatEnd = ends[o];\n        }\n        for (i = flatOffset; i < flatEnd; i += stride) {\n          this.coordinates.push(flatCoordinates[i], flatCoordinates[i + 1]);\n        }\n        end = this.coordinates.length;\n        flatOffset = ends[o];\n        this.drawChars_(begin, end, this.declutterGroup_);\n        begin = end;\n      }\n      this.endGeometry(geometry, feature);\n\n    } else {\n      const label = this.getImage(this.text_, this.textKey_, this.fillKey_, this.strokeKey_);\n      const width = label.width / this.pixelRatio;\n      switch (geometryType) {\n        case GeometryType.POINT:\n        case GeometryType.MULTI_POINT:\n          flatCoordinates = geometry.getFlatCoordinates();\n          end = flatCoordinates.length;\n          break;\n        case GeometryType.LINE_STRING:\n          flatCoordinates = /** @type {module:ol/geom/LineString} */ (geometry).getFlatMidpoint();\n          break;\n        case GeometryType.CIRCLE:\n          flatCoordinates = /** @type {module:ol/geom/Circle} */ (geometry).getCenter();\n          break;\n        case GeometryType.MULTI_LINE_STRING:\n          flatCoordinates = /** @type {module:ol/geom/MultiLineString} */ (geometry).getFlatMidpoints();\n          end = flatCoordinates.length;\n          break;\n        case GeometryType.POLYGON:\n          flatCoordinates = /** @type {module:ol/geom/Polygon} */ (geometry).getFlatInteriorPoint();\n          if (!textState.overflow && flatCoordinates[2] / this.resolution < width) {\n            return;\n          }\n          stride = 3;\n          break;\n        case GeometryType.MULTI_POLYGON:\n          const interiorPoints = /** @type {module:ol/geom/MultiPolygon} */ (geometry).getFlatInteriorPoints();\n          flatCoordinates = [];\n          for (i = 0, ii = interiorPoints.length; i < ii; i += 3) {\n            if (textState.overflow || interiorPoints[i + 2] / this.resolution >= width) {\n              flatCoordinates.push(interiorPoints[i], interiorPoints[i + 1]);\n            }\n          }\n          end = flatCoordinates.length;\n          if (end == 0) {\n            return;\n          }\n          break;\n        default:\n      }\n      end = this.appendFlatCoordinates(flatCoordinates, 0, end, stride, false, false);\n      if (textState.backgroundFill || textState.backgroundStroke) {\n        this.setFillStrokeStyle(textState.backgroundFill, textState.backgroundStroke);\n        if (textState.backgroundFill) {\n          this.updateFillStyle(this.state, this.createFill, geometry);\n          this.hitDetectionInstructions.push(this.createFill(this.state, geometry));\n        }\n        if (textState.backgroundStroke) {\n          this.updateStrokeStyle(this.state, this.applyStroke);\n          this.hitDetectionInstructions.push(this.createStroke(this.state));\n        }\n      }\n      this.beginGeometry(geometry, feature);\n      this.drawTextImage_(label, begin, end);\n      this.endGeometry(geometry, feature);\n    }\n  }\n\n  /**\n   * @param {string} text Text.\n   * @param {string} textKey Text style key.\n   * @param {string} fillKey Fill style key.\n   * @param {string} strokeKey Stroke style key.\n   * @return {HTMLCanvasElement} Image.\n   */\n  getImage(text, textKey, fillKey, strokeKey) {\n    let label;\n    const key = strokeKey + textKey + text + fillKey + this.pixelRatio;\n\n    if (!labelCache.containsKey(key)) {\n      const strokeState = strokeKey ? this.strokeStates[strokeKey] || this.textStrokeState_ : null;\n      const fillState = fillKey ? this.fillStates[fillKey] || this.textFillState_ : null;\n      const textState = this.textStates[textKey] || this.textState_;\n      const pixelRatio = this.pixelRatio;\n      const scale = textState.scale * pixelRatio;\n      const align = TEXT_ALIGN[textState.textAlign || defaultTextAlign];\n      const strokeWidth = strokeKey && strokeState.lineWidth ? strokeState.lineWidth : 0;\n\n      const lines = text.split('\\n');\n      const numLines = lines.length;\n      const widths = [];\n      const width = measureTextWidths(textState.font, lines, widths);\n      const lineHeight = measureTextHeight(textState.font);\n      const height = lineHeight * numLines;\n      const renderWidth = (width + strokeWidth);\n      const context = createCanvasContext2D(\n        Math.ceil(renderWidth * scale),\n        Math.ceil((height + strokeWidth) * scale));\n      label = context.canvas;\n      labelCache.set(key, label);\n      if (scale != 1) {\n        context.scale(scale, scale);\n      }\n      context.font = textState.font;\n      if (strokeKey) {\n        context.strokeStyle = strokeState.strokeStyle;\n        context.lineWidth = strokeWidth;\n        context.lineCap = strokeState.lineCap;\n        context.lineJoin = strokeState.lineJoin;\n        context.miterLimit = strokeState.miterLimit;\n        if (CANVAS_LINE_DASH && strokeState.lineDash.length) {\n          context.setLineDash(strokeState.lineDash);\n          context.lineDashOffset = strokeState.lineDashOffset;\n        }\n      }\n      if (fillKey) {\n        context.fillStyle = fillState.fillStyle;\n      }\n      context.textBaseline = 'middle';\n      context.textAlign = 'center';\n      const leftRight = (0.5 - align);\n      const x = align * label.width / scale + leftRight * strokeWidth;\n      let i;\n      if (strokeKey) {\n        for (i = 0; i < numLines; ++i) {\n          context.strokeText(lines[i], x + leftRight * widths[i], 0.5 * (strokeWidth + lineHeight) + i * lineHeight);\n        }\n      }\n      if (fillKey) {\n        for (i = 0; i < numLines; ++i) {\n          context.fillText(lines[i], x + leftRight * widths[i], 0.5 * (strokeWidth + lineHeight) + i * lineHeight);\n        }\n      }\n    }\n    return labelCache.get(key);\n  }\n\n  /**\n   * @private\n   * @param {HTMLCanvasElement} label Label.\n   * @param {number} begin Begin.\n   * @param {number} end End.\n   */\n  drawTextImage_(label, begin, end) {\n    const textState = this.textState_;\n    const strokeState = this.textStrokeState_;\n    const pixelRatio = this.pixelRatio;\n    const align = TEXT_ALIGN[textState.textAlign || defaultTextAlign];\n    const baseline = TEXT_ALIGN[textState.textBaseline];\n    const strokeWidth = strokeState && strokeState.lineWidth ? strokeState.lineWidth : 0;\n\n    const anchorX = align * label.width / pixelRatio + 2 * (0.5 - align) * strokeWidth;\n    const anchorY = baseline * label.height / pixelRatio + 2 * (0.5 - baseline) * strokeWidth;\n    this.instructions.push([CanvasInstruction.DRAW_IMAGE, begin, end,\n      label, (anchorX - this.textOffsetX_) * pixelRatio, (anchorY - this.textOffsetY_) * pixelRatio,\n      this.declutterGroup_, label.height, 1, 0, 0, this.textRotateWithView_, this.textRotation_,\n      1, true, label.width,\n      textState.padding == defaultPadding ?\n        defaultPadding : textState.padding.map(function(p) {\n          return p * pixelRatio;\n        }),\n      !!textState.backgroundFill, !!textState.backgroundStroke\n    ]);\n    this.hitDetectionInstructions.push([CanvasInstruction.DRAW_IMAGE, begin, end,\n      label, (anchorX - this.textOffsetX_) * pixelRatio, (anchorY - this.textOffsetY_) * pixelRatio,\n      this.declutterGroup_, label.height, 1, 0, 0, this.textRotateWithView_, this.textRotation_,\n      1 / pixelRatio, true, label.width, textState.padding,\n      !!textState.backgroundFill, !!textState.backgroundStroke\n    ]);\n  }\n\n  /**\n   * @private\n   * @param {number} begin Begin.\n   * @param {number} end End.\n   * @param {module:ol/render/canvas~DeclutterGroup} declutterGroup Declutter group.\n   */\n  drawChars_(begin, end, declutterGroup) {\n    const strokeState = this.textStrokeState_;\n    const textState = this.textState_;\n    const fillState = this.textFillState_;\n\n    const strokeKey = this.strokeKey_;\n    if (strokeState) {\n      if (!(strokeKey in this.strokeStates)) {\n        this.strokeStates[strokeKey] = /** @type {module:ol/render/canvas~StrokeState} */ ({\n          strokeStyle: strokeState.strokeStyle,\n          lineCap: strokeState.lineCap,\n          lineDashOffset: strokeState.lineDashOffset,\n          lineWidth: strokeState.lineWidth,\n          lineJoin: strokeState.lineJoin,\n          miterLimit: strokeState.miterLimit,\n          lineDash: strokeState.lineDash\n        });\n      }\n    }\n    const textKey = this.textKey_;\n    if (!(this.textKey_ in this.textStates)) {\n      this.textStates[this.textKey_] = /** @type {module:ol/render/canvas~TextState} */ ({\n        font: textState.font,\n        textAlign: textState.textAlign || defaultTextAlign,\n        scale: textState.scale\n      });\n    }\n    const fillKey = this.fillKey_;\n    if (fillState) {\n      if (!(fillKey in this.fillStates)) {\n        this.fillStates[fillKey] = /** @type {module:ol/render/canvas~FillState} */ ({\n          fillStyle: fillState.fillStyle\n        });\n      }\n    }\n\n    const pixelRatio = this.pixelRatio;\n    const baseline = TEXT_ALIGN[textState.textBaseline];\n\n    const offsetY = this.textOffsetY_ * pixelRatio;\n    const text = this.text_;\n    const font = textState.font;\n    const textScale = textState.scale;\n    const strokeWidth = strokeState ? strokeState.lineWidth * textScale / 2 : 0;\n    let widths = this.widths_[font];\n    if (!widths) {\n      this.widths_[font] = widths = {};\n    }\n    this.instructions.push([CanvasInstruction.DRAW_CHARS,\n      begin, end, baseline, declutterGroup,\n      textState.overflow, fillKey, textState.maxAngle,\n      function(text) {\n        let width = widths[text];\n        if (!width) {\n          width = widths[text] = measureTextWidth(font, text);\n        }\n        return width * textScale * pixelRatio;\n      },\n      offsetY, strokeKey, strokeWidth * pixelRatio, text, textKey, 1\n    ]);\n    this.hitDetectionInstructions.push([CanvasInstruction.DRAW_CHARS,\n      begin, end, baseline, declutterGroup,\n      textState.overflow, fillKey, textState.maxAngle,\n      function(text) {\n        let width = widths[text];\n        if (!width) {\n          width = widths[text] = measureTextWidth(font, text);\n        }\n        return width * textScale;\n      },\n      offsetY, strokeKey, strokeWidth, text, textKey, 1 / pixelRatio\n    ]);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setTextStyle(textStyle, declutterGroup) {\n    let textState, fillState, strokeState;\n    if (!textStyle) {\n      this.text_ = '';\n    } else {\n      this.declutterGroup_ = /** @type {module:ol/render/canvas~DeclutterGroup} */ (declutterGroup);\n\n      const textFillStyle = textStyle.getFill();\n      if (!textFillStyle) {\n        fillState = this.textFillState_ = null;\n      } else {\n        fillState = this.textFillState_;\n        if (!fillState) {\n          fillState = this.textFillState_ = /** @type {module:ol/render/canvas~FillState} */ ({});\n        }\n        fillState.fillStyle = asColorLike(\n          textFillStyle.getColor() || defaultFillStyle);\n      }\n\n      const textStrokeStyle = textStyle.getStroke();\n      if (!textStrokeStyle) {\n        strokeState = this.textStrokeState_ = null;\n      } else {\n        strokeState = this.textStrokeState_;\n        if (!strokeState) {\n          strokeState = this.textStrokeState_ = /** @type {module:ol/render/canvas~StrokeState} */ ({});\n        }\n        const lineDash = textStrokeStyle.getLineDash();\n        const lineDashOffset = textStrokeStyle.getLineDashOffset();\n        const lineWidth = textStrokeStyle.getWidth();\n        const miterLimit = textStrokeStyle.getMiterLimit();\n        strokeState.lineCap = textStrokeStyle.getLineCap() || defaultLineCap;\n        strokeState.lineDash = lineDash ? lineDash.slice() : defaultLineDash;\n        strokeState.lineDashOffset =\n            lineDashOffset === undefined ? defaultLineDashOffset : lineDashOffset;\n        strokeState.lineJoin = textStrokeStyle.getLineJoin() || defaultLineJoin;\n        strokeState.lineWidth =\n            lineWidth === undefined ? defaultLineWidth : lineWidth;\n        strokeState.miterLimit =\n            miterLimit === undefined ? defaultMiterLimit : miterLimit;\n        strokeState.strokeStyle = asColorLike(\n          textStrokeStyle.getColor() || defaultStrokeStyle);\n      }\n\n      textState = this.textState_;\n      const font = textStyle.getFont() || defaultFont;\n      checkFont(font);\n      const textScale = textStyle.getScale();\n      textState.overflow = textStyle.getOverflow();\n      textState.font = font;\n      textState.maxAngle = textStyle.getMaxAngle();\n      textState.placement = textStyle.getPlacement();\n      textState.textAlign = textStyle.getTextAlign();\n      textState.textBaseline = textStyle.getTextBaseline() || defaultTextBaseline;\n      textState.backgroundFill = textStyle.getBackgroundFill();\n      textState.backgroundStroke = textStyle.getBackgroundStroke();\n      textState.padding = textStyle.getPadding() || defaultPadding;\n      textState.scale = textScale === undefined ? 1 : textScale;\n\n      const textOffsetX = textStyle.getOffsetX();\n      const textOffsetY = textStyle.getOffsetY();\n      const textRotateWithView = textStyle.getRotateWithView();\n      const textRotation = textStyle.getRotation();\n      this.text_ = textStyle.getText() || '';\n      this.textOffsetX_ = textOffsetX === undefined ? 0 : textOffsetX;\n      this.textOffsetY_ = textOffsetY === undefined ? 0 : textOffsetY;\n      this.textRotateWithView_ = textRotateWithView === undefined ? false : textRotateWithView;\n      this.textRotation_ = textRotation === undefined ? 0 : textRotation;\n\n      this.strokeKey_ = strokeState ?\n        (typeof strokeState.strokeStyle == 'string' ? strokeState.strokeStyle : getUid(strokeState.strokeStyle)) +\n        strokeState.lineCap + strokeState.lineDashOffset + '|' + strokeState.lineWidth +\n        strokeState.lineJoin + strokeState.miterLimit + '[' + strokeState.lineDash.join() + ']' :\n        '';\n      this.textKey_ = textState.font + textState.scale + (textState.textAlign || '?');\n      this.fillKey_ = fillState ?\n        (typeof fillState.fillStyle == 'string' ? fillState.fillStyle : ('|' + getUid(fillState.fillStyle))) :\n        '';\n    }\n  }\n}\n\n\n/**\n * @param {string} font Font to use for measuring.\n * @param {Array.<string>} lines Lines to measure.\n * @param {Array.<number>} widths Array will be populated with the widths of\n * each line.\n * @return {number} Width of the whole text.\n */\nexport function measureTextWidths(font, lines, widths) {\n  const numLines = lines.length;\n  let width = 0;\n  for (let i = 0; i < numLines; ++i) {\n    const currentWidth = measureTextWidth(font, lines[i]);\n    width = Math.max(width, currentWidth);\n    widths.push(currentWidth);\n  }\n  return width;\n}\n\n\nexport default CanvasTextReplay;\n","/**\n * @module ol/renderer/vector\n */\nimport {getUid} from '../util.js';\nimport ImageState from '../ImageState.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport ReplayType from '../render/ReplayType.js';\n\n\n/**\n * Tolerance for geometry simplification in device pixels.\n * @type {number}\n */\nconst SIMPLIFY_TOLERANCE = 0.5;\n\n\n/**\n * @const\n * @type {Object.<module:ol/geom/GeometryType,\n *                function(module:ol/render/ReplayGroup, module:ol/geom/Geometry,\n *                         module:ol/style/Style, Object)>}\n */\nconst GEOMETRY_RENDERERS = {\n  'Point': renderPointGeometry,\n  'LineString': renderLineStringGeometry,\n  'Polygon': renderPolygonGeometry,\n  'MultiPoint': renderMultiPointGeometry,\n  'MultiLineString': renderMultiLineStringGeometry,\n  'MultiPolygon': renderMultiPolygonGeometry,\n  'GeometryCollection': renderGeometryCollectionGeometry,\n  'Circle': renderCircleGeometry\n};\n\n\n/**\n * @param {module:ol/Feature|module:ol/render/Feature} feature1 Feature 1.\n * @param {module:ol/Feature|module:ol/render/Feature} feature2 Feature 2.\n * @return {number} Order.\n */\nexport function defaultOrder(feature1, feature2) {\n  return getUid(feature1) - getUid(feature2);\n}\n\n\n/**\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Squared pixel tolerance.\n */\nexport function getSquaredTolerance(resolution, pixelRatio) {\n  const tolerance = getTolerance(resolution, pixelRatio);\n  return tolerance * tolerance;\n}\n\n\n/**\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Pixel tolerance.\n */\nexport function getTolerance(resolution, pixelRatio) {\n  return SIMPLIFY_TOLERANCE * resolution / pixelRatio;\n}\n\n\n/**\n * @param {module:ol/render/ReplayGroup} replayGroup Replay group.\n * @param {module:ol/geom/Circle} geometry Geometry.\n * @param {module:ol/style/Style} style Style.\n * @param {module:ol/Feature} feature Feature.\n */\nfunction renderCircleGeometry(replayGroup, geometry, style, feature) {\n  const fillStyle = style.getFill();\n  const strokeStyle = style.getStroke();\n  if (fillStyle || strokeStyle) {\n    const circleReplay = replayGroup.getReplay(style.getZIndex(), ReplayType.CIRCLE);\n    circleReplay.setFillStrokeStyle(fillStyle, strokeStyle);\n    circleReplay.drawCircle(geometry, feature);\n  }\n  const textStyle = style.getText();\n  if (textStyle) {\n    const textReplay = replayGroup.getReplay(style.getZIndex(), ReplayType.TEXT);\n    textReplay.setTextStyle(textStyle, replayGroup.addDeclutter(false));\n    textReplay.drawText(geometry, feature);\n  }\n}\n\n\n/**\n * @param {module:ol/render/ReplayGroup} replayGroup Replay group.\n * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n * @param {module:ol/style/Style} style Style.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {function(this: T, module:ol/events/Event)} listener Listener function.\n * @param {T} thisArg Value to use as `this` when executing `listener`.\n * @return {boolean} `true` if style is loading.\n * @template T\n */\nexport function renderFeature(replayGroup, feature, style, squaredTolerance, listener, thisArg) {\n  let loading = false;\n  const imageStyle = style.getImage();\n  if (imageStyle) {\n    let imageState = imageStyle.getImageState();\n    if (imageState == ImageState.LOADED || imageState == ImageState.ERROR) {\n      imageStyle.unlistenImageChange(listener, thisArg);\n    } else {\n      if (imageState == ImageState.IDLE) {\n        imageStyle.load();\n      }\n      imageState = imageStyle.getImageState();\n      imageStyle.listenImageChange(listener, thisArg);\n      loading = true;\n    }\n  }\n  renderFeatureInternal(replayGroup, feature, style, squaredTolerance);\n\n  return loading;\n}\n\n\n/**\n * @param {module:ol/render/ReplayGroup} replayGroup Replay group.\n * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n * @param {module:ol/style/Style} style Style.\n * @param {number} squaredTolerance Squared tolerance.\n */\nfunction renderFeatureInternal(replayGroup, feature, style, squaredTolerance) {\n  const geometry = style.getGeometryFunction()(feature);\n  if (!geometry) {\n    return;\n  }\n  const simplifiedGeometry = geometry.getSimplifiedGeometry(squaredTolerance);\n  const renderer = style.getRenderer();\n  if (renderer) {\n    renderGeometry(replayGroup, simplifiedGeometry, style, feature);\n  } else {\n    const geometryRenderer = GEOMETRY_RENDERERS[simplifiedGeometry.getType()];\n    geometryRenderer(replayGroup, simplifiedGeometry, style, feature);\n  }\n}\n\n\n/**\n * @param {module:ol/render/ReplayGroup} replayGroup Replay group.\n * @param {module:ol/geom/Geometry} geometry Geometry.\n * @param {module:ol/style/Style} style Style.\n * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n */\nfunction renderGeometry(replayGroup, geometry, style, feature) {\n  if (geometry.getType() == GeometryType.GEOMETRY_COLLECTION) {\n    const geometries = /** @type {module:ol/geom/GeometryCollection} */ (geometry).getGeometries();\n    for (let i = 0, ii = geometries.length; i < ii; ++i) {\n      renderGeometry(replayGroup, geometries[i], style, feature);\n    }\n    return;\n  }\n  const replay = replayGroup.getReplay(style.getZIndex(), ReplayType.DEFAULT);\n  replay.drawCustom(/** @type {module:ol/geom/SimpleGeometry} */ (geometry), feature, style.getRenderer());\n}\n\n\n/**\n * @param {module:ol/render/ReplayGroup} replayGroup Replay group.\n * @param {module:ol/geom/GeometryCollection} geometry Geometry.\n * @param {module:ol/style/Style} style Style.\n * @param {module:ol/Feature} feature Feature.\n */\nfunction renderGeometryCollectionGeometry(replayGroup, geometry, style, feature) {\n  const geometries = geometry.getGeometriesArray();\n  let i, ii;\n  for (i = 0, ii = geometries.length; i < ii; ++i) {\n    const geometryRenderer =\n        GEOMETRY_RENDERERS[geometries[i].getType()];\n    geometryRenderer(replayGroup, geometries[i], style, feature);\n  }\n}\n\n\n/**\n * @param {module:ol/render/ReplayGroup} replayGroup Replay group.\n * @param {module:ol/geom/LineString|module:ol/render/Feature} geometry Geometry.\n * @param {module:ol/style/Style} style Style.\n * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n */\nfunction renderLineStringGeometry(replayGroup, geometry, style, feature) {\n  const strokeStyle = style.getStroke();\n  if (strokeStyle) {\n    const lineStringReplay = replayGroup.getReplay(style.getZIndex(), ReplayType.LINE_STRING);\n    lineStringReplay.setFillStrokeStyle(null, strokeStyle);\n    lineStringReplay.drawLineString(geometry, feature);\n  }\n  const textStyle = style.getText();\n  if (textStyle) {\n    const textReplay = replayGroup.getReplay(style.getZIndex(), ReplayType.TEXT);\n    textReplay.setTextStyle(textStyle, replayGroup.addDeclutter(false));\n    textReplay.drawText(geometry, feature);\n  }\n}\n\n\n/**\n * @param {module:ol/render/ReplayGroup} replayGroup Replay group.\n * @param {module:ol/geom/MultiLineString|module:ol/render/Feature} geometry Geometry.\n * @param {module:ol/style/Style} style Style.\n * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n */\nfunction renderMultiLineStringGeometry(replayGroup, geometry, style, feature) {\n  const strokeStyle = style.getStroke();\n  if (strokeStyle) {\n    const lineStringReplay = replayGroup.getReplay(style.getZIndex(), ReplayType.LINE_STRING);\n    lineStringReplay.setFillStrokeStyle(null, strokeStyle);\n    lineStringReplay.drawMultiLineString(geometry, feature);\n  }\n  const textStyle = style.getText();\n  if (textStyle) {\n    const textReplay = replayGroup.getReplay(style.getZIndex(), ReplayType.TEXT);\n    textReplay.setTextStyle(textStyle, replayGroup.addDeclutter(false));\n    textReplay.drawText(geometry, feature);\n  }\n}\n\n\n/**\n * @param {module:ol/render/ReplayGroup} replayGroup Replay group.\n * @param {module:ol/geom/MultiPolygon} geometry Geometry.\n * @param {module:ol/style/Style} style Style.\n * @param {module:ol/Feature} feature Feature.\n */\nfunction renderMultiPolygonGeometry(replayGroup, geometry, style, feature) {\n  const fillStyle = style.getFill();\n  const strokeStyle = style.getStroke();\n  if (strokeStyle || fillStyle) {\n    const polygonReplay = replayGroup.getReplay(style.getZIndex(), ReplayType.POLYGON);\n    polygonReplay.setFillStrokeStyle(fillStyle, strokeStyle);\n    polygonReplay.drawMultiPolygon(geometry, feature);\n  }\n  const textStyle = style.getText();\n  if (textStyle) {\n    const textReplay = replayGroup.getReplay(style.getZIndex(), ReplayType.TEXT);\n    textReplay.setTextStyle(textStyle, replayGroup.addDeclutter(false));\n    textReplay.drawText(geometry, feature);\n  }\n}\n\n\n/**\n * @param {module:ol/render/ReplayGroup} replayGroup Replay group.\n * @param {module:ol/geom/Point|module:ol/render/Feature} geometry Geometry.\n * @param {module:ol/style/Style} style Style.\n * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n */\nfunction renderPointGeometry(replayGroup, geometry, style, feature) {\n  const imageStyle = style.getImage();\n  if (imageStyle) {\n    if (imageStyle.getImageState() != ImageState.LOADED) {\n      return;\n    }\n    const imageReplay = replayGroup.getReplay(style.getZIndex(), ReplayType.IMAGE);\n    imageReplay.setImageStyle(imageStyle, replayGroup.addDeclutter(false));\n    imageReplay.drawPoint(geometry, feature);\n  }\n  const textStyle = style.getText();\n  if (textStyle) {\n    const textReplay = replayGroup.getReplay(style.getZIndex(), ReplayType.TEXT);\n    textReplay.setTextStyle(textStyle, replayGroup.addDeclutter(!!imageStyle));\n    textReplay.drawText(geometry, feature);\n  }\n}\n\n\n/**\n * @param {module:ol/render/ReplayGroup} replayGroup Replay group.\n * @param {module:ol/geom/MultiPoint|module:ol/render/Feature} geometry Geometry.\n * @param {module:ol/style/Style} style Style.\n * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n */\nfunction renderMultiPointGeometry(replayGroup, geometry, style, feature) {\n  const imageStyle = style.getImage();\n  if (imageStyle) {\n    if (imageStyle.getImageState() != ImageState.LOADED) {\n      return;\n    }\n    const imageReplay = replayGroup.getReplay(style.getZIndex(), ReplayType.IMAGE);\n    imageReplay.setImageStyle(imageStyle, replayGroup.addDeclutter(false));\n    imageReplay.drawMultiPoint(geometry, feature);\n  }\n  const textStyle = style.getText();\n  if (textStyle) {\n    const textReplay = replayGroup.getReplay(style.getZIndex(), ReplayType.TEXT);\n    textReplay.setTextStyle(textStyle, replayGroup.addDeclutter(!!imageStyle));\n    textReplay.drawText(geometry, feature);\n  }\n}\n\n\n/**\n * @param {module:ol/render/ReplayGroup} replayGroup Replay group.\n * @param {module:ol/geom/Polygon|module:ol/render/Feature} geometry Geometry.\n * @param {module:ol/style/Style} style Style.\n * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n */\nfunction renderPolygonGeometry(replayGroup, geometry, style, feature) {\n  const fillStyle = style.getFill();\n  const strokeStyle = style.getStroke();\n  if (fillStyle || strokeStyle) {\n    const polygonReplay = replayGroup.getReplay(style.getZIndex(), ReplayType.POLYGON);\n    polygonReplay.setFillStrokeStyle(fillStyle, strokeStyle);\n    polygonReplay.drawPolygon(geometry, feature);\n  }\n  const textStyle = style.getText();\n  if (textStyle) {\n    const textReplay = replayGroup.getReplay(style.getZIndex(), ReplayType.TEXT);\n    textReplay.setTextStyle(textStyle, replayGroup.addDeclutter(false));\n    textReplay.drawText(geometry, feature);\n  }\n}\n","/**\n * @module ol/renderer/canvas/VectorLayer\n */\nimport {getUid} from '../../util.js';\nimport LayerType from '../../LayerType.js';\nimport ViewHint from '../../ViewHint.js';\nimport {createCanvasContext2D} from '../../dom.js';\nimport {listen, unlisten} from '../../events.js';\nimport EventType from '../../events/EventType.js';\nimport rbush from 'rbush';\nimport {buffer, createEmpty, containsExtent, getWidth} from '../../extent.js';\nimport RenderEventType from '../../render/EventType.js';\nimport {labelCache, rotateAtOffset} from '../../render/canvas.js';\nimport CanvasReplayGroup from '../../render/canvas/ReplayGroup.js';\nimport CanvasLayerRenderer from '../canvas/Layer.js';\nimport {defaultOrder as defaultRenderOrder, getTolerance as getRenderTolerance, getSquaredTolerance as getSquaredRenderTolerance, renderFeature} from '../vector.js';\n\n/**\n * @classdesc\n * Canvas renderer for vector layers.\n * @api\n */\nclass CanvasVectorLayerRenderer extends CanvasLayerRenderer {\n\n  /**\n   * @param {module:ol/layer/Vector} vectorLayer Vector layer.\n   */\n  constructor(vectorLayer) {\n\n    super(vectorLayer);\n\n    /**\n     * Declutter tree.\n     * @private\n     */\n    this.declutterTree_ = vectorLayer.getDeclutter() ? rbush(9, undefined) : null;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.dirty_ = false;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.renderedRevision_ = -1;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.renderedResolution_ = NaN;\n\n    /**\n     * @private\n     * @type {module:ol/extent~Extent}\n     */\n    this.renderedExtent_ = createEmpty();\n\n    /**\n     * @private\n     * @type {function(module:ol/Feature, module:ol/Feature): number|null}\n     */\n    this.renderedRenderOrder_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/render/canvas/ReplayGroup}\n     */\n    this.replayGroup_ = null;\n\n    /**\n     * A new replay group had to be created by `prepareFrame()`\n     * @type {boolean}\n     */\n    this.replayGroupChanged = true;\n\n    /**\n     * @type {CanvasRenderingContext2D}\n     */\n    this.context = createCanvasContext2D();\n\n    listen(labelCache, EventType.CLEAR, this.handleFontsChanged_, this);\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  disposeInternal() {\n    unlisten(labelCache, EventType.CLEAR, this.handleFontsChanged_, this);\n    CanvasLayerRenderer.prototype.disposeInternal.call(this);\n  }\n\n  /**\n   * @param {CanvasRenderingContext2D} context Context.\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @param {module:ol/layer/Layer~State} layerState Layer state.\n   */\n  compose(context, frameState, layerState) {\n    const extent = frameState.extent;\n    const pixelRatio = frameState.pixelRatio;\n    const skippedFeatureUids = layerState.managed ?\n      frameState.skippedFeatureUids : {};\n    const viewState = frameState.viewState;\n    const projection = viewState.projection;\n    const rotation = viewState.rotation;\n    const projectionExtent = projection.getExtent();\n    const vectorSource = /** @type {module:ol/source/Vector} */ (this.getLayer().getSource());\n\n    let transform = this.getTransform(frameState, 0);\n\n    // clipped rendering if layer extent is set\n    const clipExtent = layerState.extent;\n    const clipped = clipExtent !== undefined;\n    if (clipped) {\n      this.clip(context, frameState, /** @type {module:ol/extent~Extent} */ (clipExtent));\n    }\n    const replayGroup = this.replayGroup_;\n    if (replayGroup && !replayGroup.isEmpty()) {\n      if (this.declutterTree_) {\n        this.declutterTree_.clear();\n      }\n      const layer = /** @type {module:ol/layer/Vector} */ (this.getLayer());\n      let drawOffsetX = 0;\n      let drawOffsetY = 0;\n      let replayContext;\n      const transparentLayer = layerState.opacity !== 1;\n      const hasRenderListeners = layer.hasListener(RenderEventType.RENDER);\n      if (transparentLayer || hasRenderListeners) {\n        let drawWidth = context.canvas.width;\n        let drawHeight = context.canvas.height;\n        if (rotation) {\n          const drawSize = Math.round(Math.sqrt(drawWidth * drawWidth + drawHeight * drawHeight));\n          drawOffsetX = (drawSize - drawWidth) / 2;\n          drawOffsetY = (drawSize - drawHeight) / 2;\n          drawWidth = drawHeight = drawSize;\n        }\n        // resize and clear\n        this.context.canvas.width = drawWidth;\n        this.context.canvas.height = drawHeight;\n        replayContext = this.context;\n      } else {\n        replayContext = context;\n      }\n\n      const alpha = replayContext.globalAlpha;\n      if (!transparentLayer) {\n        // for performance reasons, context.save / context.restore is not used\n        // to save and restore the transformation matrix and the opacity.\n        // see http://jsperf.com/context-save-restore-versus-variable\n        replayContext.globalAlpha = layerState.opacity;\n      }\n\n      if (replayContext != context) {\n        replayContext.translate(drawOffsetX, drawOffsetY);\n      }\n\n      const width = frameState.size[0] * pixelRatio;\n      const height = frameState.size[1] * pixelRatio;\n      rotateAtOffset(replayContext, -rotation,\n        width / 2, height / 2);\n      replayGroup.replay(replayContext, transform, rotation, skippedFeatureUids);\n      if (vectorSource.getWrapX() && projection.canWrapX() &&\n          !containsExtent(projectionExtent, extent)) {\n        let startX = extent[0];\n        const worldWidth = getWidth(projectionExtent);\n        let world = 0;\n        let offsetX;\n        while (startX < projectionExtent[0]) {\n          --world;\n          offsetX = worldWidth * world;\n          transform = this.getTransform(frameState, offsetX);\n          replayGroup.replay(replayContext, transform, rotation, skippedFeatureUids);\n          startX += worldWidth;\n        }\n        world = 0;\n        startX = extent[2];\n        while (startX > projectionExtent[2]) {\n          ++world;\n          offsetX = worldWidth * world;\n          transform = this.getTransform(frameState, offsetX);\n          replayGroup.replay(replayContext, transform, rotation, skippedFeatureUids);\n          startX -= worldWidth;\n        }\n      }\n      rotateAtOffset(replayContext, rotation,\n        width / 2, height / 2);\n\n      if (hasRenderListeners) {\n        this.dispatchRenderEvent(replayContext, frameState, transform);\n      }\n      if (replayContext != context) {\n        if (transparentLayer) {\n          const mainContextAlpha = context.globalAlpha;\n          context.globalAlpha = layerState.opacity;\n          context.drawImage(replayContext.canvas, -drawOffsetX, -drawOffsetY);\n          context.globalAlpha = mainContextAlpha;\n        } else {\n          context.drawImage(replayContext.canvas, -drawOffsetX, -drawOffsetY);\n        }\n        replayContext.translate(-drawOffsetX, -drawOffsetY);\n      }\n\n      if (!transparentLayer) {\n        replayContext.globalAlpha = alpha;\n      }\n    }\n\n    if (clipped) {\n      context.restore();\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  composeFrame(frameState, layerState, context) {\n    const transform = this.getTransform(frameState, 0);\n    this.preCompose(context, frameState, transform);\n    this.compose(context, frameState, layerState);\n    this.postCompose(context, frameState, layerState, transform);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback, thisArg) {\n    if (!this.replayGroup_) {\n      return undefined;\n    } else {\n      const resolution = frameState.viewState.resolution;\n      const rotation = frameState.viewState.rotation;\n      const layer = /** @type {module:ol/layer/Vector} */ (this.getLayer());\n      /** @type {!Object.<string, boolean>} */\n      const features = {};\n      const result = this.replayGroup_.forEachFeatureAtCoordinate(coordinate, resolution, rotation, hitTolerance, {},\n        /**\n         * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n         * @return {?} Callback result.\n         */\n        function(feature) {\n          const key = getUid(feature).toString();\n          if (!(key in features)) {\n            features[key] = true;\n            return callback.call(thisArg, feature, layer);\n          }\n        }, null);\n      return result;\n    }\n  }\n\n  /**\n   * @param {module:ol/events/Event} event Event.\n   */\n  handleFontsChanged_(event) {\n    const layer = this.getLayer();\n    if (layer.getVisible() && this.replayGroup_) {\n      layer.changed();\n    }\n  }\n\n  /**\n   * Handle changes in image style state.\n   * @param {module:ol/events/Event} event Image style change event.\n   * @private\n   */\n  handleStyleImageChange_(event) {\n    this.renderIfReadyAndVisible();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  prepareFrame(frameState, layerState) {\n    const vectorLayer = /** @type {module:ol/layer/Vector} */ (this.getLayer());\n    const vectorSource = vectorLayer.getSource();\n\n    const animating = frameState.viewHints[ViewHint.ANIMATING];\n    const interacting = frameState.viewHints[ViewHint.INTERACTING];\n    const updateWhileAnimating = vectorLayer.getUpdateWhileAnimating();\n    const updateWhileInteracting = vectorLayer.getUpdateWhileInteracting();\n\n    if (!this.dirty_ && (!updateWhileAnimating && animating) ||\n        (!updateWhileInteracting && interacting)) {\n      return true;\n    }\n\n    const frameStateExtent = frameState.extent;\n    const viewState = frameState.viewState;\n    const projection = viewState.projection;\n    const resolution = viewState.resolution;\n    const pixelRatio = frameState.pixelRatio;\n    const vectorLayerRevision = vectorLayer.getRevision();\n    const vectorLayerRenderBuffer = vectorLayer.getRenderBuffer();\n    let vectorLayerRenderOrder = vectorLayer.getRenderOrder();\n\n    if (vectorLayerRenderOrder === undefined) {\n      vectorLayerRenderOrder = defaultRenderOrder;\n    }\n\n    const extent = buffer(frameStateExtent,\n      vectorLayerRenderBuffer * resolution);\n    const projectionExtent = viewState.projection.getExtent();\n\n    if (vectorSource.getWrapX() && viewState.projection.canWrapX() &&\n        !containsExtent(projectionExtent, frameState.extent)) {\n      // For the replay group, we need an extent that intersects the real world\n      // (-180° to +180°). To support geometries in a coordinate range from -540°\n      // to +540°, we add at least 1 world width on each side of the projection\n      // extent. If the viewport is wider than the world, we need to add half of\n      // the viewport width to make sure we cover the whole viewport.\n      const worldWidth = getWidth(projectionExtent);\n      const gutter = Math.max(getWidth(extent) / 2, worldWidth);\n      extent[0] = projectionExtent[0] - gutter;\n      extent[2] = projectionExtent[2] + gutter;\n    }\n\n    if (!this.dirty_ &&\n        this.renderedResolution_ == resolution &&\n        this.renderedRevision_ == vectorLayerRevision &&\n        this.renderedRenderOrder_ == vectorLayerRenderOrder &&\n        containsExtent(this.renderedExtent_, extent)) {\n      this.replayGroupChanged = false;\n      return true;\n    }\n\n    this.replayGroup_ = null;\n\n    this.dirty_ = false;\n\n    const replayGroup = new CanvasReplayGroup(\n      getRenderTolerance(resolution, pixelRatio), extent, resolution,\n      pixelRatio, vectorSource.getOverlaps(), this.declutterTree_, vectorLayer.getRenderBuffer());\n    vectorSource.loadFeatures(extent, resolution, projection);\n    /**\n     * @param {module:ol/Feature} feature Feature.\n     * @this {module:ol/renderer/canvas/VectorLayer}\n     */\n    const render = function(feature) {\n      let styles;\n      const styleFunction = feature.getStyleFunction() || vectorLayer.getStyleFunction();\n      if (styleFunction) {\n        styles = styleFunction(feature, resolution);\n      }\n      if (styles) {\n        const dirty = this.renderFeature(\n          feature, resolution, pixelRatio, styles, replayGroup);\n        this.dirty_ = this.dirty_ || dirty;\n      }\n    }.bind(this);\n    if (vectorLayerRenderOrder) {\n      /** @type {Array.<module:ol/Feature>} */\n      const features = [];\n      vectorSource.forEachFeatureInExtent(extent,\n        /**\n         * @param {module:ol/Feature} feature Feature.\n         */\n        function(feature) {\n          features.push(feature);\n        }, this);\n      features.sort(vectorLayerRenderOrder);\n      for (let i = 0, ii = features.length; i < ii; ++i) {\n        render(features[i]);\n      }\n    } else {\n      vectorSource.forEachFeatureInExtent(extent, render, this);\n    }\n    replayGroup.finish();\n\n    this.renderedResolution_ = resolution;\n    this.renderedRevision_ = vectorLayerRevision;\n    this.renderedRenderOrder_ = vectorLayerRenderOrder;\n    this.renderedExtent_ = extent;\n    this.replayGroup_ = replayGroup;\n\n    this.replayGroupChanged = true;\n    return true;\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature.\n   * @param {number} resolution Resolution.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {(module:ol/style/Style|Array.<module:ol/style/Style>)} styles The style or array of styles.\n   * @param {module:ol/render/canvas/ReplayGroup} replayGroup Replay group.\n   * @return {boolean} `true` if an image is loading.\n   */\n  renderFeature(feature, resolution, pixelRatio, styles, replayGroup) {\n    if (!styles) {\n      return false;\n    }\n    let loading = false;\n    if (Array.isArray(styles)) {\n      for (let i = 0, ii = styles.length; i < ii; ++i) {\n        loading = renderFeature(\n          replayGroup, feature, styles[i],\n          getSquaredRenderTolerance(resolution, pixelRatio),\n          this.handleStyleImageChange_, this) || loading;\n      }\n    } else {\n      loading = renderFeature(\n        replayGroup, feature, styles,\n        getSquaredRenderTolerance(resolution, pixelRatio),\n        this.handleStyleImageChange_, this);\n    }\n    return loading;\n  }\n}\n\n\n/**\n * Determine if this renderer handles the provided layer.\n * @param {module:ol/layer/Layer} layer The candidate layer.\n * @return {boolean} The renderer can render the layer.\n */\nCanvasVectorLayerRenderer['handles'] = function(layer) {\n  return layer.getType() === LayerType.VECTOR;\n};\n\n\n/**\n * Create a layer renderer.\n * @param {module:ol/renderer/Map} mapRenderer The map renderer.\n * @param {module:ol/layer/Layer} layer The layer to be rendererd.\n * @return {module:ol/renderer/canvas/VectorLayer} The layer renderer.\n */\nCanvasVectorLayerRenderer['create'] = function(mapRenderer, layer) {\n  return new CanvasVectorLayerRenderer(/** @type {module:ol/layer/Vector} */ (layer));\n};\n\n\nexport default CanvasVectorLayerRenderer;\n","/**\n * @module ol/layer/VectorTileRenderType\n */\n\n/**\n * @enum {string}\n * Render mode for vector tiles:\n *  * `'image'`: Vector tiles are rendered as images. Great performance, but\n *    point symbols and texts are always rotated with the view and pixels are\n *    scaled during zoom animations.\n *  * `'hybrid'`: Polygon and line elements are rendered as images, so pixels\n *    are scaled during zoom animations. Point symbols and texts are accurately\n *    rendered as vectors and can stay upright on rotated views.\n *  * `'vector'`: Vector tiles are rendered as vectors. Most accurate rendering\n *    even during animations, but slower performance than the other options.\n * @api\n */\nexport default {\n  IMAGE: 'image',\n  HYBRID: 'hybrid',\n  VECTOR: 'vector'\n};\n","/**\n * @module ol/renderer/canvas/VectorTileLayer\n */\nimport {getUid} from '../../util.js';\nimport LayerType from '../../LayerType.js';\nimport TileState from '../../TileState.js';\nimport {createCanvasContext2D} from '../../dom.js';\nimport {listen, unlisten} from '../../events.js';\nimport EventType from '../../events/EventType.js';\nimport rbush from 'rbush';\nimport {buffer, containsCoordinate, equals, getIntersection, getTopLeft, intersects} from '../../extent.js';\nimport VectorTileRenderType from '../../layer/VectorTileRenderType.js';\nimport {equivalent as equivalentProjection} from '../../proj.js';\nimport Units from '../../proj/Units.js';\nimport ReplayType from '../../render/ReplayType.js';\nimport {labelCache, rotateAtOffset} from '../../render/canvas.js';\nimport CanvasReplayGroup, {replayDeclutter} from '../../render/canvas/ReplayGroup.js';\nimport {ORDER} from '../../render/replay.js';\nimport CanvasTileLayerRenderer from '../canvas/TileLayer.js';\nimport {getSquaredTolerance as getSquaredRenderTolerance, renderFeature} from '../vector.js';\nimport {\n  create as createTransform,\n  compose as composeTransform,\n  reset as resetTransform,\n  scale as scaleTransform,\n  translate as translateTransform\n} from '../../transform.js';\n\n\n/**\n * @type {!Object.<string, Array.<module:ol/render/ReplayType>>}\n */\nconst IMAGE_REPLAYS = {\n  'image': [ReplayType.POLYGON, ReplayType.CIRCLE,\n    ReplayType.LINE_STRING, ReplayType.IMAGE, ReplayType.TEXT],\n  'hybrid': [ReplayType.POLYGON, ReplayType.LINE_STRING]\n};\n\n\n/**\n * @type {!Object.<string, Array.<module:ol/render/ReplayType>>}\n */\nconst VECTOR_REPLAYS = {\n  'image': [ReplayType.DEFAULT],\n  'hybrid': [ReplayType.IMAGE, ReplayType.TEXT, ReplayType.DEFAULT],\n  'vector': ORDER\n};\n\n\n/**\n * @classdesc\n * Canvas renderer for vector tile layers.\n * @api\n */\nclass CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {\n\n  /**\n   * @param {module:ol/layer/VectorTile} layer VectorTile layer.\n   */\n  constructor(layer) {\n\n    super(layer, true);\n\n    /**\n     * Declutter tree.\n     * @private\n     */\n    this.declutterTree_ = layer.getDeclutter() ? rbush(9, undefined) : null;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.dirty_ = false;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.renderedLayerRevision_;\n\n    /**\n     * @private\n     * @type {module:ol/transform~Transform}\n     */\n    this.tmpTransform_ = createTransform();\n\n    // Use lower resolution for pure vector rendering. Closest resolution otherwise.\n    this.zDirection = layer.getRenderMode() == VectorTileRenderType.VECTOR ? 1 : 0;\n\n    listen(labelCache, EventType.CLEAR, this.handleFontsChanged_, this);\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  disposeInternal() {\n    unlisten(labelCache, EventType.CLEAR, this.handleFontsChanged_, this);\n    CanvasTileLayerRenderer.prototype.disposeInternal.call(this);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getTile(z, x, y, pixelRatio, projection) {\n    const tile = CanvasTileLayerRenderer.prototype.getTile.call(this, z, x, y, pixelRatio, projection);\n    if (tile.getState() === TileState.LOADED) {\n      this.createReplayGroup_(tile, pixelRatio, projection);\n      if (this.context) {\n        this.renderTileImage_(tile, pixelRatio, projection);\n      }\n    }\n    return tile;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  prepareFrame(frameState, layerState) {\n    const layer = this.getLayer();\n    const layerRevision = layer.getRevision();\n    if (this.renderedLayerRevision_ != layerRevision) {\n      this.renderedTiles.length = 0;\n      const renderMode = layer.getRenderMode();\n      if (!this.context && renderMode != VectorTileRenderType.VECTOR) {\n        this.context = createCanvasContext2D();\n      }\n      if (this.context && renderMode == VectorTileRenderType.VECTOR) {\n        this.context = null;\n      }\n    }\n    this.renderedLayerRevision_ = layerRevision;\n    return CanvasTileLayerRenderer.prototype.prepareFrame.apply(this, arguments);\n  }\n\n  /**\n   * @param {module:ol/VectorImageTile} tile Tile.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @private\n   */\n  createReplayGroup_(tile, pixelRatio, projection) {\n    const layer = this.getLayer();\n    const revision = layer.getRevision();\n    const renderOrder = /** @type {module:ol/render~OrderFunction} */ (layer.getRenderOrder()) || null;\n\n    const replayState = tile.getReplayState(layer);\n    if (!replayState.dirty && replayState.renderedRevision == revision &&\n        replayState.renderedRenderOrder == renderOrder) {\n      return;\n    }\n\n    const source = /** @type {module:ol/source/VectorTile} */ (layer.getSource());\n    const sourceTileGrid = source.getTileGrid();\n    const tileGrid = source.getTileGridForProjection(projection);\n    const resolution = tileGrid.getResolution(tile.tileCoord[0]);\n    const tileExtent = tile.extent;\n\n    const zIndexKeys = {};\n    for (let t = 0, tt = tile.tileKeys.length; t < tt; ++t) {\n      const sourceTile = tile.getTile(tile.tileKeys[t]);\n      if (sourceTile.getState() != TileState.LOADED) {\n        continue;\n      }\n\n      const sourceTileCoord = sourceTile.tileCoord;\n      const sourceTileExtent = sourceTileGrid.getTileCoordExtent(sourceTileCoord);\n      const sharedExtent = getIntersection(tileExtent, sourceTileExtent);\n      const bufferedExtent = equals(sourceTileExtent, sharedExtent) ? null :\n        buffer(sharedExtent, layer.getRenderBuffer() * resolution, this.tmpExtent);\n      const tileProjection = sourceTile.getProjection();\n      let reproject = false;\n      if (!equivalentProjection(projection, tileProjection)) {\n        reproject = true;\n        sourceTile.setProjection(projection);\n      }\n      replayState.dirty = false;\n      const replayGroup = new CanvasReplayGroup(0, sharedExtent, resolution,\n        pixelRatio, source.getOverlaps(), this.declutterTree_, layer.getRenderBuffer());\n      const squaredTolerance = getSquaredRenderTolerance(resolution, pixelRatio);\n\n      /**\n       * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n       * @this {module:ol/renderer/canvas/VectorTileLayer}\n       */\n      const render = function(feature) {\n        let styles;\n        const styleFunction = feature.getStyleFunction() || layer.getStyleFunction();\n        if (styleFunction) {\n          styles = styleFunction(feature, resolution);\n        }\n        if (styles) {\n          const dirty = this.renderFeature(feature, squaredTolerance, styles, replayGroup);\n          this.dirty_ = this.dirty_ || dirty;\n          replayState.dirty = replayState.dirty || dirty;\n        }\n      };\n\n      const features = sourceTile.getFeatures();\n      if (renderOrder && renderOrder !== replayState.renderedRenderOrder) {\n        features.sort(renderOrder);\n      }\n      for (let i = 0, ii = features.length; i < ii; ++i) {\n        const feature = features[i];\n        if (reproject) {\n          if (tileProjection.getUnits() == Units.TILE_PIXELS) {\n            // projected tile extent\n            tileProjection.setWorldExtent(sourceTileExtent);\n            // tile extent in tile pixel space\n            tileProjection.setExtent(sourceTile.getExtent());\n          }\n          feature.getGeometry().transform(tileProjection, projection);\n        }\n        if (!bufferedExtent || intersects(bufferedExtent, feature.getGeometry().getExtent())) {\n          render.call(this, feature);\n        }\n      }\n      replayGroup.finish();\n      for (const r in replayGroup.getReplays()) {\n        zIndexKeys[r] = true;\n      }\n      sourceTile.setReplayGroup(layer, tile.tileCoord.toString(), replayGroup);\n    }\n    replayState.renderedRevision = revision;\n    replayState.renderedRenderOrder = renderOrder;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback, thisArg) {\n    const resolution = frameState.viewState.resolution;\n    const rotation = frameState.viewState.rotation;\n    hitTolerance = hitTolerance == undefined ? 0 : hitTolerance;\n    const layer = this.getLayer();\n    /** @type {!Object.<string, boolean>} */\n    const features = {};\n\n    /** @type {Array.<module:ol/VectorImageTile>} */\n    const renderedTiles = this.renderedTiles;\n\n    let bufferedExtent, found;\n    let i, ii, replayGroup;\n    for (i = 0, ii = renderedTiles.length; i < ii; ++i) {\n      const tile = renderedTiles[i];\n      bufferedExtent = buffer(tile.extent, hitTolerance * resolution, bufferedExtent);\n      if (!containsCoordinate(bufferedExtent, coordinate)) {\n        continue;\n      }\n      for (let t = 0, tt = tile.tileKeys.length; t < tt; ++t) {\n        const sourceTile = tile.getTile(tile.tileKeys[t]);\n        if (sourceTile.getState() != TileState.LOADED) {\n          continue;\n        }\n        replayGroup = sourceTile.getReplayGroup(layer, tile.tileCoord.toString());\n        found = found || replayGroup.forEachFeatureAtCoordinate(coordinate, resolution, rotation, hitTolerance, {},\n          /**\n           * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n           * @return {?} Callback result.\n           */\n          function(feature) {\n            const key = getUid(feature).toString();\n            if (!(key in features)) {\n              features[key] = true;\n              return callback.call(thisArg, feature, layer);\n            }\n          }, null);\n      }\n    }\n    return found;\n  }\n\n  /**\n   * @param {module:ol/VectorTile} tile Tile.\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @return {module:ol/transform~Transform} transform Transform.\n   * @private\n   */\n  getReplayTransform_(tile, frameState) {\n    const layer = this.getLayer();\n    const source = /** @type {module:ol/source/VectorTile} */ (layer.getSource());\n    const tileGrid = source.getTileGrid();\n    const tileCoord = tile.tileCoord;\n    const tileResolution = tileGrid.getResolution(tileCoord[0]);\n    const viewState = frameState.viewState;\n    const pixelRatio = frameState.pixelRatio;\n    const renderResolution = viewState.resolution / pixelRatio;\n    const tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent);\n    const center = viewState.center;\n    const origin = getTopLeft(tileExtent);\n    const size = frameState.size;\n    const offsetX = Math.round(pixelRatio * size[0] / 2);\n    const offsetY = Math.round(pixelRatio * size[1] / 2);\n    return composeTransform(this.tmpTransform_,\n      offsetX, offsetY,\n      tileResolution / renderResolution, tileResolution / renderResolution,\n      viewState.rotation,\n      (origin[0] - center[0]) / tileResolution,\n      (center[1] - origin[1]) / tileResolution);\n  }\n\n  /**\n   * @param {module:ol/events/Event} event Event.\n   */\n  handleFontsChanged_(event) {\n    const layer = this.getLayer();\n    if (layer.getVisible() && this.renderedLayerRevision_ !== undefined) {\n      layer.changed();\n    }\n  }\n\n  /**\n   * Handle changes in image style state.\n   * @param {module:ol/events/Event} event Image style change event.\n   * @private\n   */\n  handleStyleImageChange_(event) {\n    this.renderIfReadyAndVisible();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  postCompose(context, frameState, layerState) {\n    const layer = this.getLayer();\n    const renderMode = layer.getRenderMode();\n    if (renderMode != VectorTileRenderType.IMAGE) {\n      const declutterReplays = layer.getDeclutter() ? {} : null;\n      const source = /** @type {module:ol/source/VectorTile} */ (layer.getSource());\n      const replayTypes = VECTOR_REPLAYS[renderMode];\n      const pixelRatio = frameState.pixelRatio;\n      const rotation = frameState.viewState.rotation;\n      const size = frameState.size;\n      let offsetX, offsetY;\n      if (rotation) {\n        offsetX = Math.round(pixelRatio * size[0] / 2);\n        offsetY = Math.round(pixelRatio * size[1] / 2);\n        rotateAtOffset(context, -rotation, offsetX, offsetY);\n      }\n      if (declutterReplays) {\n        this.declutterTree_.clear();\n      }\n      const tiles = this.renderedTiles;\n      const tileGrid = source.getTileGridForProjection(frameState.viewState.projection);\n      const clips = [];\n      const zs = [];\n      for (let i = tiles.length - 1; i >= 0; --i) {\n        const tile = /** @type {module:ol/VectorImageTile} */ (tiles[i]);\n        if (tile.getState() == TileState.ABORT) {\n          continue;\n        }\n        const tileCoord = tile.tileCoord;\n        const worldOffset = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent)[0] - tile.extent[0];\n        let transform = undefined;\n        for (let t = 0, tt = tile.tileKeys.length; t < tt; ++t) {\n          const sourceTile = tile.getTile(tile.tileKeys[t]);\n          if (sourceTile.getState() != TileState.LOADED) {\n            continue;\n          }\n          const replayGroup = sourceTile.getReplayGroup(layer, tileCoord.toString());\n          if (!replayGroup || !replayGroup.hasReplays(replayTypes)) {\n            // sourceTile was not yet loaded when this.createReplayGroup_() was\n            // called, or it has no replays of the types we want to render\n            continue;\n          }\n          if (!transform) {\n            transform = this.getTransform(frameState, worldOffset);\n          }\n          const currentZ = sourceTile.tileCoord[0];\n          const currentClip = replayGroup.getClipCoords(transform);\n          context.save();\n          context.globalAlpha = layerState.opacity;\n          // Create a clip mask for regions in this low resolution tile that are\n          // already filled by a higher resolution tile\n          for (let j = 0, jj = clips.length; j < jj; ++j) {\n            const clip = clips[j];\n            if (currentZ < zs[j]) {\n              context.beginPath();\n              // counter-clockwise (outer ring) for current tile\n              context.moveTo(currentClip[0], currentClip[1]);\n              context.lineTo(currentClip[2], currentClip[3]);\n              context.lineTo(currentClip[4], currentClip[5]);\n              context.lineTo(currentClip[6], currentClip[7]);\n              // clockwise (inner ring) for higher resolution tile\n              context.moveTo(clip[6], clip[7]);\n              context.lineTo(clip[4], clip[5]);\n              context.lineTo(clip[2], clip[3]);\n              context.lineTo(clip[0], clip[1]);\n              context.clip();\n            }\n          }\n          replayGroup.replay(context, transform, rotation, {}, replayTypes, declutterReplays);\n          context.restore();\n          clips.push(currentClip);\n          zs.push(currentZ);\n        }\n      }\n      if (declutterReplays) {\n        replayDeclutter(declutterReplays, context, rotation);\n      }\n      if (rotation) {\n        rotateAtOffset(context, rotation,\n          /** @type {number} */ (offsetX), /** @type {number} */ (offsetY));\n      }\n    }\n    CanvasTileLayerRenderer.prototype.postCompose.apply(this, arguments);\n  }\n\n  /**\n   * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n   * @param {number} squaredTolerance Squared tolerance.\n   * @param {(module:ol/style/Style|Array.<module:ol/style/Style>)} styles The style or array of styles.\n   * @param {module:ol/render/canvas/ReplayGroup} replayGroup Replay group.\n   * @return {boolean} `true` if an image is loading.\n   */\n  renderFeature(feature, squaredTolerance, styles, replayGroup) {\n    if (!styles) {\n      return false;\n    }\n    let loading = false;\n    if (Array.isArray(styles)) {\n      for (let i = 0, ii = styles.length; i < ii; ++i) {\n        loading = renderFeature(\n          replayGroup, feature, styles[i], squaredTolerance,\n          this.handleStyleImageChange_, this) || loading;\n      }\n    } else {\n      loading = renderFeature(\n        replayGroup, feature, styles, squaredTolerance,\n        this.handleStyleImageChange_, this);\n    }\n    return loading;\n  }\n\n  /**\n   * @param {module:ol/VectorImageTile} tile Tile.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @private\n   */\n  renderTileImage_(tile, pixelRatio, projection) {\n    const layer = this.getLayer();\n    const replayState = tile.getReplayState(layer);\n    const revision = layer.getRevision();\n    const replays = IMAGE_REPLAYS[layer.getRenderMode()];\n    if (replays && replayState.renderedTileRevision !== revision) {\n      replayState.renderedTileRevision = revision;\n      const tileCoord = tile.wrappedTileCoord;\n      const z = tileCoord[0];\n      const source = /** @type {module:ol/source/VectorTile} */ (layer.getSource());\n      const tileGrid = source.getTileGridForProjection(projection);\n      const resolution = tileGrid.getResolution(z);\n      const context = tile.getContext(layer);\n      const size = source.getTilePixelSize(z, pixelRatio, projection);\n      context.canvas.width = size[0];\n      context.canvas.height = size[1];\n      const tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent);\n      for (let i = 0, ii = tile.tileKeys.length; i < ii; ++i) {\n        const sourceTile = tile.getTile(tile.tileKeys[i]);\n        if (sourceTile.getState() != TileState.LOADED) {\n          continue;\n        }\n        const pixelScale = pixelRatio / resolution;\n        const transform = resetTransform(this.tmpTransform_);\n        scaleTransform(transform, pixelScale, -pixelScale);\n        translateTransform(transform, -tileExtent[0], -tileExtent[3]);\n        const replayGroup = sourceTile.getReplayGroup(layer, tile.tileCoord.toString());\n        replayGroup.replay(context, transform, 0, {}, replays);\n      }\n    }\n  }\n}\n\n\n/**\n * Determine if this renderer handles the provided layer.\n * @param {module:ol/layer/Layer} layer The candidate layer.\n * @return {boolean} The renderer can render the layer.\n */\nCanvasVectorTileLayerRenderer['handles'] = function(layer) {\n  return layer.getType() === LayerType.VECTOR_TILE;\n};\n\n\n/**\n * Create a layer renderer.\n * @param {module:ol/renderer/Map} mapRenderer The map renderer.\n * @param {module:ol/layer/Layer} layer The layer to be rendererd.\n * @return {module:ol/renderer/canvas/VectorTileLayer} The layer renderer.\n */\nCanvasVectorTileLayerRenderer['create'] = function(mapRenderer, layer) {\n  return new CanvasVectorTileLayerRenderer(/** @type {module:ol/layer/VectorTile} */ (layer));\n};\n\n\nexport default CanvasVectorTileLayerRenderer;\n","/**\n * @module ol/Map\n */\nimport PluggableMap from './PluggableMap.js';\nimport {defaults as defaultControls} from './control/util.js';\nimport {defaults as defaultInteractions} from './interaction.js';\nimport {assign} from './obj.js';\nimport CanvasImageLayerRenderer from './renderer/canvas/ImageLayer.js';\nimport CanvasMapRenderer from './renderer/canvas/Map.js';\nimport CanvasTileLayerRenderer from './renderer/canvas/TileLayer.js';\nimport CanvasVectorLayerRenderer from './renderer/canvas/VectorLayer.js';\nimport CanvasVectorTileLayerRenderer from './renderer/canvas/VectorTileLayer.js';\n\n/**\n * @classdesc\n * The map is the core component of OpenLayers. For a map to render, a view,\n * one or more layers, and a target container are needed:\n *\n *     import Map from 'ol/Map';\n *     import View from 'ol/View';\n *     import TileLayer from 'ol/layer/Tile';\n *     import OSM from 'ol/source/OSM';\n *\n *     var map = new Map({\n *       view: new View({\n *         center: [0, 0],\n *         zoom: 1\n *       }),\n *       layers: [\n *         new TileLayer({\n *           source: new OSM()\n *         })\n *       ],\n *       target: 'map'\n *     });\n *\n * The above snippet creates a map using a {@link module:ol/layer/Tile} to\n * display {@link module:ol/source/OSM~OSM} OSM data and render it to a DOM\n * element with the id `map`.\n *\n * The constructor places a viewport container (with CSS class name\n * `ol-viewport`) in the target element (see `getViewport()`), and then two\n * further elements within the viewport: one with CSS class name\n * `ol-overlaycontainer-stopevent` for controls and some overlays, and one with\n * CSS class name `ol-overlaycontainer` for other overlays (see the `stopEvent`\n * option of {@link module:ol/Overlay~Overlay} for the difference). The map\n * itself is placed in a further element within the viewport.\n *\n * Layers are stored as a {@link module:ol/Collection~Collection} in\n * layerGroups. A top-level group is provided by the library. This is what is\n * accessed by `getLayerGroup` and `setLayerGroup`. Layers entered in the\n * options are added to this group, and `addLayer` and `removeLayer` change the\n * layer collection in the group. `getLayers` is a convenience function for\n * `getLayerGroup().getLayers()`. Note that {@link module:ol/layer/Group~Group}\n * is a subclass of {@link module:ol/layer/Base}, so layers entered in the\n * options or added with `addLayer` can be groups, which can contain further\n * groups, and so on.\n *\n * @fires module:ol/MapBrowserEvent~MapBrowserEvent\n * @fires module:ol/MapEvent~MapEvent\n * @fires module:ol/render/Event~RenderEvent#postcompose\n * @fires module:ol/render/Event~RenderEvent#precompose\n * @api\n */\nclass Map extends PluggableMap {\n\n  /**\n   * @param {module:ol/PluggableMap~MapOptions} options Map options.\n   */\n  constructor(options) {\n    options = assign({}, options);\n    if (!options.controls) {\n      options.controls = defaultControls();\n    }\n    if (!options.interactions) {\n      options.interactions = defaultInteractions();\n    }\n\n    super(options);\n  }\n\n  createRenderer() {\n    const renderer = new CanvasMapRenderer(this);\n    renderer.registerLayerRenderers([\n      CanvasImageLayerRenderer,\n      CanvasTileLayerRenderer,\n      CanvasVectorLayerRenderer,\n      CanvasVectorTileLayerRenderer\n    ]);\n    return renderer;\n  }\n}\n\n\nexport default Map;\n","/**\n * @module ol/control/FullScreen\n */\nimport Control from '../control/Control.js';\nimport {CLASS_CONTROL, CLASS_UNSELECTABLE, CLASS_UNSUPPORTED} from '../css.js';\nimport {replaceNode} from '../dom.js';\nimport {listen} from '../events.js';\nimport EventType from '../events/EventType.js';\n\n\n/**\n * @return {string} Change type.\n */\nconst getChangeType = (function() {\n  let changeType;\n  return function() {\n    if (!changeType) {\n      const body = document.body;\n      if (body.webkitRequestFullscreen) {\n        changeType = 'webkitfullscreenchange';\n      } else if (body.mozRequestFullScreen) {\n        changeType = 'mozfullscreenchange';\n      } else if (body.msRequestFullscreen) {\n        changeType = 'MSFullscreenChange';\n      } else if (body.requestFullscreen) {\n        changeType = 'fullscreenchange';\n      }\n    }\n    return changeType;\n  };\n})();\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-full-screen'] CSS class name.\n * @property {string|HTMLElement} [label='\\u2922'] Text label to use for the button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string|HTMLElement} [labelActive='\\u00d7'] Text label to use for the\n * button when full-screen is active.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string} [tipLabel='Toggle full-screen'] Text label to use for the button tip.\n * @property {boolean} [keys=false] Full keyboard access.\n * @property {HTMLElement|string} [target] Specify a target if you want the\n * control to be rendered outside of the map's viewport.\n * @property {HTMLElement|string} [source] The element to be displayed\n * fullscreen. When not provided, the element containing the map viewport will\n * be displayed fullscreen.\n */\n\n\n/**\n * @classdesc\n * Provides a button that when clicked fills up the full screen with the map.\n * The full screen source element is by default the element containing the map viewport unless\n * overridden by providing the `source` option. In which case, the dom\n * element introduced using this parameter will be displayed in full screen.\n *\n * When in full screen mode, a close button is shown to exit full screen mode.\n * The [Fullscreen API](http://www.w3.org/TR/fullscreen/) is used to\n * toggle the map in full screen mode.\n *\n * @api\n */\nclass FullScreen extends Control {\n\n  /**\n   * @param {module:ol/control/FullScreen~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options ? opt_options : {};\n\n    super({\n      element: document.createElement('div'),\n      target: options.target\n    });\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.cssClassName_ = options.className !== undefined ? options.className :\n      'ol-full-screen';\n\n    const label = options.label !== undefined ? options.label : '\\u2922';\n\n    /**\n     * @private\n     * @type {HTMLElement}\n     */\n    this.labelNode_ = typeof label === 'string' ?\n      document.createTextNode(label) : label;\n\n    const labelActive = options.labelActive !== undefined ? options.labelActive : '\\u00d7';\n\n    /**\n     * @private\n     * @type {HTMLElement}\n     */\n    this.labelActiveNode_ = typeof labelActive === 'string' ?\n      document.createTextNode(labelActive) : labelActive;\n\n    const tipLabel = options.tipLabel ? options.tipLabel : 'Toggle full-screen';\n    const button = document.createElement('button');\n    button.className = this.cssClassName_ + '-' + isFullScreen();\n    button.setAttribute('type', 'button');\n    button.title = tipLabel;\n    button.appendChild(this.labelNode_);\n\n    listen(button, EventType.CLICK,\n      this.handleClick_, this);\n\n    const cssClasses = this.cssClassName_ + ' ' + CLASS_UNSELECTABLE +\n        ' ' + CLASS_CONTROL + ' ' +\n        (!isFullScreenSupported() ? CLASS_UNSUPPORTED : '');\n    const element = this.element;\n    element.className = cssClasses;\n    element.appendChild(button);\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.keys_ = options.keys !== undefined ? options.keys : false;\n\n    /**\n     * @private\n     * @type {HTMLElement|string|undefined}\n     */\n    this.source_ = options.source;\n\n  }\n\n  /**\n   * @param {MouseEvent} event The event to handle\n   * @private\n   */\n  handleClick_(event) {\n    event.preventDefault();\n    this.handleFullScreen_();\n  }\n\n  /**\n   * @private\n   */\n  handleFullScreen_() {\n    if (!isFullScreenSupported()) {\n      return;\n    }\n    const map = this.getMap();\n    if (!map) {\n      return;\n    }\n    if (isFullScreen()) {\n      exitFullScreen();\n    } else {\n      let element;\n      if (this.source_) {\n        element = typeof this.source_ === 'string' ?\n          document.getElementById(this.source_) :\n          this.source_;\n      } else {\n        element = map.getTargetElement();\n      }\n      if (this.keys_) {\n        requestFullScreenWithKeys(element);\n\n      } else {\n        requestFullScreen(element);\n      }\n    }\n  }\n\n  /**\n   * @private\n   */\n  handleFullScreenChange_() {\n    const button = this.element.firstElementChild;\n    const map = this.getMap();\n    if (isFullScreen()) {\n      button.className = this.cssClassName_ + '-true';\n      replaceNode(this.labelActiveNode_, this.labelNode_);\n    } else {\n      button.className = this.cssClassName_ + '-false';\n      replaceNode(this.labelNode_, this.labelActiveNode_);\n    }\n    if (map) {\n      map.updateSize();\n    }\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  setMap(map) {\n    super.setMap(map);\n    if (map) {\n      this.listenerKeys.push(listen(document,\n        getChangeType(),\n        this.handleFullScreenChange_, this)\n      );\n    }\n  }\n}\n\n\n/**\n * @return {boolean} Fullscreen is supported by the current platform.\n */\nfunction isFullScreenSupported() {\n  const body = document.body;\n  return !!(\n    body.webkitRequestFullscreen ||\n    (body.mozRequestFullScreen && document.mozFullScreenEnabled) ||\n    (body.msRequestFullscreen && document.msFullscreenEnabled) ||\n    (body.requestFullscreen && document.fullscreenEnabled)\n  );\n}\n\n/**\n * @return {boolean} Element is currently in fullscreen.\n */\nfunction isFullScreen() {\n  return !!(\n    document.webkitIsFullScreen || document.mozFullScreen ||\n    document.msFullscreenElement || document.fullscreenElement\n  );\n}\n\n/**\n * Request to fullscreen an element.\n * @param {HTMLElement} element Element to request fullscreen\n */\nfunction requestFullScreen(element) {\n  if (element.requestFullscreen) {\n    element.requestFullscreen();\n  } else if (element.msRequestFullscreen) {\n    element.msRequestFullscreen();\n  } else if (element.mozRequestFullScreen) {\n    element.mozRequestFullScreen();\n  } else if (element.webkitRequestFullscreen) {\n    element.webkitRequestFullscreen();\n  }\n}\n\n/**\n * Request to fullscreen an element with keyboard input.\n * @param {HTMLElement} element Element to request fullscreen\n */\nfunction requestFullScreenWithKeys(element) {\n  if (element.mozRequestFullScreenWithKeys) {\n    element.mozRequestFullScreenWithKeys();\n  } else if (element.webkitRequestFullscreen) {\n    element.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);\n  } else {\n    requestFullScreen(element);\n  }\n}\n\n/**\n * Exit fullscreen.\n */\nfunction exitFullScreen() {\n  if (document.exitFullscreen) {\n    document.exitFullscreen();\n  } else if (document.msExitFullscreen) {\n    document.msExitFullscreen();\n  } else if (document.mozCancelFullScreen) {\n    document.mozCancelFullScreen();\n  } else if (document.webkitExitFullscreen) {\n    document.webkitExitFullscreen();\n  }\n}\n\nexport default FullScreen;\n","/**\n * @module ol/OverlayPositioning\n */\n\n/**\n * Overlay position: `'bottom-left'`, `'bottom-center'`,  `'bottom-right'`,\n * `'center-left'`, `'center-center'`, `'center-right'`, `'top-left'`,\n * `'top-center'`, `'top-right'`\n * @enum {string}\n */\nexport default {\n  BOTTOM_LEFT: 'bottom-left',\n  BOTTOM_CENTER: 'bottom-center',\n  BOTTOM_RIGHT: 'bottom-right',\n  CENTER_LEFT: 'center-left',\n  CENTER_CENTER: 'center-center',\n  CENTER_RIGHT: 'center-right',\n  TOP_LEFT: 'top-left',\n  TOP_CENTER: 'top-center',\n  TOP_RIGHT: 'top-right'\n};\n","/**\n * @module ol/Overlay\n */\nimport MapEventType from './MapEventType.js';\nimport BaseObject, {getChangeEventType} from './Object.js';\nimport OverlayPositioning from './OverlayPositioning.js';\nimport {CLASS_SELECTABLE} from './css.js';\nimport {removeNode, removeChildren, outerWidth, outerHeight} from './dom.js';\nimport {listen, unlistenByKey} from './events.js';\nimport {containsExtent} from './extent.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {number|string} [id] Set the overlay id. The overlay id can be used\n * with the {@link module:ol/Map~Map#getOverlayById} method.\n * @property {HTMLElement} [element] The overlay element.\n * @property {Array.<number>} [offset=[0, 0]] Offsets in pixels used when positioning\n * the overlay. The first element in the\n * array is the horizontal offset. A positive value shifts the overlay right.\n * The second element in the array is the vertical offset. A positive value\n * shifts the overlay down.\n * @property {module:ol/coordinate~Coordinate} [position] The overlay position\n * in map projection.\n * @property {module:ol/OverlayPositioning} [positioning='top-left'] Defines how\n * the overlay is actually positioned with respect to its `position` property.\n * Possible values are `'bottom-left'`, `'bottom-center'`, `'bottom-right'`,\n * `'center-left'`, `'center-center'`, `'center-right'`, `'top-left'`,\n * `'top-center'`, and `'top-right'`.\n * @property {boolean} [stopEvent=true] Whether event propagation to the map\n * viewport should be stopped. If `true` the overlay is placed in the same\n * container as that of the controls (CSS class name\n * `ol-overlaycontainer-stopevent`); if `false` it is placed in the container\n * with CSS class name specified by the `className` property.\n * @property {boolean} [insertFirst=true] Whether the overlay is inserted first\n * in the overlay container, or appended. If the overlay is placed in the same\n * container as that of the controls (see the `stopEvent` option) you will\n * probably set `insertFirst` to `true` so the overlay is displayed below the\n * controls.\n * @property {boolean} [autoPan=false] If set to `true` the map is panned when\n * calling `setPosition`, so that the overlay is entirely visible in the current\n * viewport.\n * @property {module:ol/Overlay~PanOptions} [autoPanAnimation] The\n * animation options used to pan the overlay into view. This animation is only\n * used when `autoPan` is enabled. A `duration` and `easing` may be provided to\n * customize the animation.\n * @property {number} [autoPanMargin=20] The margin (in pixels) between the\n * overlay and the borders of the map when autopanning.\n * @property {string} [className='ol-overlay-container ol-selectable'] CSS class\n * name.\n */\n\n\n/**\n * @typedef {Object} PanOptions\n * @property {number} [duration=1000] The duration of the animation in\n * milliseconds.\n * @property {function(number):number} [easing] The easing function to use. Can\n * be one from {@link module:ol/easing} or a custom function.\n * Default is {@link module:ol/easing~inAndOut}.\n */\n\n\n/**\n * @enum {string}\n * @protected\n */\nconst Property = {\n  ELEMENT: 'element',\n  MAP: 'map',\n  OFFSET: 'offset',\n  POSITION: 'position',\n  POSITIONING: 'positioning'\n};\n\n\n/**\n * @classdesc\n * An element to be displayed over the map and attached to a single map\n * location.  Like {@link module:ol/control/Control~Control}, Overlays are\n * visible widgets. Unlike Controls, they are not in a fixed position on the\n * screen, but are tied to a geographical coordinate, so panning the map will\n * move an Overlay but not a Control.\n *\n * Example:\n *\n *     import Overlay from 'ol/Overlay';\n *\n *     var popup = new Overlay({\n *       element: document.getElementById('popup')\n *     });\n *     popup.setPosition(coordinate);\n *     map.addOverlay(popup);\n *\n * @api\n */\nclass Overlay extends BaseObject {\n\n  /**\n   * @param {module:ol/Overlay~Options} options Overlay options.\n   */\n  constructor(options) {\n\n    super();\n\n    /**\n     * @protected\n     * @type {module:ol/Overlay~Options}\n     */\n    this.options = options;\n\n    /**\n     * @protected\n     * @type {number|string|undefined}\n     */\n    this.id = options.id;\n\n    /**\n     * @protected\n     * @type {boolean}\n     */\n    this.insertFirst = options.insertFirst !== undefined ?\n      options.insertFirst : true;\n\n    /**\n     * @protected\n     * @type {boolean}\n     */\n    this.stopEvent = options.stopEvent !== undefined ? options.stopEvent : true;\n\n    /**\n     * @protected\n     * @type {HTMLElement}\n     */\n    this.element = document.createElement('DIV');\n    this.element.className = options.className !== undefined ?\n      options.className : 'ol-overlay-container ' + CLASS_SELECTABLE;\n    this.element.style.position = 'absolute';\n\n    /**\n     * @protected\n     * @type {boolean}\n     */\n    this.autoPan = options.autoPan !== undefined ? options.autoPan : false;\n\n    /**\n     * @protected\n     * @type {module:ol/Overlay~PanOptions}\n     */\n    this.autoPanAnimation = options.autoPanAnimation || /** @type {module:ol/Overlay~PanOptions} */ ({});\n\n    /**\n     * @protected\n     * @type {number}\n     */\n    this.autoPanMargin = options.autoPanMargin !== undefined ?\n      options.autoPanMargin : 20;\n\n    /**\n     * @protected\n     * @type {{bottom_: string,\n     *         left_: string,\n     *         right_: string,\n     *         top_: string,\n     *         visible: boolean}}\n     */\n    this.rendered = {\n      bottom_: '',\n      left_: '',\n      right_: '',\n      top_: '',\n      visible: true\n    };\n\n    /**\n     * @protected\n     * @type {?module:ol/events~EventsKey}\n     */\n    this.mapPostrenderListenerKey = null;\n\n    listen(\n      this, getChangeEventType(Property.ELEMENT),\n      this.handleElementChanged, this);\n\n    listen(\n      this, getChangeEventType(Property.MAP),\n      this.handleMapChanged, this);\n\n    listen(\n      this, getChangeEventType(Property.OFFSET),\n      this.handleOffsetChanged, this);\n\n    listen(\n      this, getChangeEventType(Property.POSITION),\n      this.handlePositionChanged, this);\n\n    listen(\n      this, getChangeEventType(Property.POSITIONING),\n      this.handlePositioningChanged, this);\n\n    if (options.element !== undefined) {\n      this.setElement(options.element);\n    }\n\n    this.setOffset(options.offset !== undefined ? options.offset : [0, 0]);\n\n    this.setPositioning(options.positioning !== undefined ?\n      /** @type {module:ol/OverlayPositioning} */ (options.positioning) :\n      OverlayPositioning.TOP_LEFT);\n\n    if (options.position !== undefined) {\n      this.setPosition(options.position);\n    }\n\n  }\n\n  /**\n   * Get the DOM element of this overlay.\n   * @return {HTMLElement|undefined} The Element containing the overlay.\n   * @observable\n   * @api\n   */\n  getElement() {\n    return /** @type {HTMLElement|undefined} */ (this.get(Property.ELEMENT));\n  }\n\n  /**\n   * Get the overlay identifier which is set on constructor.\n   * @return {number|string|undefined} Id.\n   * @api\n   */\n  getId() {\n    return this.id;\n  }\n\n  /**\n   * Get the map associated with this overlay.\n   * @return {module:ol/PluggableMap|undefined} The map that the\n   * overlay is part of.\n   * @observable\n   * @api\n   */\n  getMap() {\n    return (\n      /** @type {module:ol/PluggableMap|undefined} */ (this.get(Property.MAP))\n    );\n  }\n\n  /**\n   * Get the offset of this overlay.\n   * @return {Array.<number>} The offset.\n   * @observable\n   * @api\n   */\n  getOffset() {\n    return /** @type {Array.<number>} */ (this.get(Property.OFFSET));\n  }\n\n  /**\n   * Get the current position of this overlay.\n   * @return {module:ol/coordinate~Coordinate|undefined} The spatial point that the overlay is\n   *     anchored at.\n   * @observable\n   * @api\n   */\n  getPosition() {\n    return (\n      /** @type {module:ol/coordinate~Coordinate|undefined} */ (this.get(Property.POSITION))\n    );\n  }\n\n  /**\n   * Get the current positioning of this overlay.\n   * @return {module:ol/OverlayPositioning} How the overlay is positioned\n   *     relative to its point on the map.\n   * @observable\n   * @api\n   */\n  getPositioning() {\n    return (\n      /** @type {module:ol/OverlayPositioning} */ (this.get(Property.POSITIONING))\n    );\n  }\n\n  /**\n   * @protected\n   */\n  handleElementChanged() {\n    removeChildren(this.element);\n    const element = this.getElement();\n    if (element) {\n      this.element.appendChild(element);\n    }\n  }\n\n  /**\n   * @protected\n   */\n  handleMapChanged() {\n    if (this.mapPostrenderListenerKey) {\n      removeNode(this.element);\n      unlistenByKey(this.mapPostrenderListenerKey);\n      this.mapPostrenderListenerKey = null;\n    }\n    const map = this.getMap();\n    if (map) {\n      this.mapPostrenderListenerKey = listen(map,\n        MapEventType.POSTRENDER, this.render, this);\n      this.updatePixelPosition();\n      const container = this.stopEvent ?\n        map.getOverlayContainerStopEvent() : map.getOverlayContainer();\n      if (this.insertFirst) {\n        container.insertBefore(this.element, container.childNodes[0] || null);\n      } else {\n        container.appendChild(this.element);\n      }\n    }\n  }\n\n  /**\n   * @protected\n   */\n  render() {\n    this.updatePixelPosition();\n  }\n\n  /**\n   * @protected\n   */\n  handleOffsetChanged() {\n    this.updatePixelPosition();\n  }\n\n  /**\n   * @protected\n   */\n  handlePositionChanged() {\n    this.updatePixelPosition();\n    if (this.get(Property.POSITION) && this.autoPan) {\n      this.panIntoView();\n    }\n  }\n\n  /**\n   * @protected\n   */\n  handlePositioningChanged() {\n    this.updatePixelPosition();\n  }\n\n  /**\n   * Set the DOM element to be associated with this overlay.\n   * @param {HTMLElement|undefined} element The Element containing the overlay.\n   * @observable\n   * @api\n   */\n  setElement(element) {\n    this.set(Property.ELEMENT, element);\n  }\n\n  /**\n   * Set the map to be associated with this overlay.\n   * @param {module:ol/PluggableMap|undefined} map The map that the\n   * overlay is part of.\n   * @observable\n   * @api\n   */\n  setMap(map) {\n    this.set(Property.MAP, map);\n  }\n\n  /**\n   * Set the offset for this overlay.\n   * @param {Array.<number>} offset Offset.\n   * @observable\n   * @api\n   */\n  setOffset(offset) {\n    this.set(Property.OFFSET, offset);\n  }\n\n  /**\n   * Set the position for this overlay. If the position is `undefined` the\n   * overlay is hidden.\n   * @param {module:ol/coordinate~Coordinate|undefined} position The spatial point that the overlay\n   *     is anchored at.\n   * @observable\n   * @api\n   */\n  setPosition(position) {\n    this.set(Property.POSITION, position);\n  }\n\n  /**\n   * Pan the map so that the overlay is entirely visible in the current viewport\n   * (if necessary).\n   * @protected\n   */\n  panIntoView() {\n    const map = this.getMap();\n\n    if (!map || !map.getTargetElement()) {\n      return;\n    }\n\n    const mapRect = this.getRect(map.getTargetElement(), map.getSize());\n    const element = this.getElement();\n    const overlayRect = this.getRect(element, [outerWidth(element), outerHeight(element)]);\n\n    const margin = this.autoPanMargin;\n    if (!containsExtent(mapRect, overlayRect)) {\n      // the overlay is not completely inside the viewport, so pan the map\n      const offsetLeft = overlayRect[0] - mapRect[0];\n      const offsetRight = mapRect[2] - overlayRect[2];\n      const offsetTop = overlayRect[1] - mapRect[1];\n      const offsetBottom = mapRect[3] - overlayRect[3];\n\n      const delta = [0, 0];\n      if (offsetLeft < 0) {\n        // move map to the left\n        delta[0] = offsetLeft - margin;\n      } else if (offsetRight < 0) {\n        // move map to the right\n        delta[0] = Math.abs(offsetRight) + margin;\n      }\n      if (offsetTop < 0) {\n        // move map up\n        delta[1] = offsetTop - margin;\n      } else if (offsetBottom < 0) {\n        // move map down\n        delta[1] = Math.abs(offsetBottom) + margin;\n      }\n\n      if (delta[0] !== 0 || delta[1] !== 0) {\n        const center = /** @type {module:ol/coordinate~Coordinate} */ (map.getView().getCenter());\n        const centerPx = map.getPixelFromCoordinate(center);\n        const newCenterPx = [\n          centerPx[0] + delta[0],\n          centerPx[1] + delta[1]\n        ];\n\n        map.getView().animate({\n          center: map.getCoordinateFromPixel(newCenterPx),\n          duration: this.autoPanAnimation.duration,\n          easing: this.autoPanAnimation.easing\n        });\n      }\n    }\n  }\n\n  /**\n   * Get the extent of an element relative to the document\n   * @param {HTMLElement|undefined} element The element.\n   * @param {module:ol/size~Size|undefined} size The size of the element.\n   * @return {module:ol/extent~Extent} The extent.\n   * @protected\n   */\n  getRect(element, size) {\n    const box = element.getBoundingClientRect();\n    const offsetX = box.left + window.pageXOffset;\n    const offsetY = box.top + window.pageYOffset;\n    return [\n      offsetX,\n      offsetY,\n      offsetX + size[0],\n      offsetY + size[1]\n    ];\n  }\n\n  /**\n   * Set the positioning for this overlay.\n   * @param {module:ol/OverlayPositioning} positioning how the overlay is\n   *     positioned relative to its point on the map.\n   * @observable\n   * @api\n   */\n  setPositioning(positioning) {\n    this.set(Property.POSITIONING, positioning);\n  }\n\n  /**\n   * Modify the visibility of the element.\n   * @param {boolean} visible Element visibility.\n   * @protected\n   */\n  setVisible(visible) {\n    if (this.rendered.visible !== visible) {\n      this.element.style.display = visible ? '' : 'none';\n      this.rendered.visible = visible;\n    }\n  }\n\n  /**\n   * Update pixel position.\n   * @protected\n   */\n  updatePixelPosition() {\n    const map = this.getMap();\n    const position = this.getPosition();\n    if (!map || !map.isRendered() || !position) {\n      this.setVisible(false);\n      return;\n    }\n\n    const pixel = map.getPixelFromCoordinate(position);\n    const mapSize = map.getSize();\n    this.updateRenderedPosition(pixel, mapSize);\n  }\n\n  /**\n   * @param {module:ol/pixel~Pixel} pixel The pixel location.\n   * @param {module:ol/size~Size|undefined} mapSize The map size.\n   * @protected\n   */\n  updateRenderedPosition(pixel, mapSize) {\n    const style = this.element.style;\n    const offset = this.getOffset();\n\n    const positioning = this.getPositioning();\n\n    this.setVisible(true);\n\n    let offsetX = offset[0];\n    let offsetY = offset[1];\n    if (positioning == OverlayPositioning.BOTTOM_RIGHT ||\n        positioning == OverlayPositioning.CENTER_RIGHT ||\n        positioning == OverlayPositioning.TOP_RIGHT) {\n      if (this.rendered.left_ !== '') {\n        this.rendered.left_ = style.left = '';\n      }\n      const right = Math.round(mapSize[0] - pixel[0] - offsetX) + 'px';\n      if (this.rendered.right_ != right) {\n        this.rendered.right_ = style.right = right;\n      }\n    } else {\n      if (this.rendered.right_ !== '') {\n        this.rendered.right_ = style.right = '';\n      }\n      if (positioning == OverlayPositioning.BOTTOM_CENTER ||\n          positioning == OverlayPositioning.CENTER_CENTER ||\n          positioning == OverlayPositioning.TOP_CENTER) {\n        offsetX -= this.element.offsetWidth / 2;\n      }\n      const left = Math.round(pixel[0] + offsetX) + 'px';\n      if (this.rendered.left_ != left) {\n        this.rendered.left_ = style.left = left;\n      }\n    }\n    if (positioning == OverlayPositioning.BOTTOM_LEFT ||\n        positioning == OverlayPositioning.BOTTOM_CENTER ||\n        positioning == OverlayPositioning.BOTTOM_RIGHT) {\n      if (this.rendered.top_ !== '') {\n        this.rendered.top_ = style.top = '';\n      }\n      const bottom = Math.round(mapSize[1] - pixel[1] - offsetY) + 'px';\n      if (this.rendered.bottom_ != bottom) {\n        this.rendered.bottom_ = style.bottom = bottom;\n      }\n    } else {\n      if (this.rendered.bottom_ !== '') {\n        this.rendered.bottom_ = style.bottom = '';\n      }\n      if (positioning == OverlayPositioning.CENTER_LEFT ||\n          positioning == OverlayPositioning.CENTER_CENTER ||\n          positioning == OverlayPositioning.CENTER_RIGHT) {\n        offsetY -= this.element.offsetHeight / 2;\n      }\n      const top = Math.round(pixel[1] + offsetY) + 'px';\n      if (this.rendered.top_ != top) {\n        this.rendered.top_ = style.top = top;\n      }\n    }\n  }\n\n  /**\n   * returns the options this Overlay has been created with\n   * @return {module:ol/Overlay~Options} overlay options\n   */\n  getOptions() {\n    return this.options;\n  }\n}\n\n\nexport default Overlay;\n","/**\n * @module ol/VectorTile\n */\nimport {getUid} from './util.js';\nimport Tile from './Tile.js';\nimport TileState from './TileState.js';\n\n/**\n * @const\n * @type {module:ol/extent~Extent}\n */\nconst DEFAULT_EXTENT = [0, 0, 4096, 4096];\n\n\n/**\n * @typedef {function(new: module:ol/VectorTile, module:ol/tilecoord~TileCoord,\n * module:ol/TileState, string, ?string, module:ol/Tile~LoadFunction)} TileClass\n * @api\n */\n\nclass VectorTile extends Tile {\n\n  /**\n   * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n   * @param {module:ol/TileState} state State.\n   * @param {string} src Data source url.\n   * @param {module:ol/format/Feature} format Feature format.\n   * @param {module:ol/Tile~LoadFunction} tileLoadFunction Tile load function.\n   * @param {module:ol/Tile~Options=} opt_options Tile options.\n   */\n  constructor(tileCoord, state, src, format, tileLoadFunction, opt_options) {\n\n    super(tileCoord, state, opt_options);\n\n    /**\n     * @type {number}\n     */\n    this.consumers = 0;\n\n    /**\n     * @private\n     * @type {module:ol/extent~Extent}\n     */\n    this.extent_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/format/Feature}\n     */\n    this.format_ = format;\n\n    /**\n     * @private\n     * @type {Array.<module:ol/Feature>}\n     */\n    this.features_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/featureloader~FeatureLoader}\n     */\n    this.loader_;\n\n    /**\n     * Data projection\n     * @private\n     * @type {module:ol/proj/Projection}\n     */\n    this.projection_ = null;\n\n    /**\n     * @private\n     * @type {Object.<string, module:ol/render/ReplayGroup>}\n     */\n    this.replayGroups_ = {};\n\n    /**\n     * @private\n     * @type {module:ol/Tile~LoadFunction}\n     */\n    this.tileLoadFunction_ = tileLoadFunction;\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.url_ = src;\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  disposeInternal() {\n    this.features_ = null;\n    this.replayGroups_ = {};\n    this.state = TileState.ABORT;\n    this.changed();\n    super.disposeInternal();\n  }\n\n  /**\n   * Gets the extent of the vector tile.\n   * @return {module:ol/extent~Extent} The extent.\n   * @api\n   */\n  getExtent() {\n    return this.extent_ || DEFAULT_EXTENT;\n  }\n\n  /**\n   * Get the feature format assigned for reading this tile's features.\n   * @return {module:ol/format/Feature} Feature format.\n   * @api\n   */\n  getFormat() {\n    return this.format_;\n  }\n\n  /**\n   * Get the features for this tile. Geometries will be in the projection returned\n   * by {@link module:ol/VectorTile~VectorTile#getProjection}.\n   * @return {Array.<module:ol/Feature|module:ol/render/Feature>} Features.\n   * @api\n   */\n  getFeatures() {\n    return this.features_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getKey() {\n    return this.url_;\n  }\n\n  /**\n   * Get the feature projection of features returned by\n   * {@link module:ol/VectorTile~VectorTile#getFeatures}.\n   * @return {module:ol/proj/Projection} Feature projection.\n   * @api\n   */\n  getProjection() {\n    return this.projection_;\n  }\n\n  /**\n   * @param {module:ol/layer/Layer} layer Layer.\n   * @param {string} key Key.\n   * @return {module:ol/render/ReplayGroup} Replay group.\n   */\n  getReplayGroup(layer, key) {\n    return this.replayGroups_[getUid(layer) + ',' + key];\n  }\n\n  /**\n   * @inheritDoc\n   */\n  load() {\n    if (this.state == TileState.IDLE) {\n      this.setState(TileState.LOADING);\n      this.tileLoadFunction_(this, this.url_);\n      this.loader_(null, NaN, null);\n    }\n  }\n\n  /**\n   * Handler for successful tile load.\n   * @param {Array.<module:ol/Feature>} features The loaded features.\n   * @param {module:ol/proj/Projection} dataProjection Data projection.\n   * @param {module:ol/extent~Extent} extent Extent.\n   */\n  onLoad(features, dataProjection, extent) {\n    this.setProjection(dataProjection);\n    this.setFeatures(features);\n    this.setExtent(extent);\n  }\n\n  /**\n   * Handler for tile load errors.\n   */\n  onError() {\n    this.setState(TileState.ERROR);\n  }\n\n  /**\n   * Function for use in an {@link module:ol/source/VectorTile~VectorTile}'s\n   * `tileLoadFunction`. Sets the extent of the vector tile. This is only required\n   * for tiles in projections with `tile-pixels` as units. The extent should be\n   * set to `[0, 0, tilePixelSize, tilePixelSize]`, where `tilePixelSize` is\n   * calculated by multiplying the tile size with the tile pixel ratio. For\n   * sources using {@link module:ol/format/MVT~MVT} as feature format, the\n   * {@link module:ol/format/MVT~MVT#getLastExtent} method will return the correct\n   * extent. The default is `[0, 0, 4096, 4096]`.\n   * @param {module:ol/extent~Extent} extent The extent.\n   * @api\n   */\n  setExtent(extent) {\n    this.extent_ = extent;\n  }\n\n  /**\n   * Function for use in an {@link module:ol/source/VectorTile~VectorTile}'s `tileLoadFunction`.\n   * Sets the features for the tile.\n   * @param {Array.<module:ol/Feature>} features Features.\n   * @api\n   */\n  setFeatures(features) {\n    this.features_ = features;\n    this.setState(TileState.LOADED);\n  }\n\n  /**\n   * Function for use in an {@link module:ol/source/VectorTile~VectorTile}'s `tileLoadFunction`.\n   * Sets the projection of the features that were added with\n   * {@link module:ol/VectorTile~VectorTile#setFeatures}.\n   * @param {module:ol/proj/Projection} projection Feature projection.\n   * @api\n   */\n  setProjection(projection) {\n    this.projection_ = projection;\n  }\n\n  /**\n   * @param {module:ol/layer/Layer} layer Layer.\n   * @param {string} key Key.\n   * @param {module:ol/render/ReplayGroup} replayGroup Replay group.\n   */\n  setReplayGroup(layer, key, replayGroup) {\n    this.replayGroups_[getUid(layer) + ',' + key] = replayGroup;\n  }\n\n  /**\n   * Set the feature loader for reading this tile's features.\n   * @param {module:ol/featureloader~FeatureLoader} loader Feature loader.\n   * @api\n   */\n  setLoader(loader) {\n    this.loader_ = loader;\n  }\n}\n\nexport default VectorTile;\n","/**\n * @module ol/control/OverviewMap\n */\nimport Collection from '../Collection.js';\nimport Map from '../Map.js';\nimport MapEventType from '../MapEventType.js';\nimport MapProperty from '../MapProperty.js';\nimport {getChangeEventType} from '../Object.js';\nimport ObjectEventType from '../ObjectEventType.js';\nimport Overlay from '../Overlay.js';\nimport OverlayPositioning from '../OverlayPositioning.js';\nimport ViewProperty from '../ViewProperty.js';\nimport Control from '../control/Control.js';\nimport {rotate as rotateCoordinate, add as addCoordinate} from '../coordinate.js';\nimport {CLASS_CONTROL, CLASS_UNSELECTABLE, CLASS_COLLAPSED} from '../css.js';\nimport {replaceNode} from '../dom.js';\nimport {listen, listenOnce, unlisten} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport {containsExtent, getBottomLeft, getBottomRight, getTopLeft, getTopRight, scaleFromCenter} from '../extent.js';\n\n\n/**\n * Maximum width and/or height extent ratio that determines when the overview\n * map should be zoomed out.\n * @type {number}\n */\nconst MAX_RATIO = 0.75;\n\n\n/**\n * Minimum width and/or height extent ratio that determines when the overview\n * map should be zoomed in.\n * @type {number}\n */\nconst MIN_RATIO = 0.1;\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-overviewmap'] CSS class name.\n * @property {boolean} [collapsed=true] Whether the control should start collapsed or not (expanded).\n * @property {string|HTMLElement} [collapseLabel='«'] Text label to use for the\n * expanded overviewmap button. Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {boolean} [collapsible=true] Whether the control can be collapsed or not.\n * @property {string|HTMLElement} [label='»'] Text label to use for the collapsed\n * overviewmap button. Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {Array.<module:ol/layer/Layer>|module:ol/Collection.<module:ol/layer/Layer>} [layers]\n * Layers for the overview map. If not set, then all main map layers are used\n * instead.\n * @property {function(module:ol/MapEvent)} [render] Function called when the control\n * should be re-rendered. This is called in a `requestAnimationFrame` callback.\n * @property {HTMLElement|string} [target] Specify a target if you want the control\n * to be rendered outside of the map's viewport.\n * @property {string} [tipLabel='Overview map'] Text label to use for the button tip.\n * @property {module:ol/View} [view] Custom view for the overview map. If not provided,\n * a default view with an EPSG:3857 projection will be used.\n */\n\n\n/**\n * Create a new control with a map acting as an overview map for an other\n * defined map.\n *\n * @api\n */\nclass OverviewMap extends Control {\n\n  /**\n   * @param {module:ol/control/OverviewMap~Options=} opt_options OverviewMap options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options ? opt_options : {};\n\n    super({\n      element: document.createElement('div'),\n      render: options.render || render,\n      target: options.target\n    });\n\n    /**\n     * @type {boolean}\n     * @private\n     */\n    this.collapsed_ = options.collapsed !== undefined ? options.collapsed : true;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.collapsible_ = options.collapsible !== undefined ?\n      options.collapsible : true;\n\n    if (!this.collapsible_) {\n      this.collapsed_ = false;\n    }\n\n    const className = options.className !== undefined ? options.className : 'ol-overviewmap';\n\n    const tipLabel = options.tipLabel !== undefined ? options.tipLabel : 'Overview map';\n\n    const collapseLabel = options.collapseLabel !== undefined ? options.collapseLabel : '\\u00AB';\n\n    if (typeof collapseLabel === 'string') {\n      /**\n       * @private\n       * @type {HTMLElement}\n       */\n      this.collapseLabel_ = document.createElement('span');\n      this.collapseLabel_.textContent = collapseLabel;\n    } else {\n      this.collapseLabel_ = collapseLabel;\n    }\n\n    const label = options.label !== undefined ? options.label : '\\u00BB';\n\n\n    if (typeof label === 'string') {\n      /**\n       * @private\n       * @type {HTMLElement}\n       */\n      this.label_ = document.createElement('span');\n      this.label_.textContent = label;\n    } else {\n      this.label_ = label;\n    }\n\n    const activeLabel = (this.collapsible_ && !this.collapsed_) ?\n      this.collapseLabel_ : this.label_;\n    const button = document.createElement('button');\n    button.setAttribute('type', 'button');\n    button.title = tipLabel;\n    button.appendChild(activeLabel);\n\n    listen(button, EventType.CLICK,\n      this.handleClick_, this);\n\n    /**\n     * @type {HTMLElement}\n     * @private\n     */\n    this.ovmapDiv_ = document.createElement('DIV');\n    this.ovmapDiv_.className = 'ol-overviewmap-map';\n\n    /**\n     * @type {module:ol/Map}\n     * @private\n     */\n    this.ovmap_ = new Map({\n      controls: new Collection(),\n      interactions: new Collection(),\n      view: options.view\n    });\n    const ovmap = this.ovmap_;\n\n    if (options.layers) {\n      options.layers.forEach(\n        /**\n         * @param {module:ol/layer/Layer} layer Layer.\n         */\n        (function(layer) {\n          ovmap.addLayer(layer);\n        }).bind(this));\n    }\n\n    const box = document.createElement('DIV');\n    box.className = 'ol-overviewmap-box';\n    box.style.boxSizing = 'border-box';\n\n    /**\n     * @type {module:ol/Overlay}\n     * @private\n     */\n    this.boxOverlay_ = new Overlay({\n      position: [0, 0],\n      positioning: OverlayPositioning.BOTTOM_LEFT,\n      element: box\n    });\n    this.ovmap_.addOverlay(this.boxOverlay_);\n\n    const cssClasses = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL +\n        (this.collapsed_ && this.collapsible_ ? ' ' + CLASS_COLLAPSED : '') +\n        (this.collapsible_ ? '' : ' ol-uncollapsible');\n    const element = this.element;\n    element.className = cssClasses;\n    element.appendChild(this.ovmapDiv_);\n    element.appendChild(button);\n\n    /* Interactive map */\n\n    const scope = this;\n\n    const overlay = this.boxOverlay_;\n    const overlayBox = this.boxOverlay_.getElement();\n\n    /* Functions definition */\n\n    const computeDesiredMousePosition = function(mousePosition) {\n      return {\n        clientX: mousePosition.clientX - (overlayBox.offsetWidth / 2),\n        clientY: mousePosition.clientY + (overlayBox.offsetHeight / 2)\n      };\n    };\n\n    const move = function(event) {\n      const coordinates = ovmap.getEventCoordinate(computeDesiredMousePosition(event));\n\n      overlay.setPosition(coordinates);\n    };\n\n    const endMoving = function(event) {\n      const coordinates = ovmap.getEventCoordinate(event);\n\n      scope.getMap().getView().setCenter(coordinates);\n\n      window.removeEventListener('mousemove', move);\n      window.removeEventListener('mouseup', endMoving);\n    };\n\n    /* Binding */\n\n    overlayBox.addEventListener('mousedown', function() {\n      window.addEventListener('mousemove', move);\n      window.addEventListener('mouseup', endMoving);\n    });\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  setMap(map) {\n    const oldMap = this.getMap();\n    if (map === oldMap) {\n      return;\n    }\n    if (oldMap) {\n      const oldView = oldMap.getView();\n      if (oldView) {\n        this.unbindView_(oldView);\n      }\n      this.ovmap_.setTarget(null);\n    }\n    super.setMap(map);\n\n    if (map) {\n      this.ovmap_.setTarget(this.ovmapDiv_);\n      this.listenerKeys.push(listen(\n        map, ObjectEventType.PROPERTYCHANGE,\n        this.handleMapPropertyChange_, this));\n\n      // TODO: to really support map switching, this would need to be reworked\n      if (this.ovmap_.getLayers().getLength() === 0) {\n        this.ovmap_.setLayerGroup(map.getLayerGroup());\n      }\n\n      const view = map.getView();\n      if (view) {\n        this.bindView_(view);\n        if (view.isDef()) {\n          this.ovmap_.updateSize();\n          this.resetExtent_();\n        }\n      }\n    }\n  }\n\n  /**\n   * Handle map property changes.  This only deals with changes to the map's view.\n   * @param {module:ol/Object~ObjectEvent} event The propertychange event.\n   * @private\n   */\n  handleMapPropertyChange_(event) {\n    if (event.key === MapProperty.VIEW) {\n      const oldView = /** @type {module:ol/View} */ (event.oldValue);\n      if (oldView) {\n        this.unbindView_(oldView);\n      }\n      const newView = this.getMap().getView();\n      this.bindView_(newView);\n    }\n  }\n\n  /**\n   * Register listeners for view property changes.\n   * @param {module:ol/View} view The view.\n   * @private\n   */\n  bindView_(view) {\n    listen(view,\n      getChangeEventType(ViewProperty.ROTATION),\n      this.handleRotationChanged_, this);\n  }\n\n  /**\n   * Unregister listeners for view property changes.\n   * @param {module:ol/View} view The view.\n   * @private\n   */\n  unbindView_(view) {\n    unlisten(view,\n      getChangeEventType(ViewProperty.ROTATION),\n      this.handleRotationChanged_, this);\n  }\n\n  /**\n   * Handle rotation changes to the main map.\n   * TODO: This should rotate the extent rectrangle instead of the\n   * overview map's view.\n   * @private\n   */\n  handleRotationChanged_() {\n    this.ovmap_.getView().setRotation(this.getMap().getView().getRotation());\n  }\n\n  /**\n   * Reset the overview map extent if the box size (width or\n   * height) is less than the size of the overview map size times minRatio\n   * or is greater than the size of the overview size times maxRatio.\n   *\n   * If the map extent was not reset, the box size can fits in the defined\n   * ratio sizes. This method then checks if is contained inside the overview\n   * map current extent. If not, recenter the overview map to the current\n   * main map center location.\n   * @private\n   */\n  validateExtent_() {\n    const map = this.getMap();\n    const ovmap = this.ovmap_;\n\n    if (!map.isRendered() || !ovmap.isRendered()) {\n      return;\n    }\n\n    const mapSize = /** @type {module:ol/size~Size} */ (map.getSize());\n\n    const view = map.getView();\n    const extent = view.calculateExtent(mapSize);\n\n    const ovmapSize = /** @type {module:ol/size~Size} */ (ovmap.getSize());\n\n    const ovview = ovmap.getView();\n    const ovextent = ovview.calculateExtent(ovmapSize);\n\n    const topLeftPixel =\n        ovmap.getPixelFromCoordinate(getTopLeft(extent));\n    const bottomRightPixel =\n        ovmap.getPixelFromCoordinate(getBottomRight(extent));\n\n    const boxWidth = Math.abs(topLeftPixel[0] - bottomRightPixel[0]);\n    const boxHeight = Math.abs(topLeftPixel[1] - bottomRightPixel[1]);\n\n    const ovmapWidth = ovmapSize[0];\n    const ovmapHeight = ovmapSize[1];\n\n    if (boxWidth < ovmapWidth * MIN_RATIO ||\n        boxHeight < ovmapHeight * MIN_RATIO ||\n        boxWidth > ovmapWidth * MAX_RATIO ||\n        boxHeight > ovmapHeight * MAX_RATIO) {\n      this.resetExtent_();\n    } else if (!containsExtent(ovextent, extent)) {\n      this.recenter_();\n    }\n  }\n\n  /**\n   * Reset the overview map extent to half calculated min and max ratio times\n   * the extent of the main map.\n   * @private\n   */\n  resetExtent_() {\n    if (MAX_RATIO === 0 || MIN_RATIO === 0) {\n      return;\n    }\n\n    const map = this.getMap();\n    const ovmap = this.ovmap_;\n\n    const mapSize = /** @type {module:ol/size~Size} */ (map.getSize());\n\n    const view = map.getView();\n    const extent = view.calculateExtent(mapSize);\n\n    const ovview = ovmap.getView();\n\n    // get how many times the current map overview could hold different\n    // box sizes using the min and max ratio, pick the step in the middle used\n    // to calculate the extent from the main map to set it to the overview map,\n    const steps = Math.log(\n      MAX_RATIO / MIN_RATIO) / Math.LN2;\n    const ratio = 1 / (Math.pow(2, steps / 2) * MIN_RATIO);\n    scaleFromCenter(extent, ratio);\n    ovview.fit(extent);\n  }\n\n  /**\n   * Set the center of the overview map to the map center without changing its\n   * resolution.\n   * @private\n   */\n  recenter_() {\n    const map = this.getMap();\n    const ovmap = this.ovmap_;\n\n    const view = map.getView();\n\n    const ovview = ovmap.getView();\n\n    ovview.setCenter(view.getCenter());\n  }\n\n  /**\n   * Update the box using the main map extent\n   * @private\n   */\n  updateBox_() {\n    const map = this.getMap();\n    const ovmap = this.ovmap_;\n\n    if (!map.isRendered() || !ovmap.isRendered()) {\n      return;\n    }\n\n    const mapSize = /** @type {module:ol/size~Size} */ (map.getSize());\n\n    const view = map.getView();\n\n    const ovview = ovmap.getView();\n\n    const rotation = view.getRotation();\n\n    const overlay = this.boxOverlay_;\n    const box = this.boxOverlay_.getElement();\n    const extent = view.calculateExtent(mapSize);\n    const ovresolution = ovview.getResolution();\n    const bottomLeft = getBottomLeft(extent);\n    const topRight = getTopRight(extent);\n\n    // set position using bottom left coordinates\n    const rotateBottomLeft = this.calculateCoordinateRotate_(rotation, bottomLeft);\n    overlay.setPosition(rotateBottomLeft);\n\n    // set box size calculated from map extent size and overview map resolution\n    if (box) {\n      box.style.width = Math.abs((bottomLeft[0] - topRight[0]) / ovresolution) + 'px';\n      box.style.height = Math.abs((topRight[1] - bottomLeft[1]) / ovresolution) + 'px';\n    }\n  }\n\n  /**\n   * @param {number} rotation Target rotation.\n   * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n   * @return {module:ol/coordinate~Coordinate|undefined} Coordinate for rotation and center anchor.\n   * @private\n   */\n  calculateCoordinateRotate_(rotation, coordinate) {\n    let coordinateRotate;\n\n    const map = this.getMap();\n    const view = map.getView();\n\n    const currentCenter = view.getCenter();\n\n    if (currentCenter) {\n      coordinateRotate = [\n        coordinate[0] - currentCenter[0],\n        coordinate[1] - currentCenter[1]\n      ];\n      rotateCoordinate(coordinateRotate, rotation);\n      addCoordinate(coordinateRotate, currentCenter);\n    }\n    return coordinateRotate;\n  }\n\n  /**\n   * @param {MouseEvent} event The event to handle\n   * @private\n   */\n  handleClick_(event) {\n    event.preventDefault();\n    this.handleToggle_();\n  }\n\n  /**\n   * @private\n   */\n  handleToggle_() {\n    this.element.classList.toggle(CLASS_COLLAPSED);\n    if (this.collapsed_) {\n      replaceNode(this.collapseLabel_, this.label_);\n    } else {\n      replaceNode(this.label_, this.collapseLabel_);\n    }\n    this.collapsed_ = !this.collapsed_;\n\n    // manage overview map if it had not been rendered before and control\n    // is expanded\n    const ovmap = this.ovmap_;\n    if (!this.collapsed_ && !ovmap.isRendered()) {\n      ovmap.updateSize();\n      this.resetExtent_();\n      listenOnce(ovmap, MapEventType.POSTRENDER,\n        function(event) {\n          this.updateBox_();\n        },\n        this);\n    }\n  }\n\n  /**\n   * Return `true` if the overview map is collapsible, `false` otherwise.\n   * @return {boolean} True if the widget is collapsible.\n   * @api\n   */\n  getCollapsible() {\n    return this.collapsible_;\n  }\n\n  /**\n   * Set whether the overview map should be collapsible.\n   * @param {boolean} collapsible True if the widget is collapsible.\n   * @api\n   */\n  setCollapsible(collapsible) {\n    if (this.collapsible_ === collapsible) {\n      return;\n    }\n    this.collapsible_ = collapsible;\n    this.element.classList.toggle('ol-uncollapsible');\n    if (!collapsible && this.collapsed_) {\n      this.handleToggle_();\n    }\n  }\n\n  /**\n   * Collapse or expand the overview map according to the passed parameter. Will\n   * not do anything if the overview map isn't collapsible or if the current\n   * collapsed state is already the one requested.\n   * @param {boolean} collapsed True if the widget is collapsed.\n   * @api\n   */\n  setCollapsed(collapsed) {\n    if (!this.collapsible_ || this.collapsed_ === collapsed) {\n      return;\n    }\n    this.handleToggle_();\n  }\n\n  /**\n   * Determine if the overview map is collapsed.\n   * @return {boolean} The overview map is collapsed.\n   * @api\n   */\n  getCollapsed() {\n    return this.collapsed_;\n  }\n\n  /**\n   * Return the overview map.\n   * @return {module:ol/PluggableMap} Overview map.\n   * @api\n   */\n  getOverviewMap() {\n    return this.ovmap_;\n  }\n}\n\n\n/**\n * Update the overview map element.\n * @param {module:ol/MapEvent} mapEvent Map event.\n * @this {module:ol/control/OverviewMap}\n * @api\n */\nexport function render(mapEvent) {\n  this.validateExtent_();\n  this.updateBox_();\n}\n\n\nexport default OverviewMap;\n","/**\n * @module ol/control/ScaleLine\n */\nimport {getChangeEventType} from '../Object.js';\nimport {assert} from '../asserts.js';\nimport Control from '../control/Control.js';\nimport {CLASS_UNSELECTABLE} from '../css.js';\nimport {listen} from '../events.js';\nimport {getPointResolution, METERS_PER_UNIT} from '../proj.js';\nimport ProjUnits from '../proj/Units.js';\n\n\n/**\n * @type {string}\n */\nconst UNITS_PROP = 'units';\n\n/**\n * Units for the scale line. Supported values are `'degrees'`, `'imperial'`,\n * `'nautical'`, `'metric'`, `'us'`.\n * @enum {string}\n */\nexport const Units = {\n  DEGREES: 'degrees',\n  IMPERIAL: 'imperial',\n  NAUTICAL: 'nautical',\n  METRIC: 'metric',\n  US: 'us'\n};\n\n\n/**\n * @const\n * @type {Array.<number>}\n */\nconst LEADING_DIGITS = [1, 2, 5];\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-scale-line'] CSS Class name.\n * @property {number} [minWidth=64] Minimum width in pixels.\n * @property {function(module:ol/MapEvent)} [render] Function called when the control\n * should be re-rendered. This is called in a `requestAnimationFrame` callback.\n * @property {HTMLElement|string} [target] Specify a target if you want the control\n * to be rendered outside of the map's viewport.\n * @property {module:ol/control/ScaleLine~Units|string} [units='metric'] Units.\n */\n\n\n/**\n * @classdesc\n * A control displaying rough y-axis distances, calculated for the center of the\n * viewport. For conformal projections (e.g. EPSG:3857, the default view\n * projection in OpenLayers), the scale is valid for all directions.\n * No scale line will be shown when the y-axis distance of a pixel at the\n * viewport center cannot be calculated in the view projection.\n * By default the scale line will show in the bottom left portion of the map,\n * but this can be changed by using the css selector `.ol-scale-line`.\n *\n * @api\n */\nclass ScaleLine extends Control {\n\n  /**\n   * @param {module:ol/control/ScaleLine~Options=} opt_options Scale line options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options ? opt_options : {};\n\n    const className = options.className !== undefined ? options.className : 'ol-scale-line';\n\n    super({\n      element: document.createElement('DIV'),\n      render: options.render || render,\n      target: options.target\n    });\n\n    /**\n     * @private\n     * @type {HTMLElement}\n     */\n    this.innerElement_ = document.createElement('DIV');\n    this.innerElement_.className = className + '-inner';\n\n    this.element.className = className + ' ' + CLASS_UNSELECTABLE;\n    this.element.appendChild(this.innerElement_);\n\n    /**\n     * @private\n     * @type {?module:ol/View~State}\n     */\n    this.viewState_ = null;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.minWidth_ = options.minWidth !== undefined ? options.minWidth : 64;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.renderedVisible_ = false;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.renderedWidth_ = undefined;\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.renderedHTML_ = '';\n\n    listen(\n      this, getChangeEventType(UNITS_PROP),\n      this.handleUnitsChanged_, this);\n\n    this.setUnits(/** @type {module:ol/control/ScaleLine~Units} */ (options.units) ||\n        Units.METRIC);\n\n  }\n\n  /**\n   * Return the units to use in the scale line.\n   * @return {module:ol/control/ScaleLine~Units|undefined} The units\n   * to use in the scale line.\n   * @observable\n   * @api\n   */\n  getUnits() {\n    return (\n      /** @type {module:ol/control/ScaleLine~Units|undefined} */ (this.get(UNITS_PROP))\n    );\n  }\n\n  /**\n   * @private\n   */\n  handleUnitsChanged_() {\n    this.updateElement_();\n  }\n\n  /**\n   * Set the units to use in the scale line.\n   * @param {module:ol/control/ScaleLine~Units} units The units to use in the scale line.\n   * @observable\n   * @api\n   */\n  setUnits(units) {\n    this.set(UNITS_PROP, units);\n  }\n\n  /**\n   * @private\n   */\n  updateElement_() {\n    const viewState = this.viewState_;\n\n    if (!viewState) {\n      if (this.renderedVisible_) {\n        this.element.style.display = 'none';\n        this.renderedVisible_ = false;\n      }\n      return;\n    }\n\n    const center = viewState.center;\n    const projection = viewState.projection;\n    const units = this.getUnits();\n    const pointResolutionUnits = units == Units.DEGREES ?\n      ProjUnits.DEGREES :\n      ProjUnits.METERS;\n    let pointResolution =\n        getPointResolution(projection, viewState.resolution, center, pointResolutionUnits);\n    if (projection.getUnits() != ProjUnits.DEGREES && projection.getMetersPerUnit()\n      && pointResolutionUnits == ProjUnits.METERS) {\n      pointResolution *= projection.getMetersPerUnit();\n    }\n\n    let nominalCount = this.minWidth_ * pointResolution;\n    let suffix = '';\n    if (units == Units.DEGREES) {\n      const metersPerDegree = METERS_PER_UNIT[ProjUnits.DEGREES];\n      if (projection.getUnits() == ProjUnits.DEGREES) {\n        nominalCount *= metersPerDegree;\n      } else {\n        pointResolution /= metersPerDegree;\n      }\n      if (nominalCount < metersPerDegree / 60) {\n        suffix = '\\u2033'; // seconds\n        pointResolution *= 3600;\n      } else if (nominalCount < metersPerDegree) {\n        suffix = '\\u2032'; // minutes\n        pointResolution *= 60;\n      } else {\n        suffix = '\\u00b0'; // degrees\n      }\n    } else if (units == Units.IMPERIAL) {\n      if (nominalCount < 0.9144) {\n        suffix = 'in';\n        pointResolution /= 0.0254;\n      } else if (nominalCount < 1609.344) {\n        suffix = 'ft';\n        pointResolution /= 0.3048;\n      } else {\n        suffix = 'mi';\n        pointResolution /= 1609.344;\n      }\n    } else if (units == Units.NAUTICAL) {\n      pointResolution /= 1852;\n      suffix = 'nm';\n    } else if (units == Units.METRIC) {\n      if (nominalCount < 0.001) {\n        suffix = 'μm';\n        pointResolution *= 1000000;\n      } else if (nominalCount < 1) {\n        suffix = 'mm';\n        pointResolution *= 1000;\n      } else if (nominalCount < 1000) {\n        suffix = 'm';\n      } else {\n        suffix = 'km';\n        pointResolution /= 1000;\n      }\n    } else if (units == Units.US) {\n      if (nominalCount < 0.9144) {\n        suffix = 'in';\n        pointResolution *= 39.37;\n      } else if (nominalCount < 1609.344) {\n        suffix = 'ft';\n        pointResolution /= 0.30480061;\n      } else {\n        suffix = 'mi';\n        pointResolution /= 1609.3472;\n      }\n    } else {\n      assert(false, 33); // Invalid units\n    }\n\n    let i = 3 * Math.floor(\n      Math.log(this.minWidth_ * pointResolution) / Math.log(10));\n    let count, width;\n    while (true) {\n      count = LEADING_DIGITS[((i % 3) + 3) % 3] *\n          Math.pow(10, Math.floor(i / 3));\n      width = Math.round(count / pointResolution);\n      if (isNaN(width)) {\n        this.element.style.display = 'none';\n        this.renderedVisible_ = false;\n        return;\n      } else if (width >= this.minWidth_) {\n        break;\n      }\n      ++i;\n    }\n\n    const html = count + ' ' + suffix;\n    if (this.renderedHTML_ != html) {\n      this.innerElement_.innerHTML = html;\n      this.renderedHTML_ = html;\n    }\n\n    if (this.renderedWidth_ != width) {\n      this.innerElement_.style.width = width + 'px';\n      this.renderedWidth_ = width;\n    }\n\n    if (!this.renderedVisible_) {\n      this.element.style.display = '';\n      this.renderedVisible_ = true;\n    }\n\n  }\n}\n\n\n/**\n * Update the scale line element.\n * @param {module:ol/MapEvent} mapEvent Map event.\n * @this {module:ol/control/ScaleLine}\n * @api\n */\nexport function render(mapEvent) {\n  const frameState = mapEvent.frameState;\n  if (!frameState) {\n    this.viewState_ = null;\n  } else {\n    this.viewState_ = frameState.viewState;\n  }\n  this.updateElement_();\n}\n\n\nexport default ScaleLine;\n","/**\n * @module ol/control/ZoomSlider\n */\nimport ViewHint from '../ViewHint.js';\nimport Control from '../control/Control.js';\nimport {CLASS_CONTROL, CLASS_UNSELECTABLE} from '../css.js';\nimport {easeOut} from '../easing.js';\nimport {listen} from '../events.js';\nimport {stopPropagation} from '../events/Event.js';\nimport EventType from '../events/EventType.js';\nimport {clamp} from '../math.js';\nimport PointerEventType from '../pointer/EventType.js';\nimport PointerEventHandler from '../pointer/PointerEventHandler.js';\n\n\n/**\n * The enum for available directions.\n *\n * @enum {number}\n */\nconst Direction = {\n  VERTICAL: 0,\n  HORIZONTAL: 1\n};\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-zoomslider'] CSS class name.\n * @property {number} [duration=200] Animation duration in milliseconds.\n * @property {function(module:ol/MapEvent)} [render] Function called when the control\n * should be re-rendered. This is called in a `requestAnimationFrame` callback.\n */\n\n\n/**\n * @classdesc\n * A slider type of control for zooming.\n *\n * Example:\n *\n *     map.addControl(new ZoomSlider());\n *\n * @api\n */\nclass ZoomSlider extends Control {\n\n  /**\n   * @param {module:ol/control/ZoomSlider~Options=} opt_options Zoom slider options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options ? opt_options : {};\n\n    super({\n      element: document.createElement('div'),\n      render: options.render || render\n    });\n\n    /**\n     * Will hold the current resolution of the view.\n     *\n     * @type {number|undefined}\n     * @private\n     */\n    this.currentResolution_ = undefined;\n\n    /**\n     * The direction of the slider. Will be determined from actual display of the\n     * container and defaults to Direction.VERTICAL.\n     *\n     * @type {Direction}\n     * @private\n     */\n    this.direction_ = Direction.VERTICAL;\n\n    /**\n     * @type {boolean}\n     * @private\n     */\n    this.dragging_;\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.heightLimit_ = 0;\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.widthLimit_ = 0;\n\n    /**\n     * @type {number|undefined}\n     * @private\n     */\n    this.previousX_;\n\n    /**\n     * @type {number|undefined}\n     * @private\n     */\n    this.previousY_;\n\n    /**\n     * The calculated thumb size (border box plus margins).  Set when initSlider_\n     * is called.\n     * @type {module:ol/size~Size}\n     * @private\n     */\n    this.thumbSize_ = null;\n\n    /**\n     * Whether the slider is initialized.\n     * @type {boolean}\n     * @private\n     */\n    this.sliderInitialized_ = false;\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.duration_ = options.duration !== undefined ? options.duration : 200;\n\n    const className = options.className !== undefined ? options.className : 'ol-zoomslider';\n    const thumbElement = document.createElement('button');\n    thumbElement.setAttribute('type', 'button');\n    thumbElement.className = className + '-thumb ' + CLASS_UNSELECTABLE;\n    const containerElement = this.element;\n    containerElement.className = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL;\n    containerElement.appendChild(thumbElement);\n    /**\n     * @type {module:ol/pointer/PointerEventHandler}\n     * @private\n     */\n    this.dragger_ = new PointerEventHandler(containerElement);\n\n    listen(this.dragger_, PointerEventType.POINTERDOWN,\n      this.handleDraggerStart_, this);\n    listen(this.dragger_, PointerEventType.POINTERMOVE,\n      this.handleDraggerDrag_, this);\n    listen(this.dragger_, PointerEventType.POINTERUP,\n      this.handleDraggerEnd_, this);\n\n    listen(containerElement, EventType.CLICK, this.handleContainerClick_, this);\n    listen(thumbElement, EventType.CLICK, stopPropagation);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  disposeInternal() {\n    this.dragger_.dispose();\n    super.disposeInternal();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setMap(map) {\n    super.setMap(map);\n    if (map) {\n      map.render();\n    }\n  }\n\n  /**\n   * Initializes the slider element. This will determine and set this controls\n   * direction_ and also constrain the dragging of the thumb to always be within\n   * the bounds of the container.\n   *\n   * @private\n   */\n  initSlider_() {\n    const container = this.element;\n    const containerSize = {\n      width: container.offsetWidth, height: container.offsetHeight\n    };\n\n    const thumb = /** @type {HTMLElement} */ (container.firstElementChild);\n    const computedStyle = getComputedStyle(thumb);\n    const thumbWidth = thumb.offsetWidth +\n        parseFloat(computedStyle['marginRight']) +\n        parseFloat(computedStyle['marginLeft']);\n    const thumbHeight = thumb.offsetHeight +\n        parseFloat(computedStyle['marginTop']) +\n        parseFloat(computedStyle['marginBottom']);\n    this.thumbSize_ = [thumbWidth, thumbHeight];\n\n    if (containerSize.width > containerSize.height) {\n      this.direction_ = Direction.HORIZONTAL;\n      this.widthLimit_ = containerSize.width - thumbWidth;\n    } else {\n      this.direction_ = Direction.VERTICAL;\n      this.heightLimit_ = containerSize.height - thumbHeight;\n    }\n    this.sliderInitialized_ = true;\n  }\n\n  /**\n   * @param {MouseEvent} event The browser event to handle.\n   * @private\n   */\n  handleContainerClick_(event) {\n    const view = this.getMap().getView();\n\n    const relativePosition = this.getRelativePosition_(\n      event.offsetX - this.thumbSize_[0] / 2,\n      event.offsetY - this.thumbSize_[1] / 2);\n\n    const resolution = this.getResolutionForPosition_(relativePosition);\n\n    view.animate({\n      resolution: view.constrainResolution(resolution),\n      duration: this.duration_,\n      easing: easeOut\n    });\n  }\n\n  /**\n   * Handle dragger start events.\n   * @param {module:ol/pointer/PointerEvent} event The drag event.\n   * @private\n   */\n  handleDraggerStart_(event) {\n    if (!this.dragging_ && event.originalEvent.target === this.element.firstElementChild) {\n      this.getMap().getView().setHint(ViewHint.INTERACTING, 1);\n      this.previousX_ = event.clientX;\n      this.previousY_ = event.clientY;\n      this.dragging_ = true;\n    }\n  }\n\n  /**\n   * Handle dragger drag events.\n   *\n   * @param {module:ol/pointer/PointerEvent|Event} event The drag event.\n   * @private\n   */\n  handleDraggerDrag_(event) {\n    if (this.dragging_) {\n      const element = /** @type {HTMLElement} */ (this.element.firstElementChild);\n      const deltaX = event.clientX - this.previousX_ + parseInt(element.style.left, 10);\n      const deltaY = event.clientY - this.previousY_ + parseInt(element.style.top, 10);\n      const relativePosition = this.getRelativePosition_(deltaX, deltaY);\n      this.currentResolution_ = this.getResolutionForPosition_(relativePosition);\n      this.getMap().getView().setResolution(this.currentResolution_);\n      this.setThumbPosition_(this.currentResolution_);\n      this.previousX_ = event.clientX;\n      this.previousY_ = event.clientY;\n    }\n  }\n\n  /**\n   * Handle dragger end events.\n   * @param {module:ol/pointer/PointerEvent|Event} event The drag event.\n   * @private\n   */\n  handleDraggerEnd_(event) {\n    if (this.dragging_) {\n      const view = this.getMap().getView();\n      view.setHint(ViewHint.INTERACTING, -1);\n\n      view.animate({\n        resolution: view.constrainResolution(this.currentResolution_),\n        duration: this.duration_,\n        easing: easeOut\n      });\n\n      this.dragging_ = false;\n      this.previousX_ = undefined;\n      this.previousY_ = undefined;\n    }\n  }\n\n  /**\n   * Positions the thumb inside its container according to the given resolution.\n   *\n   * @param {number} res The res.\n   * @private\n   */\n  setThumbPosition_(res) {\n    const position = this.getPositionForResolution_(res);\n    const thumb = /** @type {HTMLElement} */ (this.element.firstElementChild);\n\n    if (this.direction_ == Direction.HORIZONTAL) {\n      thumb.style.left = this.widthLimit_ * position + 'px';\n    } else {\n      thumb.style.top = this.heightLimit_ * position + 'px';\n    }\n  }\n\n  /**\n   * Calculates the relative position of the thumb given x and y offsets.  The\n   * relative position scales from 0 to 1.  The x and y offsets are assumed to be\n   * in pixel units within the dragger limits.\n   *\n   * @param {number} x Pixel position relative to the left of the slider.\n   * @param {number} y Pixel position relative to the top of the slider.\n   * @return {number} The relative position of the thumb.\n   * @private\n   */\n  getRelativePosition_(x, y) {\n    let amount;\n    if (this.direction_ === Direction.HORIZONTAL) {\n      amount = x / this.widthLimit_;\n    } else {\n      amount = y / this.heightLimit_;\n    }\n    return clamp(amount, 0, 1);\n  }\n\n  /**\n   * Calculates the corresponding resolution of the thumb given its relative\n   * position (where 0 is the minimum and 1 is the maximum).\n   *\n   * @param {number} position The relative position of the thumb.\n   * @return {number} The corresponding resolution.\n   * @private\n   */\n  getResolutionForPosition_(position) {\n    const fn = this.getMap().getView().getResolutionForValueFunction();\n    return fn(1 - position);\n  }\n\n  /**\n   * Determines the relative position of the slider for the given resolution.  A\n   * relative position of 0 corresponds to the minimum view resolution.  A\n   * relative position of 1 corresponds to the maximum view resolution.\n   *\n   * @param {number} res The resolution.\n   * @return {number} The relative position value (between 0 and 1).\n   * @private\n   */\n  getPositionForResolution_(res) {\n    const fn = this.getMap().getView().getValueForResolutionFunction();\n    return 1 - fn(res);\n  }\n}\n\n\n/**\n * Update the zoomslider element.\n * @param {module:ol/MapEvent} mapEvent Map event.\n * @this {module:ol/control/ZoomSlider}\n * @api\n */\nexport function render(mapEvent) {\n  if (!mapEvent.frameState) {\n    return;\n  }\n  if (!this.sliderInitialized_) {\n    this.initSlider_();\n  }\n  const res = mapEvent.frameState.viewState.resolution;\n  if (res !== this.currentResolution_) {\n    this.currentResolution_ = res;\n    this.setThumbPosition_(res);\n  }\n}\n\n\nexport default ZoomSlider;\n","/**\n * @module ol/control/ZoomToExtent\n */\nimport {listen} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport Control from '../control/Control.js';\nimport {CLASS_CONTROL, CLASS_UNSELECTABLE} from '../css.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-zoom-extent'] Class name.\n * @property {HTMLElement|string} [target] Specify a target if you want the control\n * to be rendered outside of the map's viewport.\n * @property {string|HTMLElement} [label='E'] Text label to use for the button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string} [tipLabel='Fit to extent'] Text label to use for the button tip.\n * @property {module:ol/extent~Extent} [extent] The extent to zoom to. If undefined the validity\n * extent of the view projection is used.\n */\n\n\n/**\n * @classdesc\n * A button control which, when pressed, changes the map view to a specific\n * extent. To style this control use the css selector `.ol-zoom-extent`.\n *\n * @api\n */\nclass ZoomToExtent extends Control {\n\n  /**\n   * @param {module:ol/control/ZoomToExtent~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n    const options = opt_options ? opt_options : {};\n\n    super({\n      element: document.createElement('div'),\n      target: options.target\n    });\n\n    /**\n     * @type {module:ol/extent~Extent}\n     * @protected\n     */\n    this.extent = options.extent ? options.extent : null;\n\n    const className = options.className !== undefined ? options.className : 'ol-zoom-extent';\n\n    const label = options.label !== undefined ? options.label : 'E';\n    const tipLabel = options.tipLabel !== undefined ? options.tipLabel : 'Fit to extent';\n    const button = document.createElement('button');\n    button.setAttribute('type', 'button');\n    button.title = tipLabel;\n    button.appendChild(\n      typeof label === 'string' ? document.createTextNode(label) : label\n    );\n\n    listen(button, EventType.CLICK, this.handleClick_, this);\n\n    const cssClasses = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL;\n    const element = this.element;\n    element.className = cssClasses;\n    element.appendChild(button);\n  }\n\n  /**\n   * @param {MouseEvent} event The event to handle\n   * @private\n   */\n  handleClick_(event) {\n    event.preventDefault();\n    this.handleZoomToExtent();\n  }\n\n  /**\n   * @protected\n   */\n  handleZoomToExtent() {\n    const map = this.getMap();\n    const view = map.getView();\n    const extent = !this.extent ? view.getProjection().getExtent() : this.extent;\n    view.fit(extent);\n  }\n}\n\nexport default ZoomToExtent;\n","/**\n * @module ol/webgl/Shader\n */\nimport {FALSE} from '../functions.js';\n\n/**\n * @abstract\n */\nclass WebGLShader {\n\n  /**\n   * @param {string} source Source.\n   */\n  constructor(source) {\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.source_ = source;\n\n  }\n\n  /**\n   * @abstract\n   * @return {number} Type.\n   */\n  getType() {}\n\n  /**\n   * @return {string} Source.\n   */\n  getSource() {\n    return this.source_;\n  }\n}\n\n\n/**\n * @return {boolean} Is animated?\n */\nWebGLShader.prototype.isAnimated = FALSE;\nexport default WebGLShader;\n","/**\n * @module ol/webgl/Fragment\n */\n\nimport {FRAGMENT_SHADER} from '../webgl.js';\nimport WebGLShader from '../webgl/Shader.js';\n\nclass WebGLFragment extends WebGLShader {\n\n  /**\n   * @param {string} source Source.\n   */\n  constructor(source) {\n    super(source);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getType() {\n    return FRAGMENT_SHADER;\n  }\n}\n\n\nexport default WebGLFragment;\n","/**\n * @module ol/webgl/Vertex\n */\n\nimport {VERTEX_SHADER} from '../webgl.js';\nimport WebGLShader from '../webgl/Shader.js';\n\nclass WebGLVertex extends WebGLShader {\n\n  /**\n   * @param {string} source Source.\n   */\n  constructor(source) {\n    super(source);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getType() {\n    return VERTEX_SHADER;\n  }\n}\n\n\nexport default WebGLVertex;\n","/**\n * @module ol/render/webgl/circlereplay/defaultshader\n */\n// This file is automatically generated, do not edit.\n// Run `make shaders` to generate, and commit the result.\n\nimport {DEBUG as DEBUG_WEBGL} from '../../../webgl.js';\nimport WebGLFragment from '../../../webgl/Fragment.js';\nimport WebGLVertex from '../../../webgl/Vertex.js';\n\nexport const fragment = new WebGLFragment(DEBUG_WEBGL ?\n  'precision mediump float;\\nvarying vec2 v_center;\\nvarying vec2 v_offset;\\nvarying float v_halfWidth;\\nvarying float v_pixelRatio;\\n\\n\\n\\nuniform float u_opacity;\\nuniform vec4 u_fillColor;\\nuniform vec4 u_strokeColor;\\nuniform vec2 u_size;\\n\\nvoid main(void) {\\n  vec2 windowCenter = vec2((v_center.x + 1.0) / 2.0 * u_size.x * v_pixelRatio,\\n      (v_center.y + 1.0) / 2.0 * u_size.y * v_pixelRatio);\\n  vec2 windowOffset = vec2((v_offset.x + 1.0) / 2.0 * u_size.x * v_pixelRatio,\\n      (v_offset.y + 1.0) / 2.0 * u_size.y * v_pixelRatio);\\n  float radius = length(windowCenter - windowOffset);\\n  float dist = length(windowCenter - gl_FragCoord.xy);\\n  if (dist > radius + v_halfWidth) {\\n    if (u_strokeColor.a == 0.0) {\\n      gl_FragColor = u_fillColor;\\n    } else {\\n      gl_FragColor = u_strokeColor;\\n    }\\n    gl_FragColor.a = gl_FragColor.a - (dist - (radius + v_halfWidth));\\n  } else if (u_fillColor.a == 0.0) {\\n    // Hooray, no fill, just stroke. We can use real antialiasing.\\n    gl_FragColor = u_strokeColor;\\n    if (dist < radius - v_halfWidth) {\\n      gl_FragColor.a = gl_FragColor.a - (radius - v_halfWidth - dist);\\n    }\\n  } else {\\n    gl_FragColor = u_fillColor;\\n    float strokeDist = radius - v_halfWidth;\\n    float antialias = 2.0 * v_pixelRatio;\\n    if (dist > strokeDist) {\\n      gl_FragColor = u_strokeColor;\\n    } else if (dist >= strokeDist - antialias) {\\n      float step = smoothstep(strokeDist - antialias, strokeDist, dist);\\n      gl_FragColor = mix(u_fillColor, u_strokeColor, step);\\n    }\\n  }\\n  gl_FragColor.a = gl_FragColor.a * u_opacity;\\n  if (gl_FragColor.a <= 0.0) {\\n    discard;\\n  }\\n}\\n' :\n  'precision mediump float;varying vec2 a;varying vec2 b;varying float c;varying float d;uniform float m;uniform vec4 n;uniform vec4 o;uniform vec2 p;void main(void){vec2 windowCenter=vec2((a.x+1.0)/2.0*p.x*d,(a.y+1.0)/2.0*p.y*d);vec2 windowOffset=vec2((b.x+1.0)/2.0*p.x*d,(b.y+1.0)/2.0*p.y*d);float radius=length(windowCenter-windowOffset);float dist=length(windowCenter-gl_FragCoord.xy);if(dist>radius+c){if(o.a==0.0){gl_FragColor=n;}else{gl_FragColor=o;}gl_FragColor.a=gl_FragColor.a-(dist-(radius+c));}else if(n.a==0.0){gl_FragColor=o;if(dist<radius-c){gl_FragColor.a=gl_FragColor.a-(radius-c-dist);}} else{gl_FragColor=n;float strokeDist=radius-c;float antialias=2.0*d;if(dist>strokeDist){gl_FragColor=o;}else if(dist>=strokeDist-antialias){float step=smoothstep(strokeDist-antialias,strokeDist,dist);gl_FragColor=mix(n,o,step);}} gl_FragColor.a=gl_FragColor.a*m;if(gl_FragColor.a<=0.0){discard;}}');\n\nexport const vertex = new WebGLVertex(DEBUG_WEBGL ?\n  'varying vec2 v_center;\\nvarying vec2 v_offset;\\nvarying float v_halfWidth;\\nvarying float v_pixelRatio;\\n\\n\\nattribute vec2 a_position;\\nattribute float a_instruction;\\nattribute float a_radius;\\n\\nuniform mat4 u_projectionMatrix;\\nuniform mat4 u_offsetScaleMatrix;\\nuniform mat4 u_offsetRotateMatrix;\\nuniform float u_lineWidth;\\nuniform float u_pixelRatio;\\n\\nvoid main(void) {\\n  mat4 offsetMatrix = u_offsetScaleMatrix * u_offsetRotateMatrix;\\n  v_center = vec4(u_projectionMatrix * vec4(a_position, 0.0, 1.0)).xy;\\n  v_pixelRatio = u_pixelRatio;\\n  float lineWidth = u_lineWidth * u_pixelRatio;\\n  v_halfWidth = lineWidth / 2.0;\\n  if (lineWidth == 0.0) {\\n    lineWidth = 2.0 * u_pixelRatio;\\n  }\\n  vec2 offset;\\n  // Radius with anitaliasing (roughly).\\n  float radius = a_radius + 3.0 * u_pixelRatio;\\n  // Until we get gl_VertexID in WebGL, we store an instruction.\\n  if (a_instruction == 0.0) {\\n    // Offsetting the edges of the triangle by lineWidth / 2 is necessary, however\\n    // we should also leave some space for the antialiasing, thus we offset by lineWidth.\\n    offset = vec2(-1.0, 1.0);\\n  } else if (a_instruction == 1.0) {\\n    offset = vec2(-1.0, -1.0);\\n  } else if (a_instruction == 2.0) {\\n    offset = vec2(1.0, -1.0);\\n  } else {\\n    offset = vec2(1.0, 1.0);\\n  }\\n\\n  gl_Position = u_projectionMatrix * vec4(a_position + offset * radius, 0.0, 1.0) +\\n      offsetMatrix * vec4(offset * lineWidth, 0.0, 0.0);\\n  v_offset = vec4(u_projectionMatrix * vec4(a_position.x + a_radius, a_position.y,\\n      0.0, 1.0)).xy;\\n\\n  if (distance(v_center, v_offset) > 20000.0) {\\n    gl_Position = vec4(v_center, 0.0, 1.0);\\n  }\\n}\\n\\n\\n' :\n  'varying vec2 a;varying vec2 b;varying float c;varying float d;attribute vec2 e;attribute float f;attribute float g;uniform mat4 h;uniform mat4 i;uniform mat4 j;uniform float k;uniform float l;void main(void){mat4 offsetMatrix=i*j;a=vec4(h*vec4(e,0.0,1.0)).xy;d=l;float lineWidth=k*l;c=lineWidth/2.0;if(lineWidth==0.0){lineWidth=2.0*l;}vec2 offset;float radius=g+3.0*l;if(f==0.0){offset=vec2(-1.0,1.0);}else if(f==1.0){offset=vec2(-1.0,-1.0);}else if(f==2.0){offset=vec2(1.0,-1.0);}else{offset=vec2(1.0,1.0);}gl_Position=h*vec4(e+offset*radius,0.0,1.0)+offsetMatrix*vec4(offset*lineWidth,0.0,0.0);b=vec4(h*vec4(e.x+g,e.y,0.0,1.0)).xy;if(distance(a,b)>20000.0){gl_Position=vec4(a,0.0,1.0);}}');\n","/**\n * @module ol/render/webgl/circlereplay/defaultshader/Locations\n */\n// This file is automatically generated, do not edit\n// Run `make shaders` to generate, and commit the result.\n\nimport {DEBUG as DEBUG_WEBGL} from '../../../../webgl.js';\n\nclass Locations {\n\n  /**\n   * @param {WebGLRenderingContext} gl GL.\n   * @param {WebGLProgram} program Program.\n   */\n  constructor(gl, program) {\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_projectionMatrix = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_offsetScaleMatrix = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_offsetRotateMatrix = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_lineWidth = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_lineWidth' : 'k');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_pixelRatio = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_pixelRatio' : 'l');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_opacity = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_opacity' : 'm');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_fillColor = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_fillColor' : 'n');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_strokeColor = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_strokeColor' : 'o');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_size = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_size' : 'p');\n\n    /**\n     * @type {number}\n     */\n    this.a_position = gl.getAttribLocation(\n      program, DEBUG_WEBGL ? 'a_position' : 'e');\n\n    /**\n     * @type {number}\n     */\n    this.a_instruction = gl.getAttribLocation(\n      program, DEBUG_WEBGL ? 'a_instruction' : 'f');\n\n    /**\n     * @type {number}\n     */\n    this.a_radius = gl.getAttribLocation(\n      program, DEBUG_WEBGL ? 'a_radius' : 'g');\n\n  }\n\n}\n\nexport default Locations;\n","/**\n * @module ol/vec/mat4\n */\n\n\n/**\n * @return {Array.<number>} 4x4 matrix representing a 3D identity transform.\n */\nexport function create() {\n  return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];\n}\n\n\n/**\n * @param {Array.<number>} mat4 Flattened 4x4 matrix receiving the result.\n * @param {module:ol/transform~Transform} transform Transformation matrix.\n * @return {Array.<number>} 2D transformation matrix as flattened 4x4 matrix.\n */\nexport function fromTransform(mat4, transform) {\n  mat4[0] = transform[0];\n  mat4[1] = transform[1];\n  mat4[4] = transform[2];\n  mat4[5] = transform[3];\n  mat4[12] = transform[4];\n  mat4[13] = transform[5];\n  return mat4;\n}\n","/**\n * @module ol/render/webgl/Replay\n */\n\nimport {getCenter} from '../../extent.js';\nimport VectorContext from '../VectorContext.js';\nimport {\n  create as createTransform,\n  reset as resetTransform,\n  rotate as rotateTransform,\n  scale as scaleTransform,\n  translate as translateTransform\n} from '../../transform.js';\nimport {create, fromTransform} from '../../vec/mat4.js';\nimport {ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER, TRIANGLES,\n  UNSIGNED_INT, UNSIGNED_SHORT} from '../../webgl.js';\n\nclass WebGLReplay extends VectorContext {\n  /**\n   * @param {number} tolerance Tolerance.\n   * @param {module:ol/extent~Extent} maxExtent Max extent.\n   */\n  constructor(tolerance, maxExtent) {\n    super();\n\n    /**\n     * @protected\n     * @type {number}\n     */\n    this.tolerance = tolerance;\n\n    /**\n     * @protected\n     * @const\n     * @type {module:ol/extent~Extent}\n     */\n    this.maxExtent = maxExtent;\n\n    /**\n     * The origin of the coordinate system for the point coordinates sent to\n     * the GPU. To eliminate jitter caused by precision problems in the GPU\n     * we use the \"Rendering Relative to Eye\" technique described in the \"3D\n     * Engine Design for Virtual Globes\" book.\n     * @protected\n     * @type {module:ol/coordinate~Coordinate}\n     */\n    this.origin = getCenter(maxExtent);\n\n    /**\n     * @private\n     * @type {module:ol/transform~Transform}\n     */\n    this.projectionMatrix_ = createTransform();\n\n    /**\n     * @private\n     * @type {module:ol/transform~Transform}\n     */\n    this.offsetRotateMatrix_ = createTransform();\n\n    /**\n     * @private\n     * @type {module:ol/transform~Transform}\n     */\n    this.offsetScaleMatrix_ = createTransform();\n\n    /**\n     * @private\n     * @type {Array.<number>}\n     */\n    this.tmpMat4_ = create();\n\n    /**\n     * @protected\n     * @type {Array.<number>}\n     */\n    this.indices = [];\n\n    /**\n     * @protected\n     * @type {?module:ol/webgl/Buffer}\n     */\n    this.indicesBuffer = null;\n\n    /**\n     * Start index per feature (the index).\n     * @protected\n     * @type {Array.<number>}\n     */\n    this.startIndices = [];\n\n    /**\n     * Start index per feature (the feature).\n     * @protected\n     * @type {Array.<module:ol/Feature|module:ol/render/Feature>}\n     */\n    this.startIndicesFeature = [];\n\n    /**\n     * @protected\n     * @type {Array.<number>}\n     */\n    this.vertices = [];\n\n    /**\n     * @protected\n     * @type {?module:ol/webgl/Buffer}\n     */\n    this.verticesBuffer = null;\n\n    /**\n     * Optional parameter for PolygonReplay instances.\n     * @protected\n     * @type {module:ol/render/webgl/LineStringReplay|undefined}\n     */\n    this.lineStringReplay = undefined;\n\n  }\n\n  /**\n   * @abstract\n   * @param {module:ol/webgl/Context} context WebGL context.\n   * @return {function()} Delete resources function.\n   */\n  getDeleteResourcesFunction(context) {}\n\n  /**\n   * @abstract\n   * @param {module:ol/webgl/Context} context Context.\n   */\n  finish(context) {}\n\n  /**\n   * @abstract\n   * @protected\n   * @param {WebGLRenderingContext} gl gl.\n   * @param {module:ol/webgl/Context} context Context.\n   * @param {module:ol/size~Size} size Size.\n   * @param {number} pixelRatio Pixel ratio.\n   * @return {module:ol/render/webgl/circlereplay/defaultshader/Locations|\n     module:ol/render/webgl/linestringreplay/defaultshader/Locations|\n     module:ol/render/webgl/polygonreplay/defaultshader/Locations|\n     module:ol/render/webgl/texturereplay/defaultshader/Locations} Locations.\n   */\n  setUpProgram(gl, context, size, pixelRatio) {}\n\n  /**\n   * @abstract\n   * @protected\n   * @param {WebGLRenderingContext} gl gl.\n   * @param {module:ol/render/webgl/circlereplay/defaultshader/Locations|\n     module:ol/render/webgl/linestringreplay/defaultshader/Locations|\n     module:ol/render/webgl/polygonreplay/defaultshader/Locations|\n     module:ol/render/webgl/texturereplay/defaultshader/Locations} locations Locations.\n   */\n  shutDownProgram(gl, locations) {}\n\n  /**\n   * @abstract\n   * @protected\n   * @param {WebGLRenderingContext} gl gl.\n   * @param {module:ol/webgl/Context} context Context.\n   * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features to skip.\n   * @param {boolean} hitDetection Hit detection mode.\n   */\n  drawReplay(gl, context, skippedFeaturesHash, hitDetection) {}\n\n  /**\n   * @abstract\n   * @protected\n   * @param {WebGLRenderingContext} gl gl.\n   * @param {module:ol/webgl/Context} context Context.\n   * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features to skip.\n   * @param {function((module:ol/Feature|module:ol/render/Feature)): T|undefined} featureCallback Feature callback.\n   * @param {module:ol/extent~Extent=} opt_hitExtent Hit extent: Only features intersecting this extent are checked.\n   * @return {T|undefined} Callback result.\n   * @template T\n   */\n  drawHitDetectionReplayOneByOne(gl, context, skippedFeaturesHash, featureCallback, opt_hitExtent) {}\n\n  /**\n   * @protected\n   * @param {WebGLRenderingContext} gl gl.\n   * @param {module:ol/webgl/Context} context Context.\n   * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features to skip.\n   * @param {function((module:ol/Feature|module:ol/render/Feature)): T|undefined} featureCallback Feature callback.\n   * @param {boolean} oneByOne Draw features one-by-one for the hit-detecion.\n   * @param {module:ol/extent~Extent=} opt_hitExtent Hit extent: Only features intersecting this extent are checked.\n   * @return {T|undefined} Callback result.\n   * @template T\n   */\n  drawHitDetectionReplay(gl, context, skippedFeaturesHash, featureCallback, oneByOne, opt_hitExtent) {\n    if (!oneByOne) {\n      // draw all hit-detection features in \"once\" (by texture group)\n      return this.drawHitDetectionReplayAll(gl, context,\n        skippedFeaturesHash, featureCallback);\n    } else {\n      // draw hit-detection features one by one\n      return this.drawHitDetectionReplayOneByOne(gl, context,\n        skippedFeaturesHash, featureCallback, opt_hitExtent);\n    }\n  }\n\n  /**\n   * @protected\n   * @param {WebGLRenderingContext} gl gl.\n   * @param {module:ol/webgl/Context} context Context.\n   * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features to skip.\n   * @param {function((module:ol/Feature|module:ol/render/Feature)): T|undefined} featureCallback Feature callback.\n   * @return {T|undefined} Callback result.\n   * @template T\n   */\n  drawHitDetectionReplayAll(gl, context, skippedFeaturesHash, featureCallback) {\n    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n    this.drawReplay(gl, context, skippedFeaturesHash, true);\n\n    const result = featureCallback(null);\n    if (result) {\n      return result;\n    } else {\n      return undefined;\n    }\n  }\n\n  /**\n   * @param {module:ol/webgl/Context} context Context.\n   * @param {module:ol/coordinate~Coordinate} center Center.\n   * @param {number} resolution Resolution.\n   * @param {number} rotation Rotation.\n   * @param {module:ol/size~Size} size Size.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {number} opacity Global opacity.\n   * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features to skip.\n   * @param {function((module:ol/Feature|module:ol/render/Feature)): T|undefined} featureCallback Feature callback.\n   * @param {boolean} oneByOne Draw features one-by-one for the hit-detecion.\n   * @param {module:ol/extent~Extent=} opt_hitExtent Hit extent: Only features intersecting this extent are checked.\n   * @return {T|undefined} Callback result.\n   * @template T\n   */\n  replay(\n    context,\n    center,\n    resolution,\n    rotation,\n    size,\n    pixelRatio,\n    opacity,\n    skippedFeaturesHash,\n    featureCallback,\n    oneByOne,\n    opt_hitExtent\n  ) {\n    const gl = context.getGL();\n    let tmpStencil, tmpStencilFunc, tmpStencilMaskVal, tmpStencilRef, tmpStencilMask,\n        tmpStencilOpFail, tmpStencilOpPass, tmpStencilOpZFail;\n\n    if (this.lineStringReplay) {\n      tmpStencil = gl.isEnabled(gl.STENCIL_TEST);\n      tmpStencilFunc = gl.getParameter(gl.STENCIL_FUNC);\n      tmpStencilMaskVal = gl.getParameter(gl.STENCIL_VALUE_MASK);\n      tmpStencilRef = gl.getParameter(gl.STENCIL_REF);\n      tmpStencilMask = gl.getParameter(gl.STENCIL_WRITEMASK);\n      tmpStencilOpFail = gl.getParameter(gl.STENCIL_FAIL);\n      tmpStencilOpPass = gl.getParameter(gl.STENCIL_PASS_DEPTH_PASS);\n      tmpStencilOpZFail = gl.getParameter(gl.STENCIL_PASS_DEPTH_FAIL);\n\n      gl.enable(gl.STENCIL_TEST);\n      gl.clear(gl.STENCIL_BUFFER_BIT);\n      gl.stencilMask(255);\n      gl.stencilFunc(gl.ALWAYS, 1, 255);\n      gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);\n\n      this.lineStringReplay.replay(context,\n        center, resolution, rotation, size, pixelRatio,\n        opacity, skippedFeaturesHash,\n        featureCallback, oneByOne, opt_hitExtent);\n\n      gl.stencilMask(0);\n      gl.stencilFunc(gl.NOTEQUAL, 1, 255);\n    }\n\n    context.bindBuffer(ARRAY_BUFFER, this.verticesBuffer);\n\n    context.bindBuffer(ELEMENT_ARRAY_BUFFER, this.indicesBuffer);\n\n    const locations = this.setUpProgram(gl, context, size, pixelRatio);\n\n    // set the \"uniform\" values\n    const projectionMatrix = resetTransform(this.projectionMatrix_);\n    scaleTransform(projectionMatrix, 2 / (resolution * size[0]), 2 / (resolution * size[1]));\n    rotateTransform(projectionMatrix, -rotation);\n    translateTransform(projectionMatrix, -(center[0] - this.origin[0]), -(center[1] - this.origin[1]));\n\n    const offsetScaleMatrix = resetTransform(this.offsetScaleMatrix_);\n    scaleTransform(offsetScaleMatrix, 2 / size[0], 2 / size[1]);\n\n    const offsetRotateMatrix = resetTransform(this.offsetRotateMatrix_);\n    if (rotation !== 0) {\n      rotateTransform(offsetRotateMatrix, -rotation);\n    }\n\n    gl.uniformMatrix4fv(locations.u_projectionMatrix, false,\n      fromTransform(this.tmpMat4_, projectionMatrix));\n    gl.uniformMatrix4fv(locations.u_offsetScaleMatrix, false,\n      fromTransform(this.tmpMat4_, offsetScaleMatrix));\n    gl.uniformMatrix4fv(locations.u_offsetRotateMatrix, false,\n      fromTransform(this.tmpMat4_, offsetRotateMatrix));\n    gl.uniform1f(locations.u_opacity, opacity);\n\n    // draw!\n    let result;\n    if (featureCallback === undefined) {\n      this.drawReplay(gl, context, skippedFeaturesHash, false);\n    } else {\n      // draw feature by feature for the hit-detection\n      result = this.drawHitDetectionReplay(gl, context, skippedFeaturesHash,\n        featureCallback, oneByOne, opt_hitExtent);\n    }\n\n    // disable the vertex attrib arrays\n    this.shutDownProgram(gl, locations);\n\n    if (this.lineStringReplay) {\n      if (!tmpStencil) {\n        gl.disable(gl.STENCIL_TEST);\n      }\n      gl.clear(gl.STENCIL_BUFFER_BIT);\n      gl.stencilFunc(/** @type {number} */ (tmpStencilFunc),\n        /** @type {number} */ (tmpStencilRef), /** @type {number} */ (tmpStencilMaskVal));\n      gl.stencilMask(/** @type {number} */ (tmpStencilMask));\n      gl.stencilOp(/** @type {number} */ (tmpStencilOpFail),\n        /** @type {number} */ (tmpStencilOpZFail), /** @type {number} */ (tmpStencilOpPass));\n    }\n\n    return result;\n  }\n\n  /**\n   * @protected\n   * @param {WebGLRenderingContext} gl gl.\n   * @param {module:ol/webgl/Context} context Context.\n   * @param {number} start Start index.\n   * @param {number} end End index.\n   */\n  drawElements(gl, context, start, end) {\n    const elementType = context.hasOESElementIndexUint ?\n      UNSIGNED_INT : UNSIGNED_SHORT;\n    const elementSize = context.hasOESElementIndexUint ? 4 : 2;\n\n    const numItems = end - start;\n    const offsetInBytes = start * elementSize;\n    gl.drawElements(TRIANGLES, numItems, elementType, offsetInBytes);\n  }\n}\n\n\nexport default WebGLReplay;\n","/**\n * @module ol/render/webgl\n */\n\n\n/**\n * @const\n * @type {string}\n */\nexport const DEFAULT_FONT = '10px sans-serif';\n\n\n/**\n * @const\n * @type {module:ol/color~Color}\n */\nexport const DEFAULT_FILLSTYLE = [0.0, 0.0, 0.0, 1.0];\n\n\n/**\n * @const\n * @type {string}\n */\nexport const DEFAULT_LINECAP = 'round';\n\n\n/**\n * @const\n * @type {Array.<number>}\n */\nexport const DEFAULT_LINEDASH = [];\n\n\n/**\n * @const\n * @type {number}\n */\nexport const DEFAULT_LINEDASHOFFSET = 0;\n\n\n/**\n * @const\n * @type {string}\n */\nexport const DEFAULT_LINEJOIN = 'round';\n\n\n/**\n * @const\n * @type {number}\n */\nexport const DEFAULT_MITERLIMIT = 10;\n\n/**\n * @const\n * @type {module:ol/color~Color}\n */\nexport const DEFAULT_STROKESTYLE = [0.0, 0.0, 0.0, 1.0];\n\n\n/**\n * @const\n * @type {number}\n */\nexport const DEFAULT_TEXTALIGN = 0.5;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const DEFAULT_TEXTBASELINE = 0.5;\n\n\n/**\n * @const\n * @type {number}\n */\nexport const DEFAULT_LINEWIDTH = 1;\n\n/**\n * @const\n * @type {number}\n */\nexport const EPSILON = Number.EPSILON || 2.220446049250313e-16;\n\n/**\n * Calculates the orientation of a triangle based on the determinant method.\n * @param {number} x1 First X coordinate.\n * @param {number} y1 First Y coordinate.\n * @param {number} x2 Second X coordinate.\n * @param {number} y2 Second Y coordinate.\n * @param {number} x3 Third X coordinate.\n * @param {number} y3 Third Y coordinate.\n * @return {boolean|undefined} Triangle is clockwise.\n */\nexport const triangleIsCounterClockwise = function(x1, y1, x2, y2, x3, y3) {\n  const area = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1);\n  return (area <= EPSILON && area >= -EPSILON) ?\n    undefined : area > 0;\n};\n\n","/**\n * @module ol/webgl/Buffer\n */\nimport {STATIC_DRAW, STREAM_DRAW, DYNAMIC_DRAW} from '../webgl.js';\n\n/**\n * @enum {number}\n */\nconst BufferUsage = {\n  STATIC_DRAW: STATIC_DRAW,\n  STREAM_DRAW: STREAM_DRAW,\n  DYNAMIC_DRAW: DYNAMIC_DRAW\n};\n\n\nclass WebGLBuffer {\n\n  /**\n   * @param {Array.<number>=} opt_arr Array.\n   * @param {number=} opt_usage Usage.\n   */\n  constructor(opt_arr, opt_usage) {\n\n    /**\n     * @private\n     * @type {Array.<number>}\n     */\n    this.arr_ = opt_arr !== undefined ? opt_arr : [];\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.usage_ = opt_usage !== undefined ? opt_usage : BufferUsage.STATIC_DRAW;\n\n  }\n\n  /**\n   * @return {Array.<number>} Array.\n   */\n  getArray() {\n    return this.arr_;\n  }\n\n  /**\n   * @return {number} Usage.\n   */\n  getUsage() {\n    return this.usage_;\n  }\n}\n\nexport default WebGLBuffer;\n","/**\n * @module ol/render/webgl/CircleReplay\n */\nimport {getUid} from '../../util.js';\nimport {equals} from '../../array.js';\nimport {asArray} from '../../color.js';\nimport {intersects} from '../../extent.js';\nimport {isEmpty} from '../../obj.js';\nimport {translate} from '../../geom/flat/transform.js';\nimport {fragment, vertex} from '../webgl/circlereplay/defaultshader.js';\nimport Locations from '../webgl/circlereplay/defaultshader/Locations.js';\nimport WebGLReplay from '../webgl/Replay.js';\nimport {DEFAULT_LINEDASH, DEFAULT_LINEDASHOFFSET, DEFAULT_STROKESTYLE,\n  DEFAULT_FILLSTYLE, DEFAULT_LINEWIDTH} from '../webgl.js';\nimport {FLOAT} from '../../webgl.js';\nimport WebGLBuffer from '../../webgl/Buffer.js';\n\nclass WebGLCircleReplay extends WebGLReplay {\n  /**\n   * @param {number} tolerance Tolerance.\n   * @param {module:ol/extent~Extent} maxExtent Max extent.\n   */\n  constructor(tolerance, maxExtent) {\n    super(tolerance, maxExtent);\n\n    /**\n     * @private\n     * @type {module:ol/render/webgl/circlereplay/defaultshader/Locations}\n     */\n    this.defaultLocations_ = null;\n\n    /**\n     * @private\n     * @type {Array.<Array.<Array.<number>|number>>}\n     */\n    this.styles_ = [];\n\n    /**\n     * @private\n     * @type {Array.<number>}\n     */\n    this.styleIndices_ = [];\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.radius_ = 0;\n\n    /**\n     * @private\n     * @type {{fillColor: (Array.<number>|null),\n     *         strokeColor: (Array.<number>|null),\n     *         lineDash: Array.<number>,\n     *         lineDashOffset: (number|undefined),\n     *         lineWidth: (number|undefined),\n     *         changed: boolean}|null}\n     */\n    this.state_ = {\n      fillColor: null,\n      strokeColor: null,\n      lineDash: null,\n      lineDashOffset: undefined,\n      lineWidth: undefined,\n      changed: false\n    };\n\n  }\n\n  /**\n   * @private\n   * @param {Array.<number>} flatCoordinates Flat coordinates.\n   * @param {number} offset Offset.\n   * @param {number} end End.\n   * @param {number} stride Stride.\n   */\n  drawCoordinates_(flatCoordinates, offset, end, stride) {\n    let numVertices = this.vertices.length;\n    let numIndices = this.indices.length;\n    let n = numVertices / 4;\n    let i, ii;\n    for (i = offset, ii = end; i < ii; i += stride) {\n      this.vertices[numVertices++] = flatCoordinates[i];\n      this.vertices[numVertices++] = flatCoordinates[i + 1];\n      this.vertices[numVertices++] = 0;\n      this.vertices[numVertices++] = this.radius_;\n\n      this.vertices[numVertices++] = flatCoordinates[i];\n      this.vertices[numVertices++] = flatCoordinates[i + 1];\n      this.vertices[numVertices++] = 1;\n      this.vertices[numVertices++] = this.radius_;\n\n      this.vertices[numVertices++] = flatCoordinates[i];\n      this.vertices[numVertices++] = flatCoordinates[i + 1];\n      this.vertices[numVertices++] = 2;\n      this.vertices[numVertices++] = this.radius_;\n\n      this.vertices[numVertices++] = flatCoordinates[i];\n      this.vertices[numVertices++] = flatCoordinates[i + 1];\n      this.vertices[numVertices++] = 3;\n      this.vertices[numVertices++] = this.radius_;\n\n      this.indices[numIndices++] = n;\n      this.indices[numIndices++] = n + 1;\n      this.indices[numIndices++] = n + 2;\n\n      this.indices[numIndices++] = n + 2;\n      this.indices[numIndices++] = n + 3;\n      this.indices[numIndices++] = n;\n\n      n += 4;\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawCircle(circleGeometry, feature) {\n    const radius = circleGeometry.getRadius();\n    const stride = circleGeometry.getStride();\n    if (radius) {\n      this.startIndices.push(this.indices.length);\n      this.startIndicesFeature.push(feature);\n      if (this.state_.changed) {\n        this.styleIndices_.push(this.indices.length);\n        this.state_.changed = false;\n      }\n\n      this.radius_ = radius;\n      let flatCoordinates = circleGeometry.getFlatCoordinates();\n      flatCoordinates = translate(flatCoordinates, 0, 2,\n        stride, -this.origin[0], -this.origin[1]);\n      this.drawCoordinates_(flatCoordinates, 0, 2, stride);\n    } else {\n      if (this.state_.changed) {\n        this.styles_.pop();\n        if (this.styles_.length) {\n          const lastState = this.styles_[this.styles_.length - 1];\n          this.state_.fillColor = /** @type {Array.<number>} */ (lastState[0]);\n          this.state_.strokeColor = /** @type {Array.<number>} */ (lastState[1]);\n          this.state_.lineWidth = /** @type {number} */ (lastState[2]);\n          this.state_.changed = false;\n        }\n      }\n    }\n  }\n\n  /**\n   * @inheritDoc\n   **/\n  finish(context) {\n    // create, bind, and populate the vertices buffer\n    this.verticesBuffer = new WebGLBuffer(this.vertices);\n\n    // create, bind, and populate the indices buffer\n    this.indicesBuffer = new WebGLBuffer(this.indices);\n\n    this.startIndices.push(this.indices.length);\n\n    //Clean up, if there is nothing to draw\n    if (this.styleIndices_.length === 0 && this.styles_.length > 0) {\n      this.styles_ = [];\n    }\n\n    this.vertices = null;\n    this.indices = null;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getDeleteResourcesFunction(context) {\n    // We only delete our stuff here. The shaders and the program may\n    // be used by other CircleReplay instances (for other layers). And\n    // they will be deleted when disposing of the module:ol/webgl/Context~WebGLContext\n    // object.\n    const verticesBuffer = this.verticesBuffer;\n    const indicesBuffer = this.indicesBuffer;\n    return function() {\n      context.deleteBuffer(verticesBuffer);\n      context.deleteBuffer(indicesBuffer);\n    };\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setUpProgram(gl, context, size, pixelRatio) {\n    // get the program\n    const program = context.getProgram(fragment, vertex);\n\n    // get the locations\n    let locations;\n    if (!this.defaultLocations_) {\n      locations = new Locations(gl, program);\n      this.defaultLocations_ = locations;\n    } else {\n      locations = this.defaultLocations_;\n    }\n\n    context.useProgram(program);\n\n    // enable the vertex attrib arrays\n    gl.enableVertexAttribArray(locations.a_position);\n    gl.vertexAttribPointer(locations.a_position, 2, FLOAT,\n      false, 16, 0);\n\n    gl.enableVertexAttribArray(locations.a_instruction);\n    gl.vertexAttribPointer(locations.a_instruction, 1, FLOAT,\n      false, 16, 8);\n\n    gl.enableVertexAttribArray(locations.a_radius);\n    gl.vertexAttribPointer(locations.a_radius, 1, FLOAT,\n      false, 16, 12);\n\n    // Enable renderer specific uniforms.\n    gl.uniform2fv(locations.u_size, size);\n    gl.uniform1f(locations.u_pixelRatio, pixelRatio);\n\n    return locations;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  shutDownProgram(gl, locations) {\n    gl.disableVertexAttribArray(locations.a_position);\n    gl.disableVertexAttribArray(locations.a_instruction);\n    gl.disableVertexAttribArray(locations.a_radius);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawReplay(gl, context, skippedFeaturesHash, hitDetection) {\n    if (!isEmpty(skippedFeaturesHash)) {\n      this.drawReplaySkipping_(gl, context, skippedFeaturesHash);\n    } else {\n      //Draw by style groups to minimize drawElements() calls.\n      let i, start, end, nextStyle;\n      end = this.startIndices[this.startIndices.length - 1];\n      for (i = this.styleIndices_.length - 1; i >= 0; --i) {\n        start = this.styleIndices_[i];\n        nextStyle = this.styles_[i];\n        this.setFillStyle_(gl, /** @type {Array.<number>} */ (nextStyle[0]));\n        this.setStrokeStyle_(gl, /** @type {Array.<number>} */ (nextStyle[1]),\n          /** @type {number} */ (nextStyle[2]));\n        this.drawElements(gl, context, start, end);\n        end = start;\n      }\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawHitDetectionReplayOneByOne(gl, context, skippedFeaturesHash, featureCallback, opt_hitExtent) {\n    let i, start, end, nextStyle, groupStart, feature, featureUid, featureIndex;\n    featureIndex = this.startIndices.length - 2;\n    end = this.startIndices[featureIndex + 1];\n    for (i = this.styleIndices_.length - 1; i >= 0; --i) {\n      nextStyle = this.styles_[i];\n      this.setFillStyle_(gl, /** @type {Array.<number>} */ (nextStyle[0]));\n      this.setStrokeStyle_(gl, /** @type {Array.<number>} */ (nextStyle[1]),\n        /** @type {number} */ (nextStyle[2]));\n      groupStart = this.styleIndices_[i];\n\n      while (featureIndex >= 0 &&\n          this.startIndices[featureIndex] >= groupStart) {\n        start = this.startIndices[featureIndex];\n        feature = this.startIndicesFeature[featureIndex];\n        featureUid = getUid(feature).toString();\n\n        if (skippedFeaturesHash[featureUid] === undefined &&\n            feature.getGeometry() &&\n            (opt_hitExtent === undefined || intersects(\n              /** @type {Array<number>} */ (opt_hitExtent),\n              feature.getGeometry().getExtent()))) {\n          gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n          this.drawElements(gl, context, start, end);\n\n          const result = featureCallback(feature);\n\n          if (result) {\n            return result;\n          }\n\n        }\n        featureIndex--;\n        end = start;\n      }\n    }\n    return undefined;\n  }\n\n  /**\n   * @private\n   * @param {WebGLRenderingContext} gl gl.\n   * @param {module:ol/webgl/Context} context Context.\n   * @param {Object} skippedFeaturesHash Ids of features to skip.\n   */\n  drawReplaySkipping_(gl, context, skippedFeaturesHash) {\n    let i, start, end, nextStyle, groupStart, feature, featureUid, featureIndex, featureStart;\n    featureIndex = this.startIndices.length - 2;\n    end = start = this.startIndices[featureIndex + 1];\n    for (i = this.styleIndices_.length - 1; i >= 0; --i) {\n      nextStyle = this.styles_[i];\n      this.setFillStyle_(gl, /** @type {Array.<number>} */ (nextStyle[0]));\n      this.setStrokeStyle_(gl, /** @type {Array.<number>} */ (nextStyle[1]),\n        /** @type {number} */ (nextStyle[2]));\n      groupStart = this.styleIndices_[i];\n\n      while (featureIndex >= 0 &&\n          this.startIndices[featureIndex] >= groupStart) {\n        featureStart = this.startIndices[featureIndex];\n        feature = this.startIndicesFeature[featureIndex];\n        featureUid = getUid(feature).toString();\n\n        if (skippedFeaturesHash[featureUid]) {\n          if (start !== end) {\n            this.drawElements(gl, context, start, end);\n          }\n          end = featureStart;\n        }\n        featureIndex--;\n        start = featureStart;\n      }\n      if (start !== end) {\n        this.drawElements(gl, context, start, end);\n      }\n      start = end = groupStart;\n    }\n  }\n\n  /**\n   * @private\n   * @param {WebGLRenderingContext} gl gl.\n   * @param {Array.<number>} color Color.\n   */\n  setFillStyle_(gl, color) {\n    gl.uniform4fv(this.defaultLocations_.u_fillColor, color);\n  }\n\n  /**\n   * @private\n   * @param {WebGLRenderingContext} gl gl.\n   * @param {Array.<number>} color Color.\n   * @param {number} lineWidth Line width.\n   */\n  setStrokeStyle_(gl, color, lineWidth) {\n    gl.uniform4fv(this.defaultLocations_.u_strokeColor, color);\n    gl.uniform1f(this.defaultLocations_.u_lineWidth, lineWidth);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setFillStrokeStyle(fillStyle, strokeStyle) {\n    let strokeStyleColor, strokeStyleWidth;\n    if (strokeStyle) {\n      const strokeStyleLineDash = strokeStyle.getLineDash();\n      this.state_.lineDash = strokeStyleLineDash ?\n        strokeStyleLineDash : DEFAULT_LINEDASH;\n      const strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();\n      this.state_.lineDashOffset = strokeStyleLineDashOffset ?\n        strokeStyleLineDashOffset : DEFAULT_LINEDASHOFFSET;\n      strokeStyleColor = strokeStyle.getColor();\n      if (!(strokeStyleColor instanceof CanvasGradient) &&\n          !(strokeStyleColor instanceof CanvasPattern)) {\n        strokeStyleColor = asArray(strokeStyleColor).map(function(c, i) {\n          return i != 3 ? c / 255 : c;\n        }) || DEFAULT_STROKESTYLE;\n      } else {\n        strokeStyleColor = DEFAULT_STROKESTYLE;\n      }\n      strokeStyleWidth = strokeStyle.getWidth();\n      strokeStyleWidth = strokeStyleWidth !== undefined ?\n        strokeStyleWidth : DEFAULT_LINEWIDTH;\n    } else {\n      strokeStyleColor = [0, 0, 0, 0];\n      strokeStyleWidth = 0;\n    }\n    let fillStyleColor = fillStyle ? fillStyle.getColor() : [0, 0, 0, 0];\n    if (!(fillStyleColor instanceof CanvasGradient) &&\n        !(fillStyleColor instanceof CanvasPattern)) {\n      fillStyleColor = asArray(fillStyleColor).map(function(c, i) {\n        return i != 3 ? c / 255 : c;\n      }) || DEFAULT_FILLSTYLE;\n    } else {\n      fillStyleColor = DEFAULT_FILLSTYLE;\n    }\n    if (!this.state_.strokeColor || !equals(this.state_.strokeColor, strokeStyleColor) ||\n        !this.state_.fillColor || !equals(this.state_.fillColor, fillStyleColor) ||\n        this.state_.lineWidth !== strokeStyleWidth) {\n      this.state_.changed = true;\n      this.state_.fillColor = fillStyleColor;\n      this.state_.strokeColor = strokeStyleColor;\n      this.state_.lineWidth = strokeStyleWidth;\n      this.styles_.push([fillStyleColor, strokeStyleColor, strokeStyleWidth]);\n    }\n  }\n}\n\n\nexport default WebGLCircleReplay;\n","/**\n * @module ol/render/webgl/texturereplay/defaultshader\n */\n// This file is automatically generated, do not edit.\n// Run `make shaders` to generate, and commit the result.\n\nimport {DEBUG as DEBUG_WEBGL} from '../../../webgl.js';\nimport WebGLFragment from '../../../webgl/Fragment.js';\nimport WebGLVertex from '../../../webgl/Vertex.js';\n\nexport const fragment = new WebGLFragment(DEBUG_WEBGL ?\n  'precision mediump float;\\nvarying vec2 v_texCoord;\\nvarying float v_opacity;\\n\\nuniform float u_opacity;\\nuniform sampler2D u_image;\\n\\nvoid main(void) {\\n  vec4 texColor = texture2D(u_image, v_texCoord);\\n  gl_FragColor.rgb = texColor.rgb;\\n  float alpha = texColor.a * v_opacity * u_opacity;\\n  if (alpha == 0.0) {\\n    discard;\\n  }\\n  gl_FragColor.a = alpha;\\n}\\n' :\n  'precision mediump float;varying vec2 a;varying float b;uniform float k;uniform sampler2D l;void main(void){vec4 texColor=texture2D(l,a);gl_FragColor.rgb=texColor.rgb;float alpha=texColor.a*b*k;if(alpha==0.0){discard;}gl_FragColor.a=alpha;}');\n\nexport const vertex = new WebGLVertex(DEBUG_WEBGL ?\n  'varying vec2 v_texCoord;\\nvarying float v_opacity;\\n\\nattribute vec2 a_position;\\nattribute vec2 a_texCoord;\\nattribute vec2 a_offsets;\\nattribute float a_opacity;\\nattribute float a_rotateWithView;\\n\\nuniform mat4 u_projectionMatrix;\\nuniform mat4 u_offsetScaleMatrix;\\nuniform mat4 u_offsetRotateMatrix;\\n\\nvoid main(void) {\\n  mat4 offsetMatrix = u_offsetScaleMatrix;\\n  if (a_rotateWithView == 1.0) {\\n    offsetMatrix = u_offsetScaleMatrix * u_offsetRotateMatrix;\\n  }\\n  vec4 offsets = offsetMatrix * vec4(a_offsets, 0.0, 0.0);\\n  gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;\\n  v_texCoord = a_texCoord;\\n  v_opacity = a_opacity;\\n}\\n\\n\\n' :\n  'varying vec2 a;varying float b;attribute vec2 c;attribute vec2 d;attribute vec2 e;attribute float f;attribute float g;uniform mat4 h;uniform mat4 i;uniform mat4 j;void main(void){mat4 offsetMatrix=i;if(g==1.0){offsetMatrix=i*j;}vec4 offsets=offsetMatrix*vec4(e,0.0,0.0);gl_Position=h*vec4(c,0.0,1.0)+offsets;a=d;b=f;}');\n","/**\n * @module ol/render/webgl/texturereplay/defaultshader/Locations\n */\n// This file is automatically generated, do not edit\n// Run `make shaders` to generate, and commit the result.\n\nimport {DEBUG as DEBUG_WEBGL} from '../../../../webgl.js';\n\nclass Locations {\n\n  /**\n   * @param {WebGLRenderingContext} gl GL.\n   * @param {WebGLProgram} program Program.\n   */\n  constructor(gl, program) {\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_projectionMatrix = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_offsetScaleMatrix = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_offsetRotateMatrix = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_opacity = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_opacity' : 'k');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_image = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_image' : 'l');\n\n    /**\n     * @type {number}\n     */\n    this.a_position = gl.getAttribLocation(\n      program, DEBUG_WEBGL ? 'a_position' : 'c');\n\n    /**\n     * @type {number}\n     */\n    this.a_texCoord = gl.getAttribLocation(\n      program, DEBUG_WEBGL ? 'a_texCoord' : 'd');\n\n    /**\n     * @type {number}\n     */\n    this.a_offsets = gl.getAttribLocation(\n      program, DEBUG_WEBGL ? 'a_offsets' : 'e');\n\n    /**\n     * @type {number}\n     */\n    this.a_opacity = gl.getAttribLocation(\n      program, DEBUG_WEBGL ? 'a_opacity' : 'f');\n\n    /**\n     * @type {number}\n     */\n    this.a_rotateWithView = gl.getAttribLocation(\n      program, DEBUG_WEBGL ? 'a_rotateWithView' : 'g');\n\n  }\n\n}\n\nexport default Locations;\n","/**\n * @module ol/webgl/ContextEventType\n */\n\n/**\n * @enum {string}\n */\nexport default {\n  LOST: 'webglcontextlost',\n  RESTORED: 'webglcontextrestored'\n};\n","/**\n * @module ol/webgl/Context\n */\nimport {getUid} from '../util.js';\nimport {EXTENSIONS as WEBGL_EXTENSIONS} from '../webgl.js';\nimport Disposable from '../Disposable.js';\nimport {includes} from '../array.js';\nimport {listen, unlistenAll} from '../events.js';\nimport {clear} from '../obj.js';\nimport {ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER, TEXTURE_2D, TEXTURE_WRAP_S, TEXTURE_WRAP_T} from '../webgl.js';\nimport ContextEventType from '../webgl/ContextEventType.js';\n\n\n/**\n * @typedef {Object} BufferCacheEntry\n * @property {module:ol/webgl/Buffer} buf\n * @property {WebGLBuffer} buffer\n */\n\n\n/**\n * @classdesc\n * A WebGL context for accessing low-level WebGL capabilities.\n */\nclass WebGLContext extends Disposable {\n\n  /**\n   * @param {HTMLCanvasElement} canvas Canvas.\n   * @param {WebGLRenderingContext} gl GL.\n   */\n  constructor(canvas, gl) {\n    super();\n\n    /**\n     * @private\n     * @type {HTMLCanvasElement}\n     */\n    this.canvas_ = canvas;\n\n    /**\n     * @private\n     * @type {WebGLRenderingContext}\n     */\n    this.gl_ = gl;\n\n    /**\n     * @private\n     * @type {!Object.<string, module:ol/webgl/Context~BufferCacheEntry>}\n     */\n    this.bufferCache_ = {};\n\n    /**\n     * @private\n     * @type {!Object.<string, WebGLShader>}\n     */\n    this.shaderCache_ = {};\n\n    /**\n     * @private\n     * @type {!Object.<string, WebGLProgram>}\n     */\n    this.programCache_ = {};\n\n    /**\n     * @private\n     * @type {WebGLProgram}\n     */\n    this.currentProgram_ = null;\n\n    /**\n     * @private\n     * @type {WebGLFramebuffer}\n     */\n    this.hitDetectionFramebuffer_ = null;\n\n    /**\n     * @private\n     * @type {WebGLTexture}\n     */\n    this.hitDetectionTexture_ = null;\n\n    /**\n     * @private\n     * @type {WebGLRenderbuffer}\n     */\n    this.hitDetectionRenderbuffer_ = null;\n\n    /**\n     * @type {boolean}\n     */\n    this.hasOESElementIndexUint = includes(WEBGL_EXTENSIONS, 'OES_element_index_uint');\n\n    // use the OES_element_index_uint extension if available\n    if (this.hasOESElementIndexUint) {\n      gl.getExtension('OES_element_index_uint');\n    }\n\n    listen(this.canvas_, ContextEventType.LOST,\n      this.handleWebGLContextLost, this);\n    listen(this.canvas_, ContextEventType.RESTORED,\n      this.handleWebGLContextRestored, this);\n\n  }\n\n  /**\n   * Just bind the buffer if it's in the cache. Otherwise create\n   * the WebGL buffer, bind it, populate it, and add an entry to\n   * the cache.\n   * @param {number} target Target.\n   * @param {module:ol/webgl/Buffer} buf Buffer.\n   */\n  bindBuffer(target, buf) {\n    const gl = this.getGL();\n    const arr = buf.getArray();\n    const bufferKey = String(getUid(buf));\n    if (bufferKey in this.bufferCache_) {\n      const bufferCacheEntry = this.bufferCache_[bufferKey];\n      gl.bindBuffer(target, bufferCacheEntry.buffer);\n    } else {\n      const buffer = gl.createBuffer();\n      gl.bindBuffer(target, buffer);\n      let /** @type {ArrayBufferView} */ arrayBuffer;\n      if (target == ARRAY_BUFFER) {\n        arrayBuffer = new Float32Array(arr);\n      } else if (target == ELEMENT_ARRAY_BUFFER) {\n        arrayBuffer = this.hasOESElementIndexUint ?\n          new Uint32Array(arr) : new Uint16Array(arr);\n      }\n      gl.bufferData(target, arrayBuffer, buf.getUsage());\n      this.bufferCache_[bufferKey] = {\n        buf: buf,\n        buffer: buffer\n      };\n    }\n  }\n\n  /**\n   * @param {module:ol/webgl/Buffer} buf Buffer.\n   */\n  deleteBuffer(buf) {\n    const gl = this.getGL();\n    const bufferKey = String(getUid(buf));\n    const bufferCacheEntry = this.bufferCache_[bufferKey];\n    if (!gl.isContextLost()) {\n      gl.deleteBuffer(bufferCacheEntry.buffer);\n    }\n    delete this.bufferCache_[bufferKey];\n  }\n\n  /**\n   * @inheritDoc\n   */\n  disposeInternal() {\n    unlistenAll(this.canvas_);\n    const gl = this.getGL();\n    if (!gl.isContextLost()) {\n      for (const key in this.bufferCache_) {\n        gl.deleteBuffer(this.bufferCache_[key].buffer);\n      }\n      for (const key in this.programCache_) {\n        gl.deleteProgram(this.programCache_[key]);\n      }\n      for (const key in this.shaderCache_) {\n        gl.deleteShader(this.shaderCache_[key]);\n      }\n      // delete objects for hit-detection\n      gl.deleteFramebuffer(this.hitDetectionFramebuffer_);\n      gl.deleteRenderbuffer(this.hitDetectionRenderbuffer_);\n      gl.deleteTexture(this.hitDetectionTexture_);\n    }\n  }\n\n  /**\n   * @return {HTMLCanvasElement} Canvas.\n   */\n  getCanvas() {\n    return this.canvas_;\n  }\n\n  /**\n   * Get the WebGL rendering context\n   * @return {WebGLRenderingContext} The rendering context.\n   * @api\n   */\n  getGL() {\n    return this.gl_;\n  }\n\n  /**\n   * Get the frame buffer for hit detection.\n   * @return {WebGLFramebuffer} The hit detection frame buffer.\n   */\n  getHitDetectionFramebuffer() {\n    if (!this.hitDetectionFramebuffer_) {\n      this.initHitDetectionFramebuffer_();\n    }\n    return this.hitDetectionFramebuffer_;\n  }\n\n  /**\n   * Get shader from the cache if it's in the cache. Otherwise, create\n   * the WebGL shader, compile it, and add entry to cache.\n   * @param {module:ol/webgl/Shader} shaderObject Shader object.\n   * @return {WebGLShader} Shader.\n   */\n  getShader(shaderObject) {\n    const shaderKey = String(getUid(shaderObject));\n    if (shaderKey in this.shaderCache_) {\n      return this.shaderCache_[shaderKey];\n    } else {\n      const gl = this.getGL();\n      const shader = gl.createShader(shaderObject.getType());\n      gl.shaderSource(shader, shaderObject.getSource());\n      gl.compileShader(shader);\n      this.shaderCache_[shaderKey] = shader;\n      return shader;\n    }\n  }\n\n  /**\n   * Get the program from the cache if it's in the cache. Otherwise create\n   * the WebGL program, attach the shaders to it, and add an entry to the\n   * cache.\n   * @param {module:ol/webgl/Fragment} fragmentShaderObject Fragment shader.\n   * @param {module:ol/webgl/Vertex} vertexShaderObject Vertex shader.\n   * @return {WebGLProgram} Program.\n   */\n  getProgram(fragmentShaderObject, vertexShaderObject) {\n    const programKey = getUid(fragmentShaderObject) + '/' + getUid(vertexShaderObject);\n    if (programKey in this.programCache_) {\n      return this.programCache_[programKey];\n    } else {\n      const gl = this.getGL();\n      const program = gl.createProgram();\n      gl.attachShader(program, this.getShader(fragmentShaderObject));\n      gl.attachShader(program, this.getShader(vertexShaderObject));\n      gl.linkProgram(program);\n      this.programCache_[programKey] = program;\n      return program;\n    }\n  }\n\n  /**\n   * FIXME empty description for jsdoc\n   */\n  handleWebGLContextLost() {\n    clear(this.bufferCache_);\n    clear(this.shaderCache_);\n    clear(this.programCache_);\n    this.currentProgram_ = null;\n    this.hitDetectionFramebuffer_ = null;\n    this.hitDetectionTexture_ = null;\n    this.hitDetectionRenderbuffer_ = null;\n  }\n\n  /**\n   * FIXME empty description for jsdoc\n   */\n  handleWebGLContextRestored() {\n  }\n\n  /**\n   * Creates a 1x1 pixel framebuffer for the hit-detection.\n   * @private\n   */\n  initHitDetectionFramebuffer_() {\n    const gl = this.gl_;\n    const framebuffer = gl.createFramebuffer();\n    gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n\n    const texture = createEmptyTexture(gl, 1, 1);\n    const renderbuffer = gl.createRenderbuffer();\n    gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);\n    gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 1, 1);\n    gl.framebufferTexture2D(\n      gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\n    gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT,\n      gl.RENDERBUFFER, renderbuffer);\n\n    gl.bindTexture(gl.TEXTURE_2D, null);\n    gl.bindRenderbuffer(gl.RENDERBUFFER, null);\n    gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\n    this.hitDetectionFramebuffer_ = framebuffer;\n    this.hitDetectionTexture_ = texture;\n    this.hitDetectionRenderbuffer_ = renderbuffer;\n  }\n\n  /**\n   * Use a program.  If the program is already in use, this will return `false`.\n   * @param {WebGLProgram} program Program.\n   * @return {boolean} Changed.\n   * @api\n   */\n  useProgram(program) {\n    if (program == this.currentProgram_) {\n      return false;\n    } else {\n      const gl = this.getGL();\n      gl.useProgram(program);\n      this.currentProgram_ = program;\n      return true;\n    }\n  }\n}\n\n\n/**\n * @param {WebGLRenderingContext} gl WebGL rendering context.\n * @param {number=} opt_wrapS wrapS.\n * @param {number=} opt_wrapT wrapT.\n * @return {WebGLTexture} The texture.\n */\nfunction createTextureInternal(gl, opt_wrapS, opt_wrapT) {\n  const texture = gl.createTexture();\n  gl.bindTexture(gl.TEXTURE_2D, texture);\n  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n\n  if (opt_wrapS !== undefined) {\n    gl.texParameteri(\n      TEXTURE_2D, TEXTURE_WRAP_S, opt_wrapS);\n  }\n  if (opt_wrapT !== undefined) {\n    gl.texParameteri(\n      TEXTURE_2D, TEXTURE_WRAP_T, opt_wrapT);\n  }\n\n  return texture;\n}\n\n\n/**\n * @param {WebGLRenderingContext} gl WebGL rendering context.\n * @param {number} width Width.\n * @param {number} height Height.\n * @param {number=} opt_wrapS wrapS.\n * @param {number=} opt_wrapT wrapT.\n * @return {WebGLTexture} The texture.\n */\nexport function createEmptyTexture(gl, width, height, opt_wrapS, opt_wrapT) {\n  const texture = createTextureInternal(gl, opt_wrapS, opt_wrapT);\n  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n  return texture;\n}\n\n\n/**\n * @param {WebGLRenderingContext} gl WebGL rendering context.\n * @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image.\n * @param {number=} opt_wrapS wrapS.\n * @param {number=} opt_wrapT wrapT.\n * @return {WebGLTexture} The texture.\n */\nexport function createTexture(gl, image, opt_wrapS, opt_wrapT) {\n  const texture = createTextureInternal(gl, opt_wrapS, opt_wrapT);\n  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\n  return texture;\n}\n\nexport default WebGLContext;\n","/**\n * @module ol/render/webgl/TextureReplay\n */\nimport {getUid} from '../../util.js';\nimport {intersects} from '../../extent.js';\nimport {isEmpty} from '../../obj.js';\nimport {fragment, vertex} from '../webgl/texturereplay/defaultshader.js';\nimport Locations from '../webgl/texturereplay/defaultshader/Locations.js';\nimport WebGLReplay from '../webgl/Replay.js';\nimport {CLAMP_TO_EDGE, FLOAT, TEXTURE_2D} from '../../webgl.js';\nimport {createTexture} from '../../webgl/Context.js';\n\nclass WebGLTextureReplay extends WebGLReplay {\n  /**\n   * @param {number} tolerance Tolerance.\n   * @param {module:ol/extent~Extent} maxExtent Max extent.\n   */\n  constructor(tolerance, maxExtent) {\n    super(tolerance, maxExtent);\n\n    /**\n     * @type {number|undefined}\n     * @protected\n     */\n    this.anchorX = undefined;\n\n    /**\n     * @type {number|undefined}\n     * @protected\n     */\n    this.anchorY = undefined;\n\n    /**\n     * @type {Array.<number>}\n     * @protected\n     */\n    this.groupIndices = [];\n\n    /**\n     * @type {Array.<number>}\n     * @protected\n     */\n    this.hitDetectionGroupIndices = [];\n\n    /**\n     * @type {number|undefined}\n     * @protected\n     */\n    this.height = undefined;\n\n    /**\n     * @type {number|undefined}\n     * @protected\n     */\n    this.imageHeight = undefined;\n\n    /**\n     * @type {number|undefined}\n     * @protected\n     */\n    this.imageWidth = undefined;\n\n    /**\n     * @protected\n     * @type {module:ol/render/webgl/texturereplay/defaultshader/Locations}\n     */\n    this.defaultLocations = null;\n\n    /**\n     * @protected\n     * @type {number|undefined}\n     */\n    this.opacity = undefined;\n\n    /**\n     * @type {number|undefined}\n     * @protected\n     */\n    this.originX = undefined;\n\n    /**\n     * @type {number|undefined}\n     * @protected\n     */\n    this.originY = undefined;\n\n    /**\n     * @protected\n     * @type {boolean|undefined}\n     */\n    this.rotateWithView = undefined;\n\n    /**\n     * @protected\n     * @type {number|undefined}\n     */\n    this.rotation = undefined;\n\n    /**\n     * @protected\n     * @type {number|undefined}\n     */\n    this.scale = undefined;\n\n    /**\n     * @type {number|undefined}\n     * @protected\n     */\n    this.width = undefined;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getDeleteResourcesFunction(context) {\n    const verticesBuffer = this.verticesBuffer;\n    const indicesBuffer = this.indicesBuffer;\n    const textures = this.getTextures(true);\n    const gl = context.getGL();\n    return function() {\n      if (!gl.isContextLost()) {\n        let i, ii;\n        for (i = 0, ii = textures.length; i < ii; ++i) {\n          gl.deleteTexture(textures[i]);\n        }\n      }\n      context.deleteBuffer(verticesBuffer);\n      context.deleteBuffer(indicesBuffer);\n    };\n  }\n\n  /**\n   * @param {Array.<number>} flatCoordinates Flat coordinates.\n   * @param {number} offset Offset.\n   * @param {number} end End.\n   * @param {number} stride Stride.\n   * @return {number} My end.\n   * @protected\n   */\n  drawCoordinates(flatCoordinates, offset, end, stride) {\n    const anchorX = /** @type {number} */ (this.anchorX);\n    const anchorY = /** @type {number} */ (this.anchorY);\n    const height = /** @type {number} */ (this.height);\n    const imageHeight = /** @type {number} */ (this.imageHeight);\n    const imageWidth = /** @type {number} */ (this.imageWidth);\n    const opacity = /** @type {number} */ (this.opacity);\n    const originX = /** @type {number} */ (this.originX);\n    const originY = /** @type {number} */ (this.originY);\n    const rotateWithView = this.rotateWithView ? 1.0 : 0.0;\n    // this.rotation_ is anti-clockwise, but rotation is clockwise\n    const rotation = /** @type {number} */ (-this.rotation);\n    const scale = /** @type {number} */ (this.scale);\n    const width = /** @type {number} */ (this.width);\n    const cos = Math.cos(rotation);\n    const sin = Math.sin(rotation);\n    let numIndices = this.indices.length;\n    let numVertices = this.vertices.length;\n    let i, n, offsetX, offsetY, x, y;\n    for (i = offset; i < end; i += stride) {\n      x = flatCoordinates[i] - this.origin[0];\n      y = flatCoordinates[i + 1] - this.origin[1];\n\n      // There are 4 vertices per [x, y] point, one for each corner of the\n      // rectangle we're going to draw. We'd use 1 vertex per [x, y] point if\n      // WebGL supported Geometry Shaders (which can emit new vertices), but that\n      // is not currently the case.\n      //\n      // And each vertex includes 8 values: the x and y coordinates, the x and\n      // y offsets used to calculate the position of the corner, the u and\n      // v texture coordinates for the corner, the opacity, and whether the\n      // the image should be rotated with the view (rotateWithView).\n\n      n = numVertices / 8;\n\n      // bottom-left corner\n      offsetX = -scale * anchorX;\n      offsetY = -scale * (height - anchorY);\n      this.vertices[numVertices++] = x;\n      this.vertices[numVertices++] = y;\n      this.vertices[numVertices++] = offsetX * cos - offsetY * sin;\n      this.vertices[numVertices++] = offsetX * sin + offsetY * cos;\n      this.vertices[numVertices++] = originX / imageWidth;\n      this.vertices[numVertices++] = (originY + height) / imageHeight;\n      this.vertices[numVertices++] = opacity;\n      this.vertices[numVertices++] = rotateWithView;\n\n      // bottom-right corner\n      offsetX = scale * (width - anchorX);\n      offsetY = -scale * (height - anchorY);\n      this.vertices[numVertices++] = x;\n      this.vertices[numVertices++] = y;\n      this.vertices[numVertices++] = offsetX * cos - offsetY * sin;\n      this.vertices[numVertices++] = offsetX * sin + offsetY * cos;\n      this.vertices[numVertices++] = (originX + width) / imageWidth;\n      this.vertices[numVertices++] = (originY + height) / imageHeight;\n      this.vertices[numVertices++] = opacity;\n      this.vertices[numVertices++] = rotateWithView;\n\n      // top-right corner\n      offsetX = scale * (width - anchorX);\n      offsetY = scale * anchorY;\n      this.vertices[numVertices++] = x;\n      this.vertices[numVertices++] = y;\n      this.vertices[numVertices++] = offsetX * cos - offsetY * sin;\n      this.vertices[numVertices++] = offsetX * sin + offsetY * cos;\n      this.vertices[numVertices++] = (originX + width) / imageWidth;\n      this.vertices[numVertices++] = originY / imageHeight;\n      this.vertices[numVertices++] = opacity;\n      this.vertices[numVertices++] = rotateWithView;\n\n      // top-left corner\n      offsetX = -scale * anchorX;\n      offsetY = scale * anchorY;\n      this.vertices[numVertices++] = x;\n      this.vertices[numVertices++] = y;\n      this.vertices[numVertices++] = offsetX * cos - offsetY * sin;\n      this.vertices[numVertices++] = offsetX * sin + offsetY * cos;\n      this.vertices[numVertices++] = originX / imageWidth;\n      this.vertices[numVertices++] = originY / imageHeight;\n      this.vertices[numVertices++] = opacity;\n      this.vertices[numVertices++] = rotateWithView;\n\n      this.indices[numIndices++] = n;\n      this.indices[numIndices++] = n + 1;\n      this.indices[numIndices++] = n + 2;\n      this.indices[numIndices++] = n;\n      this.indices[numIndices++] = n + 2;\n      this.indices[numIndices++] = n + 3;\n    }\n\n    return numVertices;\n  }\n\n  /**\n   * @protected\n   * @param {Array.<WebGLTexture>} textures Textures.\n   * @param {Array.<HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>} images Images.\n   * @param {!Object.<string, WebGLTexture>} texturePerImage Texture cache.\n   * @param {WebGLRenderingContext} gl Gl.\n   */\n  createTextures(textures, images, texturePerImage, gl) {\n    let texture, image, uid, i;\n    const ii = images.length;\n    for (i = 0; i < ii; ++i) {\n      image = images[i];\n\n      uid = getUid(image).toString();\n      if (uid in texturePerImage) {\n        texture = texturePerImage[uid];\n      } else {\n        texture = createTexture(\n          gl, image, CLAMP_TO_EDGE, CLAMP_TO_EDGE);\n        texturePerImage[uid] = texture;\n      }\n      textures[i] = texture;\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setUpProgram(gl, context, size, pixelRatio) {\n    // get the program\n    const program = context.getProgram(fragment, vertex);\n\n    // get the locations\n    let locations;\n    if (!this.defaultLocations) {\n      locations = new Locations(gl, program);\n      this.defaultLocations = locations;\n    } else {\n      locations = this.defaultLocations;\n    }\n\n    // use the program (FIXME: use the return value)\n    context.useProgram(program);\n\n    // enable the vertex attrib arrays\n    gl.enableVertexAttribArray(locations.a_position);\n    gl.vertexAttribPointer(locations.a_position, 2, FLOAT,\n      false, 32, 0);\n\n    gl.enableVertexAttribArray(locations.a_offsets);\n    gl.vertexAttribPointer(locations.a_offsets, 2, FLOAT,\n      false, 32, 8);\n\n    gl.enableVertexAttribArray(locations.a_texCoord);\n    gl.vertexAttribPointer(locations.a_texCoord, 2, FLOAT,\n      false, 32, 16);\n\n    gl.enableVertexAttribArray(locations.a_opacity);\n    gl.vertexAttribPointer(locations.a_opacity, 1, FLOAT,\n      false, 32, 24);\n\n    gl.enableVertexAttribArray(locations.a_rotateWithView);\n    gl.vertexAttribPointer(locations.a_rotateWithView, 1, FLOAT,\n      false, 32, 28);\n\n    return locations;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  shutDownProgram(gl, locations) {\n    gl.disableVertexAttribArray(locations.a_position);\n    gl.disableVertexAttribArray(locations.a_offsets);\n    gl.disableVertexAttribArray(locations.a_texCoord);\n    gl.disableVertexAttribArray(locations.a_opacity);\n    gl.disableVertexAttribArray(locations.a_rotateWithView);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawReplay(gl, context, skippedFeaturesHash, hitDetection) {\n    const textures = hitDetection ? this.getHitDetectionTextures() : this.getTextures();\n    const groupIndices = hitDetection ? this.hitDetectionGroupIndices : this.groupIndices;\n\n    if (!isEmpty(skippedFeaturesHash)) {\n      this.drawReplaySkipping(gl, context, skippedFeaturesHash, textures, groupIndices);\n    } else {\n      let i, ii, start;\n      for (i = 0, ii = textures.length, start = 0; i < ii; ++i) {\n        gl.bindTexture(TEXTURE_2D, textures[i]);\n        const end = groupIndices[i];\n        this.drawElements(gl, context, start, end);\n        start = end;\n      }\n    }\n  }\n\n  /**\n   * Draw the replay while paying attention to skipped features.\n   *\n   * This functions creates groups of features that can be drawn to together,\n   * so that the number of `drawElements` calls is minimized.\n   *\n   * For example given the following texture groups:\n   *\n   *    Group 1: A B C\n   *    Group 2: D [E] F G\n   *\n   * If feature E should be skipped, the following `drawElements` calls will be\n   * made:\n   *\n   *    drawElements with feature A, B and C\n   *    drawElements with feature D\n   *    drawElements with feature F and G\n   *\n   * @protected\n   * @param {WebGLRenderingContext} gl gl.\n   * @param {module:ol/webgl/Context} context Context.\n   * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features\n   *  to skip.\n   * @param {Array.<WebGLTexture>} textures Textures.\n   * @param {Array.<number>} groupIndices Texture group indices.\n   */\n  drawReplaySkipping(gl, context, skippedFeaturesHash, textures, groupIndices) {\n    let featureIndex = 0;\n\n    let i, ii;\n    for (i = 0, ii = textures.length; i < ii; ++i) {\n      gl.bindTexture(TEXTURE_2D, textures[i]);\n      const groupStart = (i > 0) ? groupIndices[i - 1] : 0;\n      const groupEnd = groupIndices[i];\n\n      let start = groupStart;\n      let end = groupStart;\n      while (featureIndex < this.startIndices.length &&\n          this.startIndices[featureIndex] <= groupEnd) {\n        const feature = this.startIndicesFeature[featureIndex];\n\n        const featureUid = getUid(feature).toString();\n        if (skippedFeaturesHash[featureUid] !== undefined) {\n          // feature should be skipped\n          if (start !== end) {\n            // draw the features so far\n            this.drawElements(gl, context, start, end);\n          }\n          // continue with the next feature\n          start = (featureIndex === this.startIndices.length - 1) ?\n            groupEnd : this.startIndices[featureIndex + 1];\n          end = start;\n        } else {\n          // the feature is not skipped, augment the end index\n          end = (featureIndex === this.startIndices.length - 1) ?\n            groupEnd : this.startIndices[featureIndex + 1];\n        }\n        featureIndex++;\n      }\n\n      if (start !== end) {\n        // draw the remaining features (in case there was no skipped feature\n        // in this texture group, all features of a group are drawn together)\n        this.drawElements(gl, context, start, end);\n      }\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawHitDetectionReplayOneByOne(gl, context, skippedFeaturesHash, featureCallback, opt_hitExtent) {\n    let i, groupStart, start, end, feature, featureUid;\n    let featureIndex = this.startIndices.length - 1;\n    const hitDetectionTextures = this.getHitDetectionTextures();\n    for (i = hitDetectionTextures.length - 1; i >= 0; --i) {\n      gl.bindTexture(TEXTURE_2D, hitDetectionTextures[i]);\n      groupStart = (i > 0) ? this.hitDetectionGroupIndices[i - 1] : 0;\n      end = this.hitDetectionGroupIndices[i];\n\n      // draw all features for this texture group\n      while (featureIndex >= 0 &&\n          this.startIndices[featureIndex] >= groupStart) {\n        start = this.startIndices[featureIndex];\n        feature = this.startIndicesFeature[featureIndex];\n        featureUid = getUid(feature).toString();\n\n        if (skippedFeaturesHash[featureUid] === undefined &&\n            feature.getGeometry() &&\n            (opt_hitExtent === undefined || intersects(\n              /** @type {Array<number>} */ (opt_hitExtent),\n              feature.getGeometry().getExtent()))) {\n          gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n          this.drawElements(gl, context, start, end);\n\n          const result = featureCallback(feature);\n          if (result) {\n            return result;\n          }\n        }\n\n        end = start;\n        featureIndex--;\n      }\n    }\n    return undefined;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  finish(context) {\n    this.anchorX = undefined;\n    this.anchorY = undefined;\n    this.height = undefined;\n    this.imageHeight = undefined;\n    this.imageWidth = undefined;\n    this.indices = null;\n    this.opacity = undefined;\n    this.originX = undefined;\n    this.originY = undefined;\n    this.rotateWithView = undefined;\n    this.rotation = undefined;\n    this.scale = undefined;\n    this.vertices = null;\n    this.width = undefined;\n  }\n\n  /**\n   * @abstract\n   * @protected\n   * @param {boolean=} opt_all Return hit detection textures with regular ones.\n   * @returns {Array.<WebGLTexture>} Textures.\n   */\n  getTextures(opt_all) {}\n\n  /**\n   * @abstract\n   * @protected\n   * @returns {Array.<WebGLTexture>} Textures.\n   */\n  getHitDetectionTextures() {}\n}\n\n\nexport default WebGLTextureReplay;\n","/**\n * @module ol/render/webgl/ImageReplay\n */\nimport {getUid} from '../../util.js';\nimport WebGLTextureReplay from '../webgl/TextureReplay.js';\nimport WebGLBuffer from '../../webgl/Buffer.js';\n\nclass WebGLImageReplay extends WebGLTextureReplay {\n  /**\n   * @param {number} tolerance Tolerance.\n   * @param {module:ol/extent~Extent} maxExtent Max extent.\n   */\n  constructor(tolerance, maxExtent) {\n    super(tolerance, maxExtent);\n\n    /**\n     * @type {Array.<HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>}\n     * @protected\n     */\n    this.images_ = [];\n\n    /**\n     * @type {Array.<HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>}\n     * @protected\n     */\n    this.hitDetectionImages_ = [];\n\n    /**\n     * @type {Array.<WebGLTexture>}\n     * @private\n     */\n    this.textures_ = [];\n\n    /**\n     * @type {Array.<WebGLTexture>}\n     * @private\n     */\n    this.hitDetectionTextures_ = [];\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawMultiPoint(multiPointGeometry, feature) {\n    this.startIndices.push(this.indices.length);\n    this.startIndicesFeature.push(feature);\n    const flatCoordinates = multiPointGeometry.getFlatCoordinates();\n    const stride = multiPointGeometry.getStride();\n    this.drawCoordinates(\n      flatCoordinates, 0, flatCoordinates.length, stride);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawPoint(pointGeometry, feature) {\n    this.startIndices.push(this.indices.length);\n    this.startIndicesFeature.push(feature);\n    const flatCoordinates = pointGeometry.getFlatCoordinates();\n    const stride = pointGeometry.getStride();\n    this.drawCoordinates(\n      flatCoordinates, 0, flatCoordinates.length, stride);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  finish(context) {\n    const gl = context.getGL();\n\n    this.groupIndices.push(this.indices.length);\n    this.hitDetectionGroupIndices.push(this.indices.length);\n\n    // create, bind, and populate the vertices buffer\n    this.verticesBuffer = new WebGLBuffer(this.vertices);\n\n    const indices = this.indices;\n\n    // create, bind, and populate the indices buffer\n    this.indicesBuffer = new WebGLBuffer(indices);\n\n    // create textures\n    /** @type {Object.<string, WebGLTexture>} */\n    const texturePerImage = {};\n\n    this.createTextures(this.textures_, this.images_, texturePerImage, gl);\n\n    this.createTextures(this.hitDetectionTextures_, this.hitDetectionImages_,\n      texturePerImage, gl);\n\n    this.images_ = null;\n    this.hitDetectionImages_ = null;\n    WebGLTextureReplay.prototype.finish.call(this, context);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setImageStyle(imageStyle) {\n    const anchor = imageStyle.getAnchor();\n    const image = imageStyle.getImage(1);\n    const imageSize = imageStyle.getImageSize();\n    const hitDetectionImage = imageStyle.getHitDetectionImage(1);\n    const opacity = imageStyle.getOpacity();\n    const origin = imageStyle.getOrigin();\n    const rotateWithView = imageStyle.getRotateWithView();\n    const rotation = imageStyle.getRotation();\n    const size = imageStyle.getSize();\n    const scale = imageStyle.getScale();\n\n    let currentImage;\n    if (this.images_.length === 0) {\n      this.images_.push(image);\n    } else {\n      currentImage = this.images_[this.images_.length - 1];\n      if (getUid(currentImage) != getUid(image)) {\n        this.groupIndices.push(this.indices.length);\n        this.images_.push(image);\n      }\n    }\n\n    if (this.hitDetectionImages_.length === 0) {\n      this.hitDetectionImages_.push(hitDetectionImage);\n    } else {\n      currentImage =\n          this.hitDetectionImages_[this.hitDetectionImages_.length - 1];\n      if (getUid(currentImage) != getUid(hitDetectionImage)) {\n        this.hitDetectionGroupIndices.push(this.indices.length);\n        this.hitDetectionImages_.push(hitDetectionImage);\n      }\n    }\n\n    this.anchorX = anchor[0];\n    this.anchorY = anchor[1];\n    this.height = size[1];\n    this.imageHeight = imageSize[1];\n    this.imageWidth = imageSize[0];\n    this.opacity = opacity;\n    this.originX = origin[0];\n    this.originY = origin[1];\n    this.rotation = rotation;\n    this.rotateWithView = rotateWithView;\n    this.scale = scale;\n    this.width = size[0];\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getTextures(opt_all) {\n    return opt_all ? this.textures_.concat(this.hitDetectionTextures_) : this.textures_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getHitDetectionTextures() {\n    return this.hitDetectionTextures_;\n  }\n}\n\n\nexport default WebGLImageReplay;\n","/**\n * @module ol/geom/flat/topology\n */\nimport {linearRing as linearRingArea} from '../flat/area.js';\n\n/**\n * Check if the linestring is a boundary.\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {boolean} The linestring is a boundary.\n */\nexport function lineStringIsClosed(flatCoordinates, offset, end, stride) {\n  const lastCoord = end - stride;\n  if (flatCoordinates[offset] === flatCoordinates[lastCoord] &&\n      flatCoordinates[offset + 1] === flatCoordinates[lastCoord + 1] && (end - offset) / stride > 3) {\n    return !!linearRingArea(flatCoordinates, offset, end, stride);\n  }\n  return false;\n}\n","/**\n * @module ol/render/webgl/linestringreplay/defaultshader\n */\n// This file is automatically generated, do not edit.\n// Run `make shaders` to generate, and commit the result.\n\nimport {DEBUG as DEBUG_WEBGL} from '../../../webgl.js';\nimport WebGLFragment from '../../../webgl/Fragment.js';\nimport WebGLVertex from '../../../webgl/Vertex.js';\n\nexport const fragment = new WebGLFragment(DEBUG_WEBGL ?\n  'precision mediump float;\\nvarying float v_round;\\nvarying vec2 v_roundVertex;\\nvarying float v_halfWidth;\\n\\n\\n\\nuniform float u_opacity;\\nuniform vec4 u_color;\\nuniform vec2 u_size;\\nuniform float u_pixelRatio;\\n\\nvoid main(void) {\\n  if (v_round > 0.0) {\\n    vec2 windowCoords = vec2((v_roundVertex.x + 1.0) / 2.0 * u_size.x * u_pixelRatio,\\n        (v_roundVertex.y + 1.0) / 2.0 * u_size.y * u_pixelRatio);\\n    if (length(windowCoords - gl_FragCoord.xy) > v_halfWidth * u_pixelRatio) {\\n      discard;\\n    }\\n  }\\n  gl_FragColor = u_color;\\n  float alpha = u_color.a * u_opacity;\\n  if (alpha == 0.0) {\\n    discard;\\n  }\\n  gl_FragColor.a = alpha;\\n}\\n' :\n  'precision mediump float;varying float a;varying vec2 aVertex;varying float c;uniform float m;uniform vec4 n;uniform vec2 o;uniform float p;void main(void){if(a>0.0){vec2 windowCoords=vec2((aVertex.x+1.0)/2.0*o.x*p,(aVertex.y+1.0)/2.0*o.y*p);if(length(windowCoords-gl_FragCoord.xy)>c*p){discard;}} gl_FragColor=n;float alpha=n.a*m;if(alpha==0.0){discard;}gl_FragColor.a=alpha;}');\n\nexport const vertex = new WebGLVertex(DEBUG_WEBGL ?\n  'varying float v_round;\\nvarying vec2 v_roundVertex;\\nvarying float v_halfWidth;\\n\\n\\nattribute vec2 a_lastPos;\\nattribute vec2 a_position;\\nattribute vec2 a_nextPos;\\nattribute float a_direction;\\n\\nuniform mat4 u_projectionMatrix;\\nuniform mat4 u_offsetScaleMatrix;\\nuniform mat4 u_offsetRotateMatrix;\\nuniform float u_lineWidth;\\nuniform float u_miterLimit;\\n\\nbool nearlyEquals(in float value, in float ref) {\\n  float epsilon = 0.000000000001;\\n  return value >= ref - epsilon && value <= ref + epsilon;\\n}\\n\\nvoid alongNormal(out vec2 offset, in vec2 nextP, in float turnDir, in float direction) {\\n  vec2 dirVect = nextP - a_position;\\n  vec2 normal = normalize(vec2(-turnDir * dirVect.y, turnDir * dirVect.x));\\n  offset = u_lineWidth / 2.0 * normal * direction;\\n}\\n\\nvoid miterUp(out vec2 offset, out float round, in bool isRound, in float direction) {\\n  float halfWidth = u_lineWidth / 2.0;\\n  vec2 tangent = normalize(normalize(a_nextPos - a_position) + normalize(a_position - a_lastPos));\\n  vec2 normal = vec2(-tangent.y, tangent.x);\\n  vec2 dirVect = a_nextPos - a_position;\\n  vec2 tmpNormal = normalize(vec2(-dirVect.y, dirVect.x));\\n  float miterLength = abs(halfWidth / dot(normal, tmpNormal));\\n  offset = normal * direction * miterLength;\\n  round = 0.0;\\n  if (isRound) {\\n    round = 1.0;\\n  } else if (miterLength > u_miterLimit + u_lineWidth) {\\n    offset = halfWidth * tmpNormal * direction;\\n  }\\n}\\n\\nbool miterDown(out vec2 offset, in vec4 projPos, in mat4 offsetMatrix, in float direction) {\\n  bool degenerate = false;\\n  vec2 tangent = normalize(normalize(a_nextPos - a_position) + normalize(a_position - a_lastPos));\\n  vec2 normal = vec2(-tangent.y, tangent.x);\\n  vec2 dirVect = a_lastPos - a_position;\\n  vec2 tmpNormal = normalize(vec2(-dirVect.y, dirVect.x));\\n  vec2 longOffset, shortOffset, longVertex;\\n  vec4 shortProjVertex;\\n  float halfWidth = u_lineWidth / 2.0;\\n  if (length(a_nextPos - a_position) > length(a_lastPos - a_position)) {\\n    longOffset = tmpNormal * direction * halfWidth;\\n    shortOffset = normalize(vec2(dirVect.y, -dirVect.x)) * direction * halfWidth;\\n    longVertex = a_nextPos;\\n    shortProjVertex = u_projectionMatrix * vec4(a_lastPos, 0.0, 1.0);\\n  } else {\\n    shortOffset = tmpNormal * direction * halfWidth;\\n    longOffset = normalize(vec2(dirVect.y, -dirVect.x)) * direction * halfWidth;\\n    longVertex = a_lastPos;\\n    shortProjVertex = u_projectionMatrix * vec4(a_nextPos, 0.0, 1.0);\\n  }\\n  //Intersection algorithm based on theory by Paul Bourke (http://paulbourke.net/geometry/pointlineplane/).\\n  vec4 p1 = u_projectionMatrix * vec4(longVertex, 0.0, 1.0) + offsetMatrix * vec4(longOffset, 0.0, 0.0);\\n  vec4 p2 = projPos + offsetMatrix * vec4(longOffset, 0.0, 0.0);\\n  vec4 p3 = shortProjVertex + offsetMatrix * vec4(-shortOffset, 0.0, 0.0);\\n  vec4 p4 = shortProjVertex + offsetMatrix * vec4(shortOffset, 0.0, 0.0);\\n  float denom = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y);\\n  float firstU = ((p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x)) / denom;\\n  float secondU = ((p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x)) / denom;\\n  float epsilon = 0.000000000001;\\n  if (firstU > epsilon && firstU < 1.0 - epsilon && secondU > epsilon && secondU < 1.0 - epsilon) {\\n    shortProjVertex.x = p1.x + firstU * (p2.x - p1.x);\\n    shortProjVertex.y = p1.y + firstU * (p2.y - p1.y);\\n    offset = shortProjVertex.xy;\\n    degenerate = true;\\n  } else {\\n    float miterLength = abs(halfWidth / dot(normal, tmpNormal));\\n    offset = normal * direction * miterLength;\\n  }\\n  return degenerate;\\n}\\n\\nvoid squareCap(out vec2 offset, out float round, in bool isRound, in vec2 nextP,\\n    in float turnDir, in float direction) {\\n  round = 0.0;\\n  vec2 dirVect = a_position - nextP;\\n  vec2 firstNormal = normalize(dirVect);\\n  vec2 secondNormal = vec2(turnDir * firstNormal.y * direction, -turnDir * firstNormal.x * direction);\\n  vec2 hypotenuse = normalize(firstNormal - secondNormal);\\n  vec2 normal = vec2(turnDir * hypotenuse.y * direction, -turnDir * hypotenuse.x * direction);\\n  float length = sqrt(v_halfWidth * v_halfWidth * 2.0);\\n  offset = normal * length;\\n  if (isRound) {\\n    round = 1.0;\\n  }\\n}\\n\\nvoid main(void) {\\n  bool degenerate = false;\\n  float direction = float(sign(a_direction));\\n  mat4 offsetMatrix = u_offsetScaleMatrix * u_offsetRotateMatrix;\\n  vec2 offset;\\n  vec4 projPos = u_projectionMatrix * vec4(a_position, 0.0, 1.0);\\n  bool round = nearlyEquals(mod(a_direction, 2.0), 0.0);\\n\\n  v_round = 0.0;\\n  v_halfWidth = u_lineWidth / 2.0;\\n  v_roundVertex = projPos.xy;\\n\\n  if (nearlyEquals(mod(a_direction, 3.0), 0.0) || nearlyEquals(mod(a_direction, 17.0), 0.0)) {\\n    alongNormal(offset, a_nextPos, 1.0, direction);\\n  } else if (nearlyEquals(mod(a_direction, 5.0), 0.0) || nearlyEquals(mod(a_direction, 13.0), 0.0)) {\\n    alongNormal(offset, a_lastPos, -1.0, direction);\\n  } else if (nearlyEquals(mod(a_direction, 23.0), 0.0)) {\\n    miterUp(offset, v_round, round, direction);\\n  } else if (nearlyEquals(mod(a_direction, 19.0), 0.0)) {\\n    degenerate = miterDown(offset, projPos, offsetMatrix, direction);\\n  } else if (nearlyEquals(mod(a_direction, 7.0), 0.0)) {\\n    squareCap(offset, v_round, round, a_nextPos, 1.0, direction);\\n  } else if (nearlyEquals(mod(a_direction, 11.0), 0.0)) {\\n    squareCap(offset, v_round, round, a_lastPos, -1.0, direction);\\n  }\\n  if (!degenerate) {\\n    vec4 offsets = offsetMatrix * vec4(offset, 0.0, 0.0);\\n    gl_Position = projPos + offsets;\\n  } else {\\n    gl_Position = vec4(offset, 0.0, 1.0);\\n  }\\n}\\n\\n\\n' :\n  'varying float a;varying vec2 aVertex;varying float c;attribute vec2 d;attribute vec2 e;attribute vec2 f;attribute float g;uniform mat4 h;uniform mat4 i;uniform mat4 j;uniform float k;uniform float l;bool nearlyEquals(in float value,in float ref){float epsilon=0.000000000001;return value>=ref-epsilon&&value<=ref+epsilon;}void alongNormal(out vec2 offset,in vec2 nextP,in float turnDir,in float direction){vec2 dirVect=nextP-e;vec2 normal=normalize(vec2(-turnDir*dirVect.y,turnDir*dirVect.x));offset=k/2.0*normal*direction;}void miterUp(out vec2 offset,out float round,in bool isRound,in float direction){float halfWidth=k/2.0;vec2 tangent=normalize(normalize(f-e)+normalize(e-d));vec2 normal=vec2(-tangent.y,tangent.x);vec2 dirVect=f-e;vec2 tmpNormal=normalize(vec2(-dirVect.y,dirVect.x));float miterLength=abs(halfWidth/dot(normal,tmpNormal));offset=normal*direction*miterLength;round=0.0;if(isRound){round=1.0;}else if(miterLength>l+k){offset=halfWidth*tmpNormal*direction;}} bool miterDown(out vec2 offset,in vec4 projPos,in mat4 offsetMatrix,in float direction){bool degenerate=false;vec2 tangent=normalize(normalize(f-e)+normalize(e-d));vec2 normal=vec2(-tangent.y,tangent.x);vec2 dirVect=d-e;vec2 tmpNormal=normalize(vec2(-dirVect.y,dirVect.x));vec2 longOffset,shortOffset,longVertex;vec4 shortProjVertex;float halfWidth=k/2.0;if(length(f-e)>length(d-e)){longOffset=tmpNormal*direction*halfWidth;shortOffset=normalize(vec2(dirVect.y,-dirVect.x))*direction*halfWidth;longVertex=f;shortProjVertex=h*vec4(d,0.0,1.0);}else{shortOffset=tmpNormal*direction*halfWidth;longOffset=normalize(vec2(dirVect.y,-dirVect.x))*direction*halfWidth;longVertex=d;shortProjVertex=h*vec4(f,0.0,1.0);}vec4 p1=h*vec4(longVertex,0.0,1.0)+offsetMatrix*vec4(longOffset,0.0,0.0);vec4 p2=projPos+offsetMatrix*vec4(longOffset,0.0,0.0);vec4 p3=shortProjVertex+offsetMatrix*vec4(-shortOffset,0.0,0.0);vec4 p4=shortProjVertex+offsetMatrix*vec4(shortOffset,0.0,0.0);float denom=(p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y);float firstU=((p4.x-p3.x)*(p1.y-p3.y)-(p4.y-p3.y)*(p1.x-p3.x))/denom;float secondU=((p2.x-p1.x)*(p1.y-p3.y)-(p2.y-p1.y)*(p1.x-p3.x))/denom;float epsilon=0.000000000001;if(firstU>epsilon&&firstU<1.0-epsilon&&secondU>epsilon&&secondU<1.0-epsilon){shortProjVertex.x=p1.x+firstU*(p2.x-p1.x);shortProjVertex.y=p1.y+firstU*(p2.y-p1.y);offset=shortProjVertex.xy;degenerate=true;}else{float miterLength=abs(halfWidth/dot(normal,tmpNormal));offset=normal*direction*miterLength;}return degenerate;}void squareCap(out vec2 offset,out float round,in bool isRound,in vec2 nextP,in float turnDir,in float direction){round=0.0;vec2 dirVect=e-nextP;vec2 firstNormal=normalize(dirVect);vec2 secondNormal=vec2(turnDir*firstNormal.y*direction,-turnDir*firstNormal.x*direction);vec2 hypotenuse=normalize(firstNormal-secondNormal);vec2 normal=vec2(turnDir*hypotenuse.y*direction,-turnDir*hypotenuse.x*direction);float length=sqrt(c*c*2.0);offset=normal*length;if(isRound){round=1.0;}} void main(void){bool degenerate=false;float direction=float(sign(g));mat4 offsetMatrix=i*j;vec2 offset;vec4 projPos=h*vec4(e,0.0,1.0);bool round=nearlyEquals(mod(g,2.0),0.0);a=0.0;c=k/2.0;aVertex=projPos.xy;if(nearlyEquals(mod(g,3.0),0.0)||nearlyEquals(mod(g,17.0),0.0)){alongNormal(offset,f,1.0,direction);}else if(nearlyEquals(mod(g,5.0),0.0)||nearlyEquals(mod(g,13.0),0.0)){alongNormal(offset,d,-1.0,direction);}else if(nearlyEquals(mod(g,23.0),0.0)){miterUp(offset,a,round,direction);}else if(nearlyEquals(mod(g,19.0),0.0)){degenerate=miterDown(offset,projPos,offsetMatrix,direction);}else if(nearlyEquals(mod(g,7.0),0.0)){squareCap(offset,a,round,f,1.0,direction);}else if(nearlyEquals(mod(g,11.0),0.0)){squareCap(offset,a,round,d,-1.0,direction);}if(!degenerate){vec4 offsets=offsetMatrix*vec4(offset,0.0,0.0);gl_Position=projPos+offsets;}else{gl_Position=vec4(offset,0.0,1.0);}}');\n","/**\n * @module ol/render/webgl/linestringreplay/defaultshader/Locations\n */\n// This file is automatically generated, do not edit\n// Run `make shaders` to generate, and commit the result.\n\nimport {DEBUG as DEBUG_WEBGL} from '../../../../webgl.js';\n\nclass Locations {\n\n  /**\n   * @param {WebGLRenderingContext} gl GL.\n   * @param {WebGLProgram} program Program.\n   */\n  constructor(gl, program) {\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_projectionMatrix = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_offsetScaleMatrix = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_offsetRotateMatrix = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_lineWidth = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_lineWidth' : 'k');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_miterLimit = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_miterLimit' : 'l');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_opacity = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_opacity' : 'm');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_color = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_color' : 'n');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_size = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_size' : 'o');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_pixelRatio = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_pixelRatio' : 'p');\n\n    /**\n     * @type {number}\n     */\n    this.a_lastPos = gl.getAttribLocation(\n      program, DEBUG_WEBGL ? 'a_lastPos' : 'd');\n\n    /**\n     * @type {number}\n     */\n    this.a_position = gl.getAttribLocation(\n      program, DEBUG_WEBGL ? 'a_position' : 'e');\n\n    /**\n     * @type {number}\n     */\n    this.a_nextPos = gl.getAttribLocation(\n      program, DEBUG_WEBGL ? 'a_nextPos' : 'f');\n\n    /**\n     * @type {number}\n     */\n    this.a_direction = gl.getAttribLocation(\n      program, DEBUG_WEBGL ? 'a_direction' : 'g');\n\n  }\n\n}\n\nexport default Locations;\n","/**\n * @module ol/render/webgl/LineStringReplay\n */\nimport {getUid} from '../../util.js';\nimport {equals} from '../../array.js';\nimport {asArray} from '../../color.js';\nimport {intersects} from '../../extent.js';\nimport {linearRingIsClockwise} from '../../geom/flat/orient.js';\nimport {translate} from '../../geom/flat/transform.js';\nimport {lineStringIsClosed} from '../../geom/flat/topology.js';\nimport {isEmpty} from '../../obj.js';\nimport {DEFAULT_LINECAP, DEFAULT_LINEDASH, DEFAULT_LINEDASHOFFSET,\n  DEFAULT_LINEJOIN, DEFAULT_LINEWIDTH, DEFAULT_MITERLIMIT, DEFAULT_STROKESTYLE,\n  triangleIsCounterClockwise} from '../webgl.js';\nimport WebGLReplay from '../webgl/Replay.js';\nimport {fragment, vertex} from '../webgl/linestringreplay/defaultshader.js';\nimport Locations from '../webgl/linestringreplay/defaultshader/Locations.js';\nimport {FLOAT} from '../../webgl.js';\nimport WebGLBuffer from '../../webgl/Buffer.js';\n\n\n/**\n * @enum {number}\n */\nconst Instruction = {\n  ROUND: 2,\n  BEGIN_LINE: 3,\n  END_LINE: 5,\n  BEGIN_LINE_CAP: 7,\n  END_LINE_CAP: 11,\n  BEVEL_FIRST: 13,\n  BEVEL_SECOND: 17,\n  MITER_BOTTOM: 19,\n  MITER_TOP: 23\n};\n\n\nclass WebGLLineStringReplay extends WebGLReplay {\n  /**\n   * @param {number} tolerance Tolerance.\n   * @param {module:ol/extent~Extent} maxExtent Max extent.\n   */\n  constructor(tolerance, maxExtent) {\n    super(tolerance, maxExtent);\n\n    /**\n     * @private\n     * @type {module:ol/render/webgl/linestringreplay/defaultshader/Locations}\n     */\n    this.defaultLocations_ = null;\n\n    /**\n     * @private\n     * @type {Array.<Array.<?>>}\n     */\n    this.styles_ = [];\n\n    /**\n     * @private\n     * @type {Array.<number>}\n     */\n    this.styleIndices_ = [];\n\n    /**\n     * @private\n     * @type {{strokeColor: (Array.<number>|null),\n     *         lineCap: (string|undefined),\n     *         lineDash: Array.<number>,\n     *         lineDashOffset: (number|undefined),\n     *         lineJoin: (string|undefined),\n     *         lineWidth: (number|undefined),\n     *         miterLimit: (number|undefined),\n     *         changed: boolean}|null}\n     */\n    this.state_ = {\n      strokeColor: null,\n      lineCap: undefined,\n      lineDash: null,\n      lineDashOffset: undefined,\n      lineJoin: undefined,\n      lineWidth: undefined,\n      miterLimit: undefined,\n      changed: false\n    };\n\n  }\n\n  /**\n   * Draw one segment.\n   * @private\n   * @param {Array.<number>} flatCoordinates Flat coordinates.\n   * @param {number} offset Offset.\n   * @param {number} end End.\n   * @param {number} stride Stride.\n   */\n  drawCoordinates_(flatCoordinates, offset, end, stride) {\n\n    let i, ii;\n    let numVertices = this.vertices.length;\n    let numIndices = this.indices.length;\n    //To save a vertex, the direction of a point is a product of the sign (1 or -1), a prime from\n    //Instruction, and a rounding factor (1 or 2). If the product is even,\n    //we round it. If it is odd, we don't.\n    const lineJoin = this.state_.lineJoin === 'bevel' ? 0 :\n      this.state_.lineJoin === 'miter' ? 1 : 2;\n    const lineCap = this.state_.lineCap === 'butt' ? 0 :\n      this.state_.lineCap === 'square' ? 1 : 2;\n    const closed = lineStringIsClosed(flatCoordinates, offset, end, stride);\n    let startCoords, sign, n;\n    let lastIndex = numIndices;\n    let lastSign = 1;\n    //We need the adjacent vertices to define normals in joins. p0 = last, p1 = current, p2 = next.\n    let p0, p1, p2;\n\n    for (i = offset, ii = end; i < ii; i += stride) {\n\n      n = numVertices / 7;\n\n      p0 = p1;\n      p1 = p2 || [flatCoordinates[i], flatCoordinates[i + 1]];\n      //First vertex.\n      if (i === offset) {\n        p2 = [flatCoordinates[i + stride], flatCoordinates[i + stride + 1]];\n        if (end - offset === stride * 2 && equals(p1, p2)) {\n          break;\n        }\n        if (closed) {\n          //A closed line! Complete the circle.\n          p0 = [flatCoordinates[end - stride * 2],\n            flatCoordinates[end - stride * 2 + 1]];\n\n          startCoords = p2;\n        } else {\n          //Add the first two/four vertices.\n\n          if (lineCap) {\n            numVertices = this.addVertices_([0, 0], p1, p2,\n              lastSign * Instruction.BEGIN_LINE_CAP * lineCap, numVertices);\n\n            numVertices = this.addVertices_([0, 0], p1, p2,\n              -lastSign * Instruction.BEGIN_LINE_CAP * lineCap, numVertices);\n\n            this.indices[numIndices++] = n + 2;\n            this.indices[numIndices++] = n;\n            this.indices[numIndices++] = n + 1;\n\n            this.indices[numIndices++] = n + 1;\n            this.indices[numIndices++] = n + 3;\n            this.indices[numIndices++] = n + 2;\n\n          }\n\n          numVertices = this.addVertices_([0, 0], p1, p2,\n            lastSign * Instruction.BEGIN_LINE * (lineCap || 1), numVertices);\n\n          numVertices = this.addVertices_([0, 0], p1, p2,\n            -lastSign * Instruction.BEGIN_LINE * (lineCap || 1), numVertices);\n\n          lastIndex = numVertices / 7 - 1;\n\n          continue;\n        }\n      } else if (i === end - stride) {\n        //Last vertex.\n        if (closed) {\n          //Same as the first vertex.\n          p2 = startCoords;\n          break;\n        } else {\n          p0 = p0 || [0, 0];\n\n          numVertices = this.addVertices_(p0, p1, [0, 0],\n            lastSign * Instruction.END_LINE * (lineCap || 1), numVertices);\n\n          numVertices = this.addVertices_(p0, p1, [0, 0],\n            -lastSign * Instruction.END_LINE * (lineCap || 1), numVertices);\n\n          this.indices[numIndices++] = n;\n          this.indices[numIndices++] = lastIndex - 1;\n          this.indices[numIndices++] = lastIndex;\n\n          this.indices[numIndices++] = lastIndex;\n          this.indices[numIndices++] = n + 1;\n          this.indices[numIndices++] = n;\n\n          if (lineCap) {\n            numVertices = this.addVertices_(p0, p1, [0, 0],\n              lastSign * Instruction.END_LINE_CAP * lineCap, numVertices);\n\n            numVertices = this.addVertices_(p0, p1, [0, 0],\n              -lastSign * Instruction.END_LINE_CAP * lineCap, numVertices);\n\n            this.indices[numIndices++] = n + 2;\n            this.indices[numIndices++] = n;\n            this.indices[numIndices++] = n + 1;\n\n            this.indices[numIndices++] = n + 1;\n            this.indices[numIndices++] = n + 3;\n            this.indices[numIndices++] = n + 2;\n\n          }\n\n          break;\n        }\n      } else {\n        p2 = [flatCoordinates[i + stride], flatCoordinates[i + stride + 1]];\n      }\n\n      // We group CW and straight lines, thus the not so inituitive CCW checking function.\n      sign = triangleIsCounterClockwise(p0[0], p0[1], p1[0], p1[1], p2[0], p2[1])\n        ? -1 : 1;\n\n      numVertices = this.addVertices_(p0, p1, p2,\n        sign * Instruction.BEVEL_FIRST * (lineJoin || 1), numVertices);\n\n      numVertices = this.addVertices_(p0, p1, p2,\n        sign * Instruction.BEVEL_SECOND * (lineJoin || 1), numVertices);\n\n      numVertices = this.addVertices_(p0, p1, p2,\n        -sign * Instruction.MITER_BOTTOM * (lineJoin || 1), numVertices);\n\n      if (i > offset) {\n        this.indices[numIndices++] = n;\n        this.indices[numIndices++] = lastIndex - 1;\n        this.indices[numIndices++] = lastIndex;\n\n        this.indices[numIndices++] = n + 2;\n        this.indices[numIndices++] = n;\n        this.indices[numIndices++] = lastSign * sign > 0 ? lastIndex : lastIndex - 1;\n      }\n\n      this.indices[numIndices++] = n;\n      this.indices[numIndices++] = n + 2;\n      this.indices[numIndices++] = n + 1;\n\n      lastIndex = n + 2;\n      lastSign = sign;\n\n      //Add miter\n      if (lineJoin) {\n        numVertices = this.addVertices_(p0, p1, p2,\n          sign * Instruction.MITER_TOP * lineJoin, numVertices);\n\n        this.indices[numIndices++] = n + 1;\n        this.indices[numIndices++] = n + 3;\n        this.indices[numIndices++] = n;\n      }\n    }\n\n    if (closed) {\n      n = n || numVertices / 7;\n      sign = linearRingIsClockwise([p0[0], p0[1], p1[0], p1[1], p2[0], p2[1]], 0, 6, 2)\n        ? 1 : -1;\n\n      numVertices = this.addVertices_(p0, p1, p2,\n        sign * Instruction.BEVEL_FIRST * (lineJoin || 1), numVertices);\n\n      numVertices = this.addVertices_(p0, p1, p2,\n        -sign * Instruction.MITER_BOTTOM * (lineJoin || 1), numVertices);\n\n      this.indices[numIndices++] = n;\n      this.indices[numIndices++] = lastIndex - 1;\n      this.indices[numIndices++] = lastIndex;\n\n      this.indices[numIndices++] = n + 1;\n      this.indices[numIndices++] = n;\n      this.indices[numIndices++] = lastSign * sign > 0 ? lastIndex : lastIndex - 1;\n    }\n  }\n\n  /**\n   * @param {Array.<number>} p0 Last coordinates.\n   * @param {Array.<number>} p1 Current coordinates.\n   * @param {Array.<number>} p2 Next coordinates.\n   * @param {number} product Sign, instruction, and rounding product.\n   * @param {number} numVertices Vertex counter.\n   * @return {number} Vertex counter.\n   * @private\n   */\n  addVertices_(p0, p1, p2, product, numVertices) {\n    this.vertices[numVertices++] = p0[0];\n    this.vertices[numVertices++] = p0[1];\n    this.vertices[numVertices++] = p1[0];\n    this.vertices[numVertices++] = p1[1];\n    this.vertices[numVertices++] = p2[0];\n    this.vertices[numVertices++] = p2[1];\n    this.vertices[numVertices++] = product;\n\n    return numVertices;\n  }\n\n  /**\n   * Check if the linestring can be drawn (i. e. valid).\n   * @param {Array.<number>} flatCoordinates Flat coordinates.\n   * @param {number} offset Offset.\n   * @param {number} end End.\n   * @param {number} stride Stride.\n   * @return {boolean} The linestring can be drawn.\n   * @private\n   */\n  isValid_(flatCoordinates, offset, end, stride) {\n    const range = end - offset;\n    if (range < stride * 2) {\n      return false;\n    } else if (range === stride * 2) {\n      const firstP = [flatCoordinates[offset], flatCoordinates[offset + 1]];\n      const lastP = [flatCoordinates[offset + stride], flatCoordinates[offset + stride + 1]];\n      return !equals(firstP, lastP);\n    }\n\n    return true;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawLineString(lineStringGeometry, feature) {\n    let flatCoordinates = lineStringGeometry.getFlatCoordinates();\n    const stride = lineStringGeometry.getStride();\n    if (this.isValid_(flatCoordinates, 0, flatCoordinates.length, stride)) {\n      flatCoordinates = translate(flatCoordinates, 0, flatCoordinates.length,\n        stride, -this.origin[0], -this.origin[1]);\n      if (this.state_.changed) {\n        this.styleIndices_.push(this.indices.length);\n        this.state_.changed = false;\n      }\n      this.startIndices.push(this.indices.length);\n      this.startIndicesFeature.push(feature);\n      this.drawCoordinates_(\n        flatCoordinates, 0, flatCoordinates.length, stride);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawMultiLineString(multiLineStringGeometry, feature) {\n    const indexCount = this.indices.length;\n    const ends = multiLineStringGeometry.getEnds();\n    ends.unshift(0);\n    const flatCoordinates = multiLineStringGeometry.getFlatCoordinates();\n    const stride = multiLineStringGeometry.getStride();\n    let i, ii;\n    if (ends.length > 1) {\n      for (i = 1, ii = ends.length; i < ii; ++i) {\n        if (this.isValid_(flatCoordinates, ends[i - 1], ends[i], stride)) {\n          const lineString = translate(flatCoordinates, ends[i - 1], ends[i],\n            stride, -this.origin[0], -this.origin[1]);\n          this.drawCoordinates_(\n            lineString, 0, lineString.length, stride);\n        }\n      }\n    }\n    if (this.indices.length > indexCount) {\n      this.startIndices.push(indexCount);\n      this.startIndicesFeature.push(feature);\n      if (this.state_.changed) {\n        this.styleIndices_.push(indexCount);\n        this.state_.changed = false;\n      }\n    }\n  }\n\n  /**\n   * @param {Array.<number>} flatCoordinates Flat coordinates.\n   * @param {Array.<Array.<number>>} holeFlatCoordinates Hole flat coordinates.\n   * @param {number} stride Stride.\n   */\n  drawPolygonCoordinates(flatCoordinates, holeFlatCoordinates, stride) {\n    if (!lineStringIsClosed(flatCoordinates, 0, flatCoordinates.length, stride)) {\n      flatCoordinates.push(flatCoordinates[0]);\n      flatCoordinates.push(flatCoordinates[1]);\n    }\n    this.drawCoordinates_(flatCoordinates, 0, flatCoordinates.length, stride);\n    if (holeFlatCoordinates.length) {\n      let i, ii;\n      for (i = 0, ii = holeFlatCoordinates.length; i < ii; ++i) {\n        if (!lineStringIsClosed(holeFlatCoordinates[i], 0, holeFlatCoordinates[i].length, stride)) {\n          holeFlatCoordinates[i].push(holeFlatCoordinates[i][0]);\n          holeFlatCoordinates[i].push(holeFlatCoordinates[i][1]);\n        }\n        this.drawCoordinates_(holeFlatCoordinates[i], 0,\n          holeFlatCoordinates[i].length, stride);\n      }\n    }\n  }\n\n  /**\n   * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n   * @param {number=} opt_index Index count.\n   */\n  setPolygonStyle(feature, opt_index) {\n    const index = opt_index === undefined ? this.indices.length : opt_index;\n    this.startIndices.push(index);\n    this.startIndicesFeature.push(feature);\n    if (this.state_.changed) {\n      this.styleIndices_.push(index);\n      this.state_.changed = false;\n    }\n  }\n\n  /**\n   * @return {number} Current index.\n   */\n  getCurrentIndex() {\n    return this.indices.length;\n  }\n\n  /**\n   * @inheritDoc\n   **/\n  finish(context) {\n    // create, bind, and populate the vertices buffer\n    this.verticesBuffer = new WebGLBuffer(this.vertices);\n\n    // create, bind, and populate the indices buffer\n    this.indicesBuffer = new WebGLBuffer(this.indices);\n\n    this.startIndices.push(this.indices.length);\n\n    //Clean up, if there is nothing to draw\n    if (this.styleIndices_.length === 0 && this.styles_.length > 0) {\n      this.styles_ = [];\n    }\n\n    this.vertices = null;\n    this.indices = null;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getDeleteResourcesFunction(context) {\n    const verticesBuffer = this.verticesBuffer;\n    const indicesBuffer = this.indicesBuffer;\n    return function() {\n      context.deleteBuffer(verticesBuffer);\n      context.deleteBuffer(indicesBuffer);\n    };\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setUpProgram(gl, context, size, pixelRatio) {\n    // get the program\n    const program = context.getProgram(fragment, vertex);\n\n    // get the locations\n    let locations;\n    if (!this.defaultLocations_) {\n      locations = new Locations(gl, program);\n      this.defaultLocations_ = locations;\n    } else {\n      locations = this.defaultLocations_;\n    }\n\n    context.useProgram(program);\n\n    // enable the vertex attrib arrays\n    gl.enableVertexAttribArray(locations.a_lastPos);\n    gl.vertexAttribPointer(locations.a_lastPos, 2, FLOAT,\n      false, 28, 0);\n\n    gl.enableVertexAttribArray(locations.a_position);\n    gl.vertexAttribPointer(locations.a_position, 2, FLOAT,\n      false, 28, 8);\n\n    gl.enableVertexAttribArray(locations.a_nextPos);\n    gl.vertexAttribPointer(locations.a_nextPos, 2, FLOAT,\n      false, 28, 16);\n\n    gl.enableVertexAttribArray(locations.a_direction);\n    gl.vertexAttribPointer(locations.a_direction, 1, FLOAT,\n      false, 28, 24);\n\n    // Enable renderer specific uniforms.\n    gl.uniform2fv(locations.u_size, size);\n    gl.uniform1f(locations.u_pixelRatio, pixelRatio);\n\n    return locations;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  shutDownProgram(gl, locations) {\n    gl.disableVertexAttribArray(locations.a_lastPos);\n    gl.disableVertexAttribArray(locations.a_position);\n    gl.disableVertexAttribArray(locations.a_nextPos);\n    gl.disableVertexAttribArray(locations.a_direction);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawReplay(gl, context, skippedFeaturesHash, hitDetection) {\n    //Save GL parameters.\n    const tmpDepthFunc = /** @type {number} */ (gl.getParameter(gl.DEPTH_FUNC));\n    const tmpDepthMask = /** @type {boolean} */ (gl.getParameter(gl.DEPTH_WRITEMASK));\n\n    if (!hitDetection) {\n      gl.enable(gl.DEPTH_TEST);\n      gl.depthMask(true);\n      gl.depthFunc(gl.NOTEQUAL);\n    }\n\n    if (!isEmpty(skippedFeaturesHash)) {\n      this.drawReplaySkipping_(gl, context, skippedFeaturesHash);\n    } else {\n      //Draw by style groups to minimize drawElements() calls.\n      let i, start, end, nextStyle;\n      end = this.startIndices[this.startIndices.length - 1];\n      for (i = this.styleIndices_.length - 1; i >= 0; --i) {\n        start = this.styleIndices_[i];\n        nextStyle = this.styles_[i];\n        this.setStrokeStyle_(gl, nextStyle[0], nextStyle[1], nextStyle[2]);\n        this.drawElements(gl, context, start, end);\n        gl.clear(gl.DEPTH_BUFFER_BIT);\n        end = start;\n      }\n    }\n    if (!hitDetection) {\n      gl.disable(gl.DEPTH_TEST);\n      gl.clear(gl.DEPTH_BUFFER_BIT);\n      //Restore GL parameters.\n      gl.depthMask(tmpDepthMask);\n      gl.depthFunc(tmpDepthFunc);\n    }\n  }\n\n  /**\n   * @private\n   * @param {WebGLRenderingContext} gl gl.\n   * @param {module:ol/webgl/Context} context Context.\n   * @param {Object} skippedFeaturesHash Ids of features to skip.\n   */\n  drawReplaySkipping_(gl, context, skippedFeaturesHash) {\n    let i, start, end, nextStyle, groupStart, feature, featureUid, featureIndex, featureStart;\n    featureIndex = this.startIndices.length - 2;\n    end = start = this.startIndices[featureIndex + 1];\n    for (i = this.styleIndices_.length - 1; i >= 0; --i) {\n      nextStyle = this.styles_[i];\n      this.setStrokeStyle_(gl, nextStyle[0], nextStyle[1], nextStyle[2]);\n      groupStart = this.styleIndices_[i];\n\n      while (featureIndex >= 0 &&\n          this.startIndices[featureIndex] >= groupStart) {\n        featureStart = this.startIndices[featureIndex];\n        feature = this.startIndicesFeature[featureIndex];\n        featureUid = getUid(feature).toString();\n\n        if (skippedFeaturesHash[featureUid]) {\n          if (start !== end) {\n            this.drawElements(gl, context, start, end);\n            gl.clear(gl.DEPTH_BUFFER_BIT);\n          }\n          end = featureStart;\n        }\n        featureIndex--;\n        start = featureStart;\n      }\n      if (start !== end) {\n        this.drawElements(gl, context, start, end);\n        gl.clear(gl.DEPTH_BUFFER_BIT);\n      }\n      start = end = groupStart;\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawHitDetectionReplayOneByOne(gl, context, skippedFeaturesHash, featureCallback, opt_hitExtent) {\n    let i, start, end, nextStyle, groupStart, feature, featureUid, featureIndex;\n    featureIndex = this.startIndices.length - 2;\n    end = this.startIndices[featureIndex + 1];\n    for (i = this.styleIndices_.length - 1; i >= 0; --i) {\n      nextStyle = this.styles_[i];\n      this.setStrokeStyle_(gl, nextStyle[0], nextStyle[1], nextStyle[2]);\n      groupStart = this.styleIndices_[i];\n\n      while (featureIndex >= 0 &&\n          this.startIndices[featureIndex] >= groupStart) {\n        start = this.startIndices[featureIndex];\n        feature = this.startIndicesFeature[featureIndex];\n        featureUid = getUid(feature).toString();\n\n        if (skippedFeaturesHash[featureUid] === undefined &&\n            feature.getGeometry() &&\n            (opt_hitExtent === undefined || intersects(\n              /** @type {Array<number>} */ (opt_hitExtent),\n              feature.getGeometry().getExtent()))) {\n          gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n          this.drawElements(gl, context, start, end);\n\n          const result = featureCallback(feature);\n\n          if (result) {\n            return result;\n          }\n\n        }\n        featureIndex--;\n        end = start;\n      }\n    }\n    return undefined;\n  }\n\n  /**\n   * @private\n   * @param {WebGLRenderingContext} gl gl.\n   * @param {Array.<number>} color Color.\n   * @param {number} lineWidth Line width.\n   * @param {number} miterLimit Miter limit.\n   */\n  setStrokeStyle_(gl, color, lineWidth, miterLimit) {\n    gl.uniform4fv(this.defaultLocations_.u_color, color);\n    gl.uniform1f(this.defaultLocations_.u_lineWidth, lineWidth);\n    gl.uniform1f(this.defaultLocations_.u_miterLimit, miterLimit);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setFillStrokeStyle(fillStyle, strokeStyle) {\n    const strokeStyleLineCap = strokeStyle.getLineCap();\n    this.state_.lineCap = strokeStyleLineCap !== undefined ?\n      strokeStyleLineCap : DEFAULT_LINECAP;\n    const strokeStyleLineDash = strokeStyle.getLineDash();\n    this.state_.lineDash = strokeStyleLineDash ?\n      strokeStyleLineDash : DEFAULT_LINEDASH;\n    const strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();\n    this.state_.lineDashOffset = strokeStyleLineDashOffset ?\n      strokeStyleLineDashOffset : DEFAULT_LINEDASHOFFSET;\n    const strokeStyleLineJoin = strokeStyle.getLineJoin();\n    this.state_.lineJoin = strokeStyleLineJoin !== undefined ?\n      strokeStyleLineJoin : DEFAULT_LINEJOIN;\n    let strokeStyleColor = strokeStyle.getColor();\n    if (!(strokeStyleColor instanceof CanvasGradient) &&\n        !(strokeStyleColor instanceof CanvasPattern)) {\n      strokeStyleColor = asArray(strokeStyleColor).map(function(c, i) {\n        return i != 3 ? c / 255 : c;\n      }) || DEFAULT_STROKESTYLE;\n    } else {\n      strokeStyleColor = DEFAULT_STROKESTYLE;\n    }\n    let strokeStyleWidth = strokeStyle.getWidth();\n    strokeStyleWidth = strokeStyleWidth !== undefined ?\n      strokeStyleWidth : DEFAULT_LINEWIDTH;\n    let strokeStyleMiterLimit = strokeStyle.getMiterLimit();\n    strokeStyleMiterLimit = strokeStyleMiterLimit !== undefined ?\n      strokeStyleMiterLimit : DEFAULT_MITERLIMIT;\n    if (!this.state_.strokeColor || !equals(this.state_.strokeColor, strokeStyleColor) ||\n        this.state_.lineWidth !== strokeStyleWidth || this.state_.miterLimit !== strokeStyleMiterLimit) {\n      this.state_.changed = true;\n      this.state_.strokeColor = strokeStyleColor;\n      this.state_.lineWidth = strokeStyleWidth;\n      this.state_.miterLimit = strokeStyleMiterLimit;\n      this.styles_.push([strokeStyleColor, strokeStyleWidth, strokeStyleMiterLimit]);\n    }\n  }\n}\n\n\nexport default WebGLLineStringReplay;\n","/**\n * @module ol/render/webgl/polygonreplay/defaultshader\n */\n// This file is automatically generated, do not edit.\n// Run `make shaders` to generate, and commit the result.\n\nimport {DEBUG as DEBUG_WEBGL} from '../../../webgl.js';\nimport WebGLFragment from '../../../webgl/Fragment.js';\nimport WebGLVertex from '../../../webgl/Vertex.js';\n\nexport const fragment = new WebGLFragment(DEBUG_WEBGL ?\n  'precision mediump float;\\n\\n\\n\\nuniform vec4 u_color;\\nuniform float u_opacity;\\n\\nvoid main(void) {\\n  gl_FragColor = u_color;\\n  float alpha = u_color.a * u_opacity;\\n  if (alpha == 0.0) {\\n    discard;\\n  }\\n  gl_FragColor.a = alpha;\\n}\\n' :\n  'precision mediump float;uniform vec4 e;uniform float f;void main(void){gl_FragColor=e;float alpha=e.a*f;if(alpha==0.0){discard;}gl_FragColor.a=alpha;}');\n\nexport const vertex = new WebGLVertex(DEBUG_WEBGL ?\n  '\\n\\nattribute vec2 a_position;\\n\\nuniform mat4 u_projectionMatrix;\\nuniform mat4 u_offsetScaleMatrix;\\nuniform mat4 u_offsetRotateMatrix;\\n\\nvoid main(void) {\\n  gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0);\\n}\\n\\n\\n' :\n  'attribute vec2 a;uniform mat4 b;uniform mat4 c;uniform mat4 d;void main(void){gl_Position=b*vec4(a,0.0,1.0);}');\n","/**\n * @module ol/render/webgl/polygonreplay/defaultshader/Locations\n */\n// This file is automatically generated, do not edit\n// Run `make shaders` to generate, and commit the result.\n\nimport {DEBUG as DEBUG_WEBGL} from '../../../../webgl.js';\n\nclass Locations {\n\n  /**\n   * @param {WebGLRenderingContext} gl GL.\n   * @param {WebGLProgram} program Program.\n   */\n  constructor(gl, program) {\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_projectionMatrix = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_projectionMatrix' : 'b');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_offsetScaleMatrix = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'c');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_offsetRotateMatrix = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'd');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_color = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_color' : 'e');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_opacity = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_opacity' : 'f');\n\n    /**\n     * @type {number}\n     */\n    this.a_position = gl.getAttribLocation(\n      program, DEBUG_WEBGL ? 'a_position' : 'a');\n\n  }\n\n}\n\nexport default Locations;\n","/**\n * @module ol/structs/LinkedList\n */\n\n\n/**\n * @typedef {Object} Item\n * @property {module:ol/structs/LinkedList~Item} [prev]\n * @property {module:ol/structs/LinkedList~Item} [next]\n * @property {?} data\n */\n\n/**\n * @classdesc\n * Creates an empty linked list structure.\n */\nclass LinkedList {\n\n  /**\n   * @param {boolean=} opt_circular The last item is connected to the first one,\n   * and the first item to the last one. Default is true.\n   */\n  constructor(opt_circular) {\n\n    /**\n     * @private\n     * @type {module:ol/structs/LinkedList~Item|undefined}\n     */\n    this.first_;\n\n    /**\n     * @private\n     * @type {module:ol/structs/LinkedList~Item|undefined}\n     */\n    this.last_;\n\n    /**\n     * @private\n     * @type {module:ol/structs/LinkedList~Item|undefined}\n     */\n    this.head_;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.circular_ = opt_circular === undefined ? true : opt_circular;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.length_ = 0;\n\n  }\n\n  /**\n   * Inserts an item into the linked list right after the current one.\n   *\n   * @param {?} data Item data.\n   */\n  insertItem(data) {\n\n    /** @type {module:ol/structs/LinkedList~Item} */\n    const item = {\n      prev: undefined,\n      next: undefined,\n      data: data\n    };\n\n    const head = this.head_;\n\n    //Initialize the list.\n    if (!head) {\n      this.first_ = item;\n      this.last_ = item;\n      if (this.circular_) {\n        item.next = item;\n        item.prev = item;\n      }\n    } else {\n      //Link the new item to the adjacent ones.\n      const next = head.next;\n      item.prev = head;\n      item.next = next;\n      head.next = item;\n      if (next) {\n        next.prev = item;\n      }\n\n      if (head === this.last_) {\n        this.last_ = item;\n      }\n    }\n    this.head_ = item;\n    this.length_++;\n  }\n\n  /**\n   * Removes the current item from the list. Sets the cursor to the next item,\n   * if possible.\n   */\n  removeItem() {\n    const head = this.head_;\n    if (head) {\n      const next = head.next;\n      const prev = head.prev;\n      if (next) {\n        next.prev = prev;\n      }\n      if (prev) {\n        prev.next = next;\n      }\n      this.head_ = next || prev;\n\n      if (this.first_ === this.last_) {\n        this.head_ = undefined;\n        this.first_ = undefined;\n        this.last_ = undefined;\n      } else if (this.first_ === head) {\n        this.first_ = this.head_;\n      } else if (this.last_ === head) {\n        this.last_ = prev ? this.head_.prev : this.head_;\n      }\n      this.length_--;\n    }\n  }\n\n  /**\n   * Sets the cursor to the first item, and returns the associated data.\n   *\n   * @return {?} Item data.\n   */\n  firstItem() {\n    this.head_ = this.first_;\n    if (this.head_) {\n      return this.head_.data;\n    }\n    return undefined;\n  }\n\n  /**\n  * Sets the cursor to the last item, and returns the associated data.\n  *\n  * @return {?} Item data.\n  */\n  lastItem() {\n    this.head_ = this.last_;\n    if (this.head_) {\n      return this.head_.data;\n    }\n    return undefined;\n  }\n\n  /**\n   * Sets the cursor to the next item, and returns the associated data.\n   *\n   * @return {?} Item data.\n   */\n  nextItem() {\n    if (this.head_ && this.head_.next) {\n      this.head_ = this.head_.next;\n      return this.head_.data;\n    }\n    return undefined;\n  }\n\n  /**\n   * Returns the next item's data without moving the cursor.\n   *\n   * @return {?} Item data.\n   */\n  getNextItem() {\n    if (this.head_ && this.head_.next) {\n      return this.head_.next.data;\n    }\n    return undefined;\n  }\n\n  /**\n   * Sets the cursor to the previous item, and returns the associated data.\n   *\n   * @return {?} Item data.\n   */\n  prevItem() {\n    if (this.head_ && this.head_.prev) {\n      this.head_ = this.head_.prev;\n      return this.head_.data;\n    }\n    return undefined;\n  }\n\n  /**\n   * Returns the previous item's data without moving the cursor.\n   *\n   * @return {?} Item data.\n   */\n  getPrevItem() {\n    if (this.head_ && this.head_.prev) {\n      return this.head_.prev.data;\n    }\n    return undefined;\n  }\n\n  /**\n   * Returns the current item's data.\n   *\n   * @return {?} Item data.\n   */\n  getCurrItem() {\n    if (this.head_) {\n      return this.head_.data;\n    }\n    return undefined;\n  }\n\n  /**\n   * Sets the first item of the list. This only works for circular lists, and sets\n   * the last item accordingly.\n   */\n  setFirstItem() {\n    if (this.circular_ && this.head_) {\n      this.first_ = this.head_;\n      this.last_ = this.head_.prev;\n    }\n  }\n\n  /**\n   * Concatenates two lists.\n   * @param {module:ol/structs/LinkedList} list List to merge into the current list.\n   */\n  concat(list) {\n    if (list.head_) {\n      if (this.head_) {\n        const end = this.head_.next;\n        this.head_.next = list.first_;\n        list.first_.prev = this.head_;\n        end.prev = list.last_;\n        list.last_.next = end;\n        this.length_ += list.length_;\n      } else {\n        this.head_ = list.head_;\n        this.first_ = list.first_;\n        this.last_ = list.last_;\n        this.length_ = list.length_;\n      }\n      list.head_ = undefined;\n      list.first_ = undefined;\n      list.last_ = undefined;\n      list.length_ = 0;\n    }\n  }\n\n  /**\n   * Returns the current length of the list.\n   *\n   * @return {number} Length.\n   */\n  getLength() {\n    return this.length_;\n  }\n\n}\n\n\nexport default LinkedList;\n","/**\n * @module ol/render/webgl/PolygonReplay\n */\nimport {getUid} from '../../util.js';\nimport {equals} from '../../array.js';\nimport {asArray} from '../../color.js';\nimport {intersects} from '../../extent.js';\nimport {isEmpty} from '../../obj.js';\nimport {linearRingContainsXY} from '../../geom/flat/contains.js';\nimport {linearRingIsClockwise} from '../../geom/flat/orient.js';\nimport {translate} from '../../geom/flat/transform.js';\nimport {fragment, vertex} from '../webgl/polygonreplay/defaultshader.js';\nimport Locations from '../webgl/polygonreplay/defaultshader/Locations.js';\nimport WebGLLineStringReplay from '../webgl/LineStringReplay.js';\nimport WebGLReplay from '../webgl/Replay.js';\nimport {triangleIsCounterClockwise, EPSILON, DEFAULT_FILLSTYLE} from '../webgl.js';\nimport Stroke from '../../style/Stroke.js';\nimport LinkedList from '../../structs/LinkedList.js';\nimport RBush from '../../structs/RBush.js';\nimport {FLOAT} from '../../webgl.js';\nimport WebGLBuffer from '../../webgl/Buffer.js';\n\n\n/**\n * @typedef {Object} PolygonVertex\n * @property {number} x\n * @property {number} y\n * @property {number} i\n * @property {boolean} [reflex]\n */\n\n/**\n * @typedef {Object} PolygonSegment\n * @property {module:ol/render/webgl/PolygonReplay~PolygonVertex} p0\n * @property {module:ol/render/webgl/PolygonReplay~PolygonVertex} p1\n */\n\n\nclass WebGLPolygonReplay extends WebGLReplay {\n  /**\n   * @param {number} tolerance Tolerance.\n   * @param {module:ol/extent~Extent} maxExtent Max extent.\n   */\n  constructor(tolerance, maxExtent) {\n    super(tolerance, maxExtent);\n\n    this.lineStringReplay = new WebGLLineStringReplay(\n      tolerance, maxExtent);\n\n    /**\n     * @private\n     * @type {module:ol/render/webgl/polygonreplay/defaultshader/Locations}\n     */\n    this.defaultLocations_ = null;\n\n    /**\n     * @private\n     * @type {Array.<Array.<number>>}\n     */\n    this.styles_ = [];\n\n    /**\n     * @private\n     * @type {Array.<number>}\n     */\n    this.styleIndices_ = [];\n\n    /**\n     * @private\n     * @type {{fillColor: (Array.<number>|null),\n     *         changed: boolean}|null}\n     */\n    this.state_ = {\n      fillColor: null,\n      changed: false\n    };\n\n  }\n\n  /**\n   * Draw one polygon.\n   * @param {Array.<number>} flatCoordinates Flat coordinates.\n   * @param {Array.<Array.<number>>} holeFlatCoordinates Hole flat coordinates.\n   * @param {number} stride Stride.\n   * @private\n   */\n  drawCoordinates_(flatCoordinates, holeFlatCoordinates, stride) {\n    // Triangulate the polygon\n    const outerRing = new LinkedList();\n    const rtree = new RBush();\n    // Initialize the outer ring\n    this.processFlatCoordinates_(flatCoordinates, stride, outerRing, rtree, true);\n    const maxCoords = this.getMaxCoords_(outerRing);\n\n    // Eliminate holes, if there are any\n    if (holeFlatCoordinates.length) {\n      let i, ii;\n      const holeLists = [];\n      for (i = 0, ii = holeFlatCoordinates.length; i < ii; ++i) {\n        const holeList = {\n          list: new LinkedList(),\n          maxCoords: undefined,\n          rtree: new RBush()\n        };\n        holeLists.push(holeList);\n        this.processFlatCoordinates_(holeFlatCoordinates[i],\n          stride, holeList.list, holeList.rtree, false);\n        this.classifyPoints_(holeList.list, holeList.rtree, true);\n        holeList.maxCoords = this.getMaxCoords_(holeList.list);\n      }\n      holeLists.sort(function(a, b) {\n        return b.maxCoords[0] === a.maxCoords[0] ?\n          a.maxCoords[1] - b.maxCoords[1] : b.maxCoords[0] - a.maxCoords[0];\n      });\n      for (i = 0; i < holeLists.length; ++i) {\n        const currList = holeLists[i].list;\n        const start = currList.firstItem();\n        let currItem = start;\n        let intersection;\n        do {\n          //TODO: Triangulate holes when they intersect the outer ring.\n          if (this.getIntersections_(currItem, rtree).length) {\n            intersection = true;\n            break;\n          }\n          currItem = currList.nextItem();\n        } while (start !== currItem);\n        if (!intersection) {\n          if (this.bridgeHole_(currList, holeLists[i].maxCoords[0], outerRing, maxCoords[0], rtree)) {\n            rtree.concat(holeLists[i].rtree);\n            this.classifyPoints_(outerRing, rtree, false);\n          }\n        }\n      }\n    } else {\n      this.classifyPoints_(outerRing, rtree, false);\n    }\n    this.triangulate_(outerRing, rtree);\n  }\n\n  /**\n   * Inserts flat coordinates in a linked list and adds them to the vertex buffer.\n   * @private\n   * @param {Array.<number>} flatCoordinates Flat coordinates.\n   * @param {number} stride Stride.\n   * @param {module:ol/structs/LinkedList} list Linked list.\n   * @param {module:ol/structs/RBush} rtree R-Tree of the polygon.\n   * @param {boolean} clockwise Coordinate order should be clockwise.\n   */\n  processFlatCoordinates_(flatCoordinates, stride, list, rtree, clockwise) {\n    const isClockwise = linearRingIsClockwise(flatCoordinates,\n      0, flatCoordinates.length, stride);\n    let i, ii;\n    let n = this.vertices.length / 2;\n    /** @type {module:ol/render/webgl/PolygonReplay~PolygonVertex} */\n    let start;\n    /** @type {module:ol/render/webgl/PolygonReplay~PolygonVertex} */\n    let p0;\n    /** @type {module:ol/render/webgl/PolygonReplay~PolygonVertex} */\n    let p1;\n    const extents = [];\n    const segments = [];\n    if (clockwise === isClockwise) {\n      start = this.createPoint_(flatCoordinates[0], flatCoordinates[1], n++);\n      p0 = start;\n      for (i = stride, ii = flatCoordinates.length; i < ii; i += stride) {\n        p1 = this.createPoint_(flatCoordinates[i], flatCoordinates[i + 1], n++);\n        segments.push(this.insertItem_(p0, p1, list));\n        extents.push([Math.min(p0.x, p1.x), Math.min(p0.y, p1.y), Math.max(p0.x, p1.x),\n          Math.max(p0.y, p1.y)]);\n        p0 = p1;\n      }\n      segments.push(this.insertItem_(p1, start, list));\n      extents.push([Math.min(p0.x, p1.x), Math.min(p0.y, p1.y), Math.max(p0.x, p1.x),\n        Math.max(p0.y, p1.y)]);\n    } else {\n      const end = flatCoordinates.length - stride;\n      start = this.createPoint_(flatCoordinates[end], flatCoordinates[end + 1], n++);\n      p0 = start;\n      for (i = end - stride, ii = 0; i >= ii; i -= stride) {\n        p1 = this.createPoint_(flatCoordinates[i], flatCoordinates[i + 1], n++);\n        segments.push(this.insertItem_(p0, p1, list));\n        extents.push([Math.min(p0.x, p1.x), Math.min(p0.y, p1.y), Math.max(p0.x, p1.x),\n          Math.max(p0.y, p1.y)]);\n        p0 = p1;\n      }\n      segments.push(this.insertItem_(p1, start, list));\n      extents.push([Math.min(p0.x, p1.x), Math.min(p0.y, p1.y), Math.max(p0.x, p1.x),\n        Math.max(p0.y, p1.y)]);\n    }\n    rtree.load(extents, segments);\n  }\n\n  /**\n   * Returns the rightmost coordinates of a polygon on the X axis.\n   * @private\n   * @param {module:ol/structs/LinkedList} list Polygons ring.\n   * @return {Array.<number>} Max X coordinates.\n   */\n  getMaxCoords_(list) {\n    const start = list.firstItem();\n    let seg = start;\n    let maxCoords = [seg.p0.x, seg.p0.y];\n\n    do {\n      seg = list.nextItem();\n      if (seg.p0.x > maxCoords[0]) {\n        maxCoords = [seg.p0.x, seg.p0.y];\n      }\n    } while (seg !== start);\n\n    return maxCoords;\n  }\n\n  /**\n   * Classifies the points of a polygon list as convex, reflex. Removes collinear vertices.\n   * @private\n   * @param {module:ol/structs/LinkedList} list Polygon ring.\n   * @param {module:ol/structs/RBush} rtree R-Tree of the polygon.\n   * @param {boolean} ccw The orientation of the polygon is counter-clockwise.\n   * @return {boolean} There were reclassified points.\n   */\n  classifyPoints_(list, rtree, ccw) {\n    let start = list.firstItem();\n    let s0 = start;\n    let s1 = list.nextItem();\n    let pointsReclassified = false;\n    do {\n      const reflex = ccw ? triangleIsCounterClockwise(s1.p1.x,\n        s1.p1.y, s0.p1.x, s0.p1.y, s0.p0.x, s0.p0.y) :\n        triangleIsCounterClockwise(s0.p0.x, s0.p0.y, s0.p1.x,\n          s0.p1.y, s1.p1.x, s1.p1.y);\n      if (reflex === undefined) {\n        this.removeItem_(s0, s1, list, rtree);\n        pointsReclassified = true;\n        if (s1 === start) {\n          start = list.getNextItem();\n        }\n        s1 = s0;\n        list.prevItem();\n      } else if (s0.p1.reflex !== reflex) {\n        s0.p1.reflex = reflex;\n        pointsReclassified = true;\n      }\n      s0 = s1;\n      s1 = list.nextItem();\n    } while (s0 !== start);\n    return pointsReclassified;\n  }\n\n  /**\n   * @private\n   * @param {module:ol/structs/LinkedList} hole Linked list of the hole.\n   * @param {number} holeMaxX Maximum X value of the hole.\n   * @param {module:ol/structs/LinkedList} list Linked list of the polygon.\n   * @param {number} listMaxX Maximum X value of the polygon.\n   * @param {module:ol/structs/RBush} rtree R-Tree of the polygon.\n   * @return {boolean} Bridging was successful.\n   */\n  bridgeHole_(hole, holeMaxX, list, listMaxX, rtree) {\n    let seg = hole.firstItem();\n    while (seg.p1.x !== holeMaxX) {\n      seg = hole.nextItem();\n    }\n\n    const p1 = seg.p1;\n    /** @type {module:ol/render/webgl/PolygonReplay~PolygonVertex} */\n    const p2 = {x: listMaxX, y: p1.y, i: -1};\n    let minDist = Infinity;\n    let i, ii, bestPoint;\n    /** @type {module:ol/render/webgl/PolygonReplay~PolygonVertex} */\n    let p5;\n\n    const intersectingSegments = this.getIntersections_({p0: p1, p1: p2}, rtree, true);\n    for (i = 0, ii = intersectingSegments.length; i < ii; ++i) {\n      const currSeg = intersectingSegments[i];\n      const intersection = this.calculateIntersection_(p1, p2, currSeg.p0,\n        currSeg.p1, true);\n      const dist = Math.abs(p1.x - intersection[0]);\n      if (dist < minDist && triangleIsCounterClockwise(p1.x, p1.y,\n        currSeg.p0.x, currSeg.p0.y, currSeg.p1.x, currSeg.p1.y) !== undefined) {\n        minDist = dist;\n        p5 = {x: intersection[0], y: intersection[1], i: -1};\n        seg = currSeg;\n      }\n    }\n    if (minDist === Infinity) {\n      return false;\n    }\n    bestPoint = seg.p1;\n\n    if (minDist > 0) {\n      const pointsInTriangle = this.getPointsInTriangle_(p1, p5, seg.p1, rtree);\n      if (pointsInTriangle.length) {\n        let theta = Infinity;\n        for (i = 0, ii = pointsInTriangle.length; i < ii; ++i) {\n          const currPoint = pointsInTriangle[i];\n          const currTheta = Math.atan2(p1.y - currPoint.y, p2.x - currPoint.x);\n          if (currTheta < theta || (currTheta === theta && currPoint.x < bestPoint.x)) {\n            theta = currTheta;\n            bestPoint = currPoint;\n          }\n        }\n      }\n    }\n\n    seg = list.firstItem();\n    while (seg.p1.x !== bestPoint.x || seg.p1.y !== bestPoint.y) {\n      seg = list.nextItem();\n    }\n\n    //We clone the bridge points as they can have different convexity.\n    const p0Bridge = {x: p1.x, y: p1.y, i: p1.i, reflex: undefined};\n    const p1Bridge = {x: seg.p1.x, y: seg.p1.y, i: seg.p1.i, reflex: undefined};\n\n    hole.getNextItem().p0 = p0Bridge;\n    this.insertItem_(p1, seg.p1, hole, rtree);\n    this.insertItem_(p1Bridge, p0Bridge, hole, rtree);\n    seg.p1 = p1Bridge;\n    hole.setFirstItem();\n    list.concat(hole);\n\n    return true;\n  }\n\n  /**\n   * @private\n   * @param {module:ol/structs/LinkedList} list Linked list of the polygon.\n   * @param {module:ol/structs/RBush} rtree R-Tree of the polygon.\n   */\n  triangulate_(list, rtree) {\n    let ccw = false;\n    let simple = this.isSimple_(list, rtree);\n\n    // Start clipping ears\n    while (list.getLength() > 3) {\n      if (simple) {\n        if (!this.clipEars_(list, rtree, simple, ccw)) {\n          if (!this.classifyPoints_(list, rtree, ccw)) {\n            // Due to the behavior of OL's PIP algorithm, the ear clipping cannot\n            // introduce touching segments. However, the original data may have some.\n            if (!this.resolveSelfIntersections_(list, rtree, true)) {\n              break;\n            }\n          }\n        }\n      } else {\n        if (!this.clipEars_(list, rtree, simple, ccw)) {\n          // We ran out of ears, try to reclassify.\n          if (!this.classifyPoints_(list, rtree, ccw)) {\n            // We have a bad polygon, try to resolve local self-intersections.\n            if (!this.resolveSelfIntersections_(list, rtree)) {\n              simple = this.isSimple_(list, rtree);\n              if (!simple) {\n                // We have a really bad polygon, try more time consuming methods.\n                this.splitPolygon_(list, rtree);\n                break;\n              } else {\n                ccw = !this.isClockwise_(list);\n                this.classifyPoints_(list, rtree, ccw);\n              }\n            }\n          }\n        }\n      }\n    }\n    if (list.getLength() === 3) {\n      let numIndices = this.indices.length;\n      this.indices[numIndices++] = list.getPrevItem().p0.i;\n      this.indices[numIndices++] = list.getCurrItem().p0.i;\n      this.indices[numIndices++] = list.getNextItem().p0.i;\n    }\n  }\n\n  /**\n   * @private\n   * @param {module:ol/structs/LinkedList} list Linked list of the polygon.\n   * @param {module:ol/structs/RBush} rtree R-Tree of the polygon.\n   * @param {boolean} simple The polygon is simple.\n   * @param {boolean} ccw Orientation of the polygon is counter-clockwise.\n   * @return {boolean} There were processed ears.\n   */\n  clipEars_(list, rtree, simple, ccw) {\n    let numIndices = this.indices.length;\n    let start = list.firstItem();\n    let s0 = list.getPrevItem();\n    let s1 = start;\n    let s2 = list.nextItem();\n    let s3 = list.getNextItem();\n    let p0, p1, p2;\n    let processedEars = false;\n    do {\n      p0 = s1.p0;\n      p1 = s1.p1;\n      p2 = s2.p1;\n      if (p1.reflex === false) {\n        // We might have a valid ear\n        let variableCriterion;\n        if (simple) {\n          variableCriterion = this.getPointsInTriangle_(p0, p1, p2, rtree, true).length === 0;\n        } else {\n          variableCriterion = ccw ? this.diagonalIsInside_(s3.p1, p2, p1, p0,\n            s0.p0) : this.diagonalIsInside_(s0.p0, p0, p1, p2, s3.p1);\n        }\n        if ((simple || this.getIntersections_({p0: p0, p1: p2}, rtree).length === 0) &&\n            variableCriterion) {\n          //The diagonal is completely inside the polygon\n          if (simple || p0.reflex === false || p2.reflex === false ||\n              linearRingIsClockwise([s0.p0.x, s0.p0.y, p0.x,\n                p0.y, p1.x, p1.y, p2.x, p2.y, s3.p1.x, s3.p1.y], 0, 10, 2) === !ccw) {\n            //The diagonal is persumably valid, we have an ear\n            this.indices[numIndices++] = p0.i;\n            this.indices[numIndices++] = p1.i;\n            this.indices[numIndices++] = p2.i;\n            this.removeItem_(s1, s2, list, rtree);\n            if (s2 === start) {\n              start = s3;\n            }\n            processedEars = true;\n          }\n        }\n      }\n      // Else we have a reflex point.\n      s0 = list.getPrevItem();\n      s1 = list.getCurrItem();\n      s2 = list.nextItem();\n      s3 = list.getNextItem();\n    } while (s1 !== start && list.getLength() > 3);\n\n    return processedEars;\n  }\n\n  /**\n   * @private\n   * @param {module:ol/structs/LinkedList} list Linked list of the polygon.\n   * @param {module:ol/structs/RBush} rtree R-Tree of the polygon.\n   * @param {boolean=} opt_touch Resolve touching segments.\n   * @return {boolean} There were resolved intersections.\n  */\n  resolveSelfIntersections_(list, rtree, opt_touch) {\n    const start = list.firstItem();\n    list.nextItem();\n    let s0 = start;\n    let s1 = list.nextItem();\n    let resolvedIntersections = false;\n\n    do {\n      const intersection = this.calculateIntersection_(s0.p0, s0.p1, s1.p0, s1.p1,\n        opt_touch);\n      if (intersection) {\n        let breakCond = false;\n        const numVertices = this.vertices.length;\n        let numIndices = this.indices.length;\n        const n = numVertices / 2;\n        const seg = list.prevItem();\n        list.removeItem();\n        rtree.remove(seg);\n        breakCond = (seg === start);\n        let p;\n        if (opt_touch) {\n          if (intersection[0] === s0.p0.x && intersection[1] === s0.p0.y) {\n            list.prevItem();\n            p = s0.p0;\n            s1.p0 = p;\n            rtree.remove(s0);\n            breakCond = breakCond || (s0 === start);\n          } else {\n            p = s1.p1;\n            s0.p1 = p;\n            rtree.remove(s1);\n            breakCond = breakCond || (s1 === start);\n          }\n          list.removeItem();\n        } else {\n          p = this.createPoint_(intersection[0], intersection[1], n);\n          s0.p1 = p;\n          s1.p0 = p;\n          rtree.update([Math.min(s0.p0.x, s0.p1.x), Math.min(s0.p0.y, s0.p1.y),\n            Math.max(s0.p0.x, s0.p1.x), Math.max(s0.p0.y, s0.p1.y)], s0);\n          rtree.update([Math.min(s1.p0.x, s1.p1.x), Math.min(s1.p0.y, s1.p1.y),\n            Math.max(s1.p0.x, s1.p1.x), Math.max(s1.p0.y, s1.p1.y)], s1);\n        }\n\n        this.indices[numIndices++] = seg.p0.i;\n        this.indices[numIndices++] = seg.p1.i;\n        this.indices[numIndices++] = p.i;\n\n        resolvedIntersections = true;\n        if (breakCond) {\n          break;\n        }\n      }\n\n      s0 = list.getPrevItem();\n      s1 = list.nextItem();\n    } while (s0 !== start);\n    return resolvedIntersections;\n  }\n\n  /**\n   * @private\n   * @param {module:ol/structs/LinkedList} list Linked list of the polygon.\n   * @param {module:ol/structs/RBush} rtree R-Tree of the polygon.\n   * @return {boolean} The polygon is simple.\n   */\n  isSimple_(list, rtree) {\n    const start = list.firstItem();\n    let seg = start;\n    do {\n      if (this.getIntersections_(seg, rtree).length) {\n        return false;\n      }\n      seg = list.nextItem();\n    } while (seg !== start);\n    return true;\n  }\n\n  /**\n   * @private\n   * @param {module:ol/structs/LinkedList} list Linked list of the polygon.\n   * @return {boolean} Orientation is clockwise.\n   */\n  isClockwise_(list) {\n    const length = list.getLength() * 2;\n    const flatCoordinates = new Array(length);\n    const start = list.firstItem();\n    let seg = start;\n    let i = 0;\n    do {\n      flatCoordinates[i++] = seg.p0.x;\n      flatCoordinates[i++] = seg.p0.y;\n      seg = list.nextItem();\n    } while (seg !== start);\n    return linearRingIsClockwise(flatCoordinates, 0, length, 2);\n  }\n\n  /**\n   * @private\n   * @param {module:ol/structs/LinkedList} list Linked list of the polygon.\n   * @param {module:ol/structs/RBush} rtree R-Tree of the polygon.\n   */\n  splitPolygon_(list, rtree) {\n    const start = list.firstItem();\n    let s0 = start;\n    do {\n      const intersections = this.getIntersections_(s0, rtree);\n      if (intersections.length) {\n        const s1 = intersections[0];\n        const n = this.vertices.length / 2;\n        const intersection = this.calculateIntersection_(s0.p0,\n          s0.p1, s1.p0, s1.p1);\n        const p = this.createPoint_(intersection[0], intersection[1], n);\n        const newPolygon = new LinkedList();\n        const newRtree = new RBush();\n        this.insertItem_(p, s0.p1, newPolygon, newRtree);\n        s0.p1 = p;\n        rtree.update([Math.min(s0.p0.x, p.x), Math.min(s0.p0.y, p.y),\n          Math.max(s0.p0.x, p.x), Math.max(s0.p0.y, p.y)], s0);\n        let currItem = list.nextItem();\n        while (currItem !== s1) {\n          this.insertItem_(currItem.p0, currItem.p1, newPolygon, newRtree);\n          rtree.remove(currItem);\n          list.removeItem();\n          currItem = list.getCurrItem();\n        }\n        this.insertItem_(s1.p0, p, newPolygon, newRtree);\n        s1.p0 = p;\n        rtree.update([Math.min(s1.p1.x, p.x), Math.min(s1.p1.y, p.y),\n          Math.max(s1.p1.x, p.x), Math.max(s1.p1.y, p.y)], s1);\n        this.classifyPoints_(list, rtree, false);\n        this.triangulate_(list, rtree);\n        this.classifyPoints_(newPolygon, newRtree, false);\n        this.triangulate_(newPolygon, newRtree);\n        break;\n      }\n      s0 = list.nextItem();\n    } while (s0 !== start);\n  }\n\n  /**\n   * @private\n   * @param {number} x X coordinate.\n   * @param {number} y Y coordinate.\n   * @param {number} i Index.\n   * @return {module:ol/render/webgl/PolygonReplay~PolygonVertex} List item.\n   */\n  createPoint_(x, y, i) {\n    let numVertices = this.vertices.length;\n    this.vertices[numVertices++] = x;\n    this.vertices[numVertices++] = y;\n    /** @type {module:ol/render/webgl/PolygonReplay~PolygonVertex} */\n    const p = {\n      x: x,\n      y: y,\n      i: i,\n      reflex: undefined\n    };\n    return p;\n  }\n\n  /**\n   * @private\n   * @param {module:ol/render/webgl/PolygonReplay~PolygonVertex} p0 First point of segment.\n   * @param {module:ol/render/webgl/PolygonReplay~PolygonVertex} p1 Second point of segment.\n   * @param {module:ol/structs/LinkedList} list Polygon ring.\n   * @param {module:ol/structs/RBush=} opt_rtree Insert the segment into the R-Tree.\n   * @return {module:ol/render/webgl/PolygonReplay~PolygonSegment} segment.\n   */\n  insertItem_(p0, p1, list, opt_rtree) {\n    const seg = {\n      p0: p0,\n      p1: p1\n    };\n    list.insertItem(seg);\n    if (opt_rtree) {\n      opt_rtree.insert([Math.min(p0.x, p1.x), Math.min(p0.y, p1.y),\n        Math.max(p0.x, p1.x), Math.max(p0.y, p1.y)], seg);\n    }\n    return seg;\n  }\n\n  /**\n    * @private\n    * @param {module:ol/render/webgl/PolygonReplay~PolygonSegment} s0 Segment before the remove candidate.\n    * @param {module:ol/render/webgl/PolygonReplay~PolygonSegment} s1 Remove candidate segment.\n    * @param {module:ol/structs/LinkedList} list Polygon ring.\n    * @param {module:ol/structs/RBush} rtree R-Tree of the polygon.\n    */\n  removeItem_(s0, s1, list, rtree) {\n    if (list.getCurrItem() === s1) {\n      list.removeItem();\n      s0.p1 = s1.p1;\n      rtree.remove(s1);\n      rtree.update([Math.min(s0.p0.x, s0.p1.x), Math.min(s0.p0.y, s0.p1.y),\n        Math.max(s0.p0.x, s0.p1.x), Math.max(s0.p0.y, s0.p1.y)], s0);\n    }\n  }\n\n  /**\n   * @private\n   * @param {module:ol/render/webgl/PolygonReplay~PolygonVertex} p0 First point.\n   * @param {module:ol/render/webgl/PolygonReplay~PolygonVertex} p1 Second point.\n   * @param {module:ol/render/webgl/PolygonReplay~PolygonVertex} p2 Third point.\n   * @param {module:ol/structs/RBush} rtree R-Tree of the polygon.\n   * @param {boolean=} opt_reflex Only include reflex points.\n   * @return {Array.<module:ol/render/webgl/PolygonReplay~PolygonVertex>} Points in the triangle.\n   */\n  getPointsInTriangle_(p0, p1, p2, rtree, opt_reflex) {\n    const result = [];\n    const segmentsInExtent = rtree.getInExtent([Math.min(p0.x, p1.x, p2.x),\n      Math.min(p0.y, p1.y, p2.y), Math.max(p0.x, p1.x, p2.x), Math.max(p0.y,\n        p1.y, p2.y)]);\n    for (let i = 0, ii = segmentsInExtent.length; i < ii; ++i) {\n      for (const j in segmentsInExtent[i]) {\n        const p = segmentsInExtent[i][j];\n        if (typeof p === 'object' && (!opt_reflex || p.reflex)) {\n          if ((p.x !== p0.x || p.y !== p0.y) && (p.x !== p1.x || p.y !== p1.y) &&\n              (p.x !== p2.x || p.y !== p2.y) && result.indexOf(p) === -1 &&\n              linearRingContainsXY([p0.x, p0.y, p1.x, p1.y, p2.x, p2.y], 0, 6, 2, p.x, p.y)) {\n            result.push(p);\n          }\n        }\n      }\n    }\n    return result;\n  }\n\n  /**\n   * @private\n   * @param {module:ol/render/webgl/PolygonReplay~PolygonSegment} segment Segment.\n   * @param {module:ol/structs/RBush} rtree R-Tree of the polygon.\n   * @param {boolean=} opt_touch Touching segments should be considered an intersection.\n   * @return {Array.<module:ol/render/webgl/PolygonReplay~PolygonSegment>} Intersecting segments.\n   */\n  getIntersections_(segment, rtree, opt_touch) {\n    const p0 = segment.p0;\n    const p1 = segment.p1;\n    const segmentsInExtent = rtree.getInExtent([Math.min(p0.x, p1.x),\n      Math.min(p0.y, p1.y), Math.max(p0.x, p1.x), Math.max(p0.y, p1.y)]);\n    const result = [];\n    for (let i = 0, ii = segmentsInExtent.length; i < ii; ++i) {\n      const currSeg = segmentsInExtent[i];\n      if (segment !== currSeg && (opt_touch || currSeg.p0 !== p1 || currSeg.p1 !== p0) &&\n          this.calculateIntersection_(p0, p1, currSeg.p0, currSeg.p1, opt_touch)) {\n        result.push(currSeg);\n      }\n    }\n    return result;\n  }\n\n  /**\n   * Line intersection algorithm by Paul Bourke.\n   * See http://paulbourke.net/geometry/pointlineplane/.\n   *\n   * @private\n   * @param {module:ol/render/webgl/PolygonReplay~PolygonVertex} p0 First point.\n   * @param {module:ol/render/webgl/PolygonReplay~PolygonVertex} p1 Second point.\n   * @param {module:ol/render/webgl/PolygonReplay~PolygonVertex} p2 Third point.\n   * @param {module:ol/render/webgl/PolygonReplay~PolygonVertex} p3 Fourth point.\n   * @param {boolean=} opt_touch Touching segments should be considered an intersection.\n   * @return {Array.<number>|undefined} Intersection coordinates.\n   */\n  calculateIntersection_(p0, p1, p2, p3, opt_touch) {\n    const denom = (p3.y - p2.y) * (p1.x - p0.x) - (p3.x - p2.x) * (p1.y - p0.y);\n    if (denom !== 0) {\n      const ua = ((p3.x - p2.x) * (p0.y - p2.y) - (p3.y - p2.y) * (p0.x - p2.x)) / denom;\n      const ub = ((p1.x - p0.x) * (p0.y - p2.y) - (p1.y - p0.y) * (p0.x - p2.x)) / denom;\n      if ((!opt_touch && ua > EPSILON && ua < 1 - EPSILON &&\n          ub > EPSILON && ub < 1 - EPSILON) || (opt_touch &&\n          ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1)) {\n        return [p0.x + ua * (p1.x - p0.x), p0.y + ua * (p1.y - p0.y)];\n      }\n    }\n    return undefined;\n  }\n\n  /**\n   * @private\n   * @param {module:ol/render/webgl/PolygonReplay~PolygonVertex} p0 Point before the start of the diagonal.\n   * @param {module:ol/render/webgl/PolygonReplay~PolygonVertex} p1 Start point of the diagonal.\n   * @param {module:ol/render/webgl/PolygonReplay~PolygonVertex} p2 Ear candidate.\n   * @param {module:ol/render/webgl/PolygonReplay~PolygonVertex} p3 End point of the diagonal.\n   * @param {module:ol/render/webgl/PolygonReplay~PolygonVertex} p4 Point after the end of the diagonal.\n   * @return {boolean} Diagonal is inside the polygon.\n   */\n  diagonalIsInside_(p0, p1, p2, p3, p4) {\n    if (p1.reflex === undefined || p3.reflex === undefined) {\n      return false;\n    }\n    const p1IsLeftOf = (p2.x - p3.x) * (p1.y - p3.y) > (p2.y - p3.y) * (p1.x - p3.x);\n    const p1IsRightOf = (p4.x - p3.x) * (p1.y - p3.y) < (p4.y - p3.y) * (p1.x - p3.x);\n    const p3IsLeftOf = (p0.x - p1.x) * (p3.y - p1.y) > (p0.y - p1.y) * (p3.x - p1.x);\n    const p3IsRightOf = (p2.x - p1.x) * (p3.y - p1.y) < (p2.y - p1.y) * (p3.x - p1.x);\n    const p1InCone = p3.reflex ? p1IsRightOf || p1IsLeftOf : p1IsRightOf && p1IsLeftOf;\n    const p3InCone = p1.reflex ? p3IsRightOf || p3IsLeftOf : p3IsRightOf && p3IsLeftOf;\n    return p1InCone && p3InCone;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawMultiPolygon(multiPolygonGeometry, feature) {\n    const endss = multiPolygonGeometry.getEndss();\n    const stride = multiPolygonGeometry.getStride();\n    const currIndex = this.indices.length;\n    const currLineIndex = this.lineStringReplay.getCurrentIndex();\n    const flatCoordinates = multiPolygonGeometry.getFlatCoordinates();\n    let i, ii, j, jj;\n    let start = 0;\n    for (i = 0, ii = endss.length; i < ii; ++i) {\n      const ends = endss[i];\n      if (ends.length > 0) {\n        const outerRing = translate(flatCoordinates, start, ends[0],\n          stride, -this.origin[0], -this.origin[1]);\n        if (outerRing.length) {\n          const holes = [];\n          let holeFlatCoords;\n          for (j = 1, jj = ends.length; j < jj; ++j) {\n            if (ends[j] !== ends[j - 1]) {\n              holeFlatCoords = translate(flatCoordinates, ends[j - 1],\n                ends[j], stride, -this.origin[0], -this.origin[1]);\n              holes.push(holeFlatCoords);\n            }\n          }\n          this.lineStringReplay.drawPolygonCoordinates(outerRing, holes, stride);\n          this.drawCoordinates_(outerRing, holes, stride);\n        }\n      }\n      start = ends[ends.length - 1];\n    }\n    if (this.indices.length > currIndex) {\n      this.startIndices.push(currIndex);\n      this.startIndicesFeature.push(feature);\n      if (this.state_.changed) {\n        this.styleIndices_.push(currIndex);\n        this.state_.changed = false;\n      }\n    }\n    if (this.lineStringReplay.getCurrentIndex() > currLineIndex) {\n      this.lineStringReplay.setPolygonStyle(feature, currLineIndex);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawPolygon(polygonGeometry, feature) {\n    const ends = polygonGeometry.getEnds();\n    const stride = polygonGeometry.getStride();\n    if (ends.length > 0) {\n      const flatCoordinates = polygonGeometry.getFlatCoordinates().map(Number);\n      const outerRing = translate(flatCoordinates, 0, ends[0],\n        stride, -this.origin[0], -this.origin[1]);\n      if (outerRing.length) {\n        const holes = [];\n        let i, ii, holeFlatCoords;\n        for (i = 1, ii = ends.length; i < ii; ++i) {\n          if (ends[i] !== ends[i - 1]) {\n            holeFlatCoords = translate(flatCoordinates, ends[i - 1],\n              ends[i], stride, -this.origin[0], -this.origin[1]);\n            holes.push(holeFlatCoords);\n          }\n        }\n\n        this.startIndices.push(this.indices.length);\n        this.startIndicesFeature.push(feature);\n        if (this.state_.changed) {\n          this.styleIndices_.push(this.indices.length);\n          this.state_.changed = false;\n        }\n        this.lineStringReplay.setPolygonStyle(feature);\n\n        this.lineStringReplay.drawPolygonCoordinates(outerRing, holes, stride);\n        this.drawCoordinates_(outerRing, holes, stride);\n      }\n    }\n  }\n\n  /**\n   * @inheritDoc\n   **/\n  finish(context) {\n    // create, bind, and populate the vertices buffer\n    this.verticesBuffer = new WebGLBuffer(this.vertices);\n\n    // create, bind, and populate the indices buffer\n    this.indicesBuffer = new WebGLBuffer(this.indices);\n\n    this.startIndices.push(this.indices.length);\n\n    this.lineStringReplay.finish(context);\n\n    //Clean up, if there is nothing to draw\n    if (this.styleIndices_.length === 0 && this.styles_.length > 0) {\n      this.styles_ = [];\n    }\n\n    this.vertices = null;\n    this.indices = null;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getDeleteResourcesFunction(context) {\n    const verticesBuffer = this.verticesBuffer;\n    const indicesBuffer = this.indicesBuffer;\n    const lineDeleter = this.lineStringReplay.getDeleteResourcesFunction(context);\n    return function() {\n      context.deleteBuffer(verticesBuffer);\n      context.deleteBuffer(indicesBuffer);\n      lineDeleter();\n    };\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setUpProgram(gl, context, size, pixelRatio) {\n    // get the program\n    const program = context.getProgram(fragment, vertex);\n\n    // get the locations\n    let locations;\n    if (!this.defaultLocations_) {\n      locations = new Locations(gl, program);\n      this.defaultLocations_ = locations;\n    } else {\n      locations = this.defaultLocations_;\n    }\n\n    context.useProgram(program);\n\n    // enable the vertex attrib arrays\n    gl.enableVertexAttribArray(locations.a_position);\n    gl.vertexAttribPointer(locations.a_position, 2, FLOAT,\n      false, 8, 0);\n\n    return locations;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  shutDownProgram(gl, locations) {\n    gl.disableVertexAttribArray(locations.a_position);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawReplay(gl, context, skippedFeaturesHash, hitDetection) {\n    //Save GL parameters.\n    const tmpDepthFunc = /** @type {number} */ (gl.getParameter(gl.DEPTH_FUNC));\n    const tmpDepthMask = /** @type {boolean} */ (gl.getParameter(gl.DEPTH_WRITEMASK));\n\n    if (!hitDetection) {\n      gl.enable(gl.DEPTH_TEST);\n      gl.depthMask(true);\n      gl.depthFunc(gl.NOTEQUAL);\n    }\n\n    if (!isEmpty(skippedFeaturesHash)) {\n      this.drawReplaySkipping_(gl, context, skippedFeaturesHash);\n    } else {\n      //Draw by style groups to minimize drawElements() calls.\n      let i, start, end, nextStyle;\n      end = this.startIndices[this.startIndices.length - 1];\n      for (i = this.styleIndices_.length - 1; i >= 0; --i) {\n        start = this.styleIndices_[i];\n        nextStyle = this.styles_[i];\n        this.setFillStyle_(gl, nextStyle);\n        this.drawElements(gl, context, start, end);\n        end = start;\n      }\n    }\n    if (!hitDetection) {\n      gl.disable(gl.DEPTH_TEST);\n      gl.clear(gl.DEPTH_BUFFER_BIT);\n      //Restore GL parameters.\n      gl.depthMask(tmpDepthMask);\n      gl.depthFunc(tmpDepthFunc);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawHitDetectionReplayOneByOne(gl, context, skippedFeaturesHash, featureCallback, opt_hitExtent) {\n    let i, start, end, nextStyle, groupStart, feature, featureUid, featureIndex;\n    featureIndex = this.startIndices.length - 2;\n    end = this.startIndices[featureIndex + 1];\n    for (i = this.styleIndices_.length - 1; i >= 0; --i) {\n      nextStyle = this.styles_[i];\n      this.setFillStyle_(gl, nextStyle);\n      groupStart = this.styleIndices_[i];\n\n      while (featureIndex >= 0 &&\n          this.startIndices[featureIndex] >= groupStart) {\n        start = this.startIndices[featureIndex];\n        feature = this.startIndicesFeature[featureIndex];\n        featureUid = getUid(feature).toString();\n\n        if (skippedFeaturesHash[featureUid] === undefined &&\n            feature.getGeometry() &&\n            (opt_hitExtent === undefined || intersects(\n              /** @type {Array<number>} */ (opt_hitExtent),\n              feature.getGeometry().getExtent()))) {\n          gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n          this.drawElements(gl, context, start, end);\n\n          const result = featureCallback(feature);\n\n          if (result) {\n            return result;\n          }\n\n        }\n        featureIndex--;\n        end = start;\n      }\n    }\n    return undefined;\n  }\n\n  /**\n   * @private\n   * @param {WebGLRenderingContext} gl gl.\n   * @param {module:ol/webgl/Context} context Context.\n   * @param {Object} skippedFeaturesHash Ids of features to skip.\n   */\n  drawReplaySkipping_(gl, context, skippedFeaturesHash) {\n    let i, start, end, nextStyle, groupStart, feature, featureUid, featureIndex, featureStart;\n    featureIndex = this.startIndices.length - 2;\n    end = start = this.startIndices[featureIndex + 1];\n    for (i = this.styleIndices_.length - 1; i >= 0; --i) {\n      nextStyle = this.styles_[i];\n      this.setFillStyle_(gl, nextStyle);\n      groupStart = this.styleIndices_[i];\n\n      while (featureIndex >= 0 &&\n          this.startIndices[featureIndex] >= groupStart) {\n        featureStart = this.startIndices[featureIndex];\n        feature = this.startIndicesFeature[featureIndex];\n        featureUid = getUid(feature).toString();\n\n        if (skippedFeaturesHash[featureUid]) {\n          if (start !== end) {\n            this.drawElements(gl, context, start, end);\n            gl.clear(gl.DEPTH_BUFFER_BIT);\n          }\n          end = featureStart;\n        }\n        featureIndex--;\n        start = featureStart;\n      }\n      if (start !== end) {\n        this.drawElements(gl, context, start, end);\n        gl.clear(gl.DEPTH_BUFFER_BIT);\n      }\n      start = end = groupStart;\n    }\n  }\n\n  /**\n   * @private\n   * @param {WebGLRenderingContext} gl gl.\n   * @param {Array.<number>} color Color.\n   */\n  setFillStyle_(gl, color) {\n    gl.uniform4fv(this.defaultLocations_.u_color, color);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setFillStrokeStyle(fillStyle, strokeStyle) {\n    let fillStyleColor = fillStyle ? fillStyle.getColor() : [0, 0, 0, 0];\n    if (!(fillStyleColor instanceof CanvasGradient) &&\n        !(fillStyleColor instanceof CanvasPattern)) {\n      fillStyleColor = asArray(fillStyleColor).map(function(c, i) {\n        return i != 3 ? c / 255 : c;\n      }) || DEFAULT_FILLSTYLE;\n    } else {\n      fillStyleColor = DEFAULT_FILLSTYLE;\n    }\n    if (!this.state_.fillColor || !equals(fillStyleColor, this.state_.fillColor)) {\n      this.state_.fillColor = fillStyleColor;\n      this.state_.changed = true;\n      this.styles_.push(fillStyleColor);\n    }\n    //Provide a null stroke style, if no strokeStyle is provided. Required for the draw interaction to work.\n    if (strokeStyle) {\n      this.lineStringReplay.setFillStrokeStyle(null, strokeStyle);\n    } else {\n      const nullStrokeStyle = new Stroke({\n        color: [0, 0, 0, 0],\n        lineWidth: 0\n      });\n      this.lineStringReplay.setFillStrokeStyle(null, nullStrokeStyle);\n    }\n  }\n}\n\n\nexport default WebGLPolygonReplay;\n","/**\n * @module ol/style/Atlas\n */\nimport {createCanvasContext2D} from '../dom.js';\n\n\n/**\n * @typedef {Object} AtlasBlock\n * @property {number} x\n * @property {number} y\n * @property {number} width\n * @property {number} height\n */\n\n/**\n * Provides information for an image inside an atlas.\n * `offsetX` and `offsetY` are the position of the image inside the atlas image `image`.\n * @typedef {Object} AtlasInfo\n * @property {number} offsetX\n * @property {number} offsetY\n * @property {HTMLCanvasElement} image\n */\n\n\n/**\n * @classesc\n * This class facilitates the creation of image atlases.\n *\n * Images added to an atlas will be rendered onto a single\n * atlas canvas. The distribution of images on the canvas is\n * managed with the bin packing algorithm described in:\n * http://www.blackpawn.com/texts/lightmaps/\n *\n * @param {number} size The size in pixels of the sprite image.\n * @param {number} space The space in pixels between images.\n *    Because texture coordinates are float values, the edges of\n *    images might not be completely correct (in a way that the\n *    edges overlap when being rendered). To avoid this we add a\n *    padding around each image.\n */\nclass Atlas {\n\n  /**\n   * @param {number} size The size in pixels of the sprite image.\n   * @param {number} space The space in pixels between images.\n   *    Because texture coordinates are float values, the edges of\n   *    images might not be completely correct (in a way that the\n   *    edges overlap when being rendered). To avoid this we add a\n   *    padding around each image.\n   */\n  constructor(size, space) {\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.space_ = space;\n\n    /**\n     * @private\n     * @type {Array.<module:ol/style/Atlas~AtlasBlock>}\n     */\n    this.emptyBlocks_ = [{x: 0, y: 0, width: size, height: size}];\n\n    /**\n     * @private\n     * @type {Object.<string, module:ol/style/Atlas~AtlasInfo>}\n     */\n    this.entries_ = {};\n\n    /**\n     * @private\n     * @type {CanvasRenderingContext2D}\n     */\n    this.context_ = createCanvasContext2D(size, size);\n\n    /**\n     * @private\n     * @type {HTMLCanvasElement}\n     */\n    this.canvas_ = this.context_.canvas;\n  }\n\n  /**\n   * @param {string} id The identifier of the entry to check.\n   * @return {?module:ol/style/Atlas~AtlasInfo} The atlas info.\n   */\n  get(id) {\n    return this.entries_[id] || null;\n  }\n\n  /**\n   * @param {string} id The identifier of the entry to add.\n   * @param {number} width The width.\n   * @param {number} height The height.\n   * @param {function(CanvasRenderingContext2D, number, number)} renderCallback\n   *    Called to render the new image onto an atlas image.\n   * @param {Object=} opt_this Value to use as `this` when executing\n   *    `renderCallback`.\n   * @return {?module:ol/style/Atlas~AtlasInfo} The position and atlas image for the entry.\n   */\n  add(id, width, height, renderCallback, opt_this) {\n    for (let i = 0, ii = this.emptyBlocks_.length; i < ii; ++i) {\n      const block = this.emptyBlocks_[i];\n      if (block.width >= width + this.space_ &&\n          block.height >= height + this.space_) {\n        // we found a block that is big enough for our entry\n        const entry = {\n          offsetX: block.x + this.space_,\n          offsetY: block.y + this.space_,\n          image: this.canvas_\n        };\n        this.entries_[id] = entry;\n\n        // render the image on the atlas image\n        renderCallback.call(opt_this, this.context_,\n          block.x + this.space_, block.y + this.space_);\n\n        // split the block after the insertion, either horizontally or vertically\n        this.split_(i, block, width + this.space_, height + this.space_);\n\n        return entry;\n      }\n    }\n\n    // there is no space for the new entry in this atlas\n    return null;\n  }\n\n  /**\n   * @private\n   * @param {number} index The index of the block.\n   * @param {module:ol/style/Atlas~AtlasBlock} block The block to split.\n   * @param {number} width The width of the entry to insert.\n   * @param {number} height The height of the entry to insert.\n   */\n  split_(index, block, width, height) {\n    const deltaWidth = block.width - width;\n    const deltaHeight = block.height - height;\n\n    /** @type {module:ol/style/Atlas~AtlasBlock} */\n    let newBlock1;\n    /** @type {module:ol/style/Atlas~AtlasBlock} */\n    let newBlock2;\n\n    if (deltaWidth > deltaHeight) {\n      // split vertically\n      // block right of the inserted entry\n      newBlock1 = {\n        x: block.x + width,\n        y: block.y,\n        width: block.width - width,\n        height: block.height\n      };\n\n      // block below the inserted entry\n      newBlock2 = {\n        x: block.x,\n        y: block.y + height,\n        width: width,\n        height: block.height - height\n      };\n      this.updateBlocks_(index, newBlock1, newBlock2);\n    } else {\n      // split horizontally\n      // block right of the inserted entry\n      newBlock1 = {\n        x: block.x + width,\n        y: block.y,\n        width: block.width - width,\n        height: height\n      };\n\n      // block below the inserted entry\n      newBlock2 = {\n        x: block.x,\n        y: block.y + height,\n        width: block.width,\n        height: block.height - height\n      };\n      this.updateBlocks_(index, newBlock1, newBlock2);\n    }\n  }\n\n  /**\n   * Remove the old block and insert new blocks at the same array position.\n   * The new blocks are inserted at the same position, so that splitted\n   * blocks (that are potentially smaller) are filled first.\n   * @private\n   * @param {number} index The index of the block to remove.\n   * @param {module:ol/style/Atlas~AtlasBlock} newBlock1 The 1st block to add.\n   * @param {module:ol/style/Atlas~AtlasBlock} newBlock2 The 2nd block to add.\n   */\n  updateBlocks_(index, newBlock1, newBlock2) {\n    const args = [index, 1];\n    if (newBlock1.width > 0 && newBlock1.height > 0) {\n      args.push(newBlock1);\n    }\n    if (newBlock2.width > 0 && newBlock2.height > 0) {\n      args.push(newBlock2);\n    }\n    this.emptyBlocks_.splice.apply(this.emptyBlocks_, args);\n  }\n}\n\nexport default Atlas;\n","/**\n * @module ol/style/AtlasManager\n */\nimport {MAX_TEXTURE_SIZE as WEBGL_MAX_TEXTURE_SIZE} from '../webgl.js';\nimport {UNDEFINED} from '../functions.js';\nimport Atlas from '../style/Atlas.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [initialSize=256] The size in pixels of the first atlas image.\n * @property {number} [maxSize] The maximum size in pixels of atlas images. Default is\n * `webgl/MAX_TEXTURE_SIZE` or 2048 if WebGL is not supported.\n * @property {number} [space=1] The space in pixels between images.\n */\n\n\n/**\n * Provides information for an image inside an atlas manager.\n * `offsetX` and `offsetY` is the position of the image inside\n * the atlas image `image` and the position of the hit-detection image\n * inside the hit-detection atlas image `hitImage`.\n * @typedef {Object} AtlasManagerInfo\n * @property {number} offsetX\n * @property {number} offsetY\n * @property {HTMLCanvasElement} image\n * @property {HTMLCanvasElement} hitImage\n */\n\n\n/**\n * The size in pixels of the first atlas image.\n * @type {number}\n */\nconst INITIAL_ATLAS_SIZE = 256;\n\n/**\n * The maximum size in pixels of atlas images.\n * @type {number}\n */\nconst MAX_ATLAS_SIZE = -1;\n\n\n/**\n * @classdesc\n * Manages the creation of image atlases.\n *\n * Images added to this manager will be inserted into an atlas, which\n * will be used for rendering.\n * The `size` given in the constructor is the size for the first\n * atlas. After that, when new atlases are created, they will have\n * twice the size as the latest atlas (until `maxSize` is reached).\n *\n * If an application uses many images or very large images, it is recommended\n * to set a higher `size` value to avoid the creation of too many atlases.\n * @api\n */\nclass AtlasManager {\n  /**\n   * @param {module:ol/style/AtlasManager~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options || {};\n\n    /**\n     * The size in pixels of the latest atlas image.\n     * @private\n     * @type {number}\n     */\n    this.currentSize_ = options.initialSize !== undefined ?\n      options.initialSize : INITIAL_ATLAS_SIZE;\n\n    /**\n     * The maximum size in pixels of atlas images.\n     * @private\n     * @type {number}\n     */\n    this.maxSize_ = options.maxSize !== undefined ?\n      options.maxSize : MAX_ATLAS_SIZE != -1 ?\n        MAX_ATLAS_SIZE : WEBGL_MAX_TEXTURE_SIZE !== undefined ?\n          WEBGL_MAX_TEXTURE_SIZE : 2048;\n\n    /**\n     * The size in pixels between images.\n     * @private\n     * @type {number}\n     */\n    this.space_ = options.space !== undefined ? options.space : 1;\n\n    /**\n     * @private\n     * @type {Array.<module:ol/style/Atlas>}\n     */\n    this.atlases_ = [new Atlas(this.currentSize_, this.space_)];\n\n    /**\n     * The size in pixels of the latest atlas image for hit-detection images.\n     * @private\n     * @type {number}\n     */\n    this.currentHitSize_ = this.currentSize_;\n\n    /**\n     * @private\n     * @type {Array.<module:ol/style/Atlas>}\n     */\n    this.hitAtlases_ = [new Atlas(this.currentHitSize_, this.space_)];\n  }\n\n  /**\n   * @param {string} id The identifier of the entry to check.\n   * @return {?module:ol/style/AtlasManager~AtlasManagerInfo} The position and atlas image for the\n   *    entry, or `null` if the entry is not part of the atlas manager.\n   */\n  getInfo(id) {\n    /** @type {?module:ol/style/Atlas~AtlasInfo} */\n    const info = this.getInfo_(this.atlases_, id);\n\n    if (!info) {\n      return null;\n    }\n    const hitInfo = /** @type {module:ol/style/Atlas~AtlasInfo} */ (this.getInfo_(this.hitAtlases_, id));\n\n    return this.mergeInfos_(info, hitInfo);\n  }\n\n  /**\n   * @private\n   * @param {Array.<module:ol/style/Atlas>} atlases The atlases to search.\n   * @param {string} id The identifier of the entry to check.\n   * @return {?module:ol/style/Atlas~AtlasInfo} The position and atlas image for the entry,\n   *    or `null` if the entry is not part of the atlases.\n   */\n  getInfo_(atlases, id) {\n    for (let i = 0, ii = atlases.length; i < ii; ++i) {\n      const atlas = atlases[i];\n      const info = atlas.get(id);\n      if (info) {\n        return info;\n      }\n    }\n    return null;\n  }\n\n  /**\n   * @private\n   * @param {module:ol/style/Atlas~AtlasInfo} info The info for the real image.\n   * @param {module:ol/style/Atlas~AtlasInfo} hitInfo The info for the hit-detection\n   *    image.\n   * @return {?module:ol/style/AtlasManager~AtlasManagerInfo} The position and atlas image for the\n   *    entry, or `null` if the entry is not part of the atlases.\n   */\n  mergeInfos_(info, hitInfo) {\n    return (\n      /** @type {module:ol/style/AtlasManager~AtlasManagerInfo} */ ({\n        offsetX: info.offsetX,\n        offsetY: info.offsetY,\n        image: info.image,\n        hitImage: hitInfo.image\n      })\n    );\n  }\n\n  /**\n   * Add an image to the atlas manager.\n   *\n   * If an entry for the given id already exists, the entry will\n   * be overridden (but the space on the atlas graphic will not be freed).\n   *\n   * If `renderHitCallback` is provided, the image (or the hit-detection version\n   * of the image) will be rendered into a separate hit-detection atlas image.\n   *\n   * @param {string} id The identifier of the entry to add.\n   * @param {number} width The width.\n   * @param {number} height The height.\n   * @param {function(CanvasRenderingContext2D, number, number)} renderCallback\n   *    Called to render the new image onto an atlas image.\n   * @param {function(CanvasRenderingContext2D, number, number)=}\n   *    opt_renderHitCallback Called to render a hit-detection image onto a hit\n   *    detection atlas image.\n   * @param {Object=} opt_this Value to use as `this` when executing\n   *    `renderCallback` and `renderHitCallback`.\n   * @return {?module:ol/style/AtlasManager~AtlasManagerInfo}  The position and atlas image for the\n   *    entry, or `null` if the image is too big.\n   */\n  add(id, width, height, renderCallback, opt_renderHitCallback, opt_this) {\n    if (width + this.space_ > this.maxSize_ ||\n        height + this.space_ > this.maxSize_) {\n      return null;\n    }\n\n    /** @type {?module:ol/style/Atlas~AtlasInfo} */\n    const info = this.add_(false, id, width, height, renderCallback, opt_this);\n    if (!info) {\n      return null;\n    }\n\n    // even if no hit-detection entry is requested, we insert a fake entry into\n    // the hit-detection atlas, to make sure that the offset is the same for\n    // the original image and the hit-detection image.\n    const renderHitCallback = opt_renderHitCallback !== undefined ?\n      opt_renderHitCallback : UNDEFINED;\n\n    const hitInfo = /** @type {module:ol/style/Atlas~AtlasInfo} */ (this.add_(true,\n      id, width, height, renderHitCallback, opt_this));\n\n    return this.mergeInfos_(info, hitInfo);\n  }\n\n  /**\n   * @private\n   * @param {boolean} isHitAtlas If the hit-detection atlases are used.\n   * @param {string} id The identifier of the entry to add.\n   * @param {number} width The width.\n   * @param {number} height The height.\n   * @param {function(CanvasRenderingContext2D, number, number)} renderCallback\n   *    Called to render the new image onto an atlas image.\n   * @param {Object=} opt_this Value to use as `this` when executing\n   *    `renderCallback` and `renderHitCallback`.\n   * @return {?module:ol/style/Atlas~AtlasInfo}  The position and atlas image for the entry,\n   *    or `null` if the image is too big.\n   */\n  add_(isHitAtlas, id, width, height, renderCallback, opt_this) {\n    const atlases = (isHitAtlas) ? this.hitAtlases_ : this.atlases_;\n    let atlas, info, i, ii;\n    for (i = 0, ii = atlases.length; i < ii; ++i) {\n      atlas = atlases[i];\n      info = atlas.add(id, width, height, renderCallback, opt_this);\n      if (info) {\n        return info;\n      } else if (!info && i === ii - 1) {\n        // the entry could not be added to one of the existing atlases,\n        // create a new atlas that is twice as big and try to add to this one.\n        let size;\n        if (isHitAtlas) {\n          size = Math.min(this.currentHitSize_ * 2, this.maxSize_);\n          this.currentHitSize_ = size;\n        } else {\n          size = Math.min(this.currentSize_ * 2, this.maxSize_);\n          this.currentSize_ = size;\n        }\n        atlas = new Atlas(size, this.space_);\n        atlases.push(atlas);\n        // run the loop another time\n        ++ii;\n      }\n    }\n    return null;\n  }\n}\n\nexport default AtlasManager;\n","/**\n * @module ol/render/webgl/TextReplay\n */\nimport {getUid} from '../../util.js';\nimport {asColorLike} from '../../colorlike.js';\nimport {createCanvasContext2D} from '../../dom.js';\nimport GeometryType from '../../geom/GeometryType.js';\nimport {CANVAS_LINE_DASH} from '../../has.js';\nimport {TEXT_ALIGN} from '../replay.js';\nimport {DEFAULT_FILLSTYLE, DEFAULT_FONT, DEFAULT_LINECAP, DEFAULT_LINEDASH,\n  DEFAULT_LINEDASHOFFSET, DEFAULT_LINEJOIN, DEFAULT_LINEWIDTH, DEFAULT_MITERLIMIT,\n  DEFAULT_STROKESTYLE, DEFAULT_TEXTALIGN, DEFAULT_TEXTBASELINE} from '../webgl.js';\nimport WebGLTextureReplay from '../webgl/TextureReplay.js';\nimport AtlasManager from '../../style/AtlasManager.js';\nimport WebGLBuffer from '../../webgl/Buffer.js';\n\n/**\n * @typedef {Object} GlyphAtlas\n * @property {module:ol/style/AtlasManager} atlas\n * @property {Object.<string, number>} width\n * @property {number} height\n */\n\n\nclass WebGLTextReplay extends WebGLTextureReplay {\n  /**\n   * @param {number} tolerance Tolerance.\n   * @param {module:ol/extent~Extent} maxExtent Max extent.\n   */\n  constructor(tolerance, maxExtent) {\n    super(tolerance, maxExtent);\n\n    /**\n     * @private\n     * @type {Array.<HTMLCanvasElement>}\n     */\n    this.images_ = [];\n\n    /**\n     * @private\n     * @type {Array.<WebGLTexture>}\n     */\n    this.textures_ = [];\n\n    /**\n     * @private\n     * @type {HTMLCanvasElement}\n     */\n    this.measureCanvas_ = createCanvasContext2D(0, 0).canvas;\n\n    /**\n     * @private\n     * @type {{strokeColor: (module:ol/colorlike~ColorLike|null),\n     *         lineCap: (string|undefined),\n     *         lineDash: Array.<number>,\n     *         lineDashOffset: (number|undefined),\n     *         lineJoin: (string|undefined),\n     *         lineWidth: number,\n     *         miterLimit: (number|undefined),\n     *         fillColor: (module:ol/colorlike~ColorLike|null),\n     *         font: (string|undefined),\n     *         scale: (number|undefined)}}\n     */\n    this.state_ = {\n      strokeColor: null,\n      lineCap: undefined,\n      lineDash: null,\n      lineDashOffset: undefined,\n      lineJoin: undefined,\n      lineWidth: 0,\n      miterLimit: undefined,\n      fillColor: null,\n      font: undefined,\n      scale: undefined\n    };\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.text_ = '';\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.textAlign_ = undefined;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.textBaseline_ = undefined;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.offsetX_ = undefined;\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.offsetY_ = undefined;\n\n    /**\n     * @private\n     * @type {Object.<string, module:ol/render/webgl/TextReplay~GlyphAtlas>}\n     */\n    this.atlases_ = {};\n\n    /**\n     * @private\n     * @type {module:ol/render/webgl/TextReplay~GlyphAtlas|undefined}\n     */\n    this.currAtlas_ = undefined;\n\n    this.scale = 1;\n\n    this.opacity = 1;\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawText(geometry, feature) {\n    if (this.text_) {\n      let flatCoordinates = null;\n      const offset = 0;\n      let end = 2;\n      let stride = 2;\n      switch (geometry.getType()) {\n        case GeometryType.POINT:\n        case GeometryType.MULTI_POINT:\n          flatCoordinates = geometry.getFlatCoordinates();\n          end = flatCoordinates.length;\n          stride = geometry.getStride();\n          break;\n        case GeometryType.CIRCLE:\n          flatCoordinates = /** @type {module:ol/geom/Circle} */ (geometry).getCenter();\n          break;\n        case GeometryType.LINE_STRING:\n          flatCoordinates = /** @type {module:ol/geom/LineString} */ (geometry).getFlatMidpoint();\n          break;\n        case GeometryType.MULTI_LINE_STRING:\n          flatCoordinates = /** @type {module:ol/geom/MultiLineString} */ (geometry).getFlatMidpoints();\n          end = flatCoordinates.length;\n          break;\n        case GeometryType.POLYGON:\n          flatCoordinates = /** @type {module:ol/geom/Polygon} */ (geometry).getFlatInteriorPoint();\n          break;\n        case GeometryType.MULTI_POLYGON:\n          flatCoordinates = /** @type {module:ol/geom/MultiPolygon} */ (geometry).getFlatInteriorPoints();\n          end = flatCoordinates.length;\n          break;\n        default:\n      }\n      this.startIndices.push(this.indices.length);\n      this.startIndicesFeature.push(feature);\n\n      const glyphAtlas = this.currAtlas_;\n      const lines = this.text_.split('\\n');\n      const textSize = this.getTextSize_(lines);\n      let i, ii, j, jj, currX, currY, charArr, charInfo;\n      const anchorX = Math.round(textSize[0] * this.textAlign_ - this.offsetX_);\n      const anchorY = Math.round(textSize[1] * this.textBaseline_ - this.offsetY_);\n      const lineWidth = (this.state_.lineWidth / 2) * this.state_.scale;\n\n      for (i = 0, ii = lines.length; i < ii; ++i) {\n        currX = 0;\n        currY = glyphAtlas.height * i;\n        charArr = lines[i].split('');\n\n        for (j = 0, jj = charArr.length; j < jj; ++j) {\n          charInfo = glyphAtlas.atlas.getInfo(charArr[j]);\n\n          if (charInfo) {\n            const image = charInfo.image;\n\n            this.anchorX = anchorX - currX;\n            this.anchorY = anchorY - currY;\n            this.originX = j === 0 ? charInfo.offsetX - lineWidth : charInfo.offsetX;\n            this.originY = charInfo.offsetY;\n            this.height = glyphAtlas.height;\n            this.width = j === 0 || j === charArr.length - 1 ?\n              glyphAtlas.width[charArr[j]] + lineWidth : glyphAtlas.width[charArr[j]];\n            this.imageHeight = image.height;\n            this.imageWidth = image.width;\n\n            if (this.images_.length === 0) {\n              this.images_.push(image);\n            } else {\n              const currentImage = this.images_[this.images_.length - 1];\n              if (getUid(currentImage) != getUid(image)) {\n                this.groupIndices.push(this.indices.length);\n                this.images_.push(image);\n              }\n            }\n\n            this.drawText_(flatCoordinates, offset, end, stride);\n          }\n          currX += this.width;\n        }\n      }\n    }\n  }\n\n  /**\n   * @private\n   * @param {Array.<string>} lines Label to draw split to lines.\n   * @return {Array.<number>} Size of the label in pixels.\n   */\n  getTextSize_(lines) {\n    const self = this;\n    const glyphAtlas = this.currAtlas_;\n    const textHeight = lines.length * glyphAtlas.height;\n    //Split every line to an array of chars, sum up their width, and select the longest.\n    const textWidth = lines.map(function(str) {\n      let sum = 0;\n      for (let i = 0, ii = str.length; i < ii; ++i) {\n        const curr = str[i];\n        if (!glyphAtlas.width[curr]) {\n          self.addCharToAtlas_(curr);\n        }\n        sum += glyphAtlas.width[curr] ? glyphAtlas.width[curr] : 0;\n      }\n      return sum;\n    }).reduce(function(max, curr) {\n      return Math.max(max, curr);\n    });\n\n    return [textWidth, textHeight];\n  }\n\n  /**\n   * @private\n   * @param {Array.<number>} flatCoordinates Flat coordinates.\n   * @param {number} offset Offset.\n   * @param {number} end End.\n   * @param {number} stride Stride.\n   */\n  drawText_(flatCoordinates, offset, end, stride) {\n    for (let i = offset, ii = end; i < ii; i += stride) {\n      this.drawCoordinates(flatCoordinates, offset, end, stride);\n    }\n  }\n\n  /**\n   * @private\n   * @param {string} char Character.\n   */\n  addCharToAtlas_(char) {\n    if (char.length === 1) {\n      const glyphAtlas = this.currAtlas_;\n      const state = this.state_;\n      const mCtx = this.measureCanvas_.getContext('2d');\n      mCtx.font = state.font;\n      const width = Math.ceil(mCtx.measureText(char).width * state.scale);\n\n      const info = glyphAtlas.atlas.add(char, width, glyphAtlas.height,\n        function(ctx, x, y) {\n          //Parameterize the canvas\n          ctx.font = /** @type {string} */ (state.font);\n          ctx.fillStyle = state.fillColor;\n          ctx.strokeStyle = state.strokeColor;\n          ctx.lineWidth = state.lineWidth;\n          ctx.lineCap = /*** @type {string} */ (state.lineCap);\n          ctx.lineJoin = /** @type {string} */ (state.lineJoin);\n          ctx.miterLimit = /** @type {number} */ (state.miterLimit);\n          ctx.textAlign = 'left';\n          ctx.textBaseline = 'top';\n          if (CANVAS_LINE_DASH && state.lineDash) {\n            //FIXME: use pixelRatio\n            ctx.setLineDash(state.lineDash);\n            ctx.lineDashOffset = /** @type {number} */ (state.lineDashOffset);\n          }\n          if (state.scale !== 1) {\n            //FIXME: use pixelRatio\n            ctx.setTransform(/** @type {number} */ (state.scale), 0, 0,\n              /** @type {number} */ (state.scale), 0, 0);\n          }\n\n          //Draw the character on the canvas\n          if (state.strokeColor) {\n            ctx.strokeText(char, x, y);\n          }\n          if (state.fillColor) {\n            ctx.fillText(char, x, y);\n          }\n        });\n\n      if (info) {\n        glyphAtlas.width[char] = width;\n      }\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  finish(context) {\n    const gl = context.getGL();\n\n    this.groupIndices.push(this.indices.length);\n    this.hitDetectionGroupIndices = this.groupIndices;\n\n    // create, bind, and populate the vertices buffer\n    this.verticesBuffer = new WebGLBuffer(this.vertices);\n\n    // create, bind, and populate the indices buffer\n    this.indicesBuffer = new WebGLBuffer(this.indices);\n\n    // create textures\n    /** @type {Object.<string, WebGLTexture>} */\n    const texturePerImage = {};\n\n    this.createTextures(this.textures_, this.images_, texturePerImage, gl);\n\n    this.state_ = {\n      strokeColor: null,\n      lineCap: undefined,\n      lineDash: null,\n      lineDashOffset: undefined,\n      lineJoin: undefined,\n      lineWidth: 0,\n      miterLimit: undefined,\n      fillColor: null,\n      font: undefined,\n      scale: undefined\n    };\n    this.text_ = '';\n    this.textAlign_ = undefined;\n    this.textBaseline_ = undefined;\n    this.offsetX_ = undefined;\n    this.offsetY_ = undefined;\n    this.images_ = null;\n    this.atlases_ = {};\n    this.currAtlas_ = undefined;\n    WebGLTextureReplay.prototype.finish.call(this, context);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setTextStyle(textStyle) {\n    const state = this.state_;\n    const textFillStyle = textStyle.getFill();\n    const textStrokeStyle = textStyle.getStroke();\n    if (!textStyle || !textStyle.getText() || (!textFillStyle && !textStrokeStyle)) {\n      this.text_ = '';\n    } else {\n      if (!textFillStyle) {\n        state.fillColor = null;\n      } else {\n        const textFillStyleColor = textFillStyle.getColor();\n        state.fillColor = asColorLike(textFillStyleColor ?\n          textFillStyleColor : DEFAULT_FILLSTYLE);\n      }\n      if (!textStrokeStyle) {\n        state.strokeColor = null;\n        state.lineWidth = 0;\n      } else {\n        const textStrokeStyleColor = textStrokeStyle.getColor();\n        state.strokeColor = asColorLike(textStrokeStyleColor ?\n          textStrokeStyleColor : DEFAULT_STROKESTYLE);\n        state.lineWidth = textStrokeStyle.getWidth() || DEFAULT_LINEWIDTH;\n        state.lineCap = textStrokeStyle.getLineCap() || DEFAULT_LINECAP;\n        state.lineDashOffset = textStrokeStyle.getLineDashOffset() || DEFAULT_LINEDASHOFFSET;\n        state.lineJoin = textStrokeStyle.getLineJoin() || DEFAULT_LINEJOIN;\n        state.miterLimit = textStrokeStyle.getMiterLimit() || DEFAULT_MITERLIMIT;\n        const lineDash = textStrokeStyle.getLineDash();\n        state.lineDash = lineDash ? lineDash.slice() : DEFAULT_LINEDASH;\n      }\n      state.font = textStyle.getFont() || DEFAULT_FONT;\n      state.scale = textStyle.getScale() || 1;\n      this.text_ = /** @type {string} */ (textStyle.getText());\n      const textAlign = TEXT_ALIGN[textStyle.getTextAlign()];\n      const textBaseline = TEXT_ALIGN[textStyle.getTextBaseline()];\n      this.textAlign_ = textAlign === undefined ?\n        DEFAULT_TEXTALIGN : textAlign;\n      this.textBaseline_ = textBaseline === undefined ?\n        DEFAULT_TEXTBASELINE : textBaseline;\n      this.offsetX_ = textStyle.getOffsetX() || 0;\n      this.offsetY_ = textStyle.getOffsetY() || 0;\n      this.rotateWithView = !!textStyle.getRotateWithView();\n      this.rotation = textStyle.getRotation() || 0;\n\n      this.currAtlas_ = this.getAtlas_(state);\n    }\n  }\n\n  /**\n   * @private\n   * @param {Object} state Font attributes.\n   * @return {module:ol/render/webgl/TextReplay~GlyphAtlas} Glyph atlas.\n   */\n  getAtlas_(state) {\n    let params = [];\n    for (const i in state) {\n      if (state[i] || state[i] === 0) {\n        if (Array.isArray(state[i])) {\n          params = params.concat(state[i]);\n        } else {\n          params.push(state[i]);\n        }\n      }\n    }\n    const hash = this.calculateHash_(params);\n    if (!this.atlases_[hash]) {\n      const mCtx = this.measureCanvas_.getContext('2d');\n      mCtx.font = state.font;\n      const height = Math.ceil((mCtx.measureText('M').width * 1.5 +\n          state.lineWidth / 2) * state.scale);\n\n      this.atlases_[hash] = {\n        atlas: new AtlasManager({\n          space: state.lineWidth + 1\n        }),\n        width: {},\n        height: height\n      };\n    }\n    return this.atlases_[hash];\n  }\n\n  /**\n   * @private\n   * @param {Array.<string|number>} params Array of parameters.\n   * @return {string} Hash string.\n   */\n  calculateHash_(params) {\n    //TODO: Create a more performant, reliable, general hash function.\n    let hash = '';\n    for (let i = 0, ii = params.length; i < ii; ++i) {\n      hash += params[i];\n    }\n    return hash;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getTextures(opt_all) {\n    return this.textures_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getHitDetectionTextures() {\n    return this.textures_;\n  }\n}\n\n\nexport default WebGLTextReplay;\n","/**\n * @module ol/render/webgl/ReplayGroup\n */\n\nimport {numberSafeCompareFunction} from '../../array.js';\nimport {buffer, createOrUpdateFromCoordinate} from '../../extent.js';\nimport {isEmpty} from '../../obj.js';\nimport {ORDER} from '../replay.js';\nimport ReplayGroup from '../ReplayGroup.js';\nimport WebGLCircleReplay from '../webgl/CircleReplay.js';\nimport WebGLImageReplay from '../webgl/ImageReplay.js';\nimport WebGLLineStringReplay from '../webgl/LineStringReplay.js';\nimport WebGLPolygonReplay from '../webgl/PolygonReplay.js';\nimport WebGLTextReplay from '../webgl/TextReplay.js';\n\n/**\n * @type {Array.<number>}\n */\nconst HIT_DETECTION_SIZE = [1, 1];\n\n/**\n * @type {Object.<module:ol/render/ReplayType,\n *                function(new: module:ol/render/webgl/Replay, number,\n *                module:ol/extent~Extent)>}\n */\nconst BATCH_CONSTRUCTORS = {\n  'Circle': WebGLCircleReplay,\n  'Image': WebGLImageReplay,\n  'LineString': WebGLLineStringReplay,\n  'Polygon': WebGLPolygonReplay,\n  'Text': WebGLTextReplay\n};\n\n\nclass WebGLReplayGroup extends ReplayGroup {\n  /**\n   * @param {number} tolerance Tolerance.\n   * @param {module:ol/extent~Extent} maxExtent Max extent.\n   * @param {number=} opt_renderBuffer Render buffer.\n   */\n  constructor(tolerance, maxExtent, opt_renderBuffer) {\n    super();\n\n    /**\n     * @type {module:ol/extent~Extent}\n     * @private\n     */\n    this.maxExtent_ = maxExtent;\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.tolerance_ = tolerance;\n\n    /**\n     * @type {number|undefined}\n     * @private\n     */\n    this.renderBuffer_ = opt_renderBuffer;\n\n    /**\n     * @private\n     * @type {!Object.<string,\n     *        Object.<module:ol/render/ReplayType, module:ol/render/webgl/Replay>>}\n     */\n    this.replaysByZIndex_ = {};\n\n  }\n\n  /**\n   * @param {module:ol/style/Style} style Style.\n   * @param {boolean} group Group with previous replay.\n   */\n  addDeclutter(style, group) {}\n\n  /**\n   * @param {module:ol/webgl/Context} context WebGL context.\n   * @return {function()} Delete resources function.\n   */\n  getDeleteResourcesFunction(context) {\n    const functions = [];\n    let zKey;\n    for (zKey in this.replaysByZIndex_) {\n      const replays = this.replaysByZIndex_[zKey];\n      for (const replayKey in replays) {\n        functions.push(\n          replays[replayKey].getDeleteResourcesFunction(context));\n      }\n    }\n    return function() {\n      const length = functions.length;\n      let result;\n      for (let i = 0; i < length; i++) {\n        result = functions[i].apply(this, arguments);\n      }\n      return result;\n    };\n  }\n\n  /**\n   * @param {module:ol/webgl/Context} context Context.\n   */\n  finish(context) {\n    let zKey;\n    for (zKey in this.replaysByZIndex_) {\n      const replays = this.replaysByZIndex_[zKey];\n      for (const replayKey in replays) {\n        replays[replayKey].finish(context);\n      }\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getReplay(zIndex, replayType) {\n    const zIndexKey = zIndex !== undefined ? zIndex.toString() : '0';\n    let replays = this.replaysByZIndex_[zIndexKey];\n    if (replays === undefined) {\n      replays = {};\n      this.replaysByZIndex_[zIndexKey] = replays;\n    }\n    let replay = replays[replayType];\n    if (replay === undefined) {\n      /**\n       * @type {Function}\n       */\n      const Constructor = BATCH_CONSTRUCTORS[replayType];\n      replay = new Constructor(this.tolerance_, this.maxExtent_);\n      replays[replayType] = replay;\n    }\n    return replay;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  isEmpty() {\n    return isEmpty(this.replaysByZIndex_);\n  }\n\n  /**\n   * @param {module:ol/webgl/Context} context Context.\n   * @param {module:ol/coordinate~Coordinate} center Center.\n   * @param {number} resolution Resolution.\n   * @param {number} rotation Rotation.\n   * @param {module:ol/size~Size} size Size.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {number} opacity Global opacity.\n   * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features to skip.\n   */\n  replay(\n    context,\n    center,\n    resolution,\n    rotation,\n    size,\n    pixelRatio,\n    opacity,\n    skippedFeaturesHash\n  ) {\n    /** @type {Array.<number>} */\n    const zs = Object.keys(this.replaysByZIndex_).map(Number);\n    zs.sort(numberSafeCompareFunction);\n\n    let i, ii, j, jj, replays, replay;\n    for (i = 0, ii = zs.length; i < ii; ++i) {\n      replays = this.replaysByZIndex_[zs[i].toString()];\n      for (j = 0, jj = ORDER.length; j < jj; ++j) {\n        replay = replays[ORDER[j]];\n        if (replay !== undefined) {\n          replay.replay(context,\n            center, resolution, rotation, size, pixelRatio,\n            opacity, skippedFeaturesHash,\n            undefined, false);\n        }\n      }\n    }\n  }\n\n  /**\n   * @private\n   * @param {module:ol/webgl/Context} context Context.\n   * @param {module:ol/coordinate~Coordinate} center Center.\n   * @param {number} resolution Resolution.\n   * @param {number} rotation Rotation.\n   * @param {module:ol/size~Size} size Size.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {number} opacity Global opacity.\n   * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features to skip.\n   * @param {function((module:ol/Feature|module:ol/render/Feature)): T|undefined} featureCallback Feature callback.\n   * @param {boolean} oneByOne Draw features one-by-one for the hit-detecion.\n   * @param {module:ol/extent~Extent=} opt_hitExtent Hit extent: Only features intersecting\n   *  this extent are checked.\n   * @return {T|undefined} Callback result.\n   * @template T\n   */\n  replayHitDetection_(\n    context,\n    center,\n    resolution,\n    rotation,\n    size,\n    pixelRatio,\n    opacity,\n    skippedFeaturesHash,\n    featureCallback,\n    oneByOne,\n    opt_hitExtent\n  ) {\n    /** @type {Array.<number>} */\n    const zs = Object.keys(this.replaysByZIndex_).map(Number);\n    zs.sort(function(a, b) {\n      return b - a;\n    });\n\n    let i, ii, j, replays, replay, result;\n    for (i = 0, ii = zs.length; i < ii; ++i) {\n      replays = this.replaysByZIndex_[zs[i].toString()];\n      for (j = ORDER.length - 1; j >= 0; --j) {\n        replay = replays[ORDER[j]];\n        if (replay !== undefined) {\n          result = replay.replay(context,\n            center, resolution, rotation, size, pixelRatio, opacity,\n            skippedFeaturesHash, featureCallback, oneByOne, opt_hitExtent);\n          if (result) {\n            return result;\n          }\n        }\n      }\n    }\n    return undefined;\n  }\n\n  /**\n   * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n   * @param {module:ol/webgl/Context} context Context.\n   * @param {module:ol/coordinate~Coordinate} center Center.\n   * @param {number} resolution Resolution.\n   * @param {number} rotation Rotation.\n   * @param {module:ol/size~Size} size Size.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {number} opacity Global opacity.\n   * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features to skip.\n   * @param {function((module:ol/Feature|module:ol/render/Feature)): T|undefined} callback Feature callback.\n   * @return {T|undefined} Callback result.\n   * @template T\n   */\n  forEachFeatureAtCoordinate(\n    coordinate,\n    context,\n    center,\n    resolution,\n    rotation,\n    size,\n    pixelRatio,\n    opacity,\n    skippedFeaturesHash,\n    callback\n  ) {\n    const gl = context.getGL();\n    gl.bindFramebuffer(\n      gl.FRAMEBUFFER, context.getHitDetectionFramebuffer());\n\n\n    /**\n     * @type {module:ol/extent~Extent}\n     */\n    let hitExtent;\n    if (this.renderBuffer_ !== undefined) {\n      // build an extent around the coordinate, so that only features that\n      // intersect this extent are checked\n      hitExtent = buffer(createOrUpdateFromCoordinate(coordinate), resolution * this.renderBuffer_);\n    }\n\n    return this.replayHitDetection_(context,\n      coordinate, resolution, rotation, HIT_DETECTION_SIZE,\n      pixelRatio, opacity, skippedFeaturesHash,\n      /**\n       * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n       * @return {?} Callback result.\n       */\n      function(feature) {\n        const imageData = new Uint8Array(4);\n        gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, imageData);\n\n        if (imageData[3] > 0) {\n          const result = callback(feature);\n          if (result) {\n            return result;\n          }\n        }\n      }, true, hitExtent);\n  }\n\n  /**\n   * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n   * @param {module:ol/webgl/Context} context Context.\n   * @param {module:ol/coordinate~Coordinate} center Center.\n   * @param {number} resolution Resolution.\n   * @param {number} rotation Rotation.\n   * @param {module:ol/size~Size} size Size.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {number} opacity Global opacity.\n   * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features to skip.\n   * @return {boolean} Is there a feature at the given coordinate?\n   */\n  hasFeatureAtCoordinate(\n    coordinate,\n    context,\n    center,\n    resolution,\n    rotation,\n    size,\n    pixelRatio,\n    opacity,\n    skippedFeaturesHash\n  ) {\n    const gl = context.getGL();\n    gl.bindFramebuffer(\n      gl.FRAMEBUFFER, context.getHitDetectionFramebuffer());\n\n    const hasFeature = this.replayHitDetection_(context,\n      coordinate, resolution, rotation, HIT_DETECTION_SIZE,\n      pixelRatio, opacity, skippedFeaturesHash,\n      /**\n       * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n       * @return {boolean} Is there a feature?\n       */\n      function(feature) {\n        const imageData = new Uint8Array(4);\n        gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, imageData);\n        return imageData[3] > 0;\n      }, false);\n\n    return hasFeature !== undefined;\n  }\n}\n\n\nexport default WebGLReplayGroup;\n","/**\n * @module ol/render/webgl/Immediate\n */\n\nimport {intersects} from '../../extent.js';\nimport GeometryType from '../../geom/GeometryType.js';\nimport ReplayType from '../ReplayType.js';\nimport VectorContext from '../VectorContext.js';\nimport WebGLReplayGroup from '../webgl/ReplayGroup.js';\n\nclass WebGLImmediateRenderer extends VectorContext {\n  /**\n   * @param {module:ol/webgl/Context} context Context.\n   * @param {module:ol/coordinate~Coordinate} center Center.\n   * @param {number} resolution Resolution.\n   * @param {number} rotation Rotation.\n   * @param {module:ol/size~Size} size Size.\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {number} pixelRatio Pixel ratio.\n   */\n  constructor(context, center, resolution, rotation, size, extent, pixelRatio) {\n    super();\n\n    /**\n     * @private\n     */\n    this.context_ = context;\n\n    /**\n     * @private\n     */\n    this.center_ = center;\n\n    /**\n     * @private\n     */\n    this.extent_ = extent;\n\n    /**\n     * @private\n     */\n    this.pixelRatio_ = pixelRatio;\n\n    /**\n     * @private\n     */\n    this.size_ = size;\n\n    /**\n     * @private\n     */\n    this.rotation_ = rotation;\n\n    /**\n     * @private\n     */\n    this.resolution_ = resolution;\n\n    /**\n     * @private\n     * @type {module:ol/style/Image}\n     */\n    this.imageStyle_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/style/Fill}\n     */\n    this.fillStyle_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/style/Stroke}\n     */\n    this.strokeStyle_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/style/Text}\n     */\n    this.textStyle_ = null;\n\n  }\n\n  /**\n   * @param {module:ol/render/webgl/ReplayGroup} replayGroup Replay group.\n   * @param {module:ol/geom/Geometry|module:ol/render/Feature} geometry Geometry.\n   * @private\n   */\n  drawText_(replayGroup, geometry) {\n    const context = this.context_;\n    const replay = /** @type {module:ol/render/webgl/TextReplay} */ (\n      replayGroup.getReplay(0, ReplayType.TEXT));\n    replay.setTextStyle(this.textStyle_);\n    replay.drawText(geometry, null);\n    replay.finish(context);\n    // default colors\n    const opacity = 1;\n    const skippedFeatures = {};\n    let featureCallback;\n    const oneByOne = false;\n    replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,\n      this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,\n      oneByOne);\n    replay.getDeleteResourcesFunction(context)();\n  }\n\n  /**\n   * Set the rendering style.  Note that since this is an immediate rendering API,\n   * any `zIndex` on the provided style will be ignored.\n   *\n   * @param {module:ol/style/Style} style The rendering style.\n   * @override\n   * @api\n   */\n  setStyle(style) {\n    this.setFillStrokeStyle(style.getFill(), style.getStroke());\n    this.setImageStyle(style.getImage());\n    this.setTextStyle(style.getText());\n  }\n\n  /**\n   * Render a geometry into the canvas.  Call\n   * {@link ol/render/webgl/Immediate#setStyle} first to set the rendering style.\n   *\n   * @param {module:ol/geom/Geometry|module:ol/render/Feature} geometry The geometry to render.\n   * @override\n   * @api\n   */\n  drawGeometry(geometry) {\n    const type = geometry.getType();\n    switch (type) {\n      case GeometryType.POINT:\n        this.drawPoint(/** @type {module:ol/geom/Point} */ (geometry), null);\n        break;\n      case GeometryType.LINE_STRING:\n        this.drawLineString(/** @type {module:ol/geom/LineString} */ (geometry), null);\n        break;\n      case GeometryType.POLYGON:\n        this.drawPolygon(/** @type {module:ol/geom/Polygon} */ (geometry), null);\n        break;\n      case GeometryType.MULTI_POINT:\n        this.drawMultiPoint(/** @type {module:ol/geom/MultiPoint} */ (geometry), null);\n        break;\n      case GeometryType.MULTI_LINE_STRING:\n        this.drawMultiLineString(/** @type {module:ol/geom/MultiLineString} */ (geometry), null);\n        break;\n      case GeometryType.MULTI_POLYGON:\n        this.drawMultiPolygon(/** @type {module:ol/geom/MultiPolygon} */ (geometry), null);\n        break;\n      case GeometryType.GEOMETRY_COLLECTION:\n        this.drawGeometryCollection(/** @type {module:ol/geom/GeometryCollection} */ (geometry), null);\n        break;\n      case GeometryType.CIRCLE:\n        this.drawCircle(/** @type {module:ol/geom/Circle} */ (geometry), null);\n        break;\n      default:\n        // pass\n    }\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  drawFeature(feature, style) {\n    const geometry = style.getGeometryFunction()(feature);\n    if (!geometry || !intersects(this.extent_, geometry.getExtent())) {\n      return;\n    }\n    this.setStyle(style);\n    this.drawGeometry(geometry);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawGeometryCollection(geometry, data) {\n    const geometries = geometry.getGeometriesArray();\n    let i, ii;\n    for (i = 0, ii = geometries.length; i < ii; ++i) {\n      this.drawGeometry(geometries[i]);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawPoint(geometry, data) {\n    const context = this.context_;\n    const replayGroup = new WebGLReplayGroup(1, this.extent_);\n    const replay = /** @type {module:ol/render/webgl/ImageReplay} */ (\n      replayGroup.getReplay(0, ReplayType.IMAGE));\n    replay.setImageStyle(this.imageStyle_);\n    replay.drawPoint(geometry, data);\n    replay.finish(context);\n    // default colors\n    const opacity = 1;\n    const skippedFeatures = {};\n    let featureCallback;\n    const oneByOne = false;\n    replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,\n      this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,\n      oneByOne);\n    replay.getDeleteResourcesFunction(context)();\n\n    if (this.textStyle_) {\n      this.drawText_(replayGroup, geometry);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawMultiPoint(geometry, data) {\n    const context = this.context_;\n    const replayGroup = new WebGLReplayGroup(1, this.extent_);\n    const replay = /** @type {module:ol/render/webgl/ImageReplay} */ (\n      replayGroup.getReplay(0, ReplayType.IMAGE));\n    replay.setImageStyle(this.imageStyle_);\n    replay.drawMultiPoint(geometry, data);\n    replay.finish(context);\n    const opacity = 1;\n    const skippedFeatures = {};\n    let featureCallback;\n    const oneByOne = false;\n    replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,\n      this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,\n      oneByOne);\n    replay.getDeleteResourcesFunction(context)();\n\n    if (this.textStyle_) {\n      this.drawText_(replayGroup, geometry);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawLineString(geometry, data) {\n    const context = this.context_;\n    const replayGroup = new WebGLReplayGroup(1, this.extent_);\n    const replay = /** @type {module:ol/render/webgl/LineStringReplay} */ (\n      replayGroup.getReplay(0, ReplayType.LINE_STRING));\n    replay.setFillStrokeStyle(null, this.strokeStyle_);\n    replay.drawLineString(geometry, data);\n    replay.finish(context);\n    const opacity = 1;\n    const skippedFeatures = {};\n    let featureCallback;\n    const oneByOne = false;\n    replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,\n      this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,\n      oneByOne);\n    replay.getDeleteResourcesFunction(context)();\n\n    if (this.textStyle_) {\n      this.drawText_(replayGroup, geometry);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawMultiLineString(geometry, data) {\n    const context = this.context_;\n    const replayGroup = new WebGLReplayGroup(1, this.extent_);\n    const replay = /** @type {module:ol/render/webgl/LineStringReplay} */ (\n      replayGroup.getReplay(0, ReplayType.LINE_STRING));\n    replay.setFillStrokeStyle(null, this.strokeStyle_);\n    replay.drawMultiLineString(geometry, data);\n    replay.finish(context);\n    const opacity = 1;\n    const skippedFeatures = {};\n    let featureCallback;\n    const oneByOne = false;\n    replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,\n      this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,\n      oneByOne);\n    replay.getDeleteResourcesFunction(context)();\n\n    if (this.textStyle_) {\n      this.drawText_(replayGroup, geometry);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawPolygon(geometry, data) {\n    const context = this.context_;\n    const replayGroup = new WebGLReplayGroup(1, this.extent_);\n    const replay = /** @type {module:ol/render/webgl/PolygonReplay} */ (\n      replayGroup.getReplay(0, ReplayType.POLYGON));\n    replay.setFillStrokeStyle(this.fillStyle_, this.strokeStyle_);\n    replay.drawPolygon(geometry, data);\n    replay.finish(context);\n    const opacity = 1;\n    const skippedFeatures = {};\n    let featureCallback;\n    const oneByOne = false;\n    replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,\n      this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,\n      oneByOne);\n    replay.getDeleteResourcesFunction(context)();\n\n    if (this.textStyle_) {\n      this.drawText_(replayGroup, geometry);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawMultiPolygon(geometry, data) {\n    const context = this.context_;\n    const replayGroup = new WebGLReplayGroup(1, this.extent_);\n    const replay = /** @type {module:ol/render/webgl/PolygonReplay} */ (\n      replayGroup.getReplay(0, ReplayType.POLYGON));\n    replay.setFillStrokeStyle(this.fillStyle_, this.strokeStyle_);\n    replay.drawMultiPolygon(geometry, data);\n    replay.finish(context);\n    const opacity = 1;\n    const skippedFeatures = {};\n    let featureCallback;\n    const oneByOne = false;\n    replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,\n      this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,\n      oneByOne);\n    replay.getDeleteResourcesFunction(context)();\n\n    if (this.textStyle_) {\n      this.drawText_(replayGroup, geometry);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  drawCircle(geometry, data) {\n    const context = this.context_;\n    const replayGroup = new WebGLReplayGroup(1, this.extent_);\n    const replay = /** @type {module:ol/render/webgl/CircleReplay} */ (\n      replayGroup.getReplay(0, ReplayType.CIRCLE));\n    replay.setFillStrokeStyle(this.fillStyle_, this.strokeStyle_);\n    replay.drawCircle(geometry, data);\n    replay.finish(context);\n    const opacity = 1;\n    const skippedFeatures = {};\n    let featureCallback;\n    const oneByOne = false;\n    replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,\n      this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,\n      oneByOne);\n    replay.getDeleteResourcesFunction(context)();\n\n    if (this.textStyle_) {\n      this.drawText_(replayGroup, geometry);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setImageStyle(imageStyle) {\n    this.imageStyle_ = imageStyle;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setFillStrokeStyle(fillStyle, strokeStyle) {\n    this.fillStyle_ = fillStyle;\n    this.strokeStyle_ = strokeStyle;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  setTextStyle(textStyle) {\n    this.textStyle_ = textStyle;\n  }\n}\n\n\nexport default WebGLImmediateRenderer;\n","/**\n * @module ol/renderer/webgl/defaultmapshader\n */\n// This file is automatically generated, do not edit.\n// Run `make shaders` to generate, and commit the result.\n\nimport {DEBUG as DEBUG_WEBGL} from '../../webgl.js';\nimport WebGLFragment from '../../webgl/Fragment.js';\nimport WebGLVertex from '../../webgl/Vertex.js';\n\nexport const fragment = new WebGLFragment(DEBUG_WEBGL ?\n  'precision mediump float;\\nvarying vec2 v_texCoord;\\n\\n\\nuniform float u_opacity;\\nuniform sampler2D u_texture;\\n\\nvoid main(void) {\\n  vec4 texColor = texture2D(u_texture, v_texCoord);\\n  gl_FragColor.rgb = texColor.rgb;\\n  gl_FragColor.a = texColor.a * u_opacity;\\n}\\n' :\n  'precision mediump float;varying vec2 a;uniform float f;uniform sampler2D g;void main(void){vec4 texColor=texture2D(g,a);gl_FragColor.rgb=texColor.rgb;gl_FragColor.a=texColor.a*f;}');\n\nexport const vertex = new WebGLVertex(DEBUG_WEBGL ?\n  'varying vec2 v_texCoord;\\n\\n\\nattribute vec2 a_position;\\nattribute vec2 a_texCoord;\\n\\nuniform mat4 u_texCoordMatrix;\\nuniform mat4 u_projectionMatrix;\\n\\nvoid main(void) {\\n  gl_Position = u_projectionMatrix * vec4(a_position, 0., 1.);\\n  v_texCoord = (u_texCoordMatrix * vec4(a_texCoord, 0., 1.)).st;\\n}\\n\\n\\n' :\n  'varying vec2 a;attribute vec2 b;attribute vec2 c;uniform mat4 d;uniform mat4 e;void main(void){gl_Position=e*vec4(b,0.,1.);a=(d*vec4(c,0.,1.)).st;}');\n","/**\n * @module ol/renderer/webgl/defaultmapshader/Locations\n */\n// This file is automatically generated, do not edit\n// Run `make shaders` to generate, and commit the result.\n\nimport {DEBUG as DEBUG_WEBGL} from '../../../webgl.js';\n\nclass Locations {\n\n  /**\n   * @param {WebGLRenderingContext} gl GL.\n   * @param {WebGLProgram} program Program.\n   */\n  constructor(gl, program) {\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_texCoordMatrix = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_texCoordMatrix' : 'd');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_projectionMatrix = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_projectionMatrix' : 'e');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_opacity = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_opacity' : 'f');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_texture = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_texture' : 'g');\n\n    /**\n     * @type {number}\n     */\n    this.a_position = gl.getAttribLocation(\n      program, DEBUG_WEBGL ? 'a_position' : 'b');\n\n    /**\n     * @type {number}\n     */\n    this.a_texCoord = gl.getAttribLocation(\n      program, DEBUG_WEBGL ? 'a_texCoord' : 'c');\n\n  }\n\n}\n\nexport default Locations;\n","/**\n * @module ol/renderer/webgl/Layer\n */\nimport RenderEvent from '../../render/Event.js';\nimport RenderEventType from '../../render/EventType.js';\nimport WebGLImmediateRenderer from '../../render/webgl/Immediate.js';\nimport LayerRenderer from '../Layer.js';\nimport {fragment, vertex} from '../webgl/defaultmapshader.js';\nimport Locations from '../webgl/defaultmapshader/Locations.js';\nimport {create as createTransform} from '../../transform.js';\nimport {create, fromTransform} from '../../vec/mat4.js';\nimport {ARRAY_BUFFER, FRAMEBUFFER, FLOAT, TEXTURE_2D,\n  TRIANGLE_STRIP, COLOR_ATTACHMENT0} from '../../webgl.js';\nimport WebGLBuffer from '../../webgl/Buffer.js';\nimport {createEmptyTexture} from '../../webgl/Context.js';\n\nclass WebGLLayerRenderer extends LayerRenderer {\n\n  /**\n   * @param {module:ol/renderer/webgl/Map} mapRenderer Map renderer.\n   * @param {module:ol/layer/Layer} layer Layer.\n   */\n  constructor(mapRenderer, layer) {\n\n    super(layer);\n\n    /**\n     * @protected\n     * @type {module:ol/renderer/webgl/Map}\n     */\n    this.mapRenderer = mapRenderer;\n\n    /**\n     * @private\n     * @type {module:ol/webgl/Buffer}\n     */\n    this.arrayBuffer_ = new WebGLBuffer([\n      -1, -1, 0, 0,\n      1, -1, 1, 0,\n      -1, 1, 0, 1,\n      1, 1, 1, 1\n    ]);\n\n    /**\n     * @protected\n     * @type {WebGLTexture}\n     */\n    this.texture = null;\n\n    /**\n     * @protected\n     * @type {WebGLFramebuffer}\n     */\n    this.framebuffer = null;\n\n    /**\n     * @protected\n     * @type {number|undefined}\n     */\n    this.framebufferDimension = undefined;\n\n    /**\n     * @protected\n     * @type {module:ol/transform~Transform}\n     */\n    this.texCoordMatrix = createTransform();\n\n    /**\n     * @protected\n     * @type {module:ol/transform~Transform}\n     */\n    this.projectionMatrix = createTransform();\n\n    /**\n     * @type {Array.<number>}\n     * @private\n     */\n    this.tmpMat4_ = create();\n\n    /**\n     * @private\n     * @type {module:ol/renderer/webgl/defaultmapshader/Locations}\n     */\n    this.defaultLocations_ = null;\n\n  }\n\n  /**\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @param {number} framebufferDimension Framebuffer dimension.\n   * @protected\n   */\n  bindFramebuffer(frameState, framebufferDimension) {\n\n    const gl = this.mapRenderer.getGL();\n\n    if (this.framebufferDimension === undefined ||\n        this.framebufferDimension != framebufferDimension) {\n      /**\n       * @param {WebGLRenderingContext} gl GL.\n       * @param {WebGLFramebuffer} framebuffer Framebuffer.\n       * @param {WebGLTexture} texture Texture.\n       */\n      const postRenderFunction = function(gl, framebuffer, texture) {\n        if (!gl.isContextLost()) {\n          gl.deleteFramebuffer(framebuffer);\n          gl.deleteTexture(texture);\n        }\n      }.bind(null, gl, this.framebuffer, this.texture);\n\n      frameState.postRenderFunctions.push(\n        /** @type {module:ol/PluggableMap~PostRenderFunction} */ (postRenderFunction)\n      );\n\n      const texture = createEmptyTexture(\n        gl, framebufferDimension, framebufferDimension);\n\n      const framebuffer = gl.createFramebuffer();\n      gl.bindFramebuffer(FRAMEBUFFER, framebuffer);\n      gl.framebufferTexture2D(FRAMEBUFFER,\n        COLOR_ATTACHMENT0, TEXTURE_2D, texture, 0);\n\n      this.texture = texture;\n      this.framebuffer = framebuffer;\n      this.framebufferDimension = framebufferDimension;\n\n    } else {\n      gl.bindFramebuffer(FRAMEBUFFER, this.framebuffer);\n    }\n\n  }\n\n  /**\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @param {module:ol/layer/Layer~State} layerState Layer state.\n   * @param {module:ol/webgl/Context} context Context.\n   */\n  composeFrame(frameState, layerState, context) {\n\n    this.dispatchComposeEvent_(RenderEventType.PRECOMPOSE, context, frameState);\n\n    context.bindBuffer(ARRAY_BUFFER, this.arrayBuffer_);\n\n    const gl = context.getGL();\n\n    const program = context.getProgram(fragment, vertex);\n\n    let locations;\n    if (!this.defaultLocations_) {\n      locations = new Locations(gl, program);\n      this.defaultLocations_ = locations;\n    } else {\n      locations = this.defaultLocations_;\n    }\n\n    if (context.useProgram(program)) {\n      gl.enableVertexAttribArray(locations.a_position);\n      gl.vertexAttribPointer(\n        locations.a_position, 2, FLOAT, false, 16, 0);\n      gl.enableVertexAttribArray(locations.a_texCoord);\n      gl.vertexAttribPointer(\n        locations.a_texCoord, 2, FLOAT, false, 16, 8);\n      gl.uniform1i(locations.u_texture, 0);\n    }\n\n    gl.uniformMatrix4fv(locations.u_texCoordMatrix, false,\n      fromTransform(this.tmpMat4_, this.getTexCoordMatrix()));\n    gl.uniformMatrix4fv(locations.u_projectionMatrix, false,\n      fromTransform(this.tmpMat4_, this.getProjectionMatrix()));\n    gl.uniform1f(locations.u_opacity, layerState.opacity);\n    gl.bindTexture(TEXTURE_2D, this.getTexture());\n    gl.drawArrays(TRIANGLE_STRIP, 0, 4);\n\n    this.dispatchComposeEvent_(RenderEventType.POSTCOMPOSE, context, frameState);\n  }\n\n  /**\n   * @param {module:ol/render/EventType} type Event type.\n   * @param {module:ol/webgl/Context} context WebGL context.\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @private\n   */\n  dispatchComposeEvent_(type, context, frameState) {\n    const layer = this.getLayer();\n    if (layer.hasListener(type)) {\n      const viewState = frameState.viewState;\n      const resolution = viewState.resolution;\n      const pixelRatio = frameState.pixelRatio;\n      const extent = frameState.extent;\n      const center = viewState.center;\n      const rotation = viewState.rotation;\n      const size = frameState.size;\n\n      const render = new WebGLImmediateRenderer(\n        context, center, resolution, rotation, size, extent, pixelRatio);\n      const composeEvent = new RenderEvent(\n        type, render, frameState, null, context);\n      layer.dispatchEvent(composeEvent);\n    }\n  }\n\n  /**\n   * @return {!module:ol/transform~Transform} Matrix.\n   */\n  getTexCoordMatrix() {\n    return this.texCoordMatrix;\n  }\n\n  /**\n   * @return {WebGLTexture} Texture.\n   */\n  getTexture() {\n    return this.texture;\n  }\n\n  /**\n   * @return {!module:ol/transform~Transform} Matrix.\n   */\n  getProjectionMatrix() {\n    return this.projectionMatrix;\n  }\n\n  /**\n   * Handle webglcontextlost.\n   */\n  handleWebGLContextLost() {\n    this.texture = null;\n    this.framebuffer = null;\n    this.framebufferDimension = undefined;\n  }\n\n  /**\n   * @abstract\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @param {module:ol/layer/Layer~State} layerState Layer state.\n   * @param {module:ol/webgl/Context} context Context.\n   * @return {boolean} whether composeFrame should be called.\n   */\n  prepareFrame(frameState, layerState, context) {}\n\n  /**\n   * @abstract\n   * @param {module:ol/pixel~Pixel} pixel Pixel.\n   * @param {module:ol/PluggableMap~FrameState} frameState FrameState.\n   * @param {function(this: S, module:ol/layer/Layer, (Uint8ClampedArray|Uint8Array)): T} callback Layer\n   *     callback.\n   * @param {S} thisArg Value to use as `this` when executing `callback`.\n   * @return {T|undefined} Callback result.\n   * @template S,T,U\n   */\n  forEachLayerAtPixel(pixel, frameState, callback, thisArg) {}\n}\n\n\nexport default WebGLLayerRenderer;\n","/**\n * @module ol/renderer/webgl/ImageLayer\n */\nimport {ENABLE_RASTER_REPROJECTION} from '../../reproj/common.js';\nimport {TRUE, UNDEFINED} from '../../functions.js';\nimport LayerType from '../../LayerType.js';\nimport ViewHint from '../../ViewHint.js';\nimport {createCanvasContext2D} from '../../dom.js';\nimport {getIntersection, isEmpty} from '../../extent.js';\nimport WebGLLayerRenderer from '../webgl/Layer.js';\nimport {\n  create as createTransform,\n  rotate as rotateTransform,\n  translate as translateTransform,\n  scale as scaleTransform,\n  reset as resetTransform,\n  apply as applyTransform,\n  invert as invertTransform,\n  multiply as multiplyTransform\n} from '../../transform.js';\nimport {CLAMP_TO_EDGE} from '../../webgl.js';\nimport {createTexture} from '../../webgl/Context.js';\n\n/**\n * @classdesc\n * WebGL renderer for image layers.\n * @api\n */\nclass WebGLImageLayerRenderer extends WebGLLayerRenderer {\n\n  /**\n   * @param {module:ol/renderer/webgl/Map} mapRenderer Map renderer.\n   * @param {module:ol/layer/Image} imageLayer Tile layer.\n   */\n  constructor(mapRenderer, imageLayer) {\n\n    super(mapRenderer, imageLayer);\n\n    /**\n     * The last rendered image.\n     * @private\n     * @type {?module:ol/ImageBase}\n     */\n    this.image_ = null;\n\n    /**\n     * @private\n     * @type {CanvasRenderingContext2D}\n     */\n    this.hitCanvasContext_ = null;\n\n    /**\n     * @private\n     * @type {?module:ol/transform~Transform}\n     */\n    this.hitTransformationMatrix_ = null;\n\n  }\n\n  /**\n   * @param {module:ol/ImageBase} image Image.\n   * @private\n   * @return {WebGLTexture} Texture.\n   */\n  createTexture_(image) {\n\n    // We meet the conditions to work with non-power of two textures.\n    // http://www.khronos.org/webgl/wiki/WebGL_and_OpenGL_Differences#Non-Power_of_Two_Texture_Support\n    // http://learningwebgl.com/blog/?p=2101\n\n    const imageElement = image.getImage();\n    const gl = this.mapRenderer.getGL();\n\n    return createTexture(\n      gl, imageElement, CLAMP_TO_EDGE, CLAMP_TO_EDGE);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback, thisArg) {\n    const layer = this.getLayer();\n    const source = layer.getSource();\n    const resolution = frameState.viewState.resolution;\n    const rotation = frameState.viewState.rotation;\n    const skippedFeatureUids = frameState.skippedFeatureUids;\n    return source.forEachFeatureAtCoordinate(\n      coordinate, resolution, rotation, hitTolerance, skippedFeatureUids,\n\n      /**\n       * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n       * @return {?} Callback result.\n       */\n      function(feature) {\n        return callback.call(thisArg, feature, layer);\n      });\n  }\n\n  /**\n   * @inheritDoc\n   */\n  prepareFrame(frameState, layerState, context) {\n\n    const gl = this.mapRenderer.getGL();\n\n    const pixelRatio = frameState.pixelRatio;\n    const viewState = frameState.viewState;\n    const viewCenter = viewState.center;\n    const viewResolution = viewState.resolution;\n    const viewRotation = viewState.rotation;\n\n    let image = this.image_;\n    let texture = this.texture;\n    const imageLayer = /** @type {module:ol/layer/Image} */ (this.getLayer());\n    const imageSource = imageLayer.getSource();\n\n    const hints = frameState.viewHints;\n\n    let renderedExtent = frameState.extent;\n    if (layerState.extent !== undefined) {\n      renderedExtent = getIntersection(renderedExtent, layerState.extent);\n    }\n    if (!hints[ViewHint.ANIMATING] && !hints[ViewHint.INTERACTING] &&\n        !isEmpty(renderedExtent)) {\n      let projection = viewState.projection;\n      if (!ENABLE_RASTER_REPROJECTION) {\n        const sourceProjection = imageSource.getProjection();\n        if (sourceProjection) {\n          projection = sourceProjection;\n        }\n      }\n      const image_ = imageSource.getImage(renderedExtent, viewResolution,\n        pixelRatio, projection);\n      if (image_) {\n        const loaded = this.loadImage(image_);\n        if (loaded) {\n          image = image_;\n          texture = this.createTexture_(image_);\n          if (this.texture) {\n            /**\n             * @param {WebGLRenderingContext} gl GL.\n             * @param {WebGLTexture} texture Texture.\n             */\n            const postRenderFunction = function(gl, texture) {\n              if (!gl.isContextLost()) {\n                gl.deleteTexture(texture);\n              }\n            }.bind(null, gl, this.texture);\n            frameState.postRenderFunctions.push(\n              /** @type {module:ol/PluggableMap~PostRenderFunction} */ (postRenderFunction)\n            );\n          }\n        }\n      }\n    }\n\n    if (image) {\n      const canvas = this.mapRenderer.getContext().getCanvas();\n\n      this.updateProjectionMatrix_(canvas.width, canvas.height,\n        pixelRatio, viewCenter, viewResolution, viewRotation,\n        image.getExtent());\n      this.hitTransformationMatrix_ = null;\n\n      // Translate and scale to flip the Y coord.\n      const texCoordMatrix = this.texCoordMatrix;\n      resetTransform(texCoordMatrix);\n      scaleTransform(texCoordMatrix, 1, -1);\n      translateTransform(texCoordMatrix, 0, -1);\n\n      this.image_ = image;\n      this.texture = texture;\n    }\n\n    return !!image;\n  }\n\n  /**\n   * @param {number} canvasWidth Canvas width.\n   * @param {number} canvasHeight Canvas height.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {module:ol/coordinate~Coordinate} viewCenter View center.\n   * @param {number} viewResolution View resolution.\n   * @param {number} viewRotation View rotation.\n   * @param {module:ol/extent~Extent} imageExtent Image extent.\n   * @private\n   */\n  updateProjectionMatrix_(\n    canvasWidth,\n    canvasHeight,\n    pixelRatio,\n    viewCenter,\n    viewResolution,\n    viewRotation,\n    imageExtent\n  ) {\n\n    const canvasExtentWidth = canvasWidth * viewResolution;\n    const canvasExtentHeight = canvasHeight * viewResolution;\n\n    const projectionMatrix = this.projectionMatrix;\n    resetTransform(projectionMatrix);\n    scaleTransform(projectionMatrix,\n      pixelRatio * 2 / canvasExtentWidth,\n      pixelRatio * 2 / canvasExtentHeight);\n    rotateTransform(projectionMatrix, -viewRotation);\n    translateTransform(projectionMatrix,\n      imageExtent[0] - viewCenter[0],\n      imageExtent[1] - viewCenter[1]);\n    scaleTransform(projectionMatrix,\n      (imageExtent[2] - imageExtent[0]) / 2,\n      (imageExtent[3] - imageExtent[1]) / 2);\n    translateTransform(projectionMatrix, 1, 1);\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  hasFeatureAtCoordinate(coordinate, frameState) {\n    const hasFeature = this.forEachFeatureAtCoordinate(coordinate, frameState, 0, TRUE, this);\n    return hasFeature !== undefined;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  forEachLayerAtPixel(pixel, frameState, callback, thisArg) {\n    if (!this.image_ || !this.image_.getImage()) {\n      return undefined;\n    }\n\n    if (this.getLayer().getSource().forEachFeatureAtCoordinate !== UNDEFINED) {\n      // for ImageCanvas sources use the original hit-detection logic,\n      // so that for example also transparent polygons are detected\n      const coordinate = applyTransform(\n        frameState.pixelToCoordinateTransform, pixel.slice());\n      const hasFeature = this.forEachFeatureAtCoordinate(coordinate, frameState, 0, TRUE, this);\n\n      if (hasFeature) {\n        return callback.call(thisArg, this.getLayer(), null);\n      } else {\n        return undefined;\n      }\n    } else {\n      const imageSize =\n          [this.image_.getImage().width, this.image_.getImage().height];\n\n      if (!this.hitTransformationMatrix_) {\n        this.hitTransformationMatrix_ = this.getHitTransformationMatrix_(\n          frameState.size, imageSize);\n      }\n\n      const pixelOnFrameBuffer = applyTransform(\n        this.hitTransformationMatrix_, pixel.slice());\n\n      if (pixelOnFrameBuffer[0] < 0 || pixelOnFrameBuffer[0] > imageSize[0] ||\n          pixelOnFrameBuffer[1] < 0 || pixelOnFrameBuffer[1] > imageSize[1]) {\n        // outside the image, no need to check\n        return undefined;\n      }\n\n      if (!this.hitCanvasContext_) {\n        this.hitCanvasContext_ = createCanvasContext2D(1, 1);\n      }\n\n      this.hitCanvasContext_.clearRect(0, 0, 1, 1);\n      this.hitCanvasContext_.drawImage(this.image_.getImage(),\n        pixelOnFrameBuffer[0], pixelOnFrameBuffer[1], 1, 1, 0, 0, 1, 1);\n\n      const imageData = this.hitCanvasContext_.getImageData(0, 0, 1, 1).data;\n      if (imageData[3] > 0) {\n        return callback.call(thisArg, this.getLayer(), imageData);\n      } else {\n        return undefined;\n      }\n    }\n  }\n\n  /**\n   * The transformation matrix to get the pixel on the image for a\n   * pixel on the map.\n   * @param {module:ol/size~Size} mapSize The map size.\n   * @param {module:ol/size~Size} imageSize The image size.\n   * @return {module:ol/transform~Transform} The transformation matrix.\n   * @private\n   */\n  getHitTransformationMatrix_(mapSize, imageSize) {\n    // the first matrix takes a map pixel, flips the y-axis and scales to\n    // a range between -1 ... 1\n    const mapCoordTransform = createTransform();\n    translateTransform(mapCoordTransform, -1, -1);\n    scaleTransform(mapCoordTransform, 2 / mapSize[0], 2 / mapSize[1]);\n    translateTransform(mapCoordTransform, 0, mapSize[1]);\n    scaleTransform(mapCoordTransform, 1, -1);\n\n    // the second matrix is the inverse of the projection matrix used in the\n    // shader for drawing\n    const projectionMatrixInv = invertTransform(this.projectionMatrix.slice());\n\n    // the third matrix scales to the image dimensions and flips the y-axis again\n    const transform = createTransform();\n    translateTransform(transform, 0, imageSize[1]);\n    scaleTransform(transform, 1, -1);\n    scaleTransform(transform, imageSize[0] / 2, imageSize[1] / 2);\n    translateTransform(transform, 1, 1);\n\n    multiplyTransform(transform, projectionMatrixInv);\n    multiplyTransform(transform, mapCoordTransform);\n\n    return transform;\n  }\n}\n\n\n/**\n * Determine if this renderer handles the provided layer.\n * @param {module:ol/layer/Layer} layer The candidate layer.\n * @return {boolean} The renderer can render the layer.\n */\nWebGLImageLayerRenderer['handles'] = function(layer) {\n  return layer.getType() === LayerType.IMAGE;\n};\n\n\n/**\n * Create a layer renderer.\n * @param {module:ol/renderer/Map} mapRenderer The map renderer.\n * @param {module:ol/layer/Layer} layer The layer to be rendererd.\n * @return {module:ol/renderer/webgl/ImageLayer} The layer renderer.\n */\nWebGLImageLayerRenderer['create'] = function(mapRenderer, layer) {\n  return new WebGLImageLayerRenderer(\n    /** @type {module:ol/renderer/webgl/Map} */ (mapRenderer),\n    /** @type {module:ol/layer/Image} */ (layer)\n  );\n};\n\n\nexport default WebGLImageLayerRenderer;\n","/**\n * @module ol/renderer/webgl/Map\n */\n\nimport {stableSort} from '../../array.js';\nimport {CLASS_UNSELECTABLE} from '../../css.js';\nimport {createCanvasContext2D} from '../../dom.js';\nimport {listen} from '../../events.js';\nimport {visibleAtResolution} from '../../layer/Layer.js';\nimport RenderEvent from '../../render/Event.js';\nimport RenderEventType from '../../render/EventType.js';\nimport WebGLImmediateRenderer from '../../render/webgl/Immediate.js';\nimport MapRenderer, {sortByZIndex} from '../Map.js';\nimport SourceState from '../../source/State.js';\nimport LRUCache from '../../structs/LRUCache.js';\nimport PriorityQueue from '../../structs/PriorityQueue.js';\nimport {BLEND, CLAMP_TO_EDGE, COLOR_BUFFER_BIT, CULL_FACE, DEPTH_TEST, FRAMEBUFFER,\n  getContext, LINEAR, ONE, ONE_MINUS_SRC_ALPHA, RGBA, SCISSOR_TEST, SRC_ALPHA,\n  STENCIL_TEST, TEXTURE0, TEXTURE_2D, TEXTURE_MAG_FILTER, TEXTURE_MIN_FILTER,\n  TEXTURE_WRAP_S, TEXTURE_WRAP_T, UNSIGNED_BYTE} from '../../webgl.js';\nimport WebGLContext from '../../webgl/Context.js';\nimport ContextEventType from '../../webgl/ContextEventType.js';\n\n\n/**\n * @typedef {Object} TextureCacheEntry\n * @property {number} magFilter\n * @property {number} minFilter\n * @property {WebGLTexture} texture\n */\n\n\n/**\n * Texture cache high water mark.\n * @type {number}\n */\nconst WEBGL_TEXTURE_CACHE_HIGH_WATER_MARK = 1024;\n\n\n/**\n * @classdesc\n * WebGL map renderer.\n * @api\n */\nclass WebGLMapRenderer extends MapRenderer {\n\n  /**\n   * @param {module:ol/PluggableMap} map Map.\n   */\n  constructor(map) {\n    super(map);\n\n    const container = map.getViewport();\n\n    /**\n     * @private\n     * @type {HTMLCanvasElement}\n     */\n    this.canvas_ = /** @type {HTMLCanvasElement} */\n      (document.createElement('CANVAS'));\n    this.canvas_.style.width = '100%';\n    this.canvas_.style.height = '100%';\n    this.canvas_.style.display = 'block';\n    this.canvas_.className = CLASS_UNSELECTABLE;\n    container.insertBefore(this.canvas_, container.childNodes[0] || null);\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.clipTileCanvasWidth_ = 0;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.clipTileCanvasHeight_ = 0;\n\n    /**\n     * @private\n     * @type {CanvasRenderingContext2D}\n     */\n    this.clipTileContext_ = createCanvasContext2D();\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.renderedVisible_ = true;\n\n    /**\n     * @private\n     * @type {WebGLRenderingContext}\n     */\n    this.gl_ = getContext(this.canvas_, {\n      antialias: true,\n      depth: true,\n      failIfMajorPerformanceCaveat: true,\n      preserveDrawingBuffer: false,\n      stencil: true\n    });\n\n    /**\n     * @private\n     * @type {module:ol/webgl/Context}\n     */\n    this.context_ = new WebGLContext(this.canvas_, this.gl_);\n\n    listen(this.canvas_, ContextEventType.LOST,\n      this.handleWebGLContextLost, this);\n    listen(this.canvas_, ContextEventType.RESTORED,\n      this.handleWebGLContextRestored, this);\n\n    /**\n     * @private\n     * @type {module:ol/structs/LRUCache.<module:ol/renderer/webgl/Map~TextureCacheEntry|null>}\n     */\n    this.textureCache_ = new LRUCache();\n\n    /**\n     * @private\n     * @type {module:ol/coordinate~Coordinate}\n     */\n    this.focus_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/structs/PriorityQueue.<Array>}\n     */\n    this.tileTextureQueue_ = new PriorityQueue(\n      /**\n       * @param {Array.<*>} element Element.\n       * @return {number} Priority.\n       * @this {module:ol/renderer/webgl/Map}\n       */\n      (function(element) {\n        const tileCenter = /** @type {module:ol/coordinate~Coordinate} */ (element[1]);\n        const tileResolution = /** @type {number} */ (element[2]);\n        const deltaX = tileCenter[0] - this.focus_[0];\n        const deltaY = tileCenter[1] - this.focus_[1];\n        return 65536 * Math.log(tileResolution) +\n              Math.sqrt(deltaX * deltaX + deltaY * deltaY) / tileResolution;\n      }).bind(this),\n      /**\n       * @param {Array.<*>} element Element.\n       * @return {string} Key.\n       */\n      function(element) {\n        return (\n          /** @type {module:ol/Tile} */ (element[0]).getKey()\n        );\n      });\n\n\n    /**\n     * @param {module:ol/PluggableMap} map Map.\n     * @param {?module:ol/PluggableMap~FrameState} frameState Frame state.\n     * @return {boolean} false.\n     * @this {module:ol/renderer/webgl/Map}\n     */\n    this.loadNextTileTexture_ =\n        function(map, frameState) {\n          if (!this.tileTextureQueue_.isEmpty()) {\n            this.tileTextureQueue_.reprioritize();\n            const element = this.tileTextureQueue_.dequeue();\n            const tile = /** @type {module:ol/Tile} */ (element[0]);\n            const tileSize = /** @type {module:ol/size~Size} */ (element[3]);\n            const tileGutter = /** @type {number} */ (element[4]);\n            this.bindTileTexture(\n              tile, tileSize, tileGutter, LINEAR, LINEAR);\n          }\n          return false;\n        }.bind(this);\n\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.textureCacheFrameMarkerCount_ = 0;\n\n    this.initializeGL_();\n  }\n\n  /**\n   * @param {module:ol/Tile} tile Tile.\n   * @param {module:ol/size~Size} tileSize Tile size.\n   * @param {number} tileGutter Tile gutter.\n   * @param {number} magFilter Mag filter.\n   * @param {number} minFilter Min filter.\n   */\n  bindTileTexture(tile, tileSize, tileGutter, magFilter, minFilter) {\n    const gl = this.getGL();\n    const tileKey = tile.getKey();\n    if (this.textureCache_.containsKey(tileKey)) {\n      const textureCacheEntry = this.textureCache_.get(tileKey);\n      gl.bindTexture(TEXTURE_2D, textureCacheEntry.texture);\n      if (textureCacheEntry.magFilter != magFilter) {\n        gl.texParameteri(\n          TEXTURE_2D, TEXTURE_MAG_FILTER, magFilter);\n        textureCacheEntry.magFilter = magFilter;\n      }\n      if (textureCacheEntry.minFilter != minFilter) {\n        gl.texParameteri(\n          TEXTURE_2D, TEXTURE_MIN_FILTER, minFilter);\n        textureCacheEntry.minFilter = minFilter;\n      }\n    } else {\n      const texture = gl.createTexture();\n      gl.bindTexture(TEXTURE_2D, texture);\n      if (tileGutter > 0) {\n        const clipTileCanvas = this.clipTileContext_.canvas;\n        const clipTileContext = this.clipTileContext_;\n        if (this.clipTileCanvasWidth_ !== tileSize[0] ||\n            this.clipTileCanvasHeight_ !== tileSize[1]) {\n          clipTileCanvas.width = tileSize[0];\n          clipTileCanvas.height = tileSize[1];\n          this.clipTileCanvasWidth_ = tileSize[0];\n          this.clipTileCanvasHeight_ = tileSize[1];\n        } else {\n          clipTileContext.clearRect(0, 0, tileSize[0], tileSize[1]);\n        }\n        clipTileContext.drawImage(tile.getImage(), tileGutter, tileGutter,\n          tileSize[0], tileSize[1], 0, 0, tileSize[0], tileSize[1]);\n        gl.texImage2D(TEXTURE_2D, 0,\n          RGBA, RGBA,\n          UNSIGNED_BYTE, clipTileCanvas);\n      } else {\n        gl.texImage2D(TEXTURE_2D, 0,\n          RGBA, RGBA,\n          UNSIGNED_BYTE, tile.getImage());\n      }\n      gl.texParameteri(\n        TEXTURE_2D, TEXTURE_MAG_FILTER, magFilter);\n      gl.texParameteri(\n        TEXTURE_2D, TEXTURE_MIN_FILTER, minFilter);\n      gl.texParameteri(TEXTURE_2D, TEXTURE_WRAP_S,\n        CLAMP_TO_EDGE);\n      gl.texParameteri(TEXTURE_2D, TEXTURE_WRAP_T,\n        CLAMP_TO_EDGE);\n      this.textureCache_.set(tileKey, {\n        texture: texture,\n        magFilter: magFilter,\n        minFilter: minFilter\n      });\n    }\n  }\n\n  /**\n   * @param {module:ol/render/EventType} type Event type.\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @private\n   */\n  dispatchComposeEvent_(type, frameState) {\n    const map = this.getMap();\n    if (map.hasListener(type)) {\n      const context = this.context_;\n\n      const extent = frameState.extent;\n      const size = frameState.size;\n      const viewState = frameState.viewState;\n      const pixelRatio = frameState.pixelRatio;\n\n      const resolution = viewState.resolution;\n      const center = viewState.center;\n      const rotation = viewState.rotation;\n\n      const vectorContext = new WebGLImmediateRenderer(context,\n        center, resolution, rotation, size, extent, pixelRatio);\n      const composeEvent = new RenderEvent(type, vectorContext,\n        frameState, null, context);\n      map.dispatchEvent(composeEvent);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  disposeInternal() {\n    const gl = this.getGL();\n    if (!gl.isContextLost()) {\n      this.textureCache_.forEach(\n        /**\n         * @param {?module:ol/renderer/webgl/Map~TextureCacheEntry} textureCacheEntry\n         *     Texture cache entry.\n         */\n        function(textureCacheEntry) {\n          if (textureCacheEntry) {\n            gl.deleteTexture(textureCacheEntry.texture);\n          }\n        });\n    }\n    this.context_.dispose();\n    MapRenderer.prototype.disposeInternal.call(this);\n  }\n\n  /**\n   * @param {module:ol/PluggableMap} map Map.\n   * @param {module:ol/PluggableMap~FrameState} frameState Frame state.\n   * @private\n   */\n  expireCache_(map, frameState) {\n    const gl = this.getGL();\n    let textureCacheEntry;\n    while (this.textureCache_.getCount() - this.textureCacheFrameMarkerCount_ >\n        WEBGL_TEXTURE_CACHE_HIGH_WATER_MARK) {\n      textureCacheEntry = this.textureCache_.peekLast();\n      if (!textureCacheEntry) {\n        if (+this.textureCache_.peekLastKey() == frameState.index) {\n          break;\n        } else {\n          --this.textureCacheFrameMarkerCount_;\n        }\n      } else {\n        gl.deleteTexture(textureCacheEntry.texture);\n      }\n      this.textureCache_.pop();\n    }\n  }\n\n  /**\n   * @return {module:ol/webgl/Context} The context.\n   */\n  getContext() {\n    return this.context_;\n  }\n\n  /**\n   * @return {WebGLRenderingContext} GL.\n   */\n  getGL() {\n    return this.gl_;\n  }\n\n  /**\n   * @return {module:ol/structs/PriorityQueue.<Array>} Tile texture queue.\n   */\n  getTileTextureQueue() {\n    return this.tileTextureQueue_;\n  }\n\n  /**\n   * @param {module:ol/events/Event} event Event.\n   * @protected\n   */\n  handleWebGLContextLost(event) {\n    event.preventDefault();\n    this.textureCache_.clear();\n    this.textureCacheFrameMarkerCount_ = 0;\n\n    const renderers = this.getLayerRenderers();\n    for (const id in renderers) {\n      const renderer = /** @type {module:ol/renderer/webgl/Layer} */ (renderers[id]);\n      renderer.handleWebGLContextLost();\n    }\n  }\n\n  /**\n   * @protected\n   */\n  handleWebGLContextRestored() {\n    this.initializeGL_();\n    this.getMap().render();\n  }\n\n  /**\n   * @private\n   */\n  initializeGL_() {\n    const gl = this.gl_;\n    gl.activeTexture(TEXTURE0);\n    gl.blendFuncSeparate(\n      SRC_ALPHA, ONE_MINUS_SRC_ALPHA,\n      ONE, ONE_MINUS_SRC_ALPHA);\n    gl.disable(CULL_FACE);\n    gl.disable(DEPTH_TEST);\n    gl.disable(SCISSOR_TEST);\n    gl.disable(STENCIL_TEST);\n  }\n\n  /**\n   * @param {module:ol/Tile} tile Tile.\n   * @return {boolean} Is tile texture loaded.\n   */\n  isTileTextureLoaded(tile) {\n    return this.textureCache_.containsKey(tile.getKey());\n  }\n\n  /**\n   * @inheritDoc\n   */\n  renderFrame(frameState) {\n\n    const context = this.getContext();\n    const gl = this.getGL();\n\n    if (gl.isContextLost()) {\n      return false;\n    }\n\n    if (!frameState) {\n      if (this.renderedVisible_) {\n        this.canvas_.style.display = 'none';\n        this.renderedVisible_ = false;\n      }\n      return false;\n    }\n\n    this.focus_ = frameState.focus;\n\n    this.textureCache_.set((-frameState.index).toString(), null);\n    ++this.textureCacheFrameMarkerCount_;\n\n    this.dispatchComposeEvent_(RenderEventType.PRECOMPOSE, frameState);\n\n    /** @type {Array.<module:ol/layer/Layer~State>} */\n    const layerStatesToDraw = [];\n    const layerStatesArray = frameState.layerStatesArray;\n    stableSort(layerStatesArray, sortByZIndex);\n\n    const viewResolution = frameState.viewState.resolution;\n    let i, ii, layerRenderer, layerState;\n    for (i = 0, ii = layerStatesArray.length; i < ii; ++i) {\n      layerState = layerStatesArray[i];\n      if (visibleAtResolution(layerState, viewResolution) &&\n          layerState.sourceState == SourceState.READY) {\n        layerRenderer = /** @type {module:ol/renderer/webgl/Layer} */ (this.getLayerRenderer(layerState.layer));\n        if (layerRenderer.prepareFrame(frameState, layerState, context)) {\n          layerStatesToDraw.push(layerState);\n        }\n      }\n    }\n\n    const width = frameState.size[0] * frameState.pixelRatio;\n    const height = frameState.size[1] * frameState.pixelRatio;\n    if (this.canvas_.width != width || this.canvas_.height != height) {\n      this.canvas_.width = width;\n      this.canvas_.height = height;\n    }\n\n    gl.bindFramebuffer(FRAMEBUFFER, null);\n\n    gl.clearColor(0, 0, 0, 0);\n    gl.clear(COLOR_BUFFER_BIT);\n    gl.enable(BLEND);\n    gl.viewport(0, 0, this.canvas_.width, this.canvas_.height);\n\n    for (i = 0, ii = layerStatesToDraw.length; i < ii; ++i) {\n      layerState = layerStatesToDraw[i];\n      layerRenderer = /** @type {module:ol/renderer/webgl/Layer} */ (this.getLayerRenderer(layerState.layer));\n      layerRenderer.composeFrame(frameState, layerState, context);\n    }\n\n    if (!this.renderedVisible_) {\n      this.canvas_.style.display = '';\n      this.renderedVisible_ = true;\n    }\n\n    this.calculateMatrices2D(frameState);\n\n    if (this.textureCache_.getCount() - this.textureCacheFrameMarkerCount_ >\n        WEBGL_TEXTURE_CACHE_HIGH_WATER_MARK) {\n      frameState.postRenderFunctions.push(\n        /** @type {module:ol/PluggableMap~PostRenderFunction} */ (this.expireCache_.bind(this))\n      );\n    }\n\n    if (!this.tileTextureQueue_.isEmpty()) {\n      frameState.postRenderFunctions.push(this.loadNextTileTexture_);\n      frameState.animate = true;\n    }\n\n    this.dispatchComposeEvent_(RenderEventType.POSTCOMPOSE, frameState);\n\n    this.scheduleRemoveUnusedLayerRenderers(frameState);\n    this.scheduleExpireIconCache(frameState);\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  forEachFeatureAtCoordinate(\n    coordinate,\n    frameState,\n    hitTolerance,\n    callback,\n    thisArg,\n    layerFilter,\n    thisArg2\n  ) {\n    let result;\n\n    if (this.getGL().isContextLost()) {\n      return false;\n    }\n\n    const viewState = frameState.viewState;\n\n    const layerStates = frameState.layerStatesArray;\n    const numLayers = layerStates.length;\n    let i;\n    for (i = numLayers - 1; i >= 0; --i) {\n      const layerState = layerStates[i];\n      const layer = layerState.layer;\n      if (visibleAtResolution(layerState, viewState.resolution) &&\n          layerFilter.call(thisArg2, layer)) {\n        const layerRenderer = this.getLayerRenderer(layer);\n        result = layerRenderer.forEachFeatureAtCoordinate(\n          coordinate, frameState, hitTolerance, callback, thisArg);\n        if (result) {\n          return result;\n        }\n      }\n    }\n    return undefined;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  hasFeatureAtCoordinate(coordinate, frameState, hitTolerance, layerFilter, thisArg) {\n    let hasFeature = false;\n\n    if (this.getGL().isContextLost()) {\n      return false;\n    }\n\n    const viewState = frameState.viewState;\n\n    const layerStates = frameState.layerStatesArray;\n    const numLayers = layerStates.length;\n    let i;\n    for (i = numLayers - 1; i >= 0; --i) {\n      const layerState = layerStates[i];\n      const layer = layerState.layer;\n      if (visibleAtResolution(layerState, viewState.resolution) &&\n          layerFilter.call(thisArg, layer)) {\n        const layerRenderer = this.getLayerRenderer(layer);\n        hasFeature =\n            layerRenderer.hasFeatureAtCoordinate(coordinate, frameState);\n        if (hasFeature) {\n          return true;\n        }\n      }\n    }\n    return hasFeature;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  forEachLayerAtPixel(pixel, frameState, hitTolerance, callback, thisArg, layerFilter, thisArg2) {\n    if (this.getGL().isContextLost()) {\n      return false;\n    }\n\n    const viewState = frameState.viewState;\n    let result;\n\n    const layerStates = frameState.layerStatesArray;\n    const numLayers = layerStates.length;\n    let i;\n    for (i = numLayers - 1; i >= 0; --i) {\n      const layerState = layerStates[i];\n      const layer = layerState.layer;\n      if (visibleAtResolution(layerState, viewState.resolution) &&\n          layerFilter.call(thisArg, layer)) {\n        const layerRenderer = /** @type {module:ol/renderer/webgl/Layer} */ (this.getLayerRenderer(layer));\n        result = layerRenderer.forEachLayerAtPixel(\n          pixel, frameState, callback, thisArg);\n        if (result) {\n          return result;\n        }\n      }\n    }\n    return undefined;\n  }\n}\n\n\nexport default WebGLMapRenderer;\n","/**\n * @module ol/renderer/webgl/tilelayershader\n */\n// This file is automatically generated, do not edit.\n// Run `make shaders` to generate, and commit the result.\n\nimport {DEBUG as DEBUG_WEBGL} from '../../webgl.js';\nimport WebGLFragment from '../../webgl/Fragment.js';\nimport WebGLVertex from '../../webgl/Vertex.js';\n\nexport const fragment = new WebGLFragment(DEBUG_WEBGL ?\n  'precision mediump float;\\nvarying vec2 v_texCoord;\\n\\n\\nuniform sampler2D u_texture;\\n\\nvoid main(void) {\\n  gl_FragColor = texture2D(u_texture, v_texCoord);\\n}\\n' :\n  'precision mediump float;varying vec2 a;uniform sampler2D e;void main(void){gl_FragColor=texture2D(e,a);}');\n\nexport const vertex = new WebGLVertex(DEBUG_WEBGL ?\n  'varying vec2 v_texCoord;\\n\\n\\nattribute vec2 a_position;\\nattribute vec2 a_texCoord;\\nuniform vec4 u_tileOffset;\\n\\nvoid main(void) {\\n  gl_Position = vec4(a_position * u_tileOffset.xy + u_tileOffset.zw, 0., 1.);\\n  v_texCoord = a_texCoord;\\n}\\n\\n\\n' :\n  'varying vec2 a;attribute vec2 b;attribute vec2 c;uniform vec4 d;void main(void){gl_Position=vec4(b*d.xy+d.zw,0.,1.);a=c;}');\n","/**\n * @module ol/renderer/webgl/tilelayershader/Locations\n */\n// This file is automatically generated, do not edit\n// Run `make shaders` to generate, and commit the result.\n\nimport {DEBUG as DEBUG_WEBGL} from '../../../webgl.js';\n\nclass Locations {\n\n  /**\n   * @param {WebGLRenderingContext} gl GL.\n   * @param {WebGLProgram} program Program.\n   */\n  constructor(gl, program) {\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_tileOffset = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_tileOffset' : 'd');\n\n    /**\n     * @type {WebGLUniformLocation}\n     */\n    this.u_texture = gl.getUniformLocation(\n      program, DEBUG_WEBGL ? 'u_texture' : 'e');\n\n    /**\n     * @type {number}\n     */\n    this.a_position = gl.getAttribLocation(\n      program, DEBUG_WEBGL ? 'a_position' : 'b');\n\n    /**\n     * @type {number}\n     */\n    this.a_texCoord = gl.getAttribLocation(\n      program, DEBUG_WEBGL ? 'a_texCoord' : 'c');\n\n  }\n\n}\n\nexport default Locations;\n","/**\n * @module ol/renderer/webgl/TileLayer\n */\n// FIXME large resolutions lead to too large framebuffers :-(\n// FIXME animated shaders! check in redraw\n\nimport LayerType from '../../LayerType.js';\nimport TileRange from '../../TileRange.js';\nimport TileState from '../../TileState.js';\nimport {numberSafeCompareFunction} from '../../array.js';\nimport {createEmpty, intersects} from '../../extent.js';\nimport {roundUpToPowerOfTwo} from '../../math.js';\nimport WebGLLayerRenderer from '../webgl/Layer.js';\nimport {fragment, vertex} from '../webgl/tilelayershader.js';\nimport Locations from '../webgl/tilelayershader/Locations.js';\nimport {toSize} from '../../size.js';\nimport {\n  reset as resetTransform,\n  rotate as rotateTransform,\n  scale as scaleTransform,\n  translate as translateTransform,\n  apply as applyTransform\n} from '../../transform.js';\nimport {COLOR_BUFFER_BIT, BLEND, ARRAY_BUFFER, FLOAT, LINEAR, TRIANGLE_STRIP} from '../../webgl.js';\nimport WebGLBuffer from '../../webgl/Buffer.js';\n\n/**\n * @classdesc\n * WebGL renderer for tile layers.\n * @api\n */\nclass WebGLTileLayerRenderer extends WebGLLayerRenderer {\n\n  /**\n   * @param {module:ol/renderer/webgl/Map} mapRenderer Map renderer.\n   * @param {module:ol/layer/Tile} tileLayer Tile layer.\n   */\n  constructor(mapRenderer, tileLayer) {\n\n    super(mapRenderer, tileLayer);\n\n    /**\n     * @private\n     * @type {module:ol/webgl/Fragment}\n     */\n    this.fragmentShader_ = fragment;\n\n    /**\n     * @private\n     * @type {module:ol/webgl/Vertex}\n     */\n    this.vertexShader_ = vertex;\n\n    /**\n     * @private\n     * @type {module:ol/renderer/webgl/tilelayershader/Locations}\n     */\n    this.locations_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/webgl/Buffer}\n     */\n    this.renderArrayBuffer_ = new WebGLBuffer([\n      0, 0, 0, 1,\n      1, 0, 1, 1,\n      0, 1, 0, 0,\n      1, 1, 1, 0\n    ]);\n\n    /**\n     * @private\n     * @type {module:ol/TileRange}\n     */\n    this.renderedTileRange_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/extent~Extent}\n     */\n    this.renderedFramebufferExtent_ = null;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.renderedRevision_ = -1;\n\n    /**\n     * @private\n     * @type {module:ol/size~Size}\n     */\n    this.tmpSize_ = [0, 0];\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  disposeInternal() {\n    const context = this.mapRenderer.getContext();\n    context.deleteBuffer(this.renderArrayBuffer_);\n    WebGLLayerRenderer.prototype.disposeInternal.call(this);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  createLoadedTileFinder(source, projection, tiles) {\n    const mapRenderer = this.mapRenderer;\n\n    return (\n      /**\n       * @param {number} zoom Zoom level.\n       * @param {module:ol/TileRange} tileRange Tile range.\n       * @return {boolean} The tile range is fully loaded.\n       */\n      function(zoom, tileRange) {\n        function callback(tile) {\n          const loaded = mapRenderer.isTileTextureLoaded(tile);\n          if (loaded) {\n            if (!tiles[zoom]) {\n              tiles[zoom] = {};\n            }\n            tiles[zoom][tile.tileCoord.toString()] = tile;\n          }\n          return loaded;\n        }\n        return source.forEachLoadedTile(projection, zoom, tileRange, callback);\n      }\n    );\n  }\n\n  /**\n   * @inheritDoc\n   */\n  handleWebGLContextLost() {\n    WebGLLayerRenderer.prototype.handleWebGLContextLost.call(this);\n    this.locations_ = null;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  prepareFrame(frameState, layerState, context) {\n\n    const mapRenderer = this.mapRenderer;\n    const gl = context.getGL();\n\n    const viewState = frameState.viewState;\n    const projection = viewState.projection;\n\n    const tileLayer = /** @type {module:ol/layer/Tile} */ (this.getLayer());\n    const tileSource = tileLayer.getSource();\n    const tileGrid = tileSource.getTileGridForProjection(projection);\n    const z = tileGrid.getZForResolution(viewState.resolution);\n    const tileResolution = tileGrid.getResolution(z);\n\n    const tilePixelSize =\n        tileSource.getTilePixelSize(z, frameState.pixelRatio, projection);\n    const pixelRatio = tilePixelSize[0] /\n        toSize(tileGrid.getTileSize(z), this.tmpSize_)[0];\n    const tilePixelResolution = tileResolution / pixelRatio;\n    const tileGutter = tileSource.getTilePixelRatio(pixelRatio) * tileSource.getGutter(projection);\n\n    const center = viewState.center;\n    const extent = frameState.extent;\n    const tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);\n\n    let framebufferExtent;\n    if (this.renderedTileRange_ &&\n        this.renderedTileRange_.equals(tileRange) &&\n        this.renderedRevision_ == tileSource.getRevision()) {\n      framebufferExtent = this.renderedFramebufferExtent_;\n    } else {\n\n      const tileRangeSize = tileRange.getSize();\n\n      const maxDimension = Math.max(\n        tileRangeSize[0] * tilePixelSize[0],\n        tileRangeSize[1] * tilePixelSize[1]);\n      const framebufferDimension = roundUpToPowerOfTwo(maxDimension);\n      const framebufferExtentDimension = tilePixelResolution * framebufferDimension;\n      const origin = tileGrid.getOrigin(z);\n      const minX = origin[0] +\n          tileRange.minX * tilePixelSize[0] * tilePixelResolution;\n      const minY = origin[1] +\n          tileRange.minY * tilePixelSize[1] * tilePixelResolution;\n      framebufferExtent = [\n        minX, minY,\n        minX + framebufferExtentDimension, minY + framebufferExtentDimension\n      ];\n\n      this.bindFramebuffer(frameState, framebufferDimension);\n      gl.viewport(0, 0, framebufferDimension, framebufferDimension);\n\n      gl.clearColor(0, 0, 0, 0);\n      gl.clear(COLOR_BUFFER_BIT);\n      gl.disable(BLEND);\n\n      const program = context.getProgram(this.fragmentShader_, this.vertexShader_);\n      context.useProgram(program);\n      if (!this.locations_) {\n        this.locations_ = new Locations(gl, program);\n      }\n\n      context.bindBuffer(ARRAY_BUFFER, this.renderArrayBuffer_);\n      gl.enableVertexAttribArray(this.locations_.a_position);\n      gl.vertexAttribPointer(\n        this.locations_.a_position, 2, FLOAT, false, 16, 0);\n      gl.enableVertexAttribArray(this.locations_.a_texCoord);\n      gl.vertexAttribPointer(\n        this.locations_.a_texCoord, 2, FLOAT, false, 16, 8);\n      gl.uniform1i(this.locations_.u_texture, 0);\n\n      /**\n       * @type {Object.<number, Object.<string, module:ol/Tile>>}\n       */\n      const tilesToDrawByZ = {};\n      tilesToDrawByZ[z] = {};\n\n      const findLoadedTiles = this.createLoadedTileFinder(\n        tileSource, projection, tilesToDrawByZ);\n\n      const useInterimTilesOnError = tileLayer.getUseInterimTilesOnError();\n      let allTilesLoaded = true;\n      const tmpExtent = createEmpty();\n      const tmpTileRange = new TileRange(0, 0, 0, 0);\n      let childTileRange, drawable, fullyLoaded, tile, tileState;\n      let x, y, tileExtent;\n      for (x = tileRange.minX; x <= tileRange.maxX; ++x) {\n        for (y = tileRange.minY; y <= tileRange.maxY; ++y) {\n\n          tile = tileSource.getTile(z, x, y, pixelRatio, projection);\n          if (layerState.extent !== undefined) {\n            // ignore tiles outside layer extent\n            tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord, tmpExtent);\n            if (!intersects(tileExtent, layerState.extent)) {\n              continue;\n            }\n          }\n          tileState = tile.getState();\n          drawable = tileState == TileState.LOADED ||\n              tileState == TileState.EMPTY ||\n              tileState == TileState.ERROR && !useInterimTilesOnError;\n          if (!drawable) {\n            tile = tile.getInterimTile();\n          }\n          tileState = tile.getState();\n          if (tileState == TileState.LOADED) {\n            if (mapRenderer.isTileTextureLoaded(tile)) {\n              tilesToDrawByZ[z][tile.tileCoord.toString()] = tile;\n              continue;\n            }\n          } else if (tileState == TileState.EMPTY ||\n                     (tileState == TileState.ERROR &&\n                      !useInterimTilesOnError)) {\n            continue;\n          }\n\n          allTilesLoaded = false;\n          fullyLoaded = tileGrid.forEachTileCoordParentTileRange(\n            tile.tileCoord, findLoadedTiles, null, tmpTileRange, tmpExtent);\n          if (!fullyLoaded) {\n            childTileRange = tileGrid.getTileCoordChildTileRange(\n              tile.tileCoord, tmpTileRange, tmpExtent);\n            if (childTileRange) {\n              findLoadedTiles(z + 1, childTileRange);\n            }\n          }\n\n        }\n\n      }\n\n      /** @type {Array.<number>} */\n      const zs = Object.keys(tilesToDrawByZ).map(Number);\n      zs.sort(numberSafeCompareFunction);\n      const u_tileOffset = new Float32Array(4);\n      for (let i = 0, ii = zs.length; i < ii; ++i) {\n        const tilesToDraw = tilesToDrawByZ[zs[i]];\n        for (const tileKey in tilesToDraw) {\n          tile = tilesToDraw[tileKey];\n          tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord, tmpExtent);\n          u_tileOffset[0] = 2 * (tileExtent[2] - tileExtent[0]) /\n              framebufferExtentDimension;\n          u_tileOffset[1] = 2 * (tileExtent[3] - tileExtent[1]) /\n              framebufferExtentDimension;\n          u_tileOffset[2] = 2 * (tileExtent[0] - framebufferExtent[0]) /\n              framebufferExtentDimension - 1;\n          u_tileOffset[3] = 2 * (tileExtent[1] - framebufferExtent[1]) /\n              framebufferExtentDimension - 1;\n          gl.uniform4fv(this.locations_.u_tileOffset, u_tileOffset);\n          mapRenderer.bindTileTexture(tile, tilePixelSize,\n            tileGutter * pixelRatio, LINEAR, LINEAR);\n          gl.drawArrays(TRIANGLE_STRIP, 0, 4);\n        }\n      }\n\n      if (allTilesLoaded) {\n        this.renderedTileRange_ = tileRange;\n        this.renderedFramebufferExtent_ = framebufferExtent;\n        this.renderedRevision_ = tileSource.getRevision();\n      } else {\n        this.renderedTileRange_ = null;\n        this.renderedFramebufferExtent_ = null;\n        this.renderedRevision_ = -1;\n        frameState.animate = true;\n      }\n\n    }\n\n    this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);\n    const tileTextureQueue = mapRenderer.getTileTextureQueue();\n    this.manageTilePyramid(\n      frameState, tileSource, tileGrid, pixelRatio, projection, extent, z,\n      tileLayer.getPreload(),\n      /**\n       * @param {module:ol/Tile} tile Tile.\n       */\n      function(tile) {\n        if (tile.getState() == TileState.LOADED &&\n              !mapRenderer.isTileTextureLoaded(tile) &&\n              !tileTextureQueue.isKeyQueued(tile.getKey())) {\n          tileTextureQueue.enqueue([\n            tile,\n            tileGrid.getTileCoordCenter(tile.tileCoord),\n            tileGrid.getResolution(tile.tileCoord[0]),\n            tilePixelSize, tileGutter * pixelRatio\n          ]);\n        }\n      }, this);\n    this.scheduleExpireCache(frameState, tileSource);\n\n    const texCoordMatrix = this.texCoordMatrix;\n    resetTransform(texCoordMatrix);\n    translateTransform(texCoordMatrix,\n      (Math.round(center[0] / tileResolution) * tileResolution - framebufferExtent[0]) /\n            (framebufferExtent[2] - framebufferExtent[0]),\n      (Math.round(center[1] / tileResolution) * tileResolution - framebufferExtent[1]) /\n            (framebufferExtent[3] - framebufferExtent[1]));\n    if (viewState.rotation !== 0) {\n      rotateTransform(texCoordMatrix, viewState.rotation);\n    }\n    scaleTransform(texCoordMatrix,\n      frameState.size[0] * viewState.resolution /\n            (framebufferExtent[2] - framebufferExtent[0]),\n      frameState.size[1] * viewState.resolution /\n            (framebufferExtent[3] - framebufferExtent[1]));\n    translateTransform(texCoordMatrix, -0.5, -0.5);\n\n    return true;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  forEachLayerAtPixel(pixel, frameState, callback, thisArg) {\n    if (!this.framebuffer) {\n      return undefined;\n    }\n\n    const pixelOnMapScaled = [\n      pixel[0] / frameState.size[0],\n      (frameState.size[1] - pixel[1]) / frameState.size[1]];\n\n    const pixelOnFrameBufferScaled = applyTransform(\n      this.texCoordMatrix, pixelOnMapScaled.slice());\n    const pixelOnFrameBuffer = [\n      pixelOnFrameBufferScaled[0] * this.framebufferDimension,\n      pixelOnFrameBufferScaled[1] * this.framebufferDimension];\n\n    const gl = this.mapRenderer.getContext().getGL();\n    gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\n    const imageData = new Uint8Array(4);\n    gl.readPixels(pixelOnFrameBuffer[0], pixelOnFrameBuffer[1], 1, 1,\n      gl.RGBA, gl.UNSIGNED_BYTE, imageData);\n\n    if (imageData[3] > 0) {\n      return callback.call(thisArg, this.getLayer(), imageData);\n    } else {\n      return undefined;\n    }\n  }\n}\n\n\n/**\n * Determine if this renderer handles the provided layer.\n * @param {module:ol/layer/Layer} layer The candidate layer.\n * @return {boolean} The renderer can render the layer.\n */\nWebGLTileLayerRenderer['handles'] = function(layer) {\n  return layer.getType() === LayerType.TILE;\n};\n\n\n/**\n * Create a layer renderer.\n * @param {module:ol/renderer/Map} mapRenderer The map renderer.\n * @param {module:ol/layer/Layer} layer The layer to be rendererd.\n * @return {module:ol/renderer/webgl/TileLayer} The layer renderer.\n */\nWebGLTileLayerRenderer['create'] = function(mapRenderer, layer) {\n  return new WebGLTileLayerRenderer(\n    /** @type {module:ol/renderer/webgl/Map} */ (mapRenderer),\n    /** @type {module:ol/layer/Tile} */ (layer)\n  );\n};\n\n\nexport default WebGLTileLayerRenderer;\n","/**\n * @module ol/renderer/webgl/VectorLayer\n */\nimport {getUid} from '../../util.js';\nimport LayerType from '../../LayerType.js';\nimport ViewHint from '../../ViewHint.js';\nimport {buffer, containsExtent, createEmpty} from '../../extent.js';\nimport WebGLReplayGroup from '../../render/webgl/ReplayGroup.js';\nimport {defaultOrder as defaultRenderOrder, getTolerance as getRenderTolerance, getSquaredTolerance as getSquaredRenderTolerance, renderFeature} from '../vector.js';\nimport WebGLLayerRenderer from '../webgl/Layer.js';\nimport {apply as applyTransform} from '../../transform.js';\n\n\n/**\n * @classdesc\n * WebGL renderer for vector layers.\n * @api\n */\nclass WebGLVectorLayerRenderer extends WebGLLayerRenderer {\n\n  /**\n   * @param {module:ol/renderer/webgl/Map} mapRenderer Map renderer.\n   * @param {module:ol/layer/Vector} vectorLayer Vector layer.\n   */\n  constructor(mapRenderer, vectorLayer) {\n\n    super(mapRenderer, vectorLayer);\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.dirty_ = false;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.renderedRevision_ = -1;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.renderedResolution_ = NaN;\n\n    /**\n     * @private\n     * @type {module:ol/extent~Extent}\n     */\n    this.renderedExtent_ = createEmpty();\n\n    /**\n     * @private\n     * @type {function(module:ol/Feature, module:ol/Feature): number|null}\n     */\n    this.renderedRenderOrder_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/render/webgl/ReplayGroup}\n     */\n    this.replayGroup_ = null;\n\n    /**\n     * The last layer state.\n     * @private\n     * @type {?module:ol/layer/Layer~State}\n     */\n    this.layerState_ = null;\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  composeFrame(frameState, layerState, context) {\n    this.layerState_ = layerState;\n    const viewState = frameState.viewState;\n    const replayGroup = this.replayGroup_;\n    const size = frameState.size;\n    const pixelRatio = frameState.pixelRatio;\n    const gl = this.mapRenderer.getGL();\n    if (replayGroup && !replayGroup.isEmpty()) {\n      gl.enable(gl.SCISSOR_TEST);\n      gl.scissor(0, 0, size[0] * pixelRatio, size[1] * pixelRatio);\n      replayGroup.replay(context,\n        viewState.center, viewState.resolution, viewState.rotation,\n        size, pixelRatio, layerState.opacity,\n        layerState.managed ? frameState.skippedFeatureUids : {});\n      gl.disable(gl.SCISSOR_TEST);\n    }\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  disposeInternal() {\n    const replayGroup = this.replayGroup_;\n    if (replayGroup) {\n      const context = this.mapRenderer.getContext();\n      replayGroup.getDeleteResourcesFunction(context)();\n      this.replayGroup_ = null;\n    }\n    WebGLLayerRenderer.prototype.disposeInternal.call(this);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback, thisArg) {\n    if (!this.replayGroup_ || !this.layerState_) {\n      return undefined;\n    } else {\n      const context = this.mapRenderer.getContext();\n      const viewState = frameState.viewState;\n      const layer = this.getLayer();\n      const layerState = this.layerState_;\n      /** @type {!Object.<string, boolean>} */\n      const features = {};\n      return this.replayGroup_.forEachFeatureAtCoordinate(coordinate,\n        context, viewState.center, viewState.resolution, viewState.rotation,\n        frameState.size, frameState.pixelRatio, layerState.opacity,\n        {},\n        /**\n         * @param {module:ol/Feature|module:ol/render/Feature} feature Feature.\n         * @return {?} Callback result.\n         */\n        function(feature) {\n          const key = getUid(feature).toString();\n          if (!(key in features)) {\n            features[key] = true;\n            return callback.call(thisArg, feature, layer);\n          }\n        });\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  hasFeatureAtCoordinate(coordinate, frameState) {\n    if (!this.replayGroup_ || !this.layerState_) {\n      return false;\n    } else {\n      const context = this.mapRenderer.getContext();\n      const viewState = frameState.viewState;\n      const layerState = this.layerState_;\n      return this.replayGroup_.hasFeatureAtCoordinate(coordinate,\n        context, viewState.center, viewState.resolution, viewState.rotation,\n        frameState.size, frameState.pixelRatio, layerState.opacity,\n        frameState.skippedFeatureUids);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  forEachLayerAtPixel(pixel, frameState, callback, thisArg) {\n    const coordinate = applyTransform(\n      frameState.pixelToCoordinateTransform, pixel.slice());\n    const hasFeature = this.hasFeatureAtCoordinate(coordinate, frameState);\n\n    if (hasFeature) {\n      return callback.call(thisArg, this.getLayer(), null);\n    } else {\n      return undefined;\n    }\n  }\n\n  /**\n   * Handle changes in image style state.\n   * @param {module:ol/events/Event} event Image style change event.\n   * @private\n   */\n  handleStyleImageChange_(event) {\n    this.renderIfReadyAndVisible();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  prepareFrame(frameState, layerState, context) {\n    const vectorLayer = /** @type {module:ol/layer/Vector} */ (this.getLayer());\n    const vectorSource = vectorLayer.getSource();\n\n    const animating = frameState.viewHints[ViewHint.ANIMATING];\n    const interacting = frameState.viewHints[ViewHint.INTERACTING];\n    const updateWhileAnimating = vectorLayer.getUpdateWhileAnimating();\n    const updateWhileInteracting = vectorLayer.getUpdateWhileInteracting();\n\n    if (!this.dirty_ && (!updateWhileAnimating && animating) ||\n        (!updateWhileInteracting && interacting)) {\n      return true;\n    }\n\n    const frameStateExtent = frameState.extent;\n    const viewState = frameState.viewState;\n    const projection = viewState.projection;\n    const resolution = viewState.resolution;\n    const pixelRatio = frameState.pixelRatio;\n    const vectorLayerRevision = vectorLayer.getRevision();\n    const vectorLayerRenderBuffer = vectorLayer.getRenderBuffer();\n    let vectorLayerRenderOrder = vectorLayer.getRenderOrder();\n\n    if (vectorLayerRenderOrder === undefined) {\n      vectorLayerRenderOrder = defaultRenderOrder;\n    }\n\n    const extent = buffer(frameStateExtent,\n      vectorLayerRenderBuffer * resolution);\n\n    if (!this.dirty_ &&\n        this.renderedResolution_ == resolution &&\n        this.renderedRevision_ == vectorLayerRevision &&\n        this.renderedRenderOrder_ == vectorLayerRenderOrder &&\n        containsExtent(this.renderedExtent_, extent)) {\n      return true;\n    }\n\n    if (this.replayGroup_) {\n      frameState.postRenderFunctions.push(\n        this.replayGroup_.getDeleteResourcesFunction(context));\n    }\n\n    this.dirty_ = false;\n\n    const replayGroup = new WebGLReplayGroup(\n      getRenderTolerance(resolution, pixelRatio),\n      extent, vectorLayer.getRenderBuffer());\n    vectorSource.loadFeatures(extent, resolution, projection);\n    /**\n     * @param {module:ol/Feature} feature Feature.\n     * @this {module:ol/renderer/webgl/VectorLayer}\n     */\n    const render = function(feature) {\n      let styles;\n      const styleFunction = feature.getStyleFunction() || vectorLayer.getStyleFunction();\n      if (styleFunction) {\n        styles = styleFunction(feature, resolution);\n      }\n      if (styles) {\n        const dirty = this.renderFeature(\n          feature, resolution, pixelRatio, styles, replayGroup);\n        this.dirty_ = this.dirty_ || dirty;\n      }\n    };\n    if (vectorLayerRenderOrder) {\n      /** @type {Array.<module:ol/Feature>} */\n      const features = [];\n      vectorSource.forEachFeatureInExtent(extent,\n        /**\n         * @param {module:ol/Feature} feature Feature.\n         */\n        function(feature) {\n          features.push(feature);\n        }, this);\n      features.sort(vectorLayerRenderOrder);\n      features.forEach(render.bind(this));\n    } else {\n      vectorSource.forEachFeatureInExtent(extent, render, this);\n    }\n    replayGroup.finish(context);\n\n    this.renderedResolution_ = resolution;\n    this.renderedRevision_ = vectorLayerRevision;\n    this.renderedRenderOrder_ = vectorLayerRenderOrder;\n    this.renderedExtent_ = extent;\n    this.replayGroup_ = replayGroup;\n\n    return true;\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature.\n   * @param {number} resolution Resolution.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {(module:ol/style/Style|Array.<module:ol/style/Style>)} styles The style or array of\n   *     styles.\n   * @param {module:ol/render/webgl/ReplayGroup} replayGroup Replay group.\n   * @return {boolean} `true` if an image is loading.\n   */\n  renderFeature(feature, resolution, pixelRatio, styles, replayGroup) {\n    if (!styles) {\n      return false;\n    }\n    let loading = false;\n    if (Array.isArray(styles)) {\n      for (let i = styles.length - 1, ii = 0; i >= ii; --i) {\n        loading = renderFeature(\n          replayGroup, feature, styles[i],\n          getSquaredRenderTolerance(resolution, pixelRatio),\n          this.handleStyleImageChange_, this) || loading;\n      }\n    } else {\n      loading = renderFeature(\n        replayGroup, feature, styles,\n        getSquaredRenderTolerance(resolution, pixelRatio),\n        this.handleStyleImageChange_, this) || loading;\n    }\n    return loading;\n  }\n}\n\n\n/**\n * Determine if this renderer handles the provided layer.\n * @param {module:ol/layer/Layer} layer The candidate layer.\n * @return {boolean} The renderer can render the layer.\n */\nWebGLVectorLayerRenderer['handles'] = function(layer) {\n  return layer.getType() === LayerType.VECTOR;\n};\n\n\n/**\n * Create a layer renderer.\n * @param {module:ol/renderer/Map} mapRenderer The map renderer.\n * @param {module:ol/layer/Layer} layer The layer to be rendererd.\n * @return {module:ol/renderer/webgl/VectorLayer} The layer renderer.\n */\nWebGLVectorLayerRenderer['create'] = function(mapRenderer, layer) {\n  return new WebGLVectorLayerRenderer(\n    /** @type {module:ol/renderer/webgl/Map} */ (mapRenderer),\n    /** @type {module:ol/layer/Vector} */ (layer)\n  );\n};\n\n\nexport default WebGLVectorLayerRenderer;\n","/**\n * @module ol/WebGLMap\n */\nimport PluggableMap from './PluggableMap.js';\nimport {defaults as defaultControls} from './control.js';\nimport {defaults as defaultInteractions} from './interaction.js';\nimport {assign} from './obj.js';\nimport WebGLImageLayerRenderer from './renderer/webgl/ImageLayer.js';\nimport WebGLMapRenderer from './renderer/webgl/Map.js';\nimport WebGLTileLayerRenderer from './renderer/webgl/TileLayer.js';\nimport WebGLVectorLayerRenderer from './renderer/webgl/VectorLayer.js';\n\n\n/**\n * @classdesc\n * The WebGLMap uses WebGL for rendering map layers.  This renderer has limited\n * support for vector data and no support for vector tiles.\n *\n *     import WebGLMap from 'ol/WebGLMap';\n *     import TileLayer from 'ol/layer/Tile';\n *     import OSM from 'ol/source/OSM';\n *     import View from 'ol/View';\n *\n *     var map = new WebGLMap({\n *       view: new View({\n *         center: [0, 0],\n *         zoom: 1\n *       }),\n *       layers: [\n *         new TileLayer({\n *           source: new OSM()\n *         })\n *       ],\n *       target: 'map'\n *     });\n *\n * The above snippet creates a map using a {@link module:ol/layer/Tile~Tile} to\n * display {@link module:ol/source/OSM~OSM} OSM data and render it to a DOM\n * element with the id `map`.\n *\n * The constructor places a viewport container (with CSS class name\n * `ol-viewport`) in the target element (see `getViewport()`), and then two\n * further elements within the viewport: one with CSS class name\n * `ol-overlaycontainer-stopevent` for controls and some overlays, and one with\n * CSS class name `ol-overlaycontainer` for other overlays (see the `stopEvent`\n * option of {@link module:ol/Overlay~Overlay} for the difference). The map\n * itself is placed in a further element within the viewport.\n *\n * Layers are stored as a {@link module:ol/Collection~Collection} in\n * layerGroups. A top-level group is provided by the library. This is what is\n * accessed by `getLayerGroup` and `setLayerGroup`. Layers entered in the\n * options are added to this group, and `addLayer` and `removeLayer` change the\n * layer collection in the group. `getLayers` is a convenience function for\n * `getLayerGroup().getLayers()`.\n * Note that {@link module:ol/layer/Group~Group} is a subclass of\n * {@link module:ol/layer/Base}, so layers entered in the options or added\n * with `addLayer` can be groups, which can contain further groups, and so on.\n *\n * @fires module:ol/MapBrowserEvent~MapBrowserEvent\n * @fires module:ol/MapEvent~MapEvent\n * @fires module:ol/render/Event~RenderEvent#postcompose\n * @fires module:ol/render/Event~RenderEvent#precompose\n * @api\n */\nclass WebGLMap extends PluggableMap {\n\n  /**\n   * @param {module:ol/PluggableMap~MapOptions} options Map options.\n   */\n  constructor(options) {\n    options = assign({}, options);\n    if (!options.controls) {\n      options.controls = defaultControls();\n    }\n    if (!options.interactions) {\n      options.interactions = defaultInteractions();\n    }\n\n    super(options);\n  }\n\n  createRenderer() {\n    const renderer = new WebGLMapRenderer(this);\n    renderer.registerLayerRenderers([\n      WebGLImageLayerRenderer,\n      WebGLTileLayerRenderer,\n      WebGLVectorLayerRenderer\n    ]);\n    return renderer;\n  }\n}\n\n\nexport default WebGLMap;\n","/**\n * @module ol/control/MousePosition\n */\nimport {listen} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport {getChangeEventType} from '../Object.js';\nimport Control from '../control/Control.js';\nimport {getTransformFromProjections, identityTransform, get as getProjection} from '../proj.js';\n\n\n/**\n * @type {string}\n */\nconst PROJECTION = 'projection';\n\n/**\n * @type {string}\n */\nconst COORDINATE_FORMAT = 'coordinateFormat';\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-mouse-position'] CSS class name.\n * @property {module:ol/coordinate~CoordinateFormat} [coordinateFormat] Coordinate format.\n * @property {module:ol/proj~ProjectionLike} projection Projection.\n * @property {function(module:ol/MapEvent)} [render] Function called when the\n * control should be re-rendered. This is called in a `requestAnimationFrame`\n * callback.\n * @property {Element|string} [target] Specify a target if you want the\n * control to be rendered outside of the map's viewport.\n * @property {string} [undefinedHTML='&nbsp;'] Markup to show when coordinates are not\n * available (e.g. when the pointer leaves the map viewport).  By default, the last position\n * will be replaced with `'&nbsp;'` when the pointer leaves the viewport.  To\n * retain the last rendered position, set this option to something falsey (like an empty\n * string `''`).\n */\n\n\n/**\n * @classdesc\n * A control to show the 2D coordinates of the mouse cursor. By default, these\n * are in the view projection, but can be in any supported projection.\n * By default the control is shown in the top right corner of the map, but this\n * can be changed by using the css selector `.ol-mouse-position`.\n *\n * @api\n */\nclass MousePosition extends Control {\n\n  /**\n   * @param {module:ol/control/MousePosition~Options=} opt_options Mouse position options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options ? opt_options : {};\n\n    const element = document.createElement('DIV');\n    element.className = options.className !== undefined ? options.className : 'ol-mouse-position';\n\n    super({\n      element: element,\n      render: options.render || render,\n      target: options.target\n    });\n\n    listen(this,\n      getChangeEventType(PROJECTION),\n      this.handleProjectionChanged_, this);\n\n    if (options.coordinateFormat) {\n      this.setCoordinateFormat(options.coordinateFormat);\n    }\n    if (options.projection) {\n      this.setProjection(options.projection);\n    }\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.undefinedHTML_ = 'undefinedHTML' in options ? options.undefinedHTML : '&nbsp;';\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.renderOnMouseOut_ = !!this.undefinedHTML_;\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.renderedHTML_ = element.innerHTML;\n\n    /**\n     * @private\n     * @type {module:ol/proj/Projection}\n     */\n    this.mapProjection_ = null;\n\n    /**\n     * @private\n     * @type {?module:ol/proj~TransformFunction}\n     */\n    this.transform_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/pixel~Pixel}\n     */\n    this.lastMouseMovePixel_ = null;\n\n  }\n\n  /**\n   * @private\n   */\n  handleProjectionChanged_() {\n    this.transform_ = null;\n  }\n\n  /**\n   * Return the coordinate format type used to render the current position or\n   * undefined.\n   * @return {module:ol/coordinate~CoordinateFormat|undefined} The format to render the current\n   *     position in.\n   * @observable\n   * @api\n   */\n  getCoordinateFormat() {\n    return (\n      /** @type {module:ol/coordinate~CoordinateFormat|undefined} */ (this.get(COORDINATE_FORMAT))\n    );\n  }\n\n  /**\n   * Return the projection that is used to report the mouse position.\n   * @return {module:ol/proj/Projection|undefined} The projection to report mouse\n   *     position in.\n   * @observable\n   * @api\n   */\n  getProjection() {\n    return (\n      /** @type {module:ol/proj/Projection|undefined} */ (this.get(PROJECTION))\n    );\n  }\n\n  /**\n   * @param {Event} event Browser event.\n   * @protected\n   */\n  handleMouseMove(event) {\n    const map = this.getMap();\n    this.lastMouseMovePixel_ = map.getEventPixel(event);\n    this.updateHTML_(this.lastMouseMovePixel_);\n  }\n\n  /**\n   * @param {Event} event Browser event.\n   * @protected\n   */\n  handleMouseOut(event) {\n    this.updateHTML_(null);\n    this.lastMouseMovePixel_ = null;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  setMap(map) {\n    super.setMap(map);\n    if (map) {\n      const viewport = map.getViewport();\n      this.listenerKeys.push(\n        listen(viewport, EventType.MOUSEMOVE, this.handleMouseMove, this)\n      );\n      if (this.renderOnMouseOut_) {\n        this.listenerKeys.push(\n          listen(viewport, EventType.MOUSEOUT, this.handleMouseOut, this)\n        );\n      }\n    }\n  }\n\n  /**\n   * Set the coordinate format type used to render the current position.\n   * @param {module:ol/coordinate~CoordinateFormat} format The format to render the current\n   *     position in.\n   * @observable\n   * @api\n   */\n  setCoordinateFormat(format) {\n    this.set(COORDINATE_FORMAT, format);\n  }\n\n  /**\n   * Set the projection that is used to report the mouse position.\n   * @param {module:ol/proj~ProjectionLike} projection The projection to report mouse\n   *     position in.\n   * @observable\n   * @api\n   */\n  setProjection(projection) {\n    this.set(PROJECTION, getProjection(projection));\n  }\n\n  /**\n   * @param {?module:ol/pixel~Pixel} pixel Pixel.\n   * @private\n   */\n  updateHTML_(pixel) {\n    let html = this.undefinedHTML_;\n    if (pixel && this.mapProjection_) {\n      if (!this.transform_) {\n        const projection = this.getProjection();\n        if (projection) {\n          this.transform_ = getTransformFromProjections(\n            this.mapProjection_, projection);\n        } else {\n          this.transform_ = identityTransform;\n        }\n      }\n      const map = this.getMap();\n      const coordinate = map.getCoordinateFromPixel(pixel);\n      if (coordinate) {\n        this.transform_(coordinate, coordinate);\n        const coordinateFormat = this.getCoordinateFormat();\n        if (coordinateFormat) {\n          html = coordinateFormat(coordinate);\n        } else {\n          html = coordinate.toString();\n        }\n      }\n    }\n    if (!this.renderedHTML_ || html !== this.renderedHTML_) {\n      this.element.innerHTML = html;\n      this.renderedHTML_ = html;\n    }\n  }\n}\n\n\n/**\n * Update the mouseposition element.\n * @param {module:ol/MapEvent} mapEvent Map event.\n * @this {module:ol/control/MousePosition}\n * @api\n */\nexport function render(mapEvent) {\n  const frameState = mapEvent.frameState;\n  if (!frameState) {\n    this.mapProjection_ = null;\n  } else {\n    if (this.mapProjection_ != frameState.viewState.projection) {\n      this.mapProjection_ = frameState.viewState.projection;\n      this.transform_ = null;\n    }\n  }\n  this.updateHTML_(this.lastMouseMovePixel_);\n}\n\n\nexport default MousePosition;\n","/**\n * @module ol/format/Feature\n */\nimport Geometry from '../geom/Geometry.js';\nimport {assign} from '../obj.js';\nimport {get as getProjection, equivalent as equivalentProjection, transformExtent} from '../proj.js';\n\n\n/**\n * @typedef {Object} ReadOptions\n * @property {module:ol/proj~ProjectionLike} dataProjection Projection of the data we are reading.\n * If not provided, the projection will be derived from the data (where possible) or\n * the `dataProjection` of the format is assigned (where set). If the projection\n * can not be derived from the data and if no `dataProjection` is set for a format,\n * the features will not be reprojected.\n * @property {module:ol/extent~Extent} extent Tile extent of the tile being read. This is only used and\n * required for {@link module:ol/format/MVT}.\n * @property {module:ol/proj~ProjectionLike} featureProjection Projection of the feature geometries\n * created by the format reader. If not provided, features will be returned in the\n * `dataProjection`.\n */\n\n\n/**\n * @typedef {Object} WriteOptions\n * @property {module:ol/proj~ProjectionLike} dataProjection Projection of the data we are writing.\n * If not provided, the `dataProjection` of the format is assigned (where set).\n * If no `dataProjection` is set for a format, the features will be returned\n * in the `featureProjection`.\n * @property {module:ol/proj~ProjectionLike} featureProjection Projection of the feature geometries\n * that will be serialized by the format writer. If not provided, geometries are assumed\n * to be in the `dataProjection` if that is set; in other words, they are not transformed.\n * @property {boolean} [rightHanded] When writing geometries, follow the right-hand\n * rule for linear ring orientation.  This means that polygons will have counter-clockwise\n * exterior rings and clockwise interior rings.  By default, coordinates are serialized\n * as they are provided at construction.  If `true`, the right-hand rule will\n * be applied.  If `false`, the left-hand rule will be applied (clockwise for\n * exterior and counter-clockwise for interior rings).  Note that not all\n * formats support this.  The GeoJSON format does use this property when writing\n * geometries.\n * @property {number} [decimals] Maximum number of decimal places for coordinates.\n * Coordinates are stored internally as floats, but floating-point arithmetic can create\n * coordinates with a large number of decimal places, not generally wanted on output.\n * Set a number here to round coordinates. Can also be used to ensure that\n * coordinates read in can be written back out with the same number of decimals.\n * Default is no rounding.\n */\n\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Base class for feature formats.\n * {module:ol/format/Feature~FeatureFormat} subclasses provide the ability to decode and encode\n * {@link module:ol/Feature~Feature} objects from a variety of commonly used geospatial\n * file formats.  See the documentation for each format for more details.\n *\n * @abstract\n * @api\n */\nclass FeatureFormat {\n  constructor() {\n\n    /**\n     * @protected\n     * @type {module:ol/proj/Projection}\n     */\n    this.dataProjection = null;\n\n    /**\n     * @protected\n     * @type {module:ol/proj/Projection}\n     */\n    this.defaultFeatureProjection = null;\n\n  }\n\n  /**\n   * Adds the data projection to the read options.\n   * @param {Document|Node|Object|string} source Source.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Options.\n   * @return {module:ol/format/Feature~ReadOptions|undefined} Options.\n   * @protected\n   */\n  getReadOptions(source, opt_options) {\n    let options;\n    if (opt_options) {\n      options = {\n        dataProjection: opt_options.dataProjection ?\n          opt_options.dataProjection : this.readProjection(source),\n        featureProjection: opt_options.featureProjection\n      };\n    }\n    return this.adaptOptions(options);\n  }\n\n  /**\n   * Sets the `dataProjection` on the options, if no `dataProjection`\n   * is set.\n   * @param {module:ol/format/Feature~WriteOptions|module:ol/format/Feature~ReadOptions|undefined} options\n   *     Options.\n   * @protected\n   * @return {module:ol/format/Feature~WriteOptions|module:ol/format/Feature~ReadOptions|undefined}\n   *     Updated options.\n   */\n  adaptOptions(options) {\n    return assign({\n      dataProjection: this.dataProjection,\n      featureProjection: this.defaultFeatureProjection\n    }, options);\n  }\n\n  /**\n   * Get the extent from the source of the last {@link readFeatures} call.\n   * @return {module:ol/extent~Extent} Tile extent.\n   */\n  getLastExtent() {\n    return null;\n  }\n\n  /**\n   * @abstract\n   * @return {module:ol/format/FormatType} Format.\n   */\n  getType() {}\n\n  /**\n   * Read a single feature from a source.\n   *\n   * @abstract\n   * @param {Document|Node|Object|string} source Source.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n   * @return {module:ol/Feature} Feature.\n   */\n  readFeature(source, opt_options) {}\n\n  /**\n   * Read all features from a source.\n   *\n   * @abstract\n   * @param {Document|Node|ArrayBuffer|Object|string} source Source.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n   * @return {Array.<module:ol/Feature>} Features.\n   */\n  readFeatures(source, opt_options) {}\n\n  /**\n   * Read a single geometry from a source.\n   *\n   * @abstract\n   * @param {Document|Node|Object|string} source Source.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n   * @return {module:ol/geom/Geometry} Geometry.\n   */\n  readGeometry(source, opt_options) {}\n\n  /**\n   * Read the projection from a source.\n   *\n   * @abstract\n   * @param {Document|Node|Object|string} source Source.\n   * @return {module:ol/proj/Projection} Projection.\n   */\n  readProjection(source) {}\n\n  /**\n   * Encode a feature in this format.\n   *\n   * @abstract\n   * @param {module:ol/Feature} feature Feature.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @return {string} Result.\n   */\n  writeFeature(feature, opt_options) {}\n\n  /**\n   * Encode an array of features in this format.\n   *\n   * @abstract\n   * @param {Array.<module:ol/Feature>} features Features.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @return {string} Result.\n   */\n  writeFeatures(features, opt_options) {}\n\n  /**\n   * Write a single geometry in this format.\n   *\n   * @abstract\n   * @param {module:ol/geom/Geometry} geometry Geometry.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @return {string} Result.\n   */\n  writeGeometry(geometry, opt_options) {}\n}\n\nexport default FeatureFormat;\n\n/**\n * @param {module:ol/geom/Geometry|module:ol/extent~Extent} geometry Geometry.\n * @param {boolean} write Set to true for writing, false for reading.\n * @param {(module:ol/format/Feature~WriteOptions|module:ol/format/Feature~ReadOptions)=} opt_options\n *     Options.\n * @return {module:ol/geom/Geometry|module:ol/extent~Extent} Transformed geometry.\n */\nexport function transformWithOptions(geometry, write, opt_options) {\n  const featureProjection = opt_options ?\n    getProjection(opt_options.featureProjection) : null;\n  const dataProjection = opt_options ?\n    getProjection(opt_options.dataProjection) : null;\n  /**\n   * @type {module:ol/geom/Geometry|module:ol/extent~Extent}\n   */\n  let transformed;\n  if (featureProjection && dataProjection &&\n      !equivalentProjection(featureProjection, dataProjection)) {\n    if (geometry instanceof Geometry) {\n      transformed = (write ? geometry.clone() : geometry).transform(\n        write ? featureProjection : dataProjection,\n        write ? dataProjection : featureProjection);\n    } else {\n      // FIXME this is necessary because GML treats extents\n      // as geometries\n      transformed = transformExtent(\n        geometry,\n        dataProjection,\n        featureProjection);\n    }\n  } else {\n    transformed = geometry;\n  }\n  if (write && opt_options && opt_options.decimals !== undefined) {\n    const power = Math.pow(10, opt_options.decimals);\n    // if decimals option on write, round each coordinate appropriately\n    /**\n     * @param {Array.<number>} coordinates Coordinates.\n     * @return {Array.<number>} Transformed coordinates.\n     */\n    const transform = function(coordinates) {\n      for (let i = 0, ii = coordinates.length; i < ii; ++i) {\n        coordinates[i] = Math.round(coordinates[i] * power) / power;\n      }\n      return coordinates;\n    };\n    if (transformed === geometry) {\n      transformed = transformed.clone();\n    }\n    transformed.applyTransform(transform);\n  }\n  return transformed;\n}\n","/**\n * @module ol/format/JSONFeature\n */\nimport FeatureFormat from '../format/Feature.js';\nimport FormatType from '../format/FormatType.js';\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Base class for JSON feature formats.\n *\n * @abstract\n */\nclass JSONFeature extends FeatureFormat {\n  constructor() {\n    super();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getType() {\n    return FormatType.JSON;\n  }\n\n  /**\n   * Read a feature.  Only works for a single feature. Use `readFeatures` to\n   * read a feature collection.\n   *\n   * @param {ArrayBuffer|Document|Node|Object|string} source Source.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n   * @return {module:ol/Feature} Feature.\n   * @api\n   */\n  readFeature(source, opt_options) {\n    return this.readFeatureFromObject(\n      getObject(source), this.getReadOptions(source, opt_options));\n  }\n\n  /**\n   * Read all features.  Works with both a single feature and a feature\n   * collection.\n   *\n   * @param {ArrayBuffer|Document|Node|Object|string} source Source.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n   * @return {Array.<module:ol/Feature>} Features.\n   * @api\n   */\n  readFeatures(source, opt_options) {\n    return this.readFeaturesFromObject(\n      getObject(source), this.getReadOptions(source, opt_options));\n  }\n\n  /**\n   * @abstract\n   * @param {Object} object Object.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n   * @protected\n   * @return {module:ol/Feature} Feature.\n   */\n  readFeatureFromObject(object, opt_options) {}\n\n  /**\n   * @abstract\n   * @param {Object} object Object.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n   * @protected\n   * @return {Array.<module:ol/Feature>} Features.\n   */\n  readFeaturesFromObject(object, opt_options) {}\n\n  /**\n   * Read a geometry.\n   *\n   * @param {ArrayBuffer|Document|Node|Object|string} source Source.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n   * @return {module:ol/geom/Geometry} Geometry.\n   * @api\n   */\n  readGeometry(source, opt_options) {\n    return this.readGeometryFromObject(\n      getObject(source), this.getReadOptions(source, opt_options));\n  }\n\n  /**\n   * @abstract\n   * @param {Object} object Object.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n   * @protected\n   * @return {module:ol/geom/Geometry} Geometry.\n   */\n  readGeometryFromObject(object, opt_options) {}\n\n  /**\n   * Read the projection.\n   *\n   * @param {ArrayBuffer|Document|Node|Object|string} source Source.\n   * @return {module:ol/proj/Projection} Projection.\n   * @api\n   */\n  readProjection(source) {\n    return this.readProjectionFromObject(getObject(source));\n  }\n\n  /**\n   * @abstract\n   * @param {Object} object Object.\n   * @protected\n   * @return {module:ol/proj/Projection} Projection.\n   */\n  readProjectionFromObject(object) {}\n\n  /**\n   * Encode a feature as string.\n   *\n   * @param {module:ol/Feature} feature Feature.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @return {string} Encoded feature.\n   * @api\n   */\n  writeFeature(feature, opt_options) {\n    return JSON.stringify(this.writeFeatureObject(feature, opt_options));\n  }\n\n  /**\n   * @abstract\n   * @param {module:ol/Feature} feature Feature.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @return {Object} Object.\n   */\n  writeFeatureObject(feature, opt_options) {}\n\n  /**\n   * Encode an array of features as string.\n   *\n   * @param {Array.<module:ol/Feature>} features Features.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @return {string} Encoded features.\n   * @api\n   */\n  writeFeatures(features, opt_options) {\n    return JSON.stringify(this.writeFeaturesObject(features, opt_options));\n  }\n\n  /**\n   * @abstract\n   * @param {Array.<module:ol/Feature>} features Features.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @return {Object} Object.\n   */\n  writeFeaturesObject(features, opt_options) {}\n\n  /**\n   * Encode a geometry as string.\n   *\n   * @param {module:ol/geom/Geometry} geometry Geometry.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @return {string} Encoded geometry.\n   * @api\n   */\n  writeGeometry(geometry, opt_options) {\n    return JSON.stringify(this.writeGeometryObject(geometry, opt_options));\n  }\n\n  /**\n   * @abstract\n   * @param {module:ol/geom/Geometry} geometry Geometry.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @return {Object} Object.\n   */\n  writeGeometryObject(geometry, opt_options) {}\n}\n\n\n/**\n * @param {Document|Node|Object|string} source Source.\n * @return {Object} Object.\n */\nfunction getObject(source) {\n  if (typeof source === 'string') {\n    const object = JSON.parse(source);\n    return object ? /** @type {Object} */ (object) : null;\n  } else if (source !== null) {\n    return source;\n  } else {\n    return null;\n  }\n}\n\n\nexport default JSONFeature;\n","/**\n * @module ol/format/EsriJSON\n */\nimport Feature from '../Feature.js';\nimport {assert} from '../asserts.js';\nimport {containsExtent} from '../extent.js';\nimport {transformWithOptions} from '../format/Feature.js';\nimport JSONFeature from '../format/JSONFeature.js';\nimport GeometryLayout from '../geom/GeometryLayout.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport LineString from '../geom/LineString.js';\nimport LinearRing from '../geom/LinearRing.js';\nimport MultiLineString from '../geom/MultiLineString.js';\nimport MultiPoint from '../geom/MultiPoint.js';\nimport MultiPolygon from '../geom/MultiPolygon.js';\nimport Point from '../geom/Point.js';\nimport Polygon from '../geom/Polygon.js';\nimport {deflateCoordinates} from '../geom/flat/deflate.js';\nimport {linearRingIsClockwise} from '../geom/flat/orient.js';\nimport {assign, isEmpty} from '../obj.js';\nimport {get as getProjection} from '../proj.js';\n\n\n/**\n * @const\n * @type {Object.<module:ol/geom/GeometryType, function(EsriJSONGeometry): module:ol/geom/Geometry>}\n */\nconst GEOMETRY_READERS = {};\nGEOMETRY_READERS[GeometryType.POINT] = readPointGeometry;\nGEOMETRY_READERS[GeometryType.LINE_STRING] = readLineStringGeometry;\nGEOMETRY_READERS[GeometryType.POLYGON] = readPolygonGeometry;\nGEOMETRY_READERS[GeometryType.MULTI_POINT] = readMultiPointGeometry;\nGEOMETRY_READERS[GeometryType.MULTI_LINE_STRING] = readMultiLineStringGeometry;\nGEOMETRY_READERS[GeometryType.MULTI_POLYGON] = readMultiPolygonGeometry;\n\n\n/**\n * @const\n * @type {Object.<string, function(module:ol/geom/Geometry, module:ol/format/Feature~WriteOptions=): (EsriJSONGeometry)>}\n */\nconst GEOMETRY_WRITERS = {};\nGEOMETRY_WRITERS[GeometryType.POINT] = writePointGeometry;\nGEOMETRY_WRITERS[GeometryType.LINE_STRING] = writeLineStringGeometry;\nGEOMETRY_WRITERS[GeometryType.POLYGON] = writePolygonGeometry;\nGEOMETRY_WRITERS[GeometryType.MULTI_POINT] = writeMultiPointGeometry;\nGEOMETRY_WRITERS[GeometryType.MULTI_LINE_STRING] = writeMultiLineStringGeometry;\nGEOMETRY_WRITERS[GeometryType.MULTI_POLYGON] = writeMultiPolygonGeometry;\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [geometryName] Geometry name to use when creating features.\n */\n\n\n/**\n * @classdesc\n * Feature format for reading and writing data in the EsriJSON format.\n *\n * @api\n */\nclass EsriJSON extends JSONFeature {\n\n  /**\n   * @param {module:ol/format/EsriJSON~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options ? opt_options : {};\n\n    super();\n\n    /**\n     * Name of the geometry attribute for features.\n     * @type {string|undefined}\n     * @private\n     */\n    this.geometryName_ = options.geometryName;\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFeatureFromObject(object, opt_options) {\n    const esriJSONFeature = /** @type {EsriJSONFeature} */ (object);\n    const geometry = readGeometry(esriJSONFeature.geometry, opt_options);\n    const feature = new Feature();\n    if (this.geometryName_) {\n      feature.setGeometryName(this.geometryName_);\n    }\n    feature.setGeometry(geometry);\n    if (opt_options && opt_options.idField &&\n      esriJSONFeature.attributes[opt_options.idField]) {\n      feature.setId(/** @type {number} */(esriJSONFeature.attributes[opt_options.idField]));\n    }\n    if (esriJSONFeature.attributes) {\n      feature.setProperties(esriJSONFeature.attributes);\n    }\n    return feature;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFeaturesFromObject(object, opt_options) {\n    const esriJSONObject = /** @type {EsriJSONObject} */ (object);\n    const options = opt_options ? opt_options : {};\n    if (esriJSONObject.features) {\n      const esriJSONFeatureCollection = /** @type {EsriJSONFeatureCollection} */ (object);\n      /** @type {Array.<module:ol/Feature>} */\n      const features = [];\n      const esriJSONFeatures = esriJSONFeatureCollection.features;\n      options.idField = object.objectIdFieldName;\n      for (let i = 0, ii = esriJSONFeatures.length; i < ii; ++i) {\n        features.push(this.readFeatureFromObject(esriJSONFeatures[i], options));\n      }\n      return features;\n    } else {\n      return [this.readFeatureFromObject(object, options)];\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readGeometryFromObject(object, opt_options) {\n    return readGeometry(/** @type {EsriJSONGeometry} */(object), opt_options);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readProjectionFromObject(object) {\n    const esriJSONObject = /** @type {EsriJSONObject} */ (object);\n    if (esriJSONObject.spatialReference && esriJSONObject.spatialReference.wkid) {\n      const crs = esriJSONObject.spatialReference.wkid;\n      return getProjection('EPSG:' + crs);\n    } else {\n      return null;\n    }\n  }\n\n  /**\n   * Encode a geometry as a EsriJSON object.\n   *\n   * @param {module:ol/geom/Geometry} geometry Geometry.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @return {EsriJSONGeometry} Object.\n   * @override\n   * @api\n   */\n  writeGeometryObject(geometry, opt_options) {\n    return writeGeometry(geometry, this.adaptOptions(opt_options));\n  }\n\n  /**\n   * Encode a feature as a esriJSON Feature object.\n   *\n   * @param {module:ol/Feature} feature Feature.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @return {Object} Object.\n   * @override\n   * @api\n   */\n  writeFeatureObject(feature, opt_options) {\n    opt_options = this.adaptOptions(opt_options);\n    const object = {};\n    const geometry = feature.getGeometry();\n    if (geometry) {\n      object['geometry'] = writeGeometry(geometry, opt_options);\n      if (opt_options && opt_options.featureProjection) {\n        object['geometry']['spatialReference'] = /** @type {EsriJSONCRS} */({\n          wkid: getProjection(opt_options.featureProjection).getCode().split(':').pop()\n        });\n      }\n    }\n    const properties = feature.getProperties();\n    delete properties[feature.getGeometryName()];\n    if (!isEmpty(properties)) {\n      object['attributes'] = properties;\n    } else {\n      object['attributes'] = {};\n    }\n    return object;\n  }\n\n  /**\n   * Encode an array of features as a EsriJSON object.\n   *\n   * @param {Array.<module:ol/Feature>} features Features.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @return {Object} EsriJSON Object.\n   * @override\n   * @api\n   */\n  writeFeaturesObject(features, opt_options) {\n    opt_options = this.adaptOptions(opt_options);\n    const objects = [];\n    for (let i = 0, ii = features.length; i < ii; ++i) {\n      objects.push(this.writeFeatureObject(features[i], opt_options));\n    }\n    return /** @type {EsriJSONFeatureCollection} */ ({\n      'features': objects\n    });\n  }\n}\n\n\n/**\n * @param {EsriJSONGeometry} object Object.\n * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n * @return {module:ol/geom/Geometry} Geometry.\n */\nfunction readGeometry(object, opt_options) {\n  if (!object) {\n    return null;\n  }\n  /** @type {module:ol/geom/GeometryType} */\n  let type;\n  if (typeof object.x === 'number' && typeof object.y === 'number') {\n    type = GeometryType.POINT;\n  } else if (object.points) {\n    type = GeometryType.MULTI_POINT;\n  } else if (object.paths) {\n    if (object.paths.length === 1) {\n      type = GeometryType.LINE_STRING;\n    } else {\n      type = GeometryType.MULTI_LINE_STRING;\n    }\n  } else if (object.rings) {\n    const layout = getGeometryLayout(object);\n    const rings = convertRings(object.rings, layout);\n    object = /** @type {EsriJSONGeometry} */(assign({}, object));\n    if (rings.length === 1) {\n      type = GeometryType.POLYGON;\n      object.rings = rings[0];\n    } else {\n      type = GeometryType.MULTI_POLYGON;\n      object.rings = rings;\n    }\n  }\n  const geometryReader = GEOMETRY_READERS[type];\n  return (\n    /** @type {module:ol/geom/Geometry} */ (transformWithOptions(geometryReader(object), false, opt_options))\n  );\n}\n\n\n/**\n * Determines inner and outer rings.\n * Checks if any polygons in this array contain any other polygons in this\n * array. It is used for checking for holes.\n * Logic inspired by: https://github.com/Esri/terraformer-arcgis-parser\n * @param {Array.<!Array.<!Array.<number>>>} rings Rings.\n * @param {module:ol/geom/GeometryLayout} layout Geometry layout.\n * @return {Array.<!Array.<!Array.<number>>>} Transformed rings.\n */\nfunction convertRings(rings, layout) {\n  const flatRing = [];\n  const outerRings = [];\n  const holes = [];\n  let i, ii;\n  for (i = 0, ii = rings.length; i < ii; ++i) {\n    flatRing.length = 0;\n    deflateCoordinates(flatRing, 0, rings[i], layout.length);\n    // is this ring an outer ring? is it clockwise?\n    const clockwise = linearRingIsClockwise(flatRing, 0,\n      flatRing.length, layout.length);\n    if (clockwise) {\n      outerRings.push([rings[i]]);\n    } else {\n      holes.push(rings[i]);\n    }\n  }\n  while (holes.length) {\n    const hole = holes.shift();\n    let matched = false;\n    // loop over all outer rings and see if they contain our hole.\n    for (i = outerRings.length - 1; i >= 0; i--) {\n      const outerRing = outerRings[i][0];\n      const containsHole = containsExtent(\n        new LinearRing(outerRing).getExtent(),\n        new LinearRing(hole).getExtent()\n      );\n      if (containsHole) {\n        // the hole is contained push it into our polygon\n        outerRings[i].push(hole);\n        matched = true;\n        break;\n      }\n    }\n    if (!matched) {\n      // no outer rings contain this hole turn it into and outer\n      // ring (reverse it)\n      outerRings.push([hole.reverse()]);\n    }\n  }\n  return outerRings;\n}\n\n\n/**\n * @param {EsriJSONGeometry} object Object.\n * @return {module:ol/geom/Geometry} Point.\n */\nfunction readPointGeometry(object) {\n  let point;\n  if (object.m !== undefined && object.z !== undefined) {\n    point = new Point([object.x, object.y, object.z, object.m],\n      GeometryLayout.XYZM);\n  } else if (object.z !== undefined) {\n    point = new Point([object.x, object.y, object.z],\n      GeometryLayout.XYZ);\n  } else if (object.m !== undefined) {\n    point = new Point([object.x, object.y, object.m],\n      GeometryLayout.XYM);\n  } else {\n    point = new Point([object.x, object.y]);\n  }\n  return point;\n}\n\n\n/**\n * @param {EsriJSONGeometry} object Object.\n * @return {module:ol/geom/Geometry} LineString.\n */\nfunction readLineStringGeometry(object) {\n  const layout = getGeometryLayout(object);\n  return new LineString(object.paths[0], layout);\n}\n\n\n/**\n * @param {EsriJSONGeometry} object Object.\n * @return {module:ol/geom/Geometry} MultiLineString.\n */\nfunction readMultiLineStringGeometry(object) {\n  const layout = getGeometryLayout(object);\n  return new MultiLineString(object.paths, layout);\n}\n\n\n/**\n * @param {EsriJSONGeometry} object Object.\n * @return {module:ol/geom/GeometryLayout} The geometry layout to use.\n */\nfunction getGeometryLayout(object) {\n  let layout = GeometryLayout.XY;\n  if (object.hasZ === true && object.hasM === true) {\n    layout = GeometryLayout.XYZM;\n  } else if (object.hasZ === true) {\n    layout = GeometryLayout.XYZ;\n  } else if (object.hasM === true) {\n    layout = GeometryLayout.XYM;\n  }\n  return layout;\n}\n\n\n/**\n * @param {EsriJSONGeometry} object Object.\n * @return {module:ol/geom/Geometry} MultiPoint.\n */\nfunction readMultiPointGeometry(object) {\n  const layout = getGeometryLayout(object);\n  return new MultiPoint(object.points, layout);\n}\n\n\n/**\n * @param {EsriJSONGeometry} object Object.\n * @return {module:ol/geom/Geometry} MultiPolygon.\n */\nfunction readMultiPolygonGeometry(object) {\n  const layout = getGeometryLayout(object);\n  return new MultiPolygon(\n    /** @type {Array.<Array.<Array.<Array.<number>>>>} */(object.rings),\n    layout);\n}\n\n\n/**\n * @param {EsriJSONGeometry} object Object.\n * @return {module:ol/geom/Geometry} Polygon.\n */\nfunction readPolygonGeometry(object) {\n  const layout = getGeometryLayout(object);\n  return new Polygon(object.rings, layout);\n}\n\n\n/**\n * @param {module:ol/geom/Geometry} geometry Geometry.\n * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n * @return {EsriJSONGeometry} EsriJSON geometry.\n */\nfunction writePointGeometry(geometry, opt_options) {\n  const coordinates = /** @type {module:ol/geom/Point} */ (geometry).getCoordinates();\n  let esriJSON;\n  const layout = /** @type {module:ol/geom/Point} */ (geometry).getLayout();\n  if (layout === GeometryLayout.XYZ) {\n    esriJSON = /** @type {EsriJSONPoint} */ ({\n      x: coordinates[0],\n      y: coordinates[1],\n      z: coordinates[2]\n    });\n  } else if (layout === GeometryLayout.XYM) {\n    esriJSON = /** @type {EsriJSONPoint} */ ({\n      x: coordinates[0],\n      y: coordinates[1],\n      m: coordinates[2]\n    });\n  } else if (layout === GeometryLayout.XYZM) {\n    esriJSON = /** @type {EsriJSONPoint} */ ({\n      x: coordinates[0],\n      y: coordinates[1],\n      z: coordinates[2],\n      m: coordinates[3]\n    });\n  } else if (layout === GeometryLayout.XY) {\n    esriJSON = /** @type {EsriJSONPoint} */ ({\n      x: coordinates[0],\n      y: coordinates[1]\n    });\n  } else {\n    assert(false, 34); // Invalid geometry layout\n  }\n  return /** @type {EsriJSONGeometry} */ (esriJSON);\n}\n\n\n/**\n * @param {module:ol/geom/SimpleGeometry} geometry Geometry.\n * @return {Object} Object with boolean hasZ and hasM keys.\n */\nfunction getHasZM(geometry) {\n  const layout = geometry.getLayout();\n  return {\n    hasZ: (layout === GeometryLayout.XYZ ||\n      layout === GeometryLayout.XYZM),\n    hasM: (layout === GeometryLayout.XYM ||\n      layout === GeometryLayout.XYZM)\n  };\n}\n\n\n/**\n * @param {module:ol/geom/Geometry} geometry Geometry.\n * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n * @return {EsriJSONPolyline} EsriJSON geometry.\n */\nfunction writeLineStringGeometry(geometry, opt_options) {\n  const hasZM = getHasZM(/** @type {module:ol/geom/LineString} */(geometry));\n  return (\n    /** @type {EsriJSONPolyline} */ {\n      hasZ: hasZM.hasZ,\n      hasM: hasZM.hasM,\n      paths: [\n        /** @type {module:ol/geom/LineString} */ (geometry).getCoordinates()\n      ]\n    }\n  );\n}\n\n\n/**\n * @param {module:ol/geom/Geometry} geometry Geometry.\n * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n * @return {EsriJSONPolygon} EsriJSON geometry.\n */\nfunction writePolygonGeometry(geometry, opt_options) {\n  // Esri geometries use the left-hand rule\n  const hasZM = getHasZM(/** @type {module:ol/geom/Polygon} */(geometry));\n  return (\n    /** @type {EsriJSONPolygon} */ {\n      hasZ: hasZM.hasZ,\n      hasM: hasZM.hasM,\n      rings: /** @type {module:ol/geom/Polygon} */ (geometry).getCoordinates(false)\n    }\n  );\n}\n\n\n/**\n * @param {module:ol/geom/Geometry} geometry Geometry.\n * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n * @return {EsriJSONPolyline} EsriJSON geometry.\n */\nfunction writeMultiLineStringGeometry(geometry, opt_options) {\n  const hasZM = getHasZM(/** @type {module:ol/geom/MultiLineString} */(geometry));\n  return (\n    /** @type {EsriJSONPolyline} */ {\n      hasZ: hasZM.hasZ,\n      hasM: hasZM.hasM,\n      paths: /** @type {module:ol/geom/MultiLineString} */ (geometry).getCoordinates()\n    }\n  );\n}\n\n\n/**\n * @param {module:ol/geom/Geometry} geometry Geometry.\n * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n * @return {EsriJSONMultipoint} EsriJSON geometry.\n */\nfunction writeMultiPointGeometry(geometry, opt_options) {\n  const hasZM = getHasZM(/** @type {module:ol/geom/MultiPoint} */(geometry));\n  return (\n    /** @type {EsriJSONMultipoint} */ {\n      hasZ: hasZM.hasZ,\n      hasM: hasZM.hasM,\n      points: /** @type {module:ol/geom/MultiPoint} */ (geometry).getCoordinates()\n    }\n  );\n}\n\n\n/**\n * @param {module:ol/geom/Geometry} geometry Geometry.\n * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n * @return {EsriJSONPolygon} EsriJSON geometry.\n */\nfunction writeMultiPolygonGeometry(geometry, opt_options) {\n  const hasZM = getHasZM(/** @type {module:ol/geom/MultiPolygon} */(geometry));\n  const coordinates = /** @type {module:ol/geom/MultiPolygon} */ (geometry).getCoordinates(false);\n  const output = [];\n  for (let i = 0; i < coordinates.length; i++) {\n    for (let x = coordinates[i].length - 1; x >= 0; x--) {\n      output.push(coordinates[i][x]);\n    }\n  }\n  return /** @type {EsriJSONPolygon} */ ({\n    hasZ: hasZM.hasZ,\n    hasM: hasZM.hasM,\n    rings: output\n  });\n}\n\n\n/**\n * @param {module:ol/geom/Geometry} geometry Geometry.\n * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n * @return {EsriJSONGeometry} EsriJSON geometry.\n */\nfunction writeGeometry(geometry, opt_options) {\n  const geometryWriter = GEOMETRY_WRITERS[geometry.getType()];\n  return geometryWriter(/** @type {module:ol/geom/Geometry} */(\n    transformWithOptions(geometry, true, opt_options)), opt_options);\n}\n\n\nexport default EsriJSON;\n","/**\n * @module ol/xml\n */\nimport {extend} from './array.js';\n\n\n/**\n * When using {@link module:ol/xml~makeChildAppender} or\n * {@link module:ol/xml~makeSimpleNodeFactory}, the top `objectStack` item needs\n * to have this structure.\n * @typedef {Object} NodeStackItem\n * @property {Node} node\n */\n\n\n/**\n * @typedef {function(Node, Array.<*>)} Parser\n */\n\n\n/**\n * @typedef {function(Node, *, Array.<*>)} Serializer\n */\n\n\n/**\n * This document should be used when creating nodes for XML serializations. This\n * document is also used by {@link module:ol/xml~createElementNS}\n * @const\n * @type {Document}\n */\nexport const DOCUMENT = document.implementation.createDocument('', '', null);\n\n\n/**\n * @type {string}\n */\nexport const XML_SCHEMA_INSTANCE_URI = 'http://www.w3.org/2001/XMLSchema-instance';\n\n\n/**\n * @param {string} namespaceURI Namespace URI.\n * @param {string} qualifiedName Qualified name.\n * @return {Node} Node.\n */\nexport function createElementNS(namespaceURI, qualifiedName) {\n  return DOCUMENT.createElementNS(namespaceURI, qualifiedName);\n}\n\n\n/**\n * Recursively grab all text content of child nodes into a single string.\n * @param {Node} node Node.\n * @param {boolean} normalizeWhitespace Normalize whitespace: remove all line\n * breaks.\n * @return {string} All text content.\n * @api\n */\nexport function getAllTextContent(node, normalizeWhitespace) {\n  return getAllTextContent_(node, normalizeWhitespace, []).join('');\n}\n\n\n/**\n * Recursively grab all text content of child nodes into a single string.\n * @param {Node} node Node.\n * @param {boolean} normalizeWhitespace Normalize whitespace: remove all line\n * breaks.\n * @param {Array.<string>} accumulator Accumulator.\n * @private\n * @return {Array.<string>} Accumulator.\n */\nexport function getAllTextContent_(node, normalizeWhitespace, accumulator) {\n  if (node.nodeType == Node.CDATA_SECTION_NODE ||\n      node.nodeType == Node.TEXT_NODE) {\n    if (normalizeWhitespace) {\n      accumulator.push(String(node.nodeValue).replace(/(\\r\\n|\\r|\\n)/g, ''));\n    } else {\n      accumulator.push(node.nodeValue);\n    }\n  } else {\n    let n;\n    for (n = node.firstChild; n; n = n.nextSibling) {\n      getAllTextContent_(n, normalizeWhitespace, accumulator);\n    }\n  }\n  return accumulator;\n}\n\n\n/**\n * @param {?} value Value.\n * @return {boolean} Is document.\n */\nexport function isDocument(value) {\n  return value instanceof Document;\n}\n\n\n/**\n * @param {?} value Value.\n * @return {boolean} Is node.\n */\nexport function isNode(value) {\n  return value instanceof Node;\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {?string} namespaceURI Namespace URI.\n * @param {string} name Attribute name.\n * @return {string} Value\n */\nexport function getAttributeNS(node, namespaceURI, name) {\n  return node.getAttributeNS(namespaceURI, name) || '';\n}\n\n\n/**\n * Parse an XML string to an XML Document.\n * @param {string} xml XML.\n * @return {Document} Document.\n * @api\n */\nexport function parse(xml) {\n  return new DOMParser().parseFromString(xml, 'application/xml');\n}\n\n\n/**\n * Make an array extender function for extending the array at the top of the\n * object stack.\n * @param {function(this: T, Node, Array.<*>): (Array.<*>|undefined)}\n *     valueReader Value reader.\n * @param {T=} opt_this The object to use as `this` in `valueReader`.\n * @return {module:ol/xml~Parser} Parser.\n * @template T\n */\nexport function makeArrayExtender(valueReader, opt_this) {\n  return (\n    /**\n     * @param {Node} node Node.\n     * @param {Array.<*>} objectStack Object stack.\n     */\n    function(node, objectStack) {\n      const value = valueReader.call(opt_this !== undefined ? opt_this : this, node, objectStack);\n      if (value !== undefined) {\n        const array = /** @type {Array.<*>} */ (objectStack[objectStack.length - 1]);\n        extend(array, value);\n      }\n    }\n  );\n}\n\n\n/**\n * Make an array pusher function for pushing to the array at the top of the\n * object stack.\n * @param {function(this: T, Node, Array.<*>): *} valueReader Value reader.\n * @param {T=} opt_this The object to use as `this` in `valueReader`.\n * @return {module:ol/xml~Parser} Parser.\n * @template T\n */\nexport function makeArrayPusher(valueReader, opt_this) {\n  return (\n    /**\n     * @param {Node} node Node.\n     * @param {Array.<*>} objectStack Object stack.\n     */\n    function(node, objectStack) {\n      const value = valueReader.call(opt_this !== undefined ? opt_this : this, node, objectStack);\n      if (value !== undefined) {\n        const array = /** @type {Array.<*>} */ (objectStack[objectStack.length - 1]);\n        array.push(value);\n      }\n    });\n}\n\n\n/**\n * Make an object stack replacer function for replacing the object at the\n * top of the stack.\n * @param {function(this: T, Node, Array.<*>): *} valueReader Value reader.\n * @param {T=} opt_this The object to use as `this` in `valueReader`.\n * @return {module:ol/xml~Parser} Parser.\n * @template T\n */\nexport function makeReplacer(valueReader, opt_this) {\n  return (\n    /**\n     * @param {Node} node Node.\n     * @param {Array.<*>} objectStack Object stack.\n     */\n    function(node, objectStack) {\n      const value = valueReader.call(opt_this !== undefined ? opt_this : this, node, objectStack);\n      if (value !== undefined) {\n        objectStack[objectStack.length - 1] = value;\n      }\n    });\n}\n\n\n/**\n * Make an object property pusher function for adding a property to the\n * object at the top of the stack.\n * @param {function(this: T, Node, Array.<*>): *} valueReader Value reader.\n * @param {string=} opt_property Property.\n * @param {T=} opt_this The object to use as `this` in `valueReader`.\n * @return {module:ol/xml~Parser} Parser.\n * @template T\n */\nexport function makeObjectPropertyPusher(valueReader, opt_property, opt_this) {\n  return (\n    /**\n     * @param {Node} node Node.\n     * @param {Array.<*>} objectStack Object stack.\n     */\n    function(node, objectStack) {\n      const value = valueReader.call(opt_this !== undefined ? opt_this : this, node, objectStack);\n      if (value !== undefined) {\n        const object = /** @type {!Object} */ (objectStack[objectStack.length - 1]);\n        const property = opt_property !== undefined ? opt_property : node.localName;\n        let array;\n        if (property in object) {\n          array = object[property];\n        } else {\n          array = object[property] = [];\n        }\n        array.push(value);\n      }\n    });\n}\n\n\n/**\n * Make an object property setter function.\n * @param {function(this: T, Node, Array.<*>): *} valueReader Value reader.\n * @param {string=} opt_property Property.\n * @param {T=} opt_this The object to use as `this` in `valueReader`.\n * @return {module:ol/xml~Parser} Parser.\n * @template T\n */\nexport function makeObjectPropertySetter(valueReader, opt_property, opt_this) {\n  return (\n    /**\n     * @param {Node} node Node.\n     * @param {Array.<*>} objectStack Object stack.\n     */\n    function(node, objectStack) {\n      const value = valueReader.call(opt_this !== undefined ? opt_this : this, node, objectStack);\n      if (value !== undefined) {\n        const object = /** @type {!Object} */ (objectStack[objectStack.length - 1]);\n        const property = opt_property !== undefined ? opt_property : node.localName;\n        object[property] = value;\n      }\n    });\n}\n\n\n/**\n * Create a serializer that appends nodes written by its `nodeWriter` to its\n * designated parent. The parent is the `node` of the\n * {@link module:ol/xml~NodeStackItem} at the top of the `objectStack`.\n * @param {function(this: T, Node, V, Array.<*>)}\n *     nodeWriter Node writer.\n * @param {T=} opt_this The object to use as `this` in `nodeWriter`.\n * @return {module:ol/xml~Serializer} Serializer.\n * @template T, V\n */\nexport function makeChildAppender(nodeWriter, opt_this) {\n  return function(node, value, objectStack) {\n    nodeWriter.call(opt_this !== undefined ? opt_this : this, node, value, objectStack);\n    const parent = /** @type {module:ol/xml~NodeStackItem} */ (objectStack[objectStack.length - 1]);\n    const parentNode = parent.node;\n    parentNode.appendChild(node);\n  };\n}\n\n\n/**\n * Create a serializer that calls the provided `nodeWriter` from\n * {@link module:ol/xml~serialize}. This can be used by the parent writer to have the\n * 'nodeWriter' called with an array of values when the `nodeWriter` was\n * designed to serialize a single item. An example would be a LineString\n * geometry writer, which could be reused for writing MultiLineString\n * geometries.\n * @param {function(this: T, Node, V, Array.<*>)}\n *     nodeWriter Node writer.\n * @param {T=} opt_this The object to use as `this` in `nodeWriter`.\n * @return {module:ol/xml~Serializer} Serializer.\n * @template T, V\n */\nexport function makeArraySerializer(nodeWriter, opt_this) {\n  let serializersNS, nodeFactory;\n  return function(node, value, objectStack) {\n    if (serializersNS === undefined) {\n      serializersNS = {};\n      const serializers = {};\n      serializers[node.localName] = nodeWriter;\n      serializersNS[node.namespaceURI] = serializers;\n      nodeFactory = makeSimpleNodeFactory(node.localName);\n    }\n    serialize(serializersNS, nodeFactory, value, objectStack);\n  };\n}\n\n\n/**\n * Create a node factory which can use the `opt_keys` passed to\n * {@link module:ol/xml~serialize} or {@link module:ol/xml~pushSerializeAndPop} as node names,\n * or a fixed node name. The namespace of the created nodes can either be fixed,\n * or the parent namespace will be used.\n * @param {string=} opt_nodeName Fixed node name which will be used for all\n *     created nodes. If not provided, the 3rd argument to the resulting node\n *     factory needs to be provided and will be the nodeName.\n * @param {string=} opt_namespaceURI Fixed namespace URI which will be used for\n *     all created nodes. If not provided, the namespace of the parent node will\n *     be used.\n * @return {function(*, Array.<*>, string=): (Node|undefined)} Node factory.\n */\nexport function makeSimpleNodeFactory(opt_nodeName, opt_namespaceURI) {\n  const fixedNodeName = opt_nodeName;\n  return (\n    /**\n     * @param {*} value Value.\n     * @param {Array.<*>} objectStack Object stack.\n     * @param {string=} opt_nodeName Node name.\n     * @return {Node} Node.\n     */\n    function(value, objectStack, opt_nodeName) {\n      const context = /** @type {module:ol/xml~NodeStackItem} */ (objectStack[objectStack.length - 1]);\n      const node = context.node;\n      let nodeName = fixedNodeName;\n      if (nodeName === undefined) {\n        nodeName = opt_nodeName;\n      }\n\n      const namespaceURI = opt_namespaceURI !== undefined ? opt_namespaceURI : node.namespaceURI;\n      return createElementNS(namespaceURI, /** @type {string} */ (nodeName));\n    }\n  );\n}\n\n\n/**\n * A node factory that creates a node using the parent's `namespaceURI` and the\n * `nodeName` passed by {@link module:ol/xml~serialize} or\n * {@link module:ol/xml~pushSerializeAndPop} to the node factory.\n * @const\n * @type {function(*, Array.<*>, string=): (Node|undefined)}\n */\nexport const OBJECT_PROPERTY_NODE_FACTORY = makeSimpleNodeFactory();\n\n\n/**\n * Create an array of `values` to be used with {@link module:ol/xml~serialize} or\n * {@link module:ol/xml~pushSerializeAndPop}, where `orderedKeys` has to be provided as\n * `opt_key` argument.\n * @param {Object.<string, V>} object Key-value pairs for the sequence. Keys can\n *     be a subset of the `orderedKeys`.\n * @param {Array.<string>} orderedKeys Keys in the order of the sequence.\n * @return {Array.<V>} Values in the order of the sequence. The resulting array\n *     has the same length as the `orderedKeys` array. Values that are not\n *     present in `object` will be `undefined` in the resulting array.\n * @template V\n */\nexport function makeSequence(object, orderedKeys) {\n  const length = orderedKeys.length;\n  const sequence = new Array(length);\n  for (let i = 0; i < length; ++i) {\n    sequence[i] = object[orderedKeys[i]];\n  }\n  return sequence;\n}\n\n\n/**\n * Create a namespaced structure, using the same values for each namespace.\n * This can be used as a starting point for versioned parsers, when only a few\n * values are version specific.\n * @param {Array.<string>} namespaceURIs Namespace URIs.\n * @param {T} structure Structure.\n * @param {Object.<string, T>=} opt_structureNS Namespaced structure to add to.\n * @return {Object.<string, T>} Namespaced structure.\n * @template T\n */\nexport function makeStructureNS(namespaceURIs, structure, opt_structureNS) {\n  /**\n   * @type {Object.<string, T>}\n   */\n  const structureNS = opt_structureNS !== undefined ? opt_structureNS : {};\n  let i, ii;\n  for (i = 0, ii = namespaceURIs.length; i < ii; ++i) {\n    structureNS[namespaceURIs[i]] = structure;\n  }\n  return structureNS;\n}\n\n\n/**\n * Parse a node using the parsers and object stack.\n * @param {Object.<string, Object.<string, module:ol/xml~Parser>>} parsersNS\n *     Parsers by namespace.\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @param {*=} opt_this The object to use as `this`.\n */\nexport function parseNode(parsersNS, node, objectStack, opt_this) {\n  let n;\n  for (n = node.firstElementChild; n; n = n.nextElementSibling) {\n    const parsers = parsersNS[n.namespaceURI];\n    if (parsers !== undefined) {\n      const parser = parsers[n.localName];\n      if (parser !== undefined) {\n        parser.call(opt_this, n, objectStack);\n      }\n    }\n  }\n}\n\n\n/**\n * Push an object on top of the stack, parse and return the popped object.\n * @param {T} object Object.\n * @param {Object.<string, Object.<string, module:ol/xml~Parser>>} parsersNS\n *     Parsers by namespace.\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @param {*=} opt_this The object to use as `this`.\n * @return {T} Object.\n * @template T\n */\nexport function pushParseAndPop(object, parsersNS, node, objectStack, opt_this) {\n  objectStack.push(object);\n  parseNode(parsersNS, node, objectStack, opt_this);\n  return /** @type {T} */ (objectStack.pop());\n}\n\n\n/**\n * Walk through an array of `values` and call a serializer for each value.\n * @param {Object.<string, Object.<string, module:ol/xml~Serializer>>} serializersNS\n *     Namespaced serializers.\n * @param {function(this: T, *, Array.<*>, (string|undefined)): (Node|undefined)} nodeFactory\n *     Node factory. The `nodeFactory` creates the node whose namespace and name\n *     will be used to choose a node writer from `serializersNS`. This\n *     separation allows us to decide what kind of node to create, depending on\n *     the value we want to serialize. An example for this would be different\n *     geometry writers based on the geometry type.\n * @param {Array.<*>} values Values to serialize. An example would be an array\n *     of {@link module:ol/Feature~Feature} instances.\n * @param {Array.<*>} objectStack Node stack.\n * @param {Array.<string>=} opt_keys Keys of the `values`. Will be passed to the\n *     `nodeFactory`. This is used for serializing object literals where the\n *     node name relates to the property key. The array length of `opt_keys` has\n *     to match the length of `values`. For serializing a sequence, `opt_keys`\n *     determines the order of the sequence.\n * @param {T=} opt_this The object to use as `this` for the node factory and\n *     serializers.\n * @template T\n */\nexport function serialize(\n  serializersNS, nodeFactory, values, objectStack, opt_keys, opt_this) {\n  const length = (opt_keys !== undefined ? opt_keys : values).length;\n  let value, node;\n  for (let i = 0; i < length; ++i) {\n    value = values[i];\n    if (value !== undefined) {\n      node = nodeFactory.call(opt_this !== undefined ? opt_this : this, value, objectStack,\n        opt_keys !== undefined ? opt_keys[i] : undefined);\n      if (node !== undefined) {\n        serializersNS[node.namespaceURI][node.localName]\n          .call(opt_this, node, value, objectStack);\n      }\n    }\n  }\n}\n\n\n/**\n * @param {O} object Object.\n * @param {Object.<string, Object.<string, module:ol/xml~Serializer>>} serializersNS\n *     Namespaced serializers.\n * @param {function(this: T, *, Array.<*>, (string|undefined)): (Node|undefined)} nodeFactory\n *     Node factory. The `nodeFactory` creates the node whose namespace and name\n *     will be used to choose a node writer from `serializersNS`. This\n *     separation allows us to decide what kind of node to create, depending on\n *     the value we want to serialize. An example for this would be different\n *     geometry writers based on the geometry type.\n * @param {Array.<*>} values Values to serialize. An example would be an array\n *     of {@link module:ol/Feature~Feature} instances.\n * @param {Array.<*>} objectStack Node stack.\n * @param {Array.<string>=} opt_keys Keys of the `values`. Will be passed to the\n *     `nodeFactory`. This is used for serializing object literals where the\n *     node name relates to the property key. The array length of `opt_keys` has\n *     to match the length of `values`. For serializing a sequence, `opt_keys`\n *     determines the order of the sequence.\n * @param {T=} opt_this The object to use as `this` for the node factory and\n *     serializers.\n * @return {O|undefined} Object.\n * @template O, T\n */\nexport function pushSerializeAndPop(object, serializersNS, nodeFactory, values, objectStack, opt_keys, opt_this) {\n  objectStack.push(object);\n  serialize(serializersNS, nodeFactory, values, objectStack, opt_keys, opt_this);\n  return /** @type {O|undefined} */ (objectStack.pop());\n}\n","/**\n * @module ol/format/XMLFeature\n */\nimport {extend} from '../array.js';\nimport FeatureFormat from '../format/Feature.js';\nimport FormatType from '../format/FormatType.js';\nimport {isDocument, isNode, parse} from '../xml.js';\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Base class for XML feature formats.\n *\n * @abstract\n */\nclass XMLFeature extends FeatureFormat {\n  constructor() {\n    super();\n\n    /**\n     * @type {XMLSerializer}\n     * @private\n     */\n    this.xmlSerializer_ = new XMLSerializer();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getType() {\n    return FormatType.XML;\n  }\n\n  /**\n   * Read a single feature.\n   *\n   * @param {Document|Node|Object|string} source Source.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n   * @return {module:ol/Feature} Feature.\n   * @api\n   */\n  readFeature(source, opt_options) {\n    if (isDocument(source)) {\n      return this.readFeatureFromDocument(/** @type {Document} */ (source), opt_options);\n    } else if (isNode(source)) {\n      return this.readFeatureFromNode(/** @type {Node} */ (source), opt_options);\n    } else if (typeof source === 'string') {\n      const doc = parse(source);\n      return this.readFeatureFromDocument(doc, opt_options);\n    } else {\n      return null;\n    }\n  }\n\n  /**\n   * @param {Document} doc Document.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Options.\n   * @return {module:ol/Feature} Feature.\n   */\n  readFeatureFromDocument(doc, opt_options) {\n    const features = this.readFeaturesFromDocument(doc, opt_options);\n    if (features.length > 0) {\n      return features[0];\n    } else {\n      return null;\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Options.\n   * @return {module:ol/Feature} Feature.\n   */\n  readFeatureFromNode(node, opt_options) {\n    return null; // not implemented\n  }\n\n  /**\n   * Read all features from a feature collection.\n   *\n   * @function\n   * @param {Document|Node|Object|string} source Source.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Options.\n   * @return {Array.<module:ol/Feature>} Features.\n   * @api\n   */\n  readFeatures(source, opt_options) {\n    if (isDocument(source)) {\n      return this.readFeaturesFromDocument(\n        /** @type {Document} */ (source), opt_options);\n    } else if (isNode(source)) {\n      return this.readFeaturesFromNode(/** @type {Node} */ (source), opt_options);\n    } else if (typeof source === 'string') {\n      const doc = parse(source);\n      return this.readFeaturesFromDocument(doc, opt_options);\n    } else {\n      return [];\n    }\n  }\n\n  /**\n   * @param {Document} doc Document.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Options.\n   * @protected\n   * @return {Array.<module:ol/Feature>} Features.\n   */\n  readFeaturesFromDocument(doc, opt_options) {\n    /** @type {Array.<module:ol/Feature>} */\n    const features = [];\n    for (let n = doc.firstChild; n; n = n.nextSibling) {\n      if (n.nodeType == Node.ELEMENT_NODE) {\n        extend(features, this.readFeaturesFromNode(n, opt_options));\n      }\n    }\n    return features;\n  }\n\n  /**\n   * @abstract\n   * @param {Node} node Node.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Options.\n   * @protected\n   * @return {Array.<module:ol/Feature>} Features.\n   */\n  readFeaturesFromNode(node, opt_options) {}\n\n  /**\n   * @inheritDoc\n   */\n  readGeometry(source, opt_options) {\n    if (isDocument(source)) {\n      return this.readGeometryFromDocument(\n        /** @type {Document} */ (source), opt_options);\n    } else if (isNode(source)) {\n      return this.readGeometryFromNode(/** @type {Node} */ (source), opt_options);\n    } else if (typeof source === 'string') {\n      const doc = parse(source);\n      return this.readGeometryFromDocument(doc, opt_options);\n    } else {\n      return null;\n    }\n  }\n\n  /**\n   * @param {Document} doc Document.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Options.\n   * @protected\n   * @return {module:ol/geom/Geometry} Geometry.\n   */\n  readGeometryFromDocument(doc, opt_options) {\n    return null; // not implemented\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Options.\n   * @protected\n   * @return {module:ol/geom/Geometry} Geometry.\n   */\n  readGeometryFromNode(node, opt_options) {\n    return null; // not implemented\n  }\n\n  /**\n   * Read the projection from the source.\n   *\n   * @param {Document|Node|Object|string} source Source.\n   * @return {module:ol/proj/Projection} Projection.\n   * @api\n   */\n  readProjection(source) {\n    if (isDocument(source)) {\n      return this.readProjectionFromDocument(/** @type {Document} */ (source));\n    } else if (isNode(source)) {\n      return this.readProjectionFromNode(/** @type {Node} */ (source));\n    } else if (typeof source === 'string') {\n      const doc = parse(source);\n      return this.readProjectionFromDocument(doc);\n    } else {\n      return null;\n    }\n  }\n\n  /**\n   * @param {Document} doc Document.\n   * @protected\n   * @return {module:ol/proj/Projection} Projection.\n   */\n  readProjectionFromDocument(doc) {\n    return this.dataProjection;\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @protected\n   * @return {module:ol/proj/Projection} Projection.\n   */\n  readProjectionFromNode(node) {\n    return this.dataProjection;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  writeFeature(feature, opt_options) {\n    const node = this.writeFeatureNode(feature, opt_options);\n    return this.xmlSerializer_.serializeToString(node);\n  }\n\n  /**\n   * @param {module:ol/Feature} feature Feature.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Options.\n   * @protected\n   * @return {Node} Node.\n   */\n  writeFeatureNode(feature, opt_options) {\n    return null; // not implemented\n  }\n\n  /**\n   * Encode an array of features as string.\n   *\n   * @param {Array.<module:ol/Feature>} features Features.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @return {string} Result.\n   * @api\n   */\n  writeFeatures(features, opt_options) {\n    const node = this.writeFeaturesNode(features, opt_options);\n    return this.xmlSerializer_.serializeToString(node);\n  }\n\n  /**\n   * @param {Array.<module:ol/Feature>} features Features.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Options.\n   * @return {Node} Node.\n   */\n  writeFeaturesNode(features, opt_options) {\n    return null; // not implemented\n  }\n\n  /**\n   * @inheritDoc\n   */\n  writeGeometry(geometry, opt_options) {\n    const node = this.writeGeometryNode(geometry, opt_options);\n    return this.xmlSerializer_.serializeToString(node);\n  }\n\n  /**\n   * @param {module:ol/geom/Geometry} geometry Geometry.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Options.\n   * @return {Node} Node.\n   */\n  writeGeometryNode(geometry, opt_options) {\n    return null; // not implemented\n  }\n}\n\n\nexport default XMLFeature;\n","/**\n * @module ol/format/GMLBase\n */\n// FIXME Envelopes should not be treated as geometries! readEnvelope_ is part\n// of GEOMETRY_PARSERS_ and methods using GEOMETRY_PARSERS_ do not expect\n// envelopes/extents, only geometries!\nimport {extend} from '../array.js';\nimport Feature from '../Feature.js';\nimport {transformWithOptions} from '../format/Feature.js';\nimport XMLFeature from '../format/XMLFeature.js';\nimport GeometryLayout from '../geom/GeometryLayout.js';\nimport LineString from '../geom/LineString.js';\nimport LinearRing from '../geom/LinearRing.js';\nimport MultiLineString from '../geom/MultiLineString.js';\nimport MultiPoint from '../geom/MultiPoint.js';\nimport MultiPolygon from '../geom/MultiPolygon.js';\nimport Point from '../geom/Point.js';\nimport Polygon from '../geom/Polygon.js';\nimport {assign} from '../obj.js';\nimport {get as getProjection} from '../proj.js';\nimport {getAllTextContent, getAttributeNS, makeArrayPusher, makeReplacer, parseNode, pushParseAndPop} from '../xml.js';\n\n\n/**\n * @const\n * @type {string}\n */\nexport const GMLNS = 'http://www.opengis.net/gml';\n\n\n/**\n * A regular expression that matches if a string only contains whitespace\n * characters. It will e.g. match `''`, `' '`, `'\\n'` etc. The non-breaking\n * space (0xa0) is explicitly included as IE doesn't include it in its\n * definition of `\\s`.\n *\n * Information from `goog.string.isEmptyOrWhitespace`: https://github.com/google/closure-library/blob/e877b1e/closure/goog/string/string.js#L156-L160\n *\n * @const\n * @type {RegExp}\n */\nconst ONLY_WHITESPACE_RE = /^[\\s\\xa0]*$/;\n\n\n/**\n * @typedef {Object} Options\n * @property {Object.<string, string>|string} [featureNS] Feature\n * namespace. If not defined will be derived from GML. If multiple\n * feature types have been configured which come from different feature\n * namespaces, this will be an object with the keys being the prefixes used\n * in the entries of featureType array. The values of the object will be the\n * feature namespaces themselves. So for instance there might be a featureType\n * item `topp:states` in the `featureType` array and then there will be a key\n * `topp` in the featureNS object with value `http://www.openplans.org/topp`.\n * @property {Array.<string>|string} [featureType] Feature type(s) to parse.\n * If multiple feature types need to be configured\n * which come from different feature namespaces, `featureNS` will be an object\n * with the keys being the prefixes used in the entries of featureType array.\n * The values of the object will be the feature namespaces themselves.\n * So for instance there might be a featureType item `topp:states` and then\n * there will be a key named `topp` in the featureNS object with value\n * `http://www.openplans.org/topp`.\n * @property {string} srsName srsName to use when writing geometries.\n * @property {boolean} [surface=false] Write gml:Surface instead of gml:Polygon\n * elements. This also affects the elements in multi-part geometries.\n * @property {boolean} [curve=false] Write gml:Curve instead of gml:LineString\n * elements. This also affects the elements in multi-part geometries.\n * @property {boolean} [multiCurve=true] Write gml:MultiCurve instead of gml:MultiLineString.\n * Since the latter is deprecated in GML 3.\n * @property {boolean} [multiSurface=true] Write gml:multiSurface instead of\n * gml:MultiPolygon. Since the latter is deprecated in GML 3.\n * @property {string} [schemaLocation] Optional schemaLocation to use when\n * writing out the GML, this will override the default provided.\n */\n\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Feature base format for reading and writing data in the GML format.\n * This class cannot be instantiated, it contains only base content that\n * is shared with versioned format classes GML2 and GML3.\n *\n * @abstract\n */\nclass GMLBase extends XMLFeature {\n\n  /**\n   * @param {module:ol/format/GMLBase~Options=} opt_options Optional configuration object.\n   */\n  constructor(opt_options) {\n    super();\n\n    const options = /** @type {module:ol/format/GMLBase~Options} */ (opt_options ? opt_options : {});\n\n    /**\n     * @protected\n     * @type {Array.<string>|string|undefined}\n     */\n    this.featureType = options.featureType;\n\n    /**\n     * @protected\n     * @type {Object.<string, string>|string|undefined}\n     */\n    this.featureNS = options.featureNS;\n\n    /**\n     * @protected\n     * @type {string}\n     */\n    this.srsName = options.srsName;\n\n    /**\n     * @protected\n     * @type {string}\n     */\n    this.schemaLocation = '';\n\n    /**\n     * @type {Object.<string, Object.<string, Object>>}\n     */\n    this.FEATURE_COLLECTION_PARSERS = {};\n    this.FEATURE_COLLECTION_PARSERS[GMLNS] = {\n      'featureMember': makeReplacer(this.readFeaturesInternal),\n      'featureMembers': makeReplacer(this.readFeaturesInternal)\n    };\n\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @return {Array.<module:ol/Feature> | undefined} Features.\n   */\n  readFeaturesInternal(node, objectStack) {\n    const localName = node.localName;\n    let features = null;\n    if (localName == 'FeatureCollection') {\n      if (node.namespaceURI === 'http://www.opengis.net/wfs') {\n        features = pushParseAndPop([],\n          this.FEATURE_COLLECTION_PARSERS, node,\n          objectStack, this);\n      } else {\n        features = pushParseAndPop(null,\n          this.FEATURE_COLLECTION_PARSERS, node,\n          objectStack, this);\n      }\n    } else if (localName == 'featureMembers' || localName == 'featureMember') {\n      const context = objectStack[0];\n      let featureType = context['featureType'];\n      let featureNS = context['featureNS'];\n      const prefix = 'p';\n      const defaultPrefix = 'p0';\n      if (!featureType && node.childNodes) {\n        featureType = [], featureNS = {};\n        for (let i = 0, ii = node.childNodes.length; i < ii; ++i) {\n          const child = node.childNodes[i];\n          if (child.nodeType === 1) {\n            const ft = child.nodeName.split(':').pop();\n            if (featureType.indexOf(ft) === -1) {\n              let key = '';\n              let count = 0;\n              const uri = child.namespaceURI;\n              for (const candidate in featureNS) {\n                if (featureNS[candidate] === uri) {\n                  key = candidate;\n                  break;\n                }\n                ++count;\n              }\n              if (!key) {\n                key = prefix + count;\n                featureNS[key] = uri;\n              }\n              featureType.push(key + ':' + ft);\n            }\n          }\n        }\n        if (localName != 'featureMember') {\n          // recheck featureType for each featureMember\n          context['featureType'] = featureType;\n          context['featureNS'] = featureNS;\n        }\n      }\n      if (typeof featureNS === 'string') {\n        const ns = featureNS;\n        featureNS = {};\n        featureNS[defaultPrefix] = ns;\n      }\n      const parsersNS = {};\n      const featureTypes = Array.isArray(featureType) ? featureType : [featureType];\n      for (const p in featureNS) {\n        const parsers = {};\n        for (let i = 0, ii = featureTypes.length; i < ii; ++i) {\n          const featurePrefix = featureTypes[i].indexOf(':') === -1 ?\n            defaultPrefix : featureTypes[i].split(':')[0];\n          if (featurePrefix === p) {\n            parsers[featureTypes[i].split(':').pop()] =\n                (localName == 'featureMembers') ?\n                  makeArrayPusher(this.readFeatureElement, this) :\n                  makeReplacer(this.readFeatureElement, this);\n          }\n        }\n        parsersNS[featureNS[p]] = parsers;\n      }\n      if (localName == 'featureMember') {\n        features = pushParseAndPop(undefined, parsersNS, node, objectStack);\n      } else {\n        features = pushParseAndPop([], parsersNS, node, objectStack);\n      }\n    }\n    if (features === null) {\n      features = [];\n    }\n    return features;\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @return {module:ol/geom/Geometry|undefined} Geometry.\n   */\n  readGeometryElement(node, objectStack) {\n    const context = /** @type {Object} */ (objectStack[0]);\n    context['srsName'] = node.firstElementChild.getAttribute('srsName');\n    context['srsDimension'] = node.firstElementChild.getAttribute('srsDimension');\n    /** @type {module:ol/geom/Geometry} */\n    const geometry = pushParseAndPop(null, this.GEOMETRY_PARSERS_, node, objectStack, this);\n    if (geometry) {\n      return (\n        /** @type {module:ol/geom/Geometry} */ (transformWithOptions(geometry, false, context))\n      );\n    } else {\n      return undefined;\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @return {module:ol/Feature} Feature.\n   */\n  readFeatureElement(node, objectStack) {\n    let n;\n    const fid = node.getAttribute('fid') || getAttributeNS(node, GMLNS, 'id');\n    const values = {};\n    let geometryName;\n    for (n = node.firstElementChild; n; n = n.nextElementSibling) {\n      const localName = n.localName;\n      // Assume attribute elements have one child node and that the child\n      // is a text or CDATA node (to be treated as text).\n      // Otherwise assume it is a geometry node.\n      if (n.childNodes.length === 0 ||\n          (n.childNodes.length === 1 &&\n          (n.firstChild.nodeType === 3 || n.firstChild.nodeType === 4))) {\n        let value = getAllTextContent(n, false);\n        if (ONLY_WHITESPACE_RE.test(value)) {\n          value = undefined;\n        }\n        values[localName] = value;\n      } else {\n        // boundedBy is an extent and must not be considered as a geometry\n        if (localName !== 'boundedBy') {\n          geometryName = localName;\n        }\n        values[localName] = this.readGeometryElement(n, objectStack);\n      }\n    }\n    const feature = new Feature(values);\n    if (geometryName) {\n      feature.setGeometryName(geometryName);\n    }\n    if (fid) {\n      feature.setId(fid);\n    }\n    return feature;\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @return {module:ol/geom/Point|undefined} Point.\n   */\n  readPoint(node, objectStack) {\n    const flatCoordinates = this.readFlatCoordinatesFromNode_(node, objectStack);\n    if (flatCoordinates) {\n      return new Point(flatCoordinates, GeometryLayout.XYZ);\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @return {module:ol/geom/MultiPoint|undefined} MultiPoint.\n   */\n  readMultiPoint(node, objectStack) {\n    /** @type {Array.<Array.<number>>} */\n    const coordinates = pushParseAndPop([],\n      this.MULTIPOINT_PARSERS_, node, objectStack, this);\n    if (coordinates) {\n      return new MultiPoint(coordinates);\n    } else {\n      return undefined;\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @return {module:ol/geom/MultiLineString|undefined} MultiLineString.\n   */\n  readMultiLineString(node, objectStack) {\n    /** @type {Array.<module:ol/geom/LineString>} */\n    const lineStrings = pushParseAndPop([],\n      this.MULTILINESTRING_PARSERS_, node, objectStack, this);\n    if (lineStrings) {\n      return new MultiLineString(lineStrings);\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @return {module:ol/geom/MultiPolygon|undefined} MultiPolygon.\n   */\n  readMultiPolygon(node, objectStack) {\n    /** @type {Array.<module:ol/geom/Polygon>} */\n    const polygons = pushParseAndPop([], this.MULTIPOLYGON_PARSERS_, node, objectStack, this);\n    if (polygons) {\n      return new MultiPolygon(polygons);\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   */\n  pointMemberParser_(node, objectStack) {\n    parseNode(this.POINTMEMBER_PARSERS_, node, objectStack, this);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   */\n  lineStringMemberParser_(node, objectStack) {\n    parseNode(this.LINESTRINGMEMBER_PARSERS_, node, objectStack, this);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   */\n  polygonMemberParser_(node, objectStack) {\n    parseNode(this.POLYGONMEMBER_PARSERS_, node, objectStack, this);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @return {module:ol/geom/LineString|undefined} LineString.\n   */\n  readLineString(node, objectStack) {\n    const flatCoordinates = this.readFlatCoordinatesFromNode_(node, objectStack);\n    if (flatCoordinates) {\n      const lineString = new LineString(flatCoordinates, GeometryLayout.XYZ);\n      return lineString;\n    } else {\n      return undefined;\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   * @return {Array.<number>|undefined} LinearRing flat coordinates.\n   */\n  readFlatLinearRing_(node, objectStack) {\n    const ring = pushParseAndPop(null,\n      this.GEOMETRY_FLAT_COORDINATES_PARSERS_, node,\n      objectStack, this);\n    if (ring) {\n      return ring;\n    } else {\n      return undefined;\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @return {module:ol/geom/LinearRing|undefined} LinearRing.\n   */\n  readLinearRing(node, objectStack) {\n    const flatCoordinates = this.readFlatCoordinatesFromNode_(node, objectStack);\n    if (flatCoordinates) {\n      return new LinearRing(flatCoordinates, GeometryLayout.XYZ);\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @return {module:ol/geom/Polygon|undefined} Polygon.\n   */\n  readPolygon(node, objectStack) {\n    /** @type {Array.<Array.<number>>} */\n    const flatLinearRings = pushParseAndPop([null],\n      this.FLAT_LINEAR_RINGS_PARSERS_, node, objectStack, this);\n    if (flatLinearRings && flatLinearRings[0]) {\n      const flatCoordinates = flatLinearRings[0];\n      const ends = [flatCoordinates.length];\n      let i, ii;\n      for (i = 1, ii = flatLinearRings.length; i < ii; ++i) {\n        extend(flatCoordinates, flatLinearRings[i]);\n        ends.push(flatCoordinates.length);\n      }\n      return new Polygon(flatCoordinates, GeometryLayout.XYZ, ends);\n    } else {\n      return undefined;\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   * @return {Array.<number>} Flat coordinates.\n   */\n  readFlatCoordinatesFromNode_(node, objectStack) {\n    return pushParseAndPop(null, this.GEOMETRY_FLAT_COORDINATES_PARSERS_, node, objectStack, this);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readGeometryFromNode(node, opt_options) {\n    const geometry = this.readGeometryElement(node,\n      [this.getReadOptions(node, opt_options ? opt_options : {})]);\n    return geometry ? geometry : null;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFeaturesFromNode(node, opt_options) {\n    const options = {\n      featureType: this.featureType,\n      featureNS: this.featureNS\n    };\n    if (opt_options) {\n      assign(options, this.getReadOptions(node, opt_options));\n    }\n    const features = this.readFeaturesInternal(node, [options]);\n    return features || [];\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readProjectionFromNode(node) {\n    return getProjection(this.srsName ? this.srsName : node.firstElementChild.getAttribute('srsName'));\n  }\n}\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGMLBase.prototype.MULTIPOINT_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'pointMember': makeArrayPusher(GMLBase.prototype.pointMemberParser_),\n    'pointMembers': makeArrayPusher(GMLBase.prototype.pointMemberParser_)\n  }\n};\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGMLBase.prototype.MULTILINESTRING_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'lineStringMember': makeArrayPusher(GMLBase.prototype.lineStringMemberParser_),\n    'lineStringMembers': makeArrayPusher(GMLBase.prototype.lineStringMemberParser_)\n  }\n};\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGMLBase.prototype.MULTIPOLYGON_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'polygonMember': makeArrayPusher(GMLBase.prototype.polygonMemberParser_),\n    'polygonMembers': makeArrayPusher(GMLBase.prototype.polygonMemberParser_)\n  }\n};\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGMLBase.prototype.POINTMEMBER_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'Point': makeArrayPusher(GMLBase.prototype.readFlatCoordinatesFromNode_)\n  }\n};\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGMLBase.prototype.LINESTRINGMEMBER_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'LineString': makeArrayPusher(GMLBase.prototype.readLineString)\n  }\n};\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGMLBase.prototype.POLYGONMEMBER_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'Polygon': makeArrayPusher(GMLBase.prototype.readPolygon)\n  }\n};\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @protected\n */\nGMLBase.prototype.RING_PARSERS = {\n  'http://www.opengis.net/gml': {\n    'LinearRing': makeReplacer(GMLBase.prototype.readFlatLinearRing_)\n  }\n};\n\nexport default GMLBase;\n","/**\n * @module ol/format/xsd\n */\nimport {getAllTextContent, DOCUMENT} from '../xml.js';\nimport {padNumber} from '../string.js';\n\n\n/**\n * @param {Node} node Node.\n * @return {boolean|undefined} Boolean.\n */\nexport function readBoolean(node) {\n  const s = getAllTextContent(node, false);\n  return readBooleanString(s);\n}\n\n\n/**\n * @param {string} string String.\n * @return {boolean|undefined} Boolean.\n */\nexport function readBooleanString(string) {\n  const m = /^\\s*(true|1)|(false|0)\\s*$/.exec(string);\n  if (m) {\n    return m[1] !== undefined || false;\n  } else {\n    return undefined;\n  }\n}\n\n\n/**\n * @param {Node} node Node.\n * @return {number|undefined} DateTime in seconds.\n */\nexport function readDateTime(node) {\n  const s = getAllTextContent(node, false);\n  const dateTime = Date.parse(s);\n  return isNaN(dateTime) ? undefined : dateTime / 1000;\n}\n\n\n/**\n * @param {Node} node Node.\n * @return {number|undefined} Decimal.\n */\nexport function readDecimal(node) {\n  const s = getAllTextContent(node, false);\n  return readDecimalString(s);\n}\n\n\n/**\n * @param {string} string String.\n * @return {number|undefined} Decimal.\n */\nexport function readDecimalString(string) {\n  // FIXME check spec\n  const m = /^\\s*([+\\-]?\\d*\\.?\\d+(?:e[+\\-]?\\d+)?)\\s*$/i.exec(string);\n  if (m) {\n    return parseFloat(m[1]);\n  } else {\n    return undefined;\n  }\n}\n\n\n/**\n * @param {Node} node Node.\n * @return {number|undefined} Non negative integer.\n */\nexport function readNonNegativeInteger(node) {\n  const s = getAllTextContent(node, false);\n  return readNonNegativeIntegerString(s);\n}\n\n\n/**\n * @param {string} string String.\n * @return {number|undefined} Non negative integer.\n */\nexport function readNonNegativeIntegerString(string) {\n  const m = /^\\s*(\\d+)\\s*$/.exec(string);\n  if (m) {\n    return parseInt(m[1], 10);\n  } else {\n    return undefined;\n  }\n}\n\n\n/**\n * @param {Node} node Node.\n * @return {string|undefined} String.\n */\nexport function readString(node) {\n  return getAllTextContent(node, false).trim();\n}\n\n\n/**\n * @param {Node} node Node to append a TextNode with the boolean to.\n * @param {boolean} bool Boolean.\n */\nexport function writeBooleanTextNode(node, bool) {\n  writeStringTextNode(node, (bool) ? '1' : '0');\n}\n\n\n/**\n * @param {Node} node Node to append a CDATA Section with the string to.\n * @param {string} string String.\n */\nexport function writeCDATASection(node, string) {\n  node.appendChild(DOCUMENT.createCDATASection(string));\n}\n\n\n/**\n * @param {Node} node Node to append a TextNode with the dateTime to.\n * @param {number} dateTime DateTime in seconds.\n */\nexport function writeDateTimeTextNode(node, dateTime) {\n  const date = new Date(dateTime * 1000);\n  const string = date.getUTCFullYear() + '-' +\n      padNumber(date.getUTCMonth() + 1, 2) + '-' +\n      padNumber(date.getUTCDate(), 2) + 'T' +\n      padNumber(date.getUTCHours(), 2) + ':' +\n      padNumber(date.getUTCMinutes(), 2) + ':' +\n      padNumber(date.getUTCSeconds(), 2) + 'Z';\n  node.appendChild(DOCUMENT.createTextNode(string));\n}\n\n\n/**\n * @param {Node} node Node to append a TextNode with the decimal to.\n * @param {number} decimal Decimal.\n */\nexport function writeDecimalTextNode(node, decimal) {\n  const string = decimal.toPrecision();\n  node.appendChild(DOCUMENT.createTextNode(string));\n}\n\n\n/**\n * @param {Node} node Node to append a TextNode with the decimal to.\n * @param {number} nonNegativeInteger Non negative integer.\n */\nexport function writeNonNegativeIntegerTextNode(node, nonNegativeInteger) {\n  const string = nonNegativeInteger.toString();\n  node.appendChild(DOCUMENT.createTextNode(string));\n}\n\n\n/**\n * @param {Node} node Node to append a TextNode with the string to.\n * @param {string} string String.\n */\nexport function writeStringTextNode(node, string) {\n  node.appendChild(DOCUMENT.createTextNode(string));\n}\n","/**\n * @module ol/format/GML3\n */\nimport {extend} from '../array.js';\nimport {createOrUpdate} from '../extent.js';\nimport {transformWithOptions} from '../format/Feature.js';\nimport GMLBase, {GMLNS} from '../format/GMLBase.js';\nimport {readNonNegativeIntegerString, writeStringTextNode} from '../format/xsd.js';\nimport Geometry from '../geom/Geometry.js';\nimport GeometryLayout from '../geom/GeometryLayout.js';\nimport LineString from '../geom/LineString.js';\nimport MultiLineString from '../geom/MultiLineString.js';\nimport MultiPolygon from '../geom/MultiPolygon.js';\nimport Polygon from '../geom/Polygon.js';\nimport {assign} from '../obj.js';\nimport {get as getProjection, transformExtent} from '../proj.js';\nimport {createElementNS, getAllTextContent, makeArrayPusher, makeChildAppender,\n  makeReplacer, makeSimpleNodeFactory, OBJECT_PROPERTY_NODE_FACTORY, parseNode,\n  pushParseAndPop, pushSerializeAndPop, XML_SCHEMA_INSTANCE_URI} from '../xml.js';\n\n\n/**\n * @const\n * @type {string}\n * @private\n */\nconst schemaLocation = GMLNS +\n    ' http://schemas.opengis.net/gml/3.1.1/profiles/gmlsfProfile/' +\n    '1.0.0/gmlsf.xsd';\n\n\n/**\n * @const\n * @type {Object.<string, string>}\n */\nconst MULTIGEOMETRY_TO_MEMBER_NODENAME = {\n  'MultiLineString': 'lineStringMember',\n  'MultiCurve': 'curveMember',\n  'MultiPolygon': 'polygonMember',\n  'MultiSurface': 'surfaceMember'\n};\n\n\n/**\n * @classdesc\n * Feature format for reading and writing data in the GML format\n * version 3.1.1.\n * Currently only supports GML 3.1.1 Simple Features profile.\n *\n * @api\n */\nclass GML3 extends GMLBase {\n\n  /**\n   * @param {module:ol/format/GMLBase~Options=} opt_options Optional configuration object.\n   */\n  constructor(opt_options) {\n    const options = /** @type {module:ol/format/GMLBase~Options} */\n        (opt_options ? opt_options : {});\n\n    super(options);\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.surface_ = options.surface !== undefined ? options.surface : false;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.curve_ = options.curve !== undefined ? options.curve : false;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.multiCurve_ = options.multiCurve !== undefined ?\n      options.multiCurve : true;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.multiSurface_ = options.multiSurface !== undefined ?\n      options.multiSurface : true;\n\n    /**\n     * @inheritDoc\n     */\n    this.schemaLocation = options.schemaLocation ?\n      options.schemaLocation : schemaLocation;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.hasZ = options.hasZ !== undefined ?\n      options.hasZ : false;\n\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   * @return {module:ol/geom/MultiLineString|undefined} MultiLineString.\n   */\n  readMultiCurve_(node, objectStack) {\n    /** @type {Array.<module:ol/geom/LineString>} */\n    const lineStrings = pushParseAndPop([],\n      this.MULTICURVE_PARSERS_, node, objectStack, this);\n    if (lineStrings) {\n      const multiLineString = new MultiLineString(lineStrings);\n      return multiLineString;\n    } else {\n      return undefined;\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   * @return {module:ol/geom/MultiPolygon|undefined} MultiPolygon.\n   */\n  readMultiSurface_(node, objectStack) {\n    /** @type {Array.<module:ol/geom/Polygon>} */\n    const polygons = pushParseAndPop([],\n      this.MULTISURFACE_PARSERS_, node, objectStack, this);\n    if (polygons) {\n      return new MultiPolygon(polygons);\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   */\n  curveMemberParser_(node, objectStack) {\n    parseNode(this.CURVEMEMBER_PARSERS_, node, objectStack, this);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   */\n  surfaceMemberParser_(node, objectStack) {\n    parseNode(this.SURFACEMEMBER_PARSERS_,\n      node, objectStack, this);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   * @return {Array.<(Array.<number>)>|undefined} flat coordinates.\n   */\n  readPatch_(node, objectStack) {\n    return pushParseAndPop([null],\n      this.PATCHES_PARSERS_, node, objectStack, this);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   * @return {Array.<number>|undefined} flat coordinates.\n   */\n  readSegment_(node, objectStack) {\n    return pushParseAndPop([null],\n      this.SEGMENTS_PARSERS_, node, objectStack, this);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   * @return {Array.<(Array.<number>)>|undefined} flat coordinates.\n   */\n  readPolygonPatch_(node, objectStack) {\n    return pushParseAndPop([null],\n      this.FLAT_LINEAR_RINGS_PARSERS_, node, objectStack, this);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   * @return {Array.<number>|undefined} flat coordinates.\n   */\n  readLineStringSegment_(node, objectStack) {\n    return pushParseAndPop([null],\n      this.GEOMETRY_FLAT_COORDINATES_PARSERS_,\n      node, objectStack, this);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   */\n  interiorParser_(node, objectStack) {\n    /** @type {Array.<number>|undefined} */\n    const flatLinearRing = pushParseAndPop(undefined,\n      this.RING_PARSERS, node, objectStack, this);\n    if (flatLinearRing) {\n      const flatLinearRings = /** @type {Array.<Array.<number>>} */\n          (objectStack[objectStack.length - 1]);\n      flatLinearRings.push(flatLinearRing);\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   */\n  exteriorParser_(node, objectStack) {\n    /** @type {Array.<number>|undefined} */\n    const flatLinearRing = pushParseAndPop(undefined,\n      this.RING_PARSERS, node, objectStack, this);\n    if (flatLinearRing) {\n      const flatLinearRings = /** @type {Array.<Array.<number>>} */\n          (objectStack[objectStack.length - 1]);\n      flatLinearRings[0] = flatLinearRing;\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   * @return {module:ol/geom/Polygon|undefined} Polygon.\n   */\n  readSurface_(node, objectStack) {\n    /** @type {Array.<Array.<number>>} */\n    const flatLinearRings = pushParseAndPop([null],\n      this.SURFACE_PARSERS_, node, objectStack, this);\n    if (flatLinearRings && flatLinearRings[0]) {\n      const flatCoordinates = flatLinearRings[0];\n      const ends = [flatCoordinates.length];\n      let i, ii;\n      for (i = 1, ii = flatLinearRings.length; i < ii; ++i) {\n        extend(flatCoordinates, flatLinearRings[i]);\n        ends.push(flatCoordinates.length);\n      }\n      return new Polygon(flatCoordinates, GeometryLayout.XYZ, ends);\n    } else {\n      return undefined;\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   * @return {module:ol/geom/LineString|undefined} LineString.\n   */\n  readCurve_(node, objectStack) {\n    /** @type {Array.<number>} */\n    const flatCoordinates = pushParseAndPop([null],\n      this.CURVE_PARSERS_, node, objectStack, this);\n    if (flatCoordinates) {\n      const lineString = new LineString(flatCoordinates, GeometryLayout.XYZ);\n      return lineString;\n    } else {\n      return undefined;\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   * @return {module:ol/extent~Extent|undefined} Envelope.\n   */\n  readEnvelope_(node, objectStack) {\n    /** @type {Array.<number>} */\n    const flatCoordinates = pushParseAndPop([null],\n      this.ENVELOPE_PARSERS_, node, objectStack, this);\n    return createOrUpdate(flatCoordinates[1][0],\n      flatCoordinates[1][1], flatCoordinates[2][0],\n      flatCoordinates[2][1]);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   * @return {Array.<number>|undefined} Flat coordinates.\n   */\n  readFlatPos_(node, objectStack) {\n    let s = getAllTextContent(node, false);\n    const re = /^\\s*([+\\-]?\\d*\\.?\\d+(?:[eE][+\\-]?\\d+)?)\\s*/;\n    /** @type {Array.<number>} */\n    const flatCoordinates = [];\n    let m;\n    while ((m = re.exec(s))) {\n      flatCoordinates.push(parseFloat(m[1]));\n      s = s.substr(m[0].length);\n    }\n    if (s !== '') {\n      return undefined;\n    }\n    const context = objectStack[0];\n    const containerSrs = context['srsName'];\n    let axisOrientation = 'enu';\n    if (containerSrs) {\n      const proj = getProjection(containerSrs);\n      axisOrientation = proj.getAxisOrientation();\n    }\n    if (axisOrientation === 'neu') {\n      let i, ii;\n      for (i = 0, ii = flatCoordinates.length; i < ii; i += 3) {\n        const y = flatCoordinates[i];\n        const x = flatCoordinates[i + 1];\n        flatCoordinates[i] = x;\n        flatCoordinates[i + 1] = y;\n      }\n    }\n    const len = flatCoordinates.length;\n    if (len == 2) {\n      flatCoordinates.push(0);\n    }\n    if (len === 0) {\n      return undefined;\n    }\n    return flatCoordinates;\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   * @return {Array.<number>|undefined} Flat coordinates.\n   */\n  readFlatPosList_(node, objectStack) {\n    const s = getAllTextContent(node, false).replace(/^\\s*|\\s*$/g, '');\n    const context = objectStack[0];\n    const containerSrs = context['srsName'];\n    const contextDimension = context['srsDimension'];\n    let axisOrientation = 'enu';\n    if (containerSrs) {\n      const proj = getProjection(containerSrs);\n      axisOrientation = proj.getAxisOrientation();\n    }\n    const coords = s.split(/\\s+/);\n    // The \"dimension\" attribute is from the GML 3.0.1 spec.\n    let dim = 2;\n    if (node.getAttribute('srsDimension')) {\n      dim = readNonNegativeIntegerString(\n        node.getAttribute('srsDimension'));\n    } else if (node.getAttribute('dimension')) {\n      dim = readNonNegativeIntegerString(\n        node.getAttribute('dimension'));\n    } else if (node.parentNode.getAttribute('srsDimension')) {\n      dim = readNonNegativeIntegerString(\n        node.parentNode.getAttribute('srsDimension'));\n    } else if (contextDimension) {\n      dim = readNonNegativeIntegerString(contextDimension);\n    }\n    let x, y, z;\n    const flatCoordinates = [];\n    for (let i = 0, ii = coords.length; i < ii; i += dim) {\n      x = parseFloat(coords[i]);\n      y = parseFloat(coords[i + 1]);\n      z = (dim === 3) ? parseFloat(coords[i + 2]) : 0;\n      if (axisOrientation.substr(0, 2) === 'en') {\n        flatCoordinates.push(x, y, z);\n      } else {\n        flatCoordinates.push(y, x, z);\n      }\n    }\n    return flatCoordinates;\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/Point} value Point geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writePos_(node, value, objectStack) {\n    const context = objectStack[objectStack.length - 1];\n    const hasZ = context['hasZ'];\n    const srsDimension = hasZ ? 3 : 2;\n    node.setAttribute('srsDimension', srsDimension);\n    const srsName = context['srsName'];\n    let axisOrientation = 'enu';\n    if (srsName) {\n      axisOrientation = getProjection(srsName).getAxisOrientation();\n    }\n    const point = value.getCoordinates();\n    let coords;\n    // only 2d for simple features profile\n    if (axisOrientation.substr(0, 2) === 'en') {\n      coords = (point[0] + ' ' + point[1]);\n    } else {\n      coords = (point[1] + ' ' + point[0]);\n    }\n    if (hasZ) {\n      // For newly created points, Z can be undefined.\n      const z = point[2] || 0;\n      coords += ' ' + z;\n    }\n    writeStringTextNode(node, coords);\n  }\n\n  /**\n   * @param {Array.<number>} point Point geometry.\n   * @param {string=} opt_srsName Optional srsName\n   * @param {boolean=} opt_hasZ whether the geometry has a Z coordinate (is 3D) or not.\n   * @return {string} The coords string.\n   * @private\n   */\n  getCoords_(point, opt_srsName, opt_hasZ) {\n    let axisOrientation = 'enu';\n    if (opt_srsName) {\n      axisOrientation = getProjection(opt_srsName).getAxisOrientation();\n    }\n    let coords = ((axisOrientation.substr(0, 2) === 'en') ?\n      point[0] + ' ' + point[1] :\n      point[1] + ' ' + point[0]);\n    if (opt_hasZ) {\n      // For newly created points, Z can be undefined.\n      const z = point[2] || 0;\n      coords += ' ' + z;\n    }\n\n    return coords;\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/LineString|module:ol/geom/LinearRing} value Geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writePosList_(node, value, objectStack) {\n    const context = objectStack[objectStack.length - 1];\n    const hasZ = context['hasZ'];\n    const srsDimension = hasZ ? 3 : 2;\n    node.setAttribute('srsDimension', srsDimension);\n    const srsName = context['srsName'];\n    // only 2d for simple features profile\n    const points = value.getCoordinates();\n    const len = points.length;\n    const parts = new Array(len);\n    let point;\n    for (let i = 0; i < len; ++i) {\n      point = points[i];\n      parts[i] = this.getCoords_(point, srsName, hasZ);\n    }\n    writeStringTextNode(node, parts.join(' '));\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/Point} geometry Point geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writePoint_(node, geometry, objectStack) {\n    const context = objectStack[objectStack.length - 1];\n    const srsName = context['srsName'];\n    if (srsName) {\n      node.setAttribute('srsName', srsName);\n    }\n    const pos = createElementNS(node.namespaceURI, 'pos');\n    node.appendChild(pos);\n    this.writePos_(pos, geometry, objectStack);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {Array.<*>} objectStack Node stack.\n   */\n  writeEnvelope(node, extent, objectStack) {\n    const context = objectStack[objectStack.length - 1];\n    const srsName = context['srsName'];\n    if (srsName) {\n      node.setAttribute('srsName', srsName);\n    }\n    const keys = ['lowerCorner', 'upperCorner'];\n    const values = [extent[0] + ' ' + extent[1], extent[2] + ' ' + extent[3]];\n    pushSerializeAndPop(/** @type {module:ol/xml~NodeStackItem} */\n      ({node: node}), this.ENVELOPE_SERIALIZERS_,\n      OBJECT_PROPERTY_NODE_FACTORY,\n      values,\n      objectStack, keys, this);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/LinearRing} geometry LinearRing geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeLinearRing_(node, geometry, objectStack) {\n    const context = objectStack[objectStack.length - 1];\n    const srsName = context['srsName'];\n    if (srsName) {\n      node.setAttribute('srsName', srsName);\n    }\n    const posList = createElementNS(node.namespaceURI, 'posList');\n    node.appendChild(posList);\n    this.writePosList_(posList, geometry, objectStack);\n  }\n\n  /**\n   * @param {*} value Value.\n   * @param {Array.<*>} objectStack Object stack.\n   * @param {string=} opt_nodeName Node name.\n   * @return {Node} Node.\n   * @private\n   */\n  RING_NODE_FACTORY_(value, objectStack, opt_nodeName) {\n    const context = objectStack[objectStack.length - 1];\n    const parentNode = context.node;\n    const exteriorWritten = context['exteriorWritten'];\n    if (exteriorWritten === undefined) {\n      context['exteriorWritten'] = true;\n    }\n    return createElementNS(parentNode.namespaceURI,\n      exteriorWritten !== undefined ? 'interior' : 'exterior');\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/Polygon} geometry Polygon geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeSurfaceOrPolygon_(node, geometry, objectStack) {\n    const context = objectStack[objectStack.length - 1];\n    const hasZ = context['hasZ'];\n    const srsName = context['srsName'];\n    if (node.nodeName !== 'PolygonPatch' && srsName) {\n      node.setAttribute('srsName', srsName);\n    }\n    if (node.nodeName === 'Polygon' || node.nodeName === 'PolygonPatch') {\n      const rings = geometry.getLinearRings();\n      pushSerializeAndPop(\n        {node: node, hasZ: hasZ, srsName: srsName},\n        this.RING_SERIALIZERS_,\n        this.RING_NODE_FACTORY_,\n        rings, objectStack, undefined, this);\n    } else if (node.nodeName === 'Surface') {\n      const patches = createElementNS(node.namespaceURI, 'patches');\n      node.appendChild(patches);\n      this.writeSurfacePatches_(\n        patches, geometry, objectStack);\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/LineString} geometry LineString geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeCurveOrLineString_(node, geometry, objectStack) {\n    const context = objectStack[objectStack.length - 1];\n    const srsName = context['srsName'];\n    if (node.nodeName !== 'LineStringSegment' && srsName) {\n      node.setAttribute('srsName', srsName);\n    }\n    if (node.nodeName === 'LineString' ||\n        node.nodeName === 'LineStringSegment') {\n      const posList = createElementNS(node.namespaceURI, 'posList');\n      node.appendChild(posList);\n      this.writePosList_(posList, geometry, objectStack);\n    } else if (node.nodeName === 'Curve') {\n      const segments = createElementNS(node.namespaceURI, 'segments');\n      node.appendChild(segments);\n      this.writeCurveSegments_(segments,\n        geometry, objectStack);\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/MultiPolygon} geometry MultiPolygon geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeMultiSurfaceOrPolygon_(node, geometry, objectStack) {\n    const context = objectStack[objectStack.length - 1];\n    const hasZ = context['hasZ'];\n    const srsName = context['srsName'];\n    const surface = context['surface'];\n    if (srsName) {\n      node.setAttribute('srsName', srsName);\n    }\n    const polygons = geometry.getPolygons();\n    pushSerializeAndPop({node: node, hasZ: hasZ, srsName: srsName, surface: surface},\n      this.SURFACEORPOLYGONMEMBER_SERIALIZERS_,\n      this.MULTIGEOMETRY_MEMBER_NODE_FACTORY_, polygons,\n      objectStack, undefined, this);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/MultiPoint} geometry MultiPoint geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeMultiPoint_(node, geometry, objectStack) {\n    const context = objectStack[objectStack.length - 1];\n    const srsName = context['srsName'];\n    const hasZ = context['hasZ'];\n    if (srsName) {\n      node.setAttribute('srsName', srsName);\n    }\n    const points = geometry.getPoints();\n    pushSerializeAndPop({node: node, hasZ: hasZ, srsName: srsName},\n      this.POINTMEMBER_SERIALIZERS_,\n      makeSimpleNodeFactory('pointMember'), points,\n      objectStack, undefined, this);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/MultiLineString} geometry MultiLineString geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeMultiCurveOrLineString_(node, geometry, objectStack) {\n    const context = objectStack[objectStack.length - 1];\n    const hasZ = context['hasZ'];\n    const srsName = context['srsName'];\n    const curve = context['curve'];\n    if (srsName) {\n      node.setAttribute('srsName', srsName);\n    }\n    const lines = geometry.getLineStrings();\n    pushSerializeAndPop({node: node, hasZ: hasZ, srsName: srsName, curve: curve},\n      this.LINESTRINGORCURVEMEMBER_SERIALIZERS_,\n      this.MULTIGEOMETRY_MEMBER_NODE_FACTORY_, lines,\n      objectStack, undefined, this);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/LinearRing} ring LinearRing geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeRing_(node, ring, objectStack) {\n    const linearRing = createElementNS(node.namespaceURI, 'LinearRing');\n    node.appendChild(linearRing);\n    this.writeLinearRing_(linearRing, ring, objectStack);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/Polygon} polygon Polygon geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeSurfaceOrPolygonMember_(node, polygon, objectStack) {\n    const child = this.GEOMETRY_NODE_FACTORY_(\n      polygon, objectStack);\n    if (child) {\n      node.appendChild(child);\n      this.writeSurfaceOrPolygon_(child, polygon, objectStack);\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/Point} point Point geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writePointMember_(node, point, objectStack) {\n    const child = createElementNS(node.namespaceURI, 'Point');\n    node.appendChild(child);\n    this.writePoint_(child, point, objectStack);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/LineString} line LineString geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeLineStringOrCurveMember_(node, line, objectStack) {\n    const child = this.GEOMETRY_NODE_FACTORY_(line, objectStack);\n    if (child) {\n      node.appendChild(child);\n      this.writeCurveOrLineString_(child, line, objectStack);\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/Polygon} polygon Polygon geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeSurfacePatches_(node, polygon, objectStack) {\n    const child = createElementNS(node.namespaceURI, 'PolygonPatch');\n    node.appendChild(child);\n    this.writeSurfaceOrPolygon_(child, polygon, objectStack);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/LineString} line LineString geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeCurveSegments_(node, line, objectStack) {\n    const child = createElementNS(node.namespaceURI,\n      'LineStringSegment');\n    node.appendChild(child);\n    this.writeCurveOrLineString_(child, line, objectStack);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/Geometry|module:ol/extent~Extent} geometry Geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   */\n  writeGeometryElement(node, geometry, objectStack) {\n    const context = /** @type {module:ol/format/Feature~WriteOptions} */ (objectStack[objectStack.length - 1]);\n    const item = assign({}, context);\n    item.node = node;\n    let value;\n    if (Array.isArray(geometry)) {\n      if (context.dataProjection) {\n        value = transformExtent(\n          geometry, context.featureProjection, context.dataProjection);\n      } else {\n        value = geometry;\n      }\n    } else {\n      value = transformWithOptions(/** @type {module:ol/geom/Geometry} */ (geometry), true, context);\n    }\n    pushSerializeAndPop(/** @type {module:ol/xml~NodeStackItem} */\n      (item), this.GEOMETRY_SERIALIZERS_,\n      this.GEOMETRY_NODE_FACTORY_, [value],\n      objectStack, undefined, this);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/Feature} feature Feature.\n   * @param {Array.<*>} objectStack Node stack.\n   */\n  writeFeatureElement(node, feature, objectStack) {\n    const fid = feature.getId();\n    if (fid) {\n      node.setAttribute('fid', fid);\n    }\n    const context = /** @type {Object} */ (objectStack[objectStack.length - 1]);\n    const featureNS = context['featureNS'];\n    const geometryName = feature.getGeometryName();\n    if (!context.serializers) {\n      context.serializers = {};\n      context.serializers[featureNS] = {};\n    }\n    const properties = feature.getProperties();\n    const keys = [];\n    const values = [];\n    for (const key in properties) {\n      const value = properties[key];\n      if (value !== null) {\n        keys.push(key);\n        values.push(value);\n        if (key == geometryName || value instanceof Geometry) {\n          if (!(key in context.serializers[featureNS])) {\n            context.serializers[featureNS][key] = makeChildAppender(\n              this.writeGeometryElement, this);\n          }\n        } else {\n          if (!(key in context.serializers[featureNS])) {\n            context.serializers[featureNS][key] = makeChildAppender(writeStringTextNode);\n          }\n        }\n      }\n    }\n    const item = assign({}, context);\n    item.node = node;\n    pushSerializeAndPop(/** @type {module:ol/xml~NodeStackItem} */\n      (item), context.serializers,\n      makeSimpleNodeFactory(undefined, featureNS),\n      values,\n      objectStack, keys);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<module:ol/Feature>} features Features.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeFeatureMembers_(node, features, objectStack) {\n    const context = /** @type {Object} */ (objectStack[objectStack.length - 1]);\n    const featureType = context['featureType'];\n    const featureNS = context['featureNS'];\n    const serializers = {};\n    serializers[featureNS] = {};\n    serializers[featureNS][featureType] = makeChildAppender(\n      this.writeFeatureElement, this);\n    const item = assign({}, context);\n    item.node = node;\n    pushSerializeAndPop(/** @type {module:ol/xml~NodeStackItem} */\n      (item),\n      serializers,\n      makeSimpleNodeFactory(featureType, featureNS), features,\n      objectStack);\n  }\n\n  /**\n   * @const\n   * @param {*} value Value.\n   * @param {Array.<*>} objectStack Object stack.\n   * @param {string=} opt_nodeName Node name.\n   * @return {Node|undefined} Node.\n   * @private\n   */\n  MULTIGEOMETRY_MEMBER_NODE_FACTORY_(value, objectStack, opt_nodeName) {\n    const parentNode = objectStack[objectStack.length - 1].node;\n    return createElementNS('http://www.opengis.net/gml',\n      MULTIGEOMETRY_TO_MEMBER_NODENAME[parentNode.nodeName]);\n  }\n\n  /**\n   * @const\n   * @param {*} value Value.\n   * @param {Array.<*>} objectStack Object stack.\n   * @param {string=} opt_nodeName Node name.\n   * @return {Node|undefined} Node.\n   * @private\n   */\n  GEOMETRY_NODE_FACTORY_(value, objectStack, opt_nodeName) {\n    const context = objectStack[objectStack.length - 1];\n    const multiSurface = context['multiSurface'];\n    const surface = context['surface'];\n    const curve = context['curve'];\n    const multiCurve = context['multiCurve'];\n    let nodeName;\n    if (!Array.isArray(value)) {\n      nodeName = /** @type {module:ol/geom/Geometry} */ (value).getType();\n      if (nodeName === 'MultiPolygon' && multiSurface === true) {\n        nodeName = 'MultiSurface';\n      } else if (nodeName === 'Polygon' && surface === true) {\n        nodeName = 'Surface';\n      } else if (nodeName === 'LineString' && curve === true) {\n        nodeName = 'Curve';\n      } else if (nodeName === 'MultiLineString' && multiCurve === true) {\n        nodeName = 'MultiCurve';\n      }\n    } else {\n      nodeName = 'Envelope';\n    }\n    return createElementNS('http://www.opengis.net/gml',\n      nodeName);\n  }\n\n  /**\n   * Encode a geometry in GML 3.1.1 Simple Features.\n   *\n   * @param {module:ol/geom/Geometry} geometry Geometry.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Options.\n   * @return {Node} Node.\n   * @override\n   * @api\n   */\n  writeGeometryNode(geometry, opt_options) {\n    opt_options = this.adaptOptions(opt_options);\n    const geom = createElementNS('http://www.opengis.net/gml', 'geom');\n    const context = {node: geom, hasZ: this.hasZ, srsName: this.srsName,\n      curve: this.curve_, surface: this.surface_,\n      multiSurface: this.multiSurface_, multiCurve: this.multiCurve_};\n    if (opt_options) {\n      assign(context, opt_options);\n    }\n    this.writeGeometryElement(geom, geometry, [context]);\n    return geom;\n  }\n\n  /**\n   * Encode an array of features in the GML 3.1.1 format as an XML node.\n   *\n   * @param {Array.<module:ol/Feature>} features Features.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Options.\n   * @return {Node} Node.\n   * @override\n   * @api\n   */\n  writeFeaturesNode(features, opt_options) {\n    opt_options = this.adaptOptions(opt_options);\n    const node = createElementNS('http://www.opengis.net/gml', 'featureMembers');\n    node.setAttributeNS(XML_SCHEMA_INSTANCE_URI, 'xsi:schemaLocation', this.schemaLocation);\n    const context = {\n      srsName: this.srsName,\n      hasZ: this.hasZ,\n      curve: this.curve_,\n      surface: this.surface_,\n      multiSurface: this.multiSurface_,\n      multiCurve: this.multiCurve_,\n      featureNS: this.featureNS,\n      featureType: this.featureType\n    };\n    if (opt_options) {\n      assign(context, opt_options);\n    }\n    this.writeFeatureMembers_(node, features, [context]);\n    return node;\n  }\n}\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGML3.prototype.GEOMETRY_FLAT_COORDINATES_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'pos': makeReplacer(GML3.prototype.readFlatPos_),\n    'posList': makeReplacer(GML3.prototype.readFlatPosList_)\n  }\n};\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGML3.prototype.FLAT_LINEAR_RINGS_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'interior': GML3.prototype.interiorParser_,\n    'exterior': GML3.prototype.exteriorParser_\n  }\n};\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGML3.prototype.GEOMETRY_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'Point': makeReplacer(GMLBase.prototype.readPoint),\n    'MultiPoint': makeReplacer(\n      GMLBase.prototype.readMultiPoint),\n    'LineString': makeReplacer(\n      GMLBase.prototype.readLineString),\n    'MultiLineString': makeReplacer(\n      GMLBase.prototype.readMultiLineString),\n    'LinearRing': makeReplacer(\n      GMLBase.prototype.readLinearRing),\n    'Polygon': makeReplacer(GMLBase.prototype.readPolygon),\n    'MultiPolygon': makeReplacer(\n      GMLBase.prototype.readMultiPolygon),\n    'Surface': makeReplacer(GML3.prototype.readSurface_),\n    'MultiSurface': makeReplacer(\n      GML3.prototype.readMultiSurface_),\n    'Curve': makeReplacer(GML3.prototype.readCurve_),\n    'MultiCurve': makeReplacer(\n      GML3.prototype.readMultiCurve_),\n    'Envelope': makeReplacer(GML3.prototype.readEnvelope_)\n  }\n};\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGML3.prototype.MULTICURVE_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'curveMember': makeArrayPusher(\n      GML3.prototype.curveMemberParser_),\n    'curveMembers': makeArrayPusher(\n      GML3.prototype.curveMemberParser_)\n  }\n};\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGML3.prototype.MULTISURFACE_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'surfaceMember': makeArrayPusher(\n      GML3.prototype.surfaceMemberParser_),\n    'surfaceMembers': makeArrayPusher(\n      GML3.prototype.surfaceMemberParser_)\n  }\n};\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGML3.prototype.CURVEMEMBER_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'LineString': makeArrayPusher(\n      GMLBase.prototype.readLineString),\n    'Curve': makeArrayPusher(GML3.prototype.readCurve_)\n  }\n};\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGML3.prototype.SURFACEMEMBER_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'Polygon': makeArrayPusher(GMLBase.prototype.readPolygon),\n    'Surface': makeArrayPusher(GML3.prototype.readSurface_)\n  }\n};\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGML3.prototype.SURFACE_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'patches': makeReplacer(GML3.prototype.readPatch_)\n  }\n};\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGML3.prototype.CURVE_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'segments': makeReplacer(GML3.prototype.readSegment_)\n  }\n};\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGML3.prototype.ENVELOPE_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'lowerCorner': makeArrayPusher(\n      GML3.prototype.readFlatPosList_),\n    'upperCorner': makeArrayPusher(\n      GML3.prototype.readFlatPosList_)\n  }\n};\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGML3.prototype.PATCHES_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'PolygonPatch': makeReplacer(\n      GML3.prototype.readPolygonPatch_)\n  }\n};\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGML3.prototype.SEGMENTS_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'LineStringSegment': makeReplacer(\n      GML3.prototype.readLineStringSegment_)\n  }\n};\n\n\n/**\n * Encode an array of features in GML 3.1.1 Simple Features.\n *\n * @function\n * @param {Array.<module:ol/Feature>} features Features.\n * @param {module:ol/format/Feature~WriteOptions=} opt_options Options.\n * @return {string} Result.\n * @api\n */\nGML3.prototype.writeFeatures;\n\n\n/**\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n * @private\n */\nGML3.prototype.RING_SERIALIZERS_ = {\n  'http://www.opengis.net/gml': {\n    'exterior': makeChildAppender(GML3.prototype.writeRing_),\n    'interior': makeChildAppender(GML3.prototype.writeRing_)\n  }\n};\n\n\n/**\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n * @private\n */\nGML3.prototype.ENVELOPE_SERIALIZERS_ = {\n  'http://www.opengis.net/gml': {\n    'lowerCorner': makeChildAppender(writeStringTextNode),\n    'upperCorner': makeChildAppender(writeStringTextNode)\n  }\n};\n\n\n/**\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n * @private\n */\nGML3.prototype.SURFACEORPOLYGONMEMBER_SERIALIZERS_ = {\n  'http://www.opengis.net/gml': {\n    'surfaceMember': makeChildAppender(\n      GML3.prototype.writeSurfaceOrPolygonMember_),\n    'polygonMember': makeChildAppender(\n      GML3.prototype.writeSurfaceOrPolygonMember_)\n  }\n};\n\n\n/**\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n * @private\n */\nGML3.prototype.POINTMEMBER_SERIALIZERS_ = {\n  'http://www.opengis.net/gml': {\n    'pointMember': makeChildAppender(\n      GML3.prototype.writePointMember_)\n  }\n};\n\n\n/**\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n * @private\n */\nGML3.prototype.LINESTRINGORCURVEMEMBER_SERIALIZERS_ = {\n  'http://www.opengis.net/gml': {\n    'lineStringMember': makeChildAppender(\n      GML3.prototype.writeLineStringOrCurveMember_),\n    'curveMember': makeChildAppender(\n      GML3.prototype.writeLineStringOrCurveMember_)\n  }\n};\n\n\n/**\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n * @private\n */\nGML3.prototype.GEOMETRY_SERIALIZERS_ = {\n  'http://www.opengis.net/gml': {\n    'Curve': makeChildAppender(\n      GML3.prototype.writeCurveOrLineString_),\n    'MultiCurve': makeChildAppender(\n      GML3.prototype.writeMultiCurveOrLineString_),\n    'Point': makeChildAppender(GML3.prototype.writePoint_),\n    'MultiPoint': makeChildAppender(\n      GML3.prototype.writeMultiPoint_),\n    'LineString': makeChildAppender(\n      GML3.prototype.writeCurveOrLineString_),\n    'MultiLineString': makeChildAppender(\n      GML3.prototype.writeMultiCurveOrLineString_),\n    'LinearRing': makeChildAppender(\n      GML3.prototype.writeLinearRing_),\n    'Polygon': makeChildAppender(\n      GML3.prototype.writeSurfaceOrPolygon_),\n    'MultiPolygon': makeChildAppender(\n      GML3.prototype.writeMultiSurfaceOrPolygon_),\n    'Surface': makeChildAppender(\n      GML3.prototype.writeSurfaceOrPolygon_),\n    'MultiSurface': makeChildAppender(\n      GML3.prototype.writeMultiSurfaceOrPolygon_),\n    'Envelope': makeChildAppender(\n      GML3.prototype.writeEnvelope)\n  }\n};\n\nexport default GML3;\n","/**\n * @module ol/format/GML\n */\nimport GML3 from '../format/GML3.js';\n\n/**\n * @classdesc\n * Feature format for reading and writing data in the GML format\n * version 3.1.1.\n * Currently only supports GML 3.1.1 Simple Features profile.\n *\n * @param {module:ol/format/GMLBase~Options=} opt_options\n *     Optional configuration object.\n * @api\n */\nconst GML = GML3;\n\n\n/**\n * Encode an array of features in GML 3.1.1 Simple Features.\n *\n * @function\n * @param {Array.<module:ol/Feature>} features Features.\n * @param {module:ol/format/Feature~WriteOptions=} opt_options Options.\n * @return {string} Result.\n * @api\n */\nGML.prototype.writeFeatures;\n\n\n/**\n * Encode an array of features in the GML 3.1.1 format as an XML node.\n *\n * @function\n * @param {Array.<module:ol/Feature>} features Features.\n * @param {module:ol/format/Feature~WriteOptions=} opt_options Options.\n * @return {Node} Node.\n * @api\n */\nGML.prototype.writeFeaturesNode;\n\nexport default GML;\n","/**\n * @module ol/format/GML2\n */\nimport {createOrUpdate} from '../extent.js';\nimport {transformWithOptions} from '../format/Feature.js';\nimport GMLBase, {GMLNS} from '../format/GMLBase.js';\nimport {writeStringTextNode} from '../format/xsd.js';\nimport Geometry from '../geom/Geometry.js';\nimport {assign} from '../obj.js';\nimport {get as getProjection, transformExtent} from '../proj.js';\nimport {createElementNS, getAllTextContent, makeArrayPusher, makeChildAppender,\n  makeReplacer, makeSimpleNodeFactory, OBJECT_PROPERTY_NODE_FACTORY, pushParseAndPop, pushSerializeAndPop} from '../xml.js';\n\n\n/**\n * @const\n * @type {string}\n */\nconst schemaLocation = GMLNS + ' http://schemas.opengis.net/gml/2.1.2/feature.xsd';\n\n\n/**\n * @const\n * @type {Object.<string, string>}\n */\nconst MULTIGEOMETRY_TO_MEMBER_NODENAME = {\n  'MultiLineString': 'lineStringMember',\n  'MultiCurve': 'curveMember',\n  'MultiPolygon': 'polygonMember',\n  'MultiSurface': 'surfaceMember'\n};\n\n\n/**\n * @classdesc\n * Feature format for reading and writing data in the GML format,\n * version 2.1.2.\n *\n * @api\n */\nclass GML2 extends GMLBase {\n\n  /**\n   * @param {module:ol/format/GMLBase~Options=} opt_options Optional configuration object.\n   */\n  constructor(opt_options) {\n    const options = /** @type {module:ol/format/GMLBase~Options} */\n        (opt_options ? opt_options : {});\n\n    super(options);\n\n    this.FEATURE_COLLECTION_PARSERS[GMLNS][\n      'featureMember'] =\n        makeArrayPusher(this.readFeaturesInternal);\n\n    /**\n     * @inheritDoc\n     */\n    this.schemaLocation = options.schemaLocation ?\n      options.schemaLocation : schemaLocation;\n\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   * @return {Array.<number>|undefined} Flat coordinates.\n   */\n  readFlatCoordinates_(node, objectStack) {\n    const s = getAllTextContent(node, false).replace(/^\\s*|\\s*$/g, '');\n    const context = /** @type {module:ol/xml~NodeStackItem} */ (objectStack[0]);\n    const containerSrs = context['srsName'];\n    let axisOrientation = 'enu';\n    if (containerSrs) {\n      const proj = getProjection(containerSrs);\n      if (proj) {\n        axisOrientation = proj.getAxisOrientation();\n      }\n    }\n    const coordsGroups = s.trim().split(/\\s+/);\n    const flatCoordinates = [];\n    for (let i = 0, ii = coordsGroups.length; i < ii; i++) {\n      const coords = coordsGroups[i].split(/,+/);\n      const x = parseFloat(coords[0]);\n      const y = parseFloat(coords[1]);\n      const z = (coords.length === 3) ? parseFloat(coords[2]) : 0;\n      if (axisOrientation.substr(0, 2) === 'en') {\n        flatCoordinates.push(x, y, z);\n      } else {\n        flatCoordinates.push(y, x, z);\n      }\n    }\n    return flatCoordinates;\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   * @return {module:ol/extent~Extent|undefined} Envelope.\n   */\n  readBox_(node, objectStack) {\n    /** @type {Array.<number>} */\n    const flatCoordinates = pushParseAndPop([null],\n      this.BOX_PARSERS_, node, objectStack, this);\n    return createOrUpdate(flatCoordinates[1][0],\n      flatCoordinates[1][1], flatCoordinates[1][3],\n      flatCoordinates[1][4]);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   */\n  innerBoundaryIsParser_(node, objectStack) {\n    /** @type {Array.<number>|undefined} */\n    const flatLinearRing = pushParseAndPop(undefined,\n      this.RING_PARSERS, node, objectStack, this);\n    if (flatLinearRing) {\n      const flatLinearRings = /** @type {Array.<Array.<number>>} */\n          (objectStack[objectStack.length - 1]);\n      flatLinearRings.push(flatLinearRing);\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   */\n  outerBoundaryIsParser_(node, objectStack) {\n    /** @type {Array.<number>|undefined} */\n    const flatLinearRing = pushParseAndPop(undefined,\n      this.RING_PARSERS, node, objectStack, this);\n    if (flatLinearRing) {\n      const flatLinearRings = /** @type {Array.<Array.<number>>} */\n          (objectStack[objectStack.length - 1]);\n      flatLinearRings[0] = flatLinearRing;\n    }\n  }\n\n  /**\n   * @const\n   * @param {*} value Value.\n   * @param {Array.<*>} objectStack Object stack.\n   * @param {string=} opt_nodeName Node name.\n   * @return {Node|undefined} Node.\n   * @private\n   */\n  GEOMETRY_NODE_FACTORY_(value, objectStack, opt_nodeName) {\n    const context = objectStack[objectStack.length - 1];\n    const multiSurface = context['multiSurface'];\n    const surface = context['surface'];\n    const multiCurve = context['multiCurve'];\n    let nodeName;\n    if (!Array.isArray(value)) {\n      nodeName = /** @type {module:ol/geom/Geometry} */ (value).getType();\n      if (nodeName === 'MultiPolygon' && multiSurface === true) {\n        nodeName = 'MultiSurface';\n      } else if (nodeName === 'Polygon' && surface === true) {\n        nodeName = 'Surface';\n      } else if (nodeName === 'MultiLineString' && multiCurve === true) {\n        nodeName = 'MultiCurve';\n      }\n    } else {\n      nodeName = 'Envelope';\n    }\n    return createElementNS('http://www.opengis.net/gml',\n      nodeName);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/Feature} feature Feature.\n   * @param {Array.<*>} objectStack Node stack.\n   */\n  writeFeatureElement(node, feature, objectStack) {\n    const fid = feature.getId();\n    if (fid) {\n      node.setAttribute('fid', fid);\n    }\n    const context = /** @type {Object} */ (objectStack[objectStack.length - 1]);\n    const featureNS = context['featureNS'];\n    const geometryName = feature.getGeometryName();\n    if (!context.serializers) {\n      context.serializers = {};\n      context.serializers[featureNS] = {};\n    }\n    const properties = feature.getProperties();\n    const keys = [];\n    const values = [];\n    for (const key in properties) {\n      const value = properties[key];\n      if (value !== null) {\n        keys.push(key);\n        values.push(value);\n        if (key == geometryName || value instanceof Geometry) {\n          if (!(key in context.serializers[featureNS])) {\n            context.serializers[featureNS][key] = makeChildAppender(\n              this.writeGeometryElement, this);\n          }\n        } else {\n          if (!(key in context.serializers[featureNS])) {\n            context.serializers[featureNS][key] = makeChildAppender(writeStringTextNode);\n          }\n        }\n      }\n    }\n    const item = assign({}, context);\n    item.node = node;\n    pushSerializeAndPop(/** @type {module:ol/xml~NodeStackItem} */\n      (item), context.serializers,\n      makeSimpleNodeFactory(undefined, featureNS),\n      values,\n      objectStack, keys);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/LineString} geometry LineString geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeCurveOrLineString_(node, geometry, objectStack) {\n    const context = objectStack[objectStack.length - 1];\n    const srsName = context['srsName'];\n    if (node.nodeName !== 'LineStringSegment' && srsName) {\n      node.setAttribute('srsName', srsName);\n    }\n    if (node.nodeName === 'LineString' ||\n        node.nodeName === 'LineStringSegment') {\n      const coordinates = this.createCoordinatesNode_(node.namespaceURI);\n      node.appendChild(coordinates);\n      this.writeCoordinates_(coordinates, geometry, objectStack);\n    } else if (node.nodeName === 'Curve') {\n      const segments = createElementNS(node.namespaceURI, 'segments');\n      node.appendChild(segments);\n      this.writeCurveSegments_(segments,\n        geometry, objectStack);\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/LineString} line LineString geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeLineStringOrCurveMember_(node, line, objectStack) {\n    const child = this.GEOMETRY_NODE_FACTORY_(line, objectStack);\n    if (child) {\n      node.appendChild(child);\n      this.writeCurveOrLineString_(child, line, objectStack);\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/MultiLineString} geometry MultiLineString geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeMultiCurveOrLineString_(node, geometry, objectStack) {\n    const context = objectStack[objectStack.length - 1];\n    const hasZ = context['hasZ'];\n    const srsName = context['srsName'];\n    const curve = context['curve'];\n    if (srsName) {\n      node.setAttribute('srsName', srsName);\n    }\n    const lines = geometry.getLineStrings();\n    pushSerializeAndPop({node: node, hasZ: hasZ, srsName: srsName, curve: curve},\n      this.LINESTRINGORCURVEMEMBER_SERIALIZERS_,\n      this.MULTIGEOMETRY_MEMBER_NODE_FACTORY_, lines,\n      objectStack, undefined, this);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/Geometry|module:ol/extent~Extent} geometry Geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   */\n  writeGeometryElement(node, geometry, objectStack) {\n    const context = /** @type {module:ol/format/Feature~WriteOptions} */ (objectStack[objectStack.length - 1]);\n    const item = assign({}, context);\n    item.node = node;\n    let value;\n    if (Array.isArray(geometry)) {\n      if (context.dataProjection) {\n        value = transformExtent(\n          geometry, context.featureProjection, context.dataProjection);\n      } else {\n        value = geometry;\n      }\n    } else {\n      value = transformWithOptions(/** @type {module:ol/geom/Geometry} */ (geometry), true, context);\n    }\n    pushSerializeAndPop(/** @type {module:ol/xml~NodeStackItem} */\n      (item), this.GEOMETRY_SERIALIZERS_,\n      this.GEOMETRY_NODE_FACTORY_, [value],\n      objectStack, undefined, this);\n  }\n\n  /**\n   * @param {string} namespaceURI XML namespace.\n   * @returns {Node} coordinates node.\n   * @private\n   */\n  createCoordinatesNode_(namespaceURI) {\n    const coordinates = createElementNS(namespaceURI, 'coordinates');\n    coordinates.setAttribute('decimal', '.');\n    coordinates.setAttribute('cs', ',');\n    coordinates.setAttribute('ts', ' ');\n\n    return coordinates;\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/LineString|module:ol/geom/LinearRing} value Geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeCoordinates_(node, value, objectStack) {\n    const context = objectStack[objectStack.length - 1];\n    const hasZ = context['hasZ'];\n    const srsName = context['srsName'];\n    // only 2d for simple features profile\n    const points = value.getCoordinates();\n    const len = points.length;\n    const parts = new Array(len);\n    for (let i = 0; i < len; ++i) {\n      const point = points[i];\n      parts[i] = this.getCoords_(point, srsName, hasZ);\n    }\n    writeStringTextNode(node, parts.join(' '));\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/LineString} line LineString geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeCurveSegments_(node, line, objectStack) {\n    const child = createElementNS(node.namespaceURI, 'LineStringSegment');\n    node.appendChild(child);\n    this.writeCurveOrLineString_(child, line, objectStack);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/Polygon} geometry Polygon geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeSurfaceOrPolygon_(node, geometry, objectStack) {\n    const context = objectStack[objectStack.length - 1];\n    const hasZ = context['hasZ'];\n    const srsName = context['srsName'];\n    if (node.nodeName !== 'PolygonPatch' && srsName) {\n      node.setAttribute('srsName', srsName);\n    }\n    if (node.nodeName === 'Polygon' || node.nodeName === 'PolygonPatch') {\n      const rings = geometry.getLinearRings();\n      pushSerializeAndPop(\n        {node: node, hasZ: hasZ, srsName: srsName},\n        this.RING_SERIALIZERS_,\n        this.RING_NODE_FACTORY_,\n        rings, objectStack, undefined, this);\n    } else if (node.nodeName === 'Surface') {\n      const patches = createElementNS(node.namespaceURI, 'patches');\n      node.appendChild(patches);\n      this.writeSurfacePatches_(\n        patches, geometry, objectStack);\n    }\n  }\n\n  /**\n   * @param {*} value Value.\n   * @param {Array.<*>} objectStack Object stack.\n   * @param {string=} opt_nodeName Node name.\n   * @return {Node} Node.\n   * @private\n   */\n  RING_NODE_FACTORY_(value, objectStack, opt_nodeName) {\n    const context = objectStack[objectStack.length - 1];\n    const parentNode = context.node;\n    const exteriorWritten = context['exteriorWritten'];\n    if (exteriorWritten === undefined) {\n      context['exteriorWritten'] = true;\n    }\n    return createElementNS(parentNode.namespaceURI,\n      exteriorWritten !== undefined ? 'innerBoundaryIs' : 'outerBoundaryIs');\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/Polygon} polygon Polygon geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeSurfacePatches_(node, polygon, objectStack) {\n    const child = createElementNS(node.namespaceURI, 'PolygonPatch');\n    node.appendChild(child);\n    this.writeSurfaceOrPolygon_(child, polygon, objectStack);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/LinearRing} ring LinearRing geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeRing_(node, ring, objectStack) {\n    const linearRing = createElementNS(node.namespaceURI, 'LinearRing');\n    node.appendChild(linearRing);\n    this.writeLinearRing_(linearRing, ring, objectStack);\n  }\n\n  /**\n   * @param {Array.<number>} point Point geometry.\n   * @param {string=} opt_srsName Optional srsName\n   * @param {boolean=} opt_hasZ whether the geometry has a Z coordinate (is 3D) or not.\n   * @return {string} The coords string.\n   * @private\n   */\n  getCoords_(point, opt_srsName, opt_hasZ) {\n    let axisOrientation = 'enu';\n    if (opt_srsName) {\n      axisOrientation = getProjection(opt_srsName).getAxisOrientation();\n    }\n    let coords = ((axisOrientation.substr(0, 2) === 'en') ?\n      point[0] + ',' + point[1] :\n      point[1] + ',' + point[0]);\n    if (opt_hasZ) {\n      // For newly created points, Z can be undefined.\n      const z = point[2] || 0;\n      coords += ',' + z;\n    }\n\n    return coords;\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/Point} geometry Point geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writePoint_(node, geometry, objectStack) {\n    const context = objectStack[objectStack.length - 1];\n    const hasZ = context['hasZ'];\n    const srsName = context['srsName'];\n    if (srsName) {\n      node.setAttribute('srsName', srsName);\n    }\n    const coordinates = this.createCoordinatesNode_(node.namespaceURI);\n    node.appendChild(coordinates);\n    const point = geometry.getCoordinates();\n    const coord = this.getCoords_(point, srsName, hasZ);\n    writeStringTextNode(coordinates, coord);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/MultiPoint} geometry MultiPoint geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeMultiPoint_(node, geometry, objectStack) {\n    const context = objectStack[objectStack.length - 1];\n    const hasZ = context['hasZ'];\n    const srsName = context['srsName'];\n    if (srsName) {\n      node.setAttribute('srsName', srsName);\n    }\n    const points = geometry.getPoints();\n    pushSerializeAndPop({node: node, hasZ: hasZ, srsName: srsName},\n      this.POINTMEMBER_SERIALIZERS_,\n      makeSimpleNodeFactory('pointMember'), points,\n      objectStack, undefined, this);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/Point} point Point geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writePointMember_(node, point, objectStack) {\n    const child = createElementNS(node.namespaceURI, 'Point');\n    node.appendChild(child);\n    this.writePoint_(child, point, objectStack);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/LinearRing} geometry LinearRing geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeLinearRing_(node, geometry, objectStack) {\n    const context = objectStack[objectStack.length - 1];\n    const srsName = context['srsName'];\n    if (srsName) {\n      node.setAttribute('srsName', srsName);\n    }\n    const coordinates = this.createCoordinatesNode_(node.namespaceURI);\n    node.appendChild(coordinates);\n    this.writeCoordinates_(coordinates, geometry, objectStack);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/MultiPolygon} geometry MultiPolygon geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeMultiSurfaceOrPolygon_(node, geometry, objectStack) {\n    const context = objectStack[objectStack.length - 1];\n    const hasZ = context['hasZ'];\n    const srsName = context['srsName'];\n    const surface = context['surface'];\n    if (srsName) {\n      node.setAttribute('srsName', srsName);\n    }\n    const polygons = geometry.getPolygons();\n    pushSerializeAndPop({node: node, hasZ: hasZ, srsName: srsName, surface: surface},\n      this.SURFACEORPOLYGONMEMBER_SERIALIZERS_,\n      this.MULTIGEOMETRY_MEMBER_NODE_FACTORY_, polygons,\n      objectStack, undefined, this);\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/geom/Polygon} polygon Polygon geometry.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeSurfaceOrPolygonMember_(node, polygon, objectStack) {\n    const child = this.GEOMETRY_NODE_FACTORY_(\n      polygon, objectStack);\n    if (child) {\n      node.appendChild(child);\n      this.writeSurfaceOrPolygon_(child, polygon, objectStack);\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {Array.<*>} objectStack Node stack.\n   * @private\n   */\n  writeEnvelope(node, extent, objectStack) {\n    const context = objectStack[objectStack.length - 1];\n    const srsName = context['srsName'];\n    if (srsName) {\n      node.setAttribute('srsName', srsName);\n    }\n    const keys = ['lowerCorner', 'upperCorner'];\n    const values = [extent[0] + ' ' + extent[1], extent[2] + ' ' + extent[3]];\n    pushSerializeAndPop(/** @type {module:ol/xml~NodeStackItem} */\n      ({node: node}), this.ENVELOPE_SERIALIZERS_,\n      OBJECT_PROPERTY_NODE_FACTORY,\n      values,\n      objectStack, keys, this);\n  }\n\n  /**\n   * @const\n   * @param {*} value Value.\n   * @param {Array.<*>} objectStack Object stack.\n   * @param {string=} opt_nodeName Node name.\n   * @return {Node|undefined} Node.\n   * @private\n   */\n  MULTIGEOMETRY_MEMBER_NODE_FACTORY_(value, objectStack, opt_nodeName) {\n    const parentNode = objectStack[objectStack.length - 1].node;\n    return createElementNS('http://www.opengis.net/gml',\n      MULTIGEOMETRY_TO_MEMBER_NODENAME[parentNode.nodeName]);\n  }\n}\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGML2.prototype.GEOMETRY_FLAT_COORDINATES_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'coordinates': makeReplacer(GML2.prototype.readFlatCoordinates_)\n  }\n};\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGML2.prototype.FLAT_LINEAR_RINGS_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'innerBoundaryIs': GML2.prototype.innerBoundaryIsParser_,\n    'outerBoundaryIs': GML2.prototype.outerBoundaryIsParser_\n  }\n};\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGML2.prototype.BOX_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'coordinates': makeArrayPusher(\n      GML2.prototype.readFlatCoordinates_)\n  }\n};\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n * @private\n */\nGML2.prototype.GEOMETRY_PARSERS_ = {\n  'http://www.opengis.net/gml': {\n    'Point': makeReplacer(GMLBase.prototype.readPoint),\n    'MultiPoint': makeReplacer(\n      GMLBase.prototype.readMultiPoint),\n    'LineString': makeReplacer(\n      GMLBase.prototype.readLineString),\n    'MultiLineString': makeReplacer(\n      GMLBase.prototype.readMultiLineString),\n    'LinearRing': makeReplacer(\n      GMLBase.prototype.readLinearRing),\n    'Polygon': makeReplacer(GMLBase.prototype.readPolygon),\n    'MultiPolygon': makeReplacer(\n      GMLBase.prototype.readMultiPolygon),\n    'Box': makeReplacer(GML2.prototype.readBox_)\n  }\n};\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n * @private\n */\nGML2.prototype.GEOMETRY_SERIALIZERS_ = {\n  'http://www.opengis.net/gml': {\n    'Curve': makeChildAppender(\n      GML2.prototype.writeCurveOrLineString_),\n    'MultiCurve': makeChildAppender(\n      GML2.prototype.writeMultiCurveOrLineString_),\n    'Point': makeChildAppender(GML2.prototype.writePoint_),\n    'MultiPoint': makeChildAppender(\n      GML2.prototype.writeMultiPoint_),\n    'LineString': makeChildAppender(\n      GML2.prototype.writeCurveOrLineString_),\n    'MultiLineString': makeChildAppender(\n      GML2.prototype.writeMultiCurveOrLineString_),\n    'LinearRing': makeChildAppender(\n      GML2.prototype.writeLinearRing_),\n    'Polygon': makeChildAppender(\n      GML2.prototype.writeSurfaceOrPolygon_),\n    'MultiPolygon': makeChildAppender(\n      GML2.prototype.writeMultiSurfaceOrPolygon_),\n    'Surface': makeChildAppender(\n      GML2.prototype.writeSurfaceOrPolygon_),\n    'MultiSurface': makeChildAppender(\n      GML2.prototype.writeMultiSurfaceOrPolygon_),\n    'Envelope': makeChildAppender(\n      GML2.prototype.writeEnvelope)\n  }\n};\n\n/**\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n * @private\n */\nGML2.prototype.LINESTRINGORCURVEMEMBER_SERIALIZERS_ = {\n  'http://www.opengis.net/gml': {\n    'lineStringMember': makeChildAppender(\n      GML2.prototype.writeLineStringOrCurveMember_),\n    'curveMember': makeChildAppender(\n      GML2.prototype.writeLineStringOrCurveMember_)\n  }\n};\n\n/**\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n * @private\n */\nGML2.prototype.RING_SERIALIZERS_ = {\n  'http://www.opengis.net/gml': {\n    'outerBoundaryIs': makeChildAppender(GML2.prototype.writeRing_),\n    'innerBoundaryIs': makeChildAppender(GML2.prototype.writeRing_)\n  }\n};\n\n/**\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n * @private\n */\nGML2.prototype.POINTMEMBER_SERIALIZERS_ = {\n  'http://www.opengis.net/gml': {\n    'pointMember': makeChildAppender(\n      GML2.prototype.writePointMember_)\n  }\n};\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n * @private\n */\nGML2.prototype.SURFACEORPOLYGONMEMBER_SERIALIZERS_ = {\n  'http://www.opengis.net/gml': {\n    'surfaceMember': makeChildAppender(\n      GML2.prototype.writeSurfaceOrPolygonMember_),\n    'polygonMember': makeChildAppender(\n      GML2.prototype.writeSurfaceOrPolygonMember_)\n  }\n};\n\n/**\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n * @private\n */\nGML2.prototype.ENVELOPE_SERIALIZERS_ = {\n  'http://www.opengis.net/gml': {\n    'lowerCorner': makeChildAppender(writeStringTextNode),\n    'upperCorner': makeChildAppender(writeStringTextNode)\n  }\n};\n\nexport default GML2;\n","/**\n * @module ol/format/GPX\n */\nimport Feature from '../Feature.js';\nimport {includes} from '../array.js';\nimport {transformWithOptions} from '../format/Feature.js';\nimport XMLFeature from '../format/XMLFeature.js';\nimport {readString, readDecimal, readNonNegativeInteger, readDateTime, writeStringTextNode, writeNonNegativeIntegerTextNode, writeDecimalTextNode, writeDateTimeTextNode} from '../format/xsd.js';\nimport GeometryLayout from '../geom/GeometryLayout.js';\nimport LineString from '../geom/LineString.js';\nimport MultiLineString from '../geom/MultiLineString.js';\nimport Point from '../geom/Point.js';\nimport {get as getProjection} from '../proj.js';\nimport {createElementNS, makeArrayPusher, makeArraySerializer, makeChildAppender,\n  makeObjectPropertySetter, makeSequence, makeSimpleNodeFactory, makeStructureNS,\n  OBJECT_PROPERTY_NODE_FACTORY, parseNode, pushParseAndPop, pushSerializeAndPop,\n  XML_SCHEMA_INSTANCE_URI} from '../xml.js';\n\n\n/**\n * @const\n * @type {Array.<null|string>}\n */\nconst NAMESPACE_URIS = [\n  null,\n  'http://www.topografix.com/GPX/1/0',\n  'http://www.topografix.com/GPX/1/1'\n];\n\n\n/**\n * @const\n * @type {string}\n */\nconst SCHEMA_LOCATION = 'http://www.topografix.com/GPX/1/1 ' +\n    'http://www.topografix.com/GPX/1/1/gpx.xsd';\n\n\n/**\n * @const\n * @type {Object.<string, function(Node, Array.<*>): (module:ol/Feature|undefined)>}\n */\nconst FEATURE_READER = {\n  'rte': readRte,\n  'trk': readTrk,\n  'wpt': readWpt\n};\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst GPX_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'rte': makeArrayPusher(readRte),\n    'trk': makeArrayPusher(readTrk),\n    'wpt': makeArrayPusher(readWpt)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst LINK_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'text': makeObjectPropertySetter(readString, 'linkText'),\n    'type': makeObjectPropertySetter(readString, 'linkType')\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst GPX_SERIALIZERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'rte': makeChildAppender(writeRte),\n    'trk': makeChildAppender(writeTrk),\n    'wpt': makeChildAppender(writeWpt)\n  });\n\n\n/**\n * @typedef {Object} Options\n * @property {function(module:ol/Feature, Node)} [readExtensions] Callback function\n * to process `extensions` nodes. To prevent memory leaks, this callback function must\n * not store any references to the node. Note that the `extensions`\n * node is not allowed in GPX 1.0. Moreover, only `extensions`\n * nodes from `wpt`, `rte` and `trk` can be processed, as those are\n * directly mapped to a feature.\n */\n\n/**\n * @typedef {Object} LayoutOptions\n * @property {boolean} [hasZ]\n * @property {boolean} [hasM]\n */\n\n/**\n * @classdesc\n * Feature format for reading and writing data in the GPX format.\n *\n * Note that {@link module:ol/format/GPX~GPX#readFeature} only reads the first\n * feature of the source.\n *\n * When reading, routes (`<rte>`) are converted into LineString geometries, and\n * tracks (`<trk>`) into MultiLineString. Any properties on route and track\n * waypoints are ignored.\n *\n * When writing, LineString geometries are output as routes (`<rte>`), and\n * MultiLineString as tracks (`<trk>`).\n *\n * @api\n */\nclass GPX extends XMLFeature {\n\n  /**\n   * @param {module:ol/format/GPX~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n    super();\n\n    const options = opt_options ? opt_options : {};\n\n\n    /**\n     * @inheritDoc\n     */\n    this.dataProjection = getProjection('EPSG:4326');\n\n    /**\n     * @type {function(module:ol/Feature, Node)|undefined}\n     * @private\n     */\n    this.readExtensions_ = options.readExtensions;\n  }\n\n  /**\n   * @param {Array.<module:ol/Feature>} features List of features.\n   * @private\n   */\n  handleReadExtensions_(features) {\n    if (!features) {\n      features = [];\n    }\n    for (let i = 0, ii = features.length; i < ii; ++i) {\n      const feature = features[i];\n      if (this.readExtensions_) {\n        const extensionsNode = feature.get('extensionsNode_') || null;\n        this.readExtensions_(feature, extensionsNode);\n      }\n      feature.set('extensionsNode_', undefined);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFeatureFromNode(node, opt_options) {\n    if (!includes(NAMESPACE_URIS, node.namespaceURI)) {\n      return null;\n    }\n    const featureReader = FEATURE_READER[node.localName];\n    if (!featureReader) {\n      return null;\n    }\n    const feature = featureReader(node, [this.getReadOptions(node, opt_options)]);\n    if (!feature) {\n      return null;\n    }\n    this.handleReadExtensions_([feature]);\n    return feature;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFeaturesFromNode(node, opt_options) {\n    if (!includes(NAMESPACE_URIS, node.namespaceURI)) {\n      return [];\n    }\n    if (node.localName == 'gpx') {\n      /** @type {Array.<module:ol/Feature>} */\n      const features = pushParseAndPop([], GPX_PARSERS,\n        node, [this.getReadOptions(node, opt_options)]);\n      if (features) {\n        this.handleReadExtensions_(features);\n        return features;\n      } else {\n        return [];\n      }\n    }\n    return [];\n  }\n\n  /**\n   * Encode an array of features in the GPX format as an XML node.\n   * LineString geometries are output as routes (`<rte>`), and MultiLineString\n   * as tracks (`<trk>`).\n   *\n   * @param {Array.<module:ol/Feature>} features Features.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Options.\n   * @return {Node} Node.\n   * @override\n   * @api\n   */\n  writeFeaturesNode(features, opt_options) {\n    opt_options = this.adaptOptions(opt_options);\n    //FIXME Serialize metadata\n    const gpx = createElementNS('http://www.topografix.com/GPX/1/1', 'gpx');\n    const xmlnsUri = 'http://www.w3.org/2000/xmlns/';\n    gpx.setAttributeNS(xmlnsUri, 'xmlns:xsi', XML_SCHEMA_INSTANCE_URI);\n    gpx.setAttributeNS(XML_SCHEMA_INSTANCE_URI, 'xsi:schemaLocation', SCHEMA_LOCATION);\n    gpx.setAttribute('version', '1.1');\n    gpx.setAttribute('creator', 'OpenLayers');\n\n    pushSerializeAndPop(/** @type {module:ol/xml~NodeStackItem} */\n      ({node: gpx}), GPX_SERIALIZERS, GPX_NODE_FACTORY, features, [opt_options]);\n    return gpx;\n  }\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst RTE_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'name': makeObjectPropertySetter(readString),\n    'cmt': makeObjectPropertySetter(readString),\n    'desc': makeObjectPropertySetter(readString),\n    'src': makeObjectPropertySetter(readString),\n    'link': parseLink,\n    'number': makeObjectPropertySetter(readNonNegativeInteger),\n    'extensions': parseExtensions,\n    'type': makeObjectPropertySetter(readString),\n    'rtept': parseRtePt\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst RTEPT_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'ele': makeObjectPropertySetter(readDecimal),\n    'time': makeObjectPropertySetter(readDateTime)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst TRK_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'name': makeObjectPropertySetter(readString),\n    'cmt': makeObjectPropertySetter(readString),\n    'desc': makeObjectPropertySetter(readString),\n    'src': makeObjectPropertySetter(readString),\n    'link': parseLink,\n    'number': makeObjectPropertySetter(readNonNegativeInteger),\n    'type': makeObjectPropertySetter(readString),\n    'extensions': parseExtensions,\n    'trkseg': parseTrkSeg\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst TRKSEG_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'trkpt': parseTrkPt\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst TRKPT_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'ele': makeObjectPropertySetter(readDecimal),\n    'time': makeObjectPropertySetter(readDateTime)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst WPT_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'ele': makeObjectPropertySetter(readDecimal),\n    'time': makeObjectPropertySetter(readDateTime),\n    'magvar': makeObjectPropertySetter(readDecimal),\n    'geoidheight': makeObjectPropertySetter(readDecimal),\n    'name': makeObjectPropertySetter(readString),\n    'cmt': makeObjectPropertySetter(readString),\n    'desc': makeObjectPropertySetter(readString),\n    'src': makeObjectPropertySetter(readString),\n    'link': parseLink,\n    'sym': makeObjectPropertySetter(readString),\n    'type': makeObjectPropertySetter(readString),\n    'fix': makeObjectPropertySetter(readString),\n    'sat': makeObjectPropertySetter(readNonNegativeInteger),\n    'hdop': makeObjectPropertySetter(readDecimal),\n    'vdop': makeObjectPropertySetter(readDecimal),\n    'pdop': makeObjectPropertySetter(readDecimal),\n    'ageofdgpsdata': makeObjectPropertySetter(readDecimal),\n    'dgpsid': makeObjectPropertySetter(readNonNegativeInteger),\n    'extensions': parseExtensions\n  });\n\n\n/**\n * @const\n * @type {Array.<string>}\n */\nconst LINK_SEQUENCE = ['text', 'type'];\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst LINK_SERIALIZERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'text': makeChildAppender(writeStringTextNode),\n    'type': makeChildAppender(writeStringTextNode)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Array.<string>>}\n */\nconst RTE_SEQUENCE = makeStructureNS(\n  NAMESPACE_URIS, [\n    'name', 'cmt', 'desc', 'src', 'link', 'number', 'type', 'rtept'\n  ]);\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst RTE_SERIALIZERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'name': makeChildAppender(writeStringTextNode),\n    'cmt': makeChildAppender(writeStringTextNode),\n    'desc': makeChildAppender(writeStringTextNode),\n    'src': makeChildAppender(writeStringTextNode),\n    'link': makeChildAppender(writeLink),\n    'number': makeChildAppender(writeNonNegativeIntegerTextNode),\n    'type': makeChildAppender(writeStringTextNode),\n    'rtept': makeArraySerializer(makeChildAppender(writeWptType))\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Array.<string>>}\n */\nconst RTEPT_TYPE_SEQUENCE = makeStructureNS(\n  NAMESPACE_URIS, [\n    'ele', 'time'\n  ]);\n\n\n/**\n * @const\n * @type {Object.<string, Array.<string>>}\n */\nconst TRK_SEQUENCE = makeStructureNS(\n  NAMESPACE_URIS, [\n    'name', 'cmt', 'desc', 'src', 'link', 'number', 'type', 'trkseg'\n  ]);\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst TRK_SERIALIZERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'name': makeChildAppender(writeStringTextNode),\n    'cmt': makeChildAppender(writeStringTextNode),\n    'desc': makeChildAppender(writeStringTextNode),\n    'src': makeChildAppender(writeStringTextNode),\n    'link': makeChildAppender(writeLink),\n    'number': makeChildAppender(writeNonNegativeIntegerTextNode),\n    'type': makeChildAppender(writeStringTextNode),\n    'trkseg': makeArraySerializer(makeChildAppender(writeTrkSeg))\n  });\n\n\n/**\n * @const\n * @type {function(*, Array.<*>, string=): (Node|undefined)}\n */\nconst TRKSEG_NODE_FACTORY = makeSimpleNodeFactory('trkpt');\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst TRKSEG_SERIALIZERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'trkpt': makeChildAppender(writeWptType)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Array.<string>>}\n */\nconst WPT_TYPE_SEQUENCE = makeStructureNS(\n  NAMESPACE_URIS, [\n    'ele', 'time', 'magvar', 'geoidheight', 'name', 'cmt', 'desc', 'src',\n    'link', 'sym', 'type', 'fix', 'sat', 'hdop', 'vdop', 'pdop',\n    'ageofdgpsdata', 'dgpsid'\n  ]);\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst WPT_TYPE_SERIALIZERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'ele': makeChildAppender(writeDecimalTextNode),\n    'time': makeChildAppender(writeDateTimeTextNode),\n    'magvar': makeChildAppender(writeDecimalTextNode),\n    'geoidheight': makeChildAppender(writeDecimalTextNode),\n    'name': makeChildAppender(writeStringTextNode),\n    'cmt': makeChildAppender(writeStringTextNode),\n    'desc': makeChildAppender(writeStringTextNode),\n    'src': makeChildAppender(writeStringTextNode),\n    'link': makeChildAppender(writeLink),\n    'sym': makeChildAppender(writeStringTextNode),\n    'type': makeChildAppender(writeStringTextNode),\n    'fix': makeChildAppender(writeStringTextNode),\n    'sat': makeChildAppender(writeNonNegativeIntegerTextNode),\n    'hdop': makeChildAppender(writeDecimalTextNode),\n    'vdop': makeChildAppender(writeDecimalTextNode),\n    'pdop': makeChildAppender(writeDecimalTextNode),\n    'ageofdgpsdata': makeChildAppender(writeDecimalTextNode),\n    'dgpsid': makeChildAppender(writeNonNegativeIntegerTextNode)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, string>}\n */\nconst GEOMETRY_TYPE_TO_NODENAME = {\n  'Point': 'wpt',\n  'LineString': 'rte',\n  'MultiLineString': 'trk'\n};\n\n\n/**\n * @param {*} value Value.\n * @param {Array.<*>} objectStack Object stack.\n * @param {string=} opt_nodeName Node name.\n * @return {Node|undefined} Node.\n */\nfunction GPX_NODE_FACTORY(value, objectStack, opt_nodeName) {\n  const geometry = /** @type {module:ol/Feature} */ (value).getGeometry();\n  if (geometry) {\n    const nodeName = GEOMETRY_TYPE_TO_NODENAME[geometry.getType()];\n    if (nodeName) {\n      const parentNode = objectStack[objectStack.length - 1].node;\n      return createElementNS(parentNode.namespaceURI, nodeName);\n    }\n  }\n}\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {module:ol/format/GPX~LayoutOptions} layoutOptions Layout options.\n * @param {Node} node Node.\n * @param {!Object} values Values.\n * @return {Array.<number>} Flat coordinates.\n */\nfunction appendCoordinate(flatCoordinates, layoutOptions, node, values) {\n  flatCoordinates.push(\n    parseFloat(node.getAttribute('lon')),\n    parseFloat(node.getAttribute('lat')));\n  if ('ele' in values) {\n    flatCoordinates.push(/** @type {number} */ (values['ele']));\n    delete values['ele'];\n    layoutOptions.hasZ = true;\n  } else {\n    flatCoordinates.push(0);\n  }\n  if ('time' in values) {\n    flatCoordinates.push(/** @type {number} */ (values['time']));\n    delete values['time'];\n    layoutOptions.hasM = true;\n  } else {\n    flatCoordinates.push(0);\n  }\n  return flatCoordinates;\n}\n\n\n/**\n * Choose GeometryLayout based on flags in layoutOptions and adjust flatCoordinates\n * and ends arrays by shrinking them accordingly (removing unused zero entries).\n *\n * @param {module:ol/format/GPX~LayoutOptions} layoutOptions Layout options.\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {Array.<number>=} ends Ends.\n * @return {module:ol/geom/GeometryLayout} Layout.\n */\nfunction applyLayoutOptions(layoutOptions, flatCoordinates, ends) {\n  let layout = GeometryLayout.XY;\n  let stride = 2;\n  if (layoutOptions.hasZ && layoutOptions.hasM) {\n    layout = GeometryLayout.XYZM;\n    stride = 4;\n  } else if (layoutOptions.hasZ) {\n    layout = GeometryLayout.XYZ;\n    stride = 3;\n  } else if (layoutOptions.hasM) {\n    layout = GeometryLayout.XYM;\n    stride = 3;\n  }\n  if (stride !== 4) {\n    for (let i = 0, ii = flatCoordinates.length / 4; i < ii; i++) {\n      flatCoordinates[i * stride] = flatCoordinates[i * 4];\n      flatCoordinates[i * stride + 1] = flatCoordinates[i * 4 + 1];\n      if (layoutOptions.hasZ) {\n        flatCoordinates[i * stride + 2] = flatCoordinates[i * 4 + 2];\n      }\n      if (layoutOptions.hasM) {\n        flatCoordinates[i * stride + 2] = flatCoordinates[i * 4 + 3];\n      }\n    }\n    flatCoordinates.length = flatCoordinates.length / 4 * stride;\n    if (ends) {\n      for (let i = 0, ii = ends.length; i < ii; i++) {\n        ends[i] = ends[i] / 4 * stride;\n      }\n    }\n  }\n  return layout;\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction parseLink(node, objectStack) {\n  const values = /** @type {Object} */ (objectStack[objectStack.length - 1]);\n  const href = node.getAttribute('href');\n  if (href !== null) {\n    values['link'] = href;\n  }\n  parseNode(LINK_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction parseExtensions(node, objectStack) {\n  const values = /** @type {Object} */ (objectStack[objectStack.length - 1]);\n  values['extensionsNode_'] = node;\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction parseRtePt(node, objectStack) {\n  const values = pushParseAndPop({}, RTEPT_PARSERS, node, objectStack);\n  if (values) {\n    const rteValues = /** @type {!Object} */ (objectStack[objectStack.length - 1]);\n    const flatCoordinates = /** @type {Array.<number>} */ (rteValues['flatCoordinates']);\n    const layoutOptions = /** @type {module:ol/format/GPX~LayoutOptions} */ (rteValues['layoutOptions']);\n    appendCoordinate(flatCoordinates, layoutOptions, node, values);\n  }\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction parseTrkPt(node, objectStack) {\n  const values = pushParseAndPop({}, TRKPT_PARSERS, node, objectStack);\n  if (values) {\n    const trkValues = /** @type {!Object} */ (objectStack[objectStack.length - 1]);\n    const flatCoordinates = /** @type {Array.<number>} */ (trkValues['flatCoordinates']);\n    const layoutOptions = /** @type {module:ol/format/GPX~LayoutOptions} */ (trkValues['layoutOptions']);\n    appendCoordinate(flatCoordinates, layoutOptions, node, values);\n  }\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction parseTrkSeg(node, objectStack) {\n  const values = /** @type {Object} */ (objectStack[objectStack.length - 1]);\n  parseNode(TRKSEG_PARSERS, node, objectStack);\n  const flatCoordinates = /** @type {Array.<number>} */\n      (values['flatCoordinates']);\n  const ends = /** @type {Array.<number>} */ (values['ends']);\n  ends.push(flatCoordinates.length);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {module:ol/Feature|undefined} Track.\n */\nfunction readRte(node, objectStack) {\n  const options = /** @type {module:ol/format/Feature~ReadOptions} */ (objectStack[0]);\n  const values = pushParseAndPop({\n    'flatCoordinates': [],\n    'layoutOptions': {}\n  }, RTE_PARSERS, node, objectStack);\n  if (!values) {\n    return undefined;\n  }\n  const flatCoordinates = /** @type {Array.<number>} */\n      (values['flatCoordinates']);\n  delete values['flatCoordinates'];\n  const layoutOptions = /** @type {module:ol/format/GPX~LayoutOptions} */ (values['layoutOptions']);\n  delete values['layoutOptions'];\n  const layout = applyLayoutOptions(layoutOptions, flatCoordinates);\n  const geometry = new LineString(flatCoordinates, layout);\n  transformWithOptions(geometry, false, options);\n  const feature = new Feature(geometry);\n  feature.setProperties(values);\n  return feature;\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {module:ol/Feature|undefined} Track.\n */\nfunction readTrk(node, objectStack) {\n  const options = /** @type {module:ol/format/Feature~ReadOptions} */ (objectStack[0]);\n  const values = pushParseAndPop({\n    'flatCoordinates': [],\n    'ends': [],\n    'layoutOptions': {}\n  }, TRK_PARSERS, node, objectStack);\n  if (!values) {\n    return undefined;\n  }\n  const flatCoordinates = /** @type {Array.<number>} */\n      (values['flatCoordinates']);\n  delete values['flatCoordinates'];\n  const ends = /** @type {Array.<number>} */ (values['ends']);\n  delete values['ends'];\n  const layoutOptions = /** @type {module:ol/format/GPX~LayoutOptions} */ (values['layoutOptions']);\n  delete values['layoutOptions'];\n  const layout = applyLayoutOptions(layoutOptions, flatCoordinates, ends);\n  const geometry = new MultiLineString(flatCoordinates, layout, ends);\n  transformWithOptions(geometry, false, options);\n  const feature = new Feature(geometry);\n  feature.setProperties(values);\n  return feature;\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {module:ol/Feature|undefined} Waypoint.\n */\nfunction readWpt(node, objectStack) {\n  const options = /** @type {module:ol/format/Feature~ReadOptions} */ (objectStack[0]);\n  const values = pushParseAndPop({}, WPT_PARSERS, node, objectStack);\n  if (!values) {\n    return undefined;\n  }\n  const layoutOptions = /** @type {module:ol/format/GPX~LayoutOptions} */ ({});\n  const coordinates = appendCoordinate([], layoutOptions, node, values);\n  const layout = applyLayoutOptions(layoutOptions, coordinates);\n  const geometry = new Point(coordinates, layout);\n  transformWithOptions(geometry, false, options);\n  const feature = new Feature(geometry);\n  feature.setProperties(values);\n  return feature;\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {string} value Value for the link's `href` attribute.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeLink(node, value, objectStack) {\n  node.setAttribute('href', value);\n  const context = objectStack[objectStack.length - 1];\n  const properties = context['properties'];\n  const link = [\n    properties['linkText'],\n    properties['linkType']\n  ];\n  pushSerializeAndPop(/** @type {module:ol/xml~NodeStackItem} */ ({node: node}),\n    LINK_SERIALIZERS, OBJECT_PROPERTY_NODE_FACTORY,\n    link, objectStack, LINK_SEQUENCE);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction writeWptType(node, coordinate, objectStack) {\n  const context = objectStack[objectStack.length - 1];\n  const parentNode = context.node;\n  const namespaceURI = parentNode.namespaceURI;\n  const properties = context['properties'];\n  //FIXME Projection handling\n  node.setAttributeNS(null, 'lat', coordinate[1]);\n  node.setAttributeNS(null, 'lon', coordinate[0]);\n  const geometryLayout = context['geometryLayout'];\n  switch (geometryLayout) {\n    case GeometryLayout.XYZM:\n      if (coordinate[3] !== 0) {\n        properties['time'] = coordinate[3];\n      }\n      // fall through\n    case GeometryLayout.XYZ:\n      if (coordinate[2] !== 0) {\n        properties['ele'] = coordinate[2];\n      }\n      break;\n    case GeometryLayout.XYM:\n      if (coordinate[2] !== 0) {\n        properties['time'] = coordinate[2];\n      }\n      break;\n    default:\n      // pass\n  }\n  const orderedKeys = (node.nodeName == 'rtept') ?\n    RTEPT_TYPE_SEQUENCE[namespaceURI] :\n    WPT_TYPE_SEQUENCE[namespaceURI];\n  const values = makeSequence(properties, orderedKeys);\n  pushSerializeAndPop(/** @type {module:ol/xml~NodeStackItem} */\n    ({node: node, 'properties': properties}),\n    WPT_TYPE_SERIALIZERS, OBJECT_PROPERTY_NODE_FACTORY,\n    values, objectStack, orderedKeys);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/Feature} feature Feature.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction writeRte(node, feature, objectStack) {\n  const options = /** @type {module:ol/format/Feature~WriteOptions} */ (objectStack[0]);\n  const properties = feature.getProperties();\n  const context = {node: node, 'properties': properties};\n  let geometry = feature.getGeometry();\n  if (geometry) {\n    geometry = /** @type {module:ol/geom/LineString} */ (transformWithOptions(geometry, true, options));\n    context['geometryLayout'] = geometry.getLayout();\n    properties['rtept'] = geometry.getCoordinates();\n  }\n  const parentNode = objectStack[objectStack.length - 1].node;\n  const orderedKeys = RTE_SEQUENCE[parentNode.namespaceURI];\n  const values = makeSequence(properties, orderedKeys);\n  pushSerializeAndPop(context,\n    RTE_SERIALIZERS, OBJECT_PROPERTY_NODE_FACTORY,\n    values, objectStack, orderedKeys);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/Feature} feature Feature.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction writeTrk(node, feature, objectStack) {\n  const options = /** @type {module:ol/format/Feature~WriteOptions} */ (objectStack[0]);\n  const properties = feature.getProperties();\n  /** @type {module:ol/xml~NodeStackItem} */\n  const context = {node: node, 'properties': properties};\n  let geometry = feature.getGeometry();\n  if (geometry) {\n    geometry = /** @type {module:ol/geom/MultiLineString} */\n      (transformWithOptions(geometry, true, options));\n    properties['trkseg'] = geometry.getLineStrings();\n  }\n  const parentNode = objectStack[objectStack.length - 1].node;\n  const orderedKeys = TRK_SEQUENCE[parentNode.namespaceURI];\n  const values = makeSequence(properties, orderedKeys);\n  pushSerializeAndPop(context,\n    TRK_SERIALIZERS, OBJECT_PROPERTY_NODE_FACTORY,\n    values, objectStack, orderedKeys);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/geom/LineString} lineString LineString.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction writeTrkSeg(node, lineString, objectStack) {\n  /** @type {module:ol/xml~NodeStackItem} */\n  const context = {node: node, 'geometryLayout': lineString.getLayout(),\n    'properties': {}};\n  pushSerializeAndPop(context,\n    TRKSEG_SERIALIZERS, TRKSEG_NODE_FACTORY,\n    lineString.getCoordinates(), objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/Feature} feature Feature.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction writeWpt(node, feature, objectStack) {\n  const options = /** @type {module:ol/format/Feature~WriteOptions} */ (objectStack[0]);\n  const context = objectStack[objectStack.length - 1];\n  context['properties'] = feature.getProperties();\n  let geometry = feature.getGeometry();\n  if (geometry) {\n    geometry = /** @type {module:ol/geom/Point} */\n      (transformWithOptions(geometry, true, options));\n    context['geometryLayout'] = geometry.getLayout();\n    writeWptType(node, geometry.getCoordinates(), objectStack);\n  }\n}\n\n\nexport default GPX;\n","/**\n * @module ol/geom/GeometryCollection\n */\nimport {listen, unlisten} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport {createOrUpdateEmpty, closestSquaredDistanceXY, extend, getCenter} from '../extent.js';\nimport Geometry from '../geom/Geometry.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport {clear} from '../obj.js';\n\n/**\n * @classdesc\n * An array of {@link module:ol/geom/Geometry} objects.\n *\n * @api\n */\nclass GeometryCollection extends Geometry {\n\n  /**\n   * @param {Array.<module:ol/geom/Geometry>=} opt_geometries Geometries.\n   */\n  constructor(opt_geometries) {\n\n    super();\n\n    /**\n     * @private\n     * @type {Array.<module:ol/geom/Geometry>}\n     */\n    this.geometries_ = opt_geometries ? opt_geometries : null;\n\n    this.listenGeometriesChange_();\n  }\n\n  /**\n   * @private\n   */\n  unlistenGeometriesChange_() {\n    if (!this.geometries_) {\n      return;\n    }\n    for (let i = 0, ii = this.geometries_.length; i < ii; ++i) {\n      unlisten(\n        this.geometries_[i], EventType.CHANGE,\n        this.changed, this);\n    }\n  }\n\n  /**\n   * @private\n   */\n  listenGeometriesChange_() {\n    if (!this.geometries_) {\n      return;\n    }\n    for (let i = 0, ii = this.geometries_.length; i < ii; ++i) {\n      listen(\n        this.geometries_[i], EventType.CHANGE,\n        this.changed, this);\n    }\n  }\n\n  /**\n   * Make a complete copy of the geometry.\n   * @return {!module:ol/geom/GeometryCollection} Clone.\n   * @override\n   * @api\n   */\n  clone() {\n    const geometryCollection = new GeometryCollection(null);\n    geometryCollection.setGeometries(this.geometries_);\n    return geometryCollection;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  closestPointXY(x, y, closestPoint, minSquaredDistance) {\n    if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n      return minSquaredDistance;\n    }\n    const geometries = this.geometries_;\n    for (let i = 0, ii = geometries.length; i < ii; ++i) {\n      minSquaredDistance = geometries[i].closestPointXY(\n        x, y, closestPoint, minSquaredDistance);\n    }\n    return minSquaredDistance;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  containsXY(x, y) {\n    const geometries = this.geometries_;\n    for (let i = 0, ii = geometries.length; i < ii; ++i) {\n      if (geometries[i].containsXY(x, y)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  computeExtent(extent) {\n    createOrUpdateEmpty(extent);\n    const geometries = this.geometries_;\n    for (let i = 0, ii = geometries.length; i < ii; ++i) {\n      extend(extent, geometries[i].getExtent());\n    }\n    return extent;\n  }\n\n  /**\n   * Return the geometries that make up this geometry collection.\n   * @return {Array.<module:ol/geom/Geometry>} Geometries.\n   * @api\n   */\n  getGeometries() {\n    return cloneGeometries(this.geometries_);\n  }\n\n  /**\n   * @return {Array.<module:ol/geom/Geometry>} Geometries.\n   */\n  getGeometriesArray() {\n    return this.geometries_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getSimplifiedGeometry(squaredTolerance) {\n    if (this.simplifiedGeometryRevision != this.getRevision()) {\n      clear(this.simplifiedGeometryCache);\n      this.simplifiedGeometryMaxMinSquaredTolerance = 0;\n      this.simplifiedGeometryRevision = this.getRevision();\n    }\n    if (squaredTolerance < 0 ||\n        (this.simplifiedGeometryMaxMinSquaredTolerance !== 0 &&\n         squaredTolerance < this.simplifiedGeometryMaxMinSquaredTolerance)) {\n      return this;\n    }\n    const key = squaredTolerance.toString();\n    if (this.simplifiedGeometryCache.hasOwnProperty(key)) {\n      return this.simplifiedGeometryCache[key];\n    } else {\n      const simplifiedGeometries = [];\n      const geometries = this.geometries_;\n      let simplified = false;\n      for (let i = 0, ii = geometries.length; i < ii; ++i) {\n        const geometry = geometries[i];\n        const simplifiedGeometry = geometry.getSimplifiedGeometry(squaredTolerance);\n        simplifiedGeometries.push(simplifiedGeometry);\n        if (simplifiedGeometry !== geometry) {\n          simplified = true;\n        }\n      }\n      if (simplified) {\n        const simplifiedGeometryCollection = new GeometryCollection(null);\n        simplifiedGeometryCollection.setGeometriesArray(simplifiedGeometries);\n        this.simplifiedGeometryCache[key] = simplifiedGeometryCollection;\n        return simplifiedGeometryCollection;\n      } else {\n        this.simplifiedGeometryMaxMinSquaredTolerance = squaredTolerance;\n        return this;\n      }\n    }\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  getType() {\n    return GeometryType.GEOMETRY_COLLECTION;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  intersectsExtent(extent) {\n    const geometries = this.geometries_;\n    for (let i = 0, ii = geometries.length; i < ii; ++i) {\n      if (geometries[i].intersectsExtent(extent)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /**\n   * @return {boolean} Is empty.\n   */\n  isEmpty() {\n    return this.geometries_.length === 0;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  rotate(angle, anchor) {\n    const geometries = this.geometries_;\n    for (let i = 0, ii = geometries.length; i < ii; ++i) {\n      geometries[i].rotate(angle, anchor);\n    }\n    this.changed();\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  scale(sx, opt_sy, opt_anchor) {\n    let anchor = opt_anchor;\n    if (!anchor) {\n      anchor = getCenter(this.getExtent());\n    }\n    const geometries = this.geometries_;\n    for (let i = 0, ii = geometries.length; i < ii; ++i) {\n      geometries[i].scale(sx, opt_sy, anchor);\n    }\n    this.changed();\n  }\n\n  /**\n   * Set the geometries that make up this geometry collection.\n   * @param {Array.<module:ol/geom/Geometry>} geometries Geometries.\n   * @api\n   */\n  setGeometries(geometries) {\n    this.setGeometriesArray(cloneGeometries(geometries));\n  }\n\n  /**\n   * @param {Array.<module:ol/geom/Geometry>} geometries Geometries.\n   */\n  setGeometriesArray(geometries) {\n    this.unlistenGeometriesChange_();\n    this.geometries_ = geometries;\n    this.listenGeometriesChange_();\n    this.changed();\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  applyTransform(transformFn) {\n    const geometries = this.geometries_;\n    for (let i = 0, ii = geometries.length; i < ii; ++i) {\n      geometries[i].applyTransform(transformFn);\n    }\n    this.changed();\n  }\n\n  /**\n   * Translate the geometry.\n   * @param {number} deltaX Delta X.\n   * @param {number} deltaY Delta Y.\n   * @override\n   * @api\n   */\n  translate(deltaX, deltaY) {\n    const geometries = this.geometries_;\n    for (let i = 0, ii = geometries.length; i < ii; ++i) {\n      geometries[i].translate(deltaX, deltaY);\n    }\n    this.changed();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  disposeInternal() {\n    this.unlistenGeometriesChange_();\n    Geometry.prototype.disposeInternal.call(this);\n  }\n}\n\n\n/**\n * @param {Array.<module:ol/geom/Geometry>} geometries Geometries.\n * @return {Array.<module:ol/geom/Geometry>} Cloned geometries.\n */\nfunction cloneGeometries(geometries) {\n  const clonedGeometries = [];\n  for (let i = 0, ii = geometries.length; i < ii; ++i) {\n    clonedGeometries.push(geometries[i].clone());\n  }\n  return clonedGeometries;\n}\n\n\nexport default GeometryCollection;\n","/**\n * @module ol/format/GeoJSON\n */\n// TODO: serialize dataProjection as crs member when writing\n// see https://github.com/openlayers/openlayers/issues/2078\n\nimport {assert} from '../asserts.js';\nimport Feature from '../Feature.js';\nimport {transformWithOptions} from '../format/Feature.js';\nimport JSONFeature from '../format/JSONFeature.js';\nimport GeometryCollection from '../geom/GeometryCollection.js';\nimport LineString from '../geom/LineString.js';\nimport MultiLineString from '../geom/MultiLineString.js';\nimport MultiPoint from '../geom/MultiPoint.js';\nimport MultiPolygon from '../geom/MultiPolygon.js';\nimport Point from '../geom/Point.js';\nimport Polygon from '../geom/Polygon.js';\nimport {assign, isEmpty} from '../obj.js';\nimport {get as getProjection} from '../proj.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/proj~ProjectionLike} [dataProjection='EPSG:4326'] Default data projection.\n * @property {module:ol/proj~ProjectionLike} [featureProjection] Projection for features read or\n * written by the format.  Options passed to read or write methods will take precedence.\n * @property {string} [geometryName] Geometry name to use when creating features.\n * @property {boolean} [extractGeometryName=false] Certain GeoJSON providers include\n * the geometry_name field in the feature GeoJSON. If set to `true` the GeoJSON reader\n * will look for that field to set the geometry name. If both this field is set to `true`\n * and a `geometryName` is provided, the `geometryName` will take precedence.\n */\n\n\n/**\n * @classdesc\n * Feature format for reading and writing data in the GeoJSON format.\n *\n  * @api\n */\nclass GeoJSON extends JSONFeature {\n\n  /**\n   * @param {module:ol/format/GeoJSON~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options ? opt_options : {};\n\n    super();\n\n    /**\n     * @inheritDoc\n     */\n    this.dataProjection = getProjection(\n      options.dataProjection ?\n        options.dataProjection : 'EPSG:4326');\n\n    if (options.featureProjection) {\n      this.defaultFeatureProjection = getProjection(options.featureProjection);\n    }\n\n    /**\n     * Name of the geometry attribute for features.\n     * @type {string|undefined}\n     * @private\n     */\n    this.geometryName_ = options.geometryName;\n\n    /**\n     * Look for the geometry name in the feature GeoJSON\n     * @type {boolean|undefined}\n     * @private\n     */\n    this.extractGeometryName_ = options.extractGeometryName;\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFeatureFromObject(object, opt_options) {\n    /**\n     * @type {GeoJSONFeature}\n     */\n    let geoJSONFeature = null;\n    if (object.type === 'Feature') {\n      geoJSONFeature = /** @type {GeoJSONFeature} */ (object);\n    } else {\n      geoJSONFeature = /** @type {GeoJSONFeature} */ ({\n        type: 'Feature',\n        geometry: /** @type {GeoJSONGeometry|GeoJSONGeometryCollection} */ (object)\n      });\n    }\n\n    const geometry = readGeometry(geoJSONFeature.geometry, opt_options);\n    const feature = new Feature();\n    if (this.geometryName_) {\n      feature.setGeometryName(this.geometryName_);\n    } else if (this.extractGeometryName_ && geoJSONFeature.geometry_name !== undefined) {\n      feature.setGeometryName(geoJSONFeature.geometry_name);\n    }\n    feature.setGeometry(geometry);\n    if (geoJSONFeature.id !== undefined) {\n      feature.setId(geoJSONFeature.id);\n    }\n    if (geoJSONFeature.properties) {\n      feature.setProperties(geoJSONFeature.properties);\n    }\n    return feature;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFeaturesFromObject(object, opt_options) {\n    const geoJSONObject = /** @type {GeoJSONObject} */ (object);\n    /** @type {Array.<module:ol/Feature>} */\n    let features = null;\n    if (geoJSONObject.type === 'FeatureCollection') {\n      const geoJSONFeatureCollection = /** @type {GeoJSONFeatureCollection} */ (object);\n      features = [];\n      const geoJSONFeatures = geoJSONFeatureCollection.features;\n      for (let i = 0, ii = geoJSONFeatures.length; i < ii; ++i) {\n        features.push(this.readFeatureFromObject(geoJSONFeatures[i], opt_options));\n      }\n    } else {\n      features = [this.readFeatureFromObject(object, opt_options)];\n    }\n    return features;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readGeometryFromObject(object, opt_options) {\n    return readGeometry(/** @type {GeoJSONGeometry} */ (object), opt_options);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readProjectionFromObject(object) {\n    const geoJSONObject = /** @type {GeoJSONObject} */ (object);\n    const crs = geoJSONObject.crs;\n    let projection;\n    if (crs) {\n      if (crs.type == 'name') {\n        projection = getProjection(crs.properties.name);\n      } else {\n        assert(false, 36); // Unknown SRS type\n      }\n    } else {\n      projection = this.dataProjection;\n    }\n    return (\n      /** @type {module:ol/proj/Projection} */ (projection)\n    );\n  }\n\n  /**\n   * Encode a feature as a GeoJSON Feature object.\n   *\n   * @param {module:ol/Feature} feature Feature.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @return {GeoJSONFeature} Object.\n   * @override\n   * @api\n   */\n  writeFeatureObject(feature, opt_options) {\n    opt_options = this.adaptOptions(opt_options);\n\n    const object = /** @type {GeoJSONFeature} */ ({\n      'type': 'Feature'\n    });\n    const id = feature.getId();\n    if (id !== undefined) {\n      object.id = id;\n    }\n    const geometry = feature.getGeometry();\n    if (geometry) {\n      object.geometry = writeGeometry(geometry, opt_options);\n    } else {\n      object.geometry = null;\n    }\n    const properties = feature.getProperties();\n    delete properties[feature.getGeometryName()];\n    if (!isEmpty(properties)) {\n      object.properties = properties;\n    } else {\n      object.properties = null;\n    }\n    return object;\n  }\n\n  /**\n   * Encode an array of features as a GeoJSON object.\n   *\n   * @param {Array.<module:ol/Feature>} features Features.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @return {GeoJSONFeatureCollection} GeoJSON Object.\n   * @override\n   * @api\n   */\n  writeFeaturesObject(features, opt_options) {\n    opt_options = this.adaptOptions(opt_options);\n    const objects = [];\n    for (let i = 0, ii = features.length; i < ii; ++i) {\n      objects.push(this.writeFeatureObject(features[i], opt_options));\n    }\n    return /** @type {GeoJSONFeatureCollection} */ ({\n      type: 'FeatureCollection',\n      features: objects\n    });\n  }\n\n  /**\n   * Encode a geometry as a GeoJSON object.\n   *\n   * @param {module:ol/geom/Geometry} geometry Geometry.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @return {GeoJSONGeometry|GeoJSONGeometryCollection} Object.\n   * @override\n   * @api\n   */\n  writeGeometryObject(geometry, opt_options) {\n    return writeGeometry(geometry, this.adaptOptions(opt_options));\n  }\n}\n\n\n/**\n * @const\n * @type {Object.<string, function(GeoJSONObject): module:ol/geom/Geometry>}\n */\nconst GEOMETRY_READERS = {\n  'Point': readPointGeometry,\n  'LineString': readLineStringGeometry,\n  'Polygon': readPolygonGeometry,\n  'MultiPoint': readMultiPointGeometry,\n  'MultiLineString': readMultiLineStringGeometry,\n  'MultiPolygon': readMultiPolygonGeometry,\n  'GeometryCollection': readGeometryCollectionGeometry\n};\n\n\n/**\n * @const\n * @type {Object.<string, function(module:ol/geom/Geometry, module:ol/format/Feature~WriteOptions=): (GeoJSONGeometry|GeoJSONGeometryCollection)>}\n */\nconst GEOMETRY_WRITERS = {\n  'Point': writePointGeometry,\n  'LineString': writeLineStringGeometry,\n  'Polygon': writePolygonGeometry,\n  'MultiPoint': writeMultiPointGeometry,\n  'MultiLineString': writeMultiLineStringGeometry,\n  'MultiPolygon': writeMultiPolygonGeometry,\n  'GeometryCollection': writeGeometryCollectionGeometry,\n  'Circle': writeEmptyGeometryCollectionGeometry\n};\n\n\n/**\n * @param {GeoJSONGeometry|GeoJSONGeometryCollection} object Object.\n * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n * @return {module:ol/geom/Geometry} Geometry.\n */\nfunction readGeometry(object, opt_options) {\n  if (!object) {\n    return null;\n  }\n  const geometryReader = GEOMETRY_READERS[object.type];\n  return (\n    /** @type {module:ol/geom/Geometry} */ (transformWithOptions(geometryReader(object), false, opt_options))\n  );\n}\n\n\n/**\n * @param {GeoJSONGeometryCollection} object Object.\n * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n * @return {module:ol/geom/GeometryCollection} Geometry collection.\n */\nfunction readGeometryCollectionGeometry(object, opt_options) {\n  const geometries = object.geometries.map(\n    /**\n     * @param {GeoJSONGeometry} geometry Geometry.\n     * @return {module:ol/geom/Geometry} geometry Geometry.\n     */\n    function(geometry) {\n      return readGeometry(geometry, opt_options);\n    });\n  return new GeometryCollection(geometries);\n}\n\n\n/**\n * @param {GeoJSONGeometry} object Object.\n * @return {module:ol/geom/Point} Point.\n */\nfunction readPointGeometry(object) {\n  return new Point(object.coordinates);\n}\n\n\n/**\n * @param {GeoJSONGeometry} object Object.\n * @return {module:ol/geom/LineString} LineString.\n */\nfunction readLineStringGeometry(object) {\n  return new LineString(object.coordinates);\n}\n\n\n/**\n * @param {GeoJSONGeometry} object Object.\n * @return {module:ol/geom/MultiLineString} MultiLineString.\n */\nfunction readMultiLineStringGeometry(object) {\n  return new MultiLineString(object.coordinates);\n}\n\n\n/**\n * @param {GeoJSONGeometry} object Object.\n * @return {module:ol/geom/MultiPoint} MultiPoint.\n */\nfunction readMultiPointGeometry(object) {\n  return new MultiPoint(object.coordinates);\n}\n\n\n/**\n * @param {GeoJSONGeometry} object Object.\n * @return {module:ol/geom/MultiPolygon} MultiPolygon.\n */\nfunction readMultiPolygonGeometry(object) {\n  return new MultiPolygon(object.coordinates);\n}\n\n\n/**\n * @param {GeoJSONGeometry} object Object.\n * @return {module:ol/geom/Polygon} Polygon.\n */\nfunction readPolygonGeometry(object) {\n  return new Polygon(object.coordinates);\n}\n\n\n/**\n * @param {module:ol/geom/Geometry} geometry Geometry.\n * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n * @return {GeoJSONGeometry|GeoJSONGeometryCollection} GeoJSON geometry.\n */\nfunction writeGeometry(geometry, opt_options) {\n  const geometryWriter = GEOMETRY_WRITERS[geometry.getType()];\n  return geometryWriter(/** @type {module:ol/geom/Geometry} */ (\n    transformWithOptions(geometry, true, opt_options)), opt_options);\n}\n\n\n/**\n * @param {module:ol/geom/Geometry} geometry Geometry.\n * @return {GeoJSONGeometryCollection} Empty GeoJSON geometry collection.\n */\nfunction writeEmptyGeometryCollectionGeometry(geometry) {\n  return /** @type {GeoJSONGeometryCollection} */ ({\n    type: 'GeometryCollection',\n    geometries: []\n  });\n}\n\n\n/**\n * @param {module:ol/geom/GeometryCollection} geometry Geometry.\n * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n * @return {GeoJSONGeometryCollection} GeoJSON geometry collection.\n */\nfunction writeGeometryCollectionGeometry(geometry, opt_options) {\n  const geometries = geometry.getGeometriesArray().map(function(geometry) {\n    const options = assign({}, opt_options);\n    delete options.featureProjection;\n    return writeGeometry(geometry, options);\n  });\n  return /** @type {GeoJSONGeometryCollection} */ ({\n    type: 'GeometryCollection',\n    geometries: geometries\n  });\n}\n\n\n/**\n * @param {module:ol/geom/LineString} geometry Geometry.\n * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n * @return {GeoJSONGeometry} GeoJSON geometry.\n */\nfunction writeLineStringGeometry(geometry, opt_options) {\n  return /** @type {GeoJSONGeometry} */ ({\n    type: 'LineString',\n    coordinates: geometry.getCoordinates()\n  });\n}\n\n\n/**\n * @param {module:ol/geom/MultiLineString} geometry Geometry.\n * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n * @return {GeoJSONGeometry} GeoJSON geometry.\n */\nfunction writeMultiLineStringGeometry(geometry, opt_options) {\n  return /** @type {GeoJSONGeometry} */ ({\n    type: 'MultiLineString',\n    coordinates: geometry.getCoordinates()\n  });\n}\n\n\n/**\n * @param {module:ol/geom/MultiPoint} geometry Geometry.\n * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n * @return {GeoJSONGeometry} GeoJSON geometry.\n */\nfunction writeMultiPointGeometry(geometry, opt_options) {\n  return /** @type {GeoJSONGeometry} */ ({\n    type: 'MultiPoint',\n    coordinates: geometry.getCoordinates()\n  });\n}\n\n\n/**\n * @param {module:ol/geom/MultiPolygon} geometry Geometry.\n * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n * @return {GeoJSONGeometry} GeoJSON geometry.\n */\nfunction writeMultiPolygonGeometry(geometry, opt_options) {\n  let right;\n  if (opt_options) {\n    right = opt_options.rightHanded;\n  }\n  return /** @type {GeoJSONGeometry} */ ({\n    type: 'MultiPolygon',\n    coordinates: geometry.getCoordinates(right)\n  });\n}\n\n\n/**\n * @param {module:ol/geom/Point} geometry Geometry.\n * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n * @return {GeoJSONGeometry} GeoJSON geometry.\n */\nfunction writePointGeometry(geometry, opt_options) {\n  return /** @type {GeoJSONGeometry} */ ({\n    type: 'Point',\n    coordinates: geometry.getCoordinates()\n  });\n}\n\n\n/**\n * @param {module:ol/geom/Polygon} geometry Geometry.\n * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n * @return {GeoJSONGeometry} GeoJSON geometry.\n */\nfunction writePolygonGeometry(geometry, opt_options) {\n  let right;\n  if (opt_options) {\n    right = opt_options.rightHanded;\n  }\n  return /** @type {GeoJSONGeometry} */ ({\n    type: 'Polygon',\n    coordinates: geometry.getCoordinates(right)\n  });\n}\n\n\nexport default GeoJSON;\n","/**\n * @module ol/format/TextFeature\n */\nimport FeatureFormat from '../format/Feature.js';\nimport FormatType from '../format/FormatType.js';\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Base class for text feature formats.\n *\n * @abstract\n */\nclass TextFeature extends FeatureFormat {\n  constructor() {\n    super();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getType() {\n    return FormatType.TEXT;\n  }\n\n  /**\n   * Read the feature from the source.\n   *\n   * @param {Document|Node|Object|string} source Source.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n   * @return {module:ol/Feature} Feature.\n   * @api\n   */\n  readFeature(source, opt_options) {\n    return this.readFeatureFromText(getText(source), this.adaptOptions(opt_options));\n  }\n\n  /**\n   * @abstract\n   * @param {string} text Text.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n   * @protected\n   * @return {module:ol/Feature} Feature.\n   */\n  readFeatureFromText(text, opt_options) {}\n\n  /**\n   * Read the features from the source.\n   *\n   * @param {Document|Node|Object|string} source Source.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n   * @return {Array.<module:ol/Feature>} Features.\n   * @api\n   */\n  readFeatures(source, opt_options) {\n    return this.readFeaturesFromText(getText(source), this.adaptOptions(opt_options));\n  }\n\n  /**\n   * @abstract\n   * @param {string} text Text.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n   * @protected\n   * @return {Array.<module:ol/Feature>} Features.\n   */\n  readFeaturesFromText(text, opt_options) {}\n\n  /**\n   * Read the geometry from the source.\n   *\n   * @param {Document|Node|Object|string} source Source.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n   * @return {module:ol/geom/Geometry} Geometry.\n   * @api\n   */\n  readGeometry(source, opt_options) {\n    return this.readGeometryFromText(getText(source), this.adaptOptions(opt_options));\n  }\n\n  /**\n   * @abstract\n   * @param {string} text Text.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n   * @protected\n   * @return {module:ol/geom/Geometry} Geometry.\n   */\n  readGeometryFromText(text, opt_options) {}\n\n  /**\n   * Read the projection from the source.\n   *\n   * @function\n   * @param {Document|Node|Object|string} source Source.\n   * @return {module:ol/proj/Projection} Projection.\n   * @api\n   */\n  readProjection(source) {\n    return this.readProjectionFromText(getText(source));\n  }\n\n  /**\n   * @param {string} text Text.\n   * @protected\n   * @return {module:ol/proj/Projection} Projection.\n   */\n  readProjectionFromText(text) {\n    return this.dataProjection;\n  }\n\n  /**\n   * Encode a feature as a string.\n   *\n   * @function\n   * @param {module:ol/Feature} feature Feature.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @return {string} Encoded feature.\n   * @api\n   */\n  writeFeature(feature, opt_options) {\n    return this.writeFeatureText(feature, this.adaptOptions(opt_options));\n  }\n\n  /**\n   * @abstract\n   * @param {module:ol/Feature} feature Features.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @protected\n   * @return {string} Text.\n   */\n  writeFeatureText(feature, opt_options) {}\n\n  /**\n   * Encode an array of features as string.\n   *\n   * @param {Array.<module:ol/Feature>} features Features.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @return {string} Encoded features.\n   * @api\n   */\n  writeFeatures(features, opt_options) {\n    return this.writeFeaturesText(features, this.adaptOptions(opt_options));\n  }\n\n  /**\n   * @abstract\n   * @param {Array.<module:ol/Feature>} features Features.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @protected\n   * @return {string} Text.\n   */\n  writeFeaturesText(features, opt_options) {}\n\n  /**\n   * Write a single geometry.\n   *\n   * @function\n   * @param {module:ol/geom/Geometry} geometry Geometry.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @return {string} Geometry.\n   * @api\n   */\n  writeGeometry(geometry, opt_options) {\n    return this.writeGeometryText(geometry, this.adaptOptions(opt_options));\n  }\n\n  /**\n   * @abstract\n   * @param {module:ol/geom/Geometry} geometry Geometry.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.\n   * @protected\n   * @return {string} Text.\n   */\n  writeGeometryText(geometry, opt_options) {}\n}\n\n\n/**\n * @param {Document|Node|Object|string} source Source.\n * @return {string} Text.\n */\nfunction getText(source) {\n  if (typeof source === 'string') {\n    return source;\n  } else {\n    return '';\n  }\n}\n\n\nexport default TextFeature;\n","/**\n * @module ol/format/IGC\n */\nimport Feature from '../Feature.js';\nimport {transformWithOptions} from '../format/Feature.js';\nimport TextFeature from '../format/TextFeature.js';\nimport GeometryLayout from '../geom/GeometryLayout.js';\nimport LineString from '../geom/LineString.js';\nimport {get as getProjection} from '../proj.js';\n\n/**\n * IGC altitude/z. One of 'barometric', 'gps', 'none'.\n * @enum {string}\n */\nconst IGCZ = {\n  BAROMETRIC: 'barometric',\n  GPS: 'gps',\n  NONE: 'none'\n};\n\n/**\n * @const\n * @type {RegExp}\n */\nconst B_RECORD_RE =\n    /^B(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{5})([NS])(\\d{3})(\\d{5})([EW])([AV])(\\d{5})(\\d{5})/;\n\n\n/**\n * @const\n * @type {RegExp}\n */\nconst H_RECORD_RE = /^H.([A-Z]{3}).*?:(.*)/;\n\n\n/**\n * @const\n * @type {RegExp}\n */\nconst HFDTE_RECORD_RE = /^HFDTE(\\d{2})(\\d{2})(\\d{2})/;\n\n\n/**\n * A regular expression matching the newline characters `\\r\\n`, `\\r` and `\\n`.\n *\n * @const\n * @type {RegExp}\n */\nconst NEWLINE_RE = /\\r\\n|\\r|\\n/;\n\n\n/**\n * @typedef {Object} Options\n * @property {IGCZ|string} [altitudeMode='none'] Altitude mode. Possible\n * values are `'barometric'`, `'gps'`, and `'none'`.\n */\n\n\n/**\n * @classdesc\n * Feature format for `*.igc` flight recording files.\n *\n * As IGC sources contain a single feature,\n * {@link module:ol/format/IGC~IGC#readFeatures} will return the feature in an\n * array\n *\n * @api\n */\nclass IGC extends TextFeature {\n\n  /**\n   * @param {module:ol/format/IGC~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n    super();\n\n    const options = opt_options ? opt_options : {};\n\n    /**\n     * @inheritDoc\n     */\n    this.dataProjection = getProjection('EPSG:4326');\n\n    /**\n     * @private\n     * @type {IGCZ}\n     */\n    this.altitudeMode_ = options.altitudeMode ? options.altitudeMode : IGCZ.NONE;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFeatureFromText(text, opt_options) {\n    const altitudeMode = this.altitudeMode_;\n    const lines = text.split(NEWLINE_RE);\n    /** @type {Object.<string, string>} */\n    const properties = {};\n    const flatCoordinates = [];\n    let year = 2000;\n    let month = 0;\n    let day = 1;\n    let lastDateTime = -1;\n    let i, ii;\n    for (i = 0, ii = lines.length; i < ii; ++i) {\n      const line = lines[i];\n      let m;\n      if (line.charAt(0) == 'B') {\n        m = B_RECORD_RE.exec(line);\n        if (m) {\n          const hour = parseInt(m[1], 10);\n          const minute = parseInt(m[2], 10);\n          const second = parseInt(m[3], 10);\n          let y = parseInt(m[4], 10) + parseInt(m[5], 10) / 60000;\n          if (m[6] == 'S') {\n            y = -y;\n          }\n          let x = parseInt(m[7], 10) + parseInt(m[8], 10) / 60000;\n          if (m[9] == 'W') {\n            x = -x;\n          }\n          flatCoordinates.push(x, y);\n          if (altitudeMode != IGCZ.NONE) {\n            let z;\n            if (altitudeMode == IGCZ.GPS) {\n              z = parseInt(m[11], 10);\n            } else if (altitudeMode == IGCZ.BAROMETRIC) {\n              z = parseInt(m[12], 10);\n            } else {\n              z = 0;\n            }\n            flatCoordinates.push(z);\n          }\n          let dateTime = Date.UTC(year, month, day, hour, minute, second);\n          // Detect UTC midnight wrap around.\n          if (dateTime < lastDateTime) {\n            dateTime = Date.UTC(year, month, day + 1, hour, minute, second);\n          }\n          flatCoordinates.push(dateTime / 1000);\n          lastDateTime = dateTime;\n        }\n      } else if (line.charAt(0) == 'H') {\n        m = HFDTE_RECORD_RE.exec(line);\n        if (m) {\n          day = parseInt(m[1], 10);\n          month = parseInt(m[2], 10) - 1;\n          year = 2000 + parseInt(m[3], 10);\n        } else {\n          m = H_RECORD_RE.exec(line);\n          if (m) {\n            properties[m[1]] = m[2].trim();\n          }\n        }\n      }\n    }\n    if (flatCoordinates.length === 0) {\n      return null;\n    }\n    const layout = altitudeMode == IGCZ.NONE ? GeometryLayout.XYM : GeometryLayout.XYZM;\n    const lineString = new LineString(flatCoordinates, layout);\n    const feature = new Feature(transformWithOptions(lineString, false, opt_options));\n    feature.setProperties(properties);\n    return feature;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFeaturesFromText(text, opt_options) {\n    const feature = this.readFeatureFromText(text, opt_options);\n    if (feature) {\n      return [feature];\n    } else {\n      return [];\n    }\n  }\n\n  /**\n   * Not implemented.\n   * @inheritDoc\n   */\n  writeFeatureText(feature, opt_options) {}\n\n  /**\n   * Not implemented.\n   * @inheritDoc\n   */\n  writeFeaturesText(features, opt_options) {}\n\n  /**\n   * Not implemented.\n   * @inheritDoc\n   */\n  writeGeometryText(geometry, opt_options) {}\n\n  /**\n   * Not implemented.\n   * @inheritDoc\n   */\n  readGeometryFromText(text, opt_options) {}\n}\n\nexport default IGC;\n","/**\n * @module ol/style/IconAnchorUnits\n */\n\n/**\n * Icon anchor units. One of 'fraction', 'pixels'.\n * @enum {string}\n */\nexport default {\n  FRACTION: 'fraction',\n  PIXELS: 'pixels'\n};\n","/**\n * @module ol/style/IconImage\n */\n\nimport {createCanvasContext2D} from '../dom.js';\nimport {listenOnce, unlistenByKey} from '../events.js';\nimport EventTarget from '../events/EventTarget.js';\nimport EventType from '../events/EventType.js';\nimport ImageState from '../ImageState.js';\nimport {shared as iconImageCache} from '../style/IconImageCache.js';\n\nclass IconImage extends EventTarget {\n  /**\n   * @param {HTMLImageElement|HTMLCanvasElement} image Image.\n   * @param {string|undefined} src Src.\n   * @param {module:ol/size~Size} size Size.\n   * @param {?string} crossOrigin Cross origin.\n   * @param {module:ol/ImageState} imageState Image state.\n   * @param {module:ol/color~Color} color Color.\n   */\n  constructor(image, src, size, crossOrigin, imageState, color) {\n\n    super();\n\n    /**\n     * @private\n     * @type {HTMLImageElement|HTMLCanvasElement}\n     */\n    this.hitDetectionImage_ = null;\n\n    /**\n     * @private\n     * @type {HTMLImageElement|HTMLCanvasElement}\n     */\n    this.image_ = !image ? new Image() : image;\n\n    if (crossOrigin !== null) {\n      this.image_.crossOrigin = crossOrigin;\n    }\n\n    /**\n     * @private\n     * @type {HTMLCanvasElement}\n     */\n    this.canvas_ = color ?\n      /** @type {HTMLCanvasElement} */ (document.createElement('CANVAS')) :\n      null;\n\n    /**\n     * @private\n     * @type {module:ol/color~Color}\n     */\n    this.color_ = color;\n\n    /**\n     * @private\n     * @type {Array.<module:ol/events~EventsKey>}\n     */\n    this.imageListenerKeys_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/ImageState}\n     */\n    this.imageState_ = imageState;\n\n    /**\n     * @private\n     * @type {module:ol/size~Size}\n     */\n    this.size_ = size;\n\n    /**\n     * @private\n     * @type {string|undefined}\n     */\n    this.src_ = src;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.tainting_ = false;\n    if (this.imageState_ == ImageState.LOADED) {\n      this.determineTainting_();\n    }\n\n  }\n\n  /**\n   * @private\n   */\n  determineTainting_() {\n    const context = createCanvasContext2D(1, 1);\n    try {\n      context.drawImage(this.image_, 0, 0);\n      context.getImageData(0, 0, 1, 1);\n    } catch (e) {\n      this.tainting_ = true;\n    }\n  }\n\n  /**\n   * @private\n   */\n  dispatchChangeEvent_() {\n    this.dispatchEvent(EventType.CHANGE);\n  }\n\n  /**\n   * @private\n   */\n  handleImageError_() {\n    this.imageState_ = ImageState.ERROR;\n    this.unlistenImage_();\n    this.dispatchChangeEvent_();\n  }\n\n  /**\n   * @private\n   */\n  handleImageLoad_() {\n    this.imageState_ = ImageState.LOADED;\n    if (this.size_) {\n      this.image_.width = this.size_[0];\n      this.image_.height = this.size_[1];\n    }\n    this.size_ = [this.image_.width, this.image_.height];\n    this.unlistenImage_();\n    this.determineTainting_();\n    this.replaceColor_();\n    this.dispatchChangeEvent_();\n  }\n\n  /**\n   * @param {number} pixelRatio Pixel ratio.\n   * @return {HTMLImageElement|HTMLCanvasElement} Image or Canvas element.\n   */\n  getImage(pixelRatio) {\n    return this.canvas_ ? this.canvas_ : this.image_;\n  }\n\n  /**\n   * @return {module:ol/ImageState} Image state.\n   */\n  getImageState() {\n    return this.imageState_;\n  }\n\n  /**\n   * @param {number} pixelRatio Pixel ratio.\n   * @return {HTMLImageElement|HTMLCanvasElement} Image element.\n   */\n  getHitDetectionImage(pixelRatio) {\n    if (!this.hitDetectionImage_) {\n      if (this.tainting_) {\n        const width = this.size_[0];\n        const height = this.size_[1];\n        const context = createCanvasContext2D(width, height);\n        context.fillRect(0, 0, width, height);\n        this.hitDetectionImage_ = context.canvas;\n      } else {\n        this.hitDetectionImage_ = this.image_;\n      }\n    }\n    return this.hitDetectionImage_;\n  }\n\n  /**\n   * @return {module:ol/size~Size} Image size.\n   */\n  getSize() {\n    return this.size_;\n  }\n\n  /**\n   * @return {string|undefined} Image src.\n   */\n  getSrc() {\n    return this.src_;\n  }\n\n  /**\n   * Load not yet loaded URI.\n   */\n  load() {\n    if (this.imageState_ == ImageState.IDLE) {\n      this.imageState_ = ImageState.LOADING;\n      this.imageListenerKeys_ = [\n        listenOnce(this.image_, EventType.ERROR,\n          this.handleImageError_, this),\n        listenOnce(this.image_, EventType.LOAD,\n          this.handleImageLoad_, this)\n      ];\n      try {\n        this.image_.src = this.src_;\n      } catch (e) {\n        this.handleImageError_();\n      }\n    }\n  }\n\n  /**\n   * @private\n   */\n  replaceColor_() {\n    if (this.tainting_ || this.color_ === null) {\n      return;\n    }\n\n    this.canvas_.width = this.image_.width;\n    this.canvas_.height = this.image_.height;\n\n    const ctx = this.canvas_.getContext('2d');\n    ctx.drawImage(this.image_, 0, 0);\n\n    const imgData = ctx.getImageData(0, 0, this.image_.width, this.image_.height);\n    const data = imgData.data;\n    const r = this.color_[0] / 255.0;\n    const g = this.color_[1] / 255.0;\n    const b = this.color_[2] / 255.0;\n\n    for (let i = 0, ii = data.length; i < ii; i += 4) {\n      data[i] *= r;\n      data[i + 1] *= g;\n      data[i + 2] *= b;\n    }\n    ctx.putImageData(imgData, 0, 0);\n  }\n\n  /**\n   * Discards event handlers which listen for load completion or errors.\n   *\n   * @private\n   */\n  unlistenImage_() {\n    this.imageListenerKeys_.forEach(unlistenByKey);\n    this.imageListenerKeys_ = null;\n  }\n}\n\n\n/**\n * @param {HTMLImageElement|HTMLCanvasElement} image Image.\n * @param {string} src Src.\n * @param {module:ol/size~Size} size Size.\n * @param {?string} crossOrigin Cross origin.\n * @param {module:ol/ImageState} imageState Image state.\n * @param {module:ol/color~Color} color Color.\n * @return {module:ol/style/IconImage} Icon image.\n */\nexport function get(image, src, size, crossOrigin, imageState, color) {\n  let iconImage = iconImageCache.get(src, crossOrigin, color);\n  if (!iconImage) {\n    iconImage = new IconImage(image, src, size, crossOrigin, imageState, color);\n    iconImageCache.set(src, crossOrigin, color, iconImage);\n  }\n  return iconImage;\n}\n\n\nexport default IconImage;\n","/**\n * @module ol/format/KML\n */\nimport Feature from '../Feature.js';\nimport {extend, includes} from '../array.js';\nimport {assert} from '../asserts.js';\nimport {asArray} from '../color.js';\nimport {transformWithOptions} from '../format/Feature.js';\nimport XMLFeature from '../format/XMLFeature.js';\nimport {readDecimal, readBoolean, readString, writeStringTextNode, writeCDATASection, writeDecimalTextNode, writeBooleanTextNode} from '../format/xsd.js';\nimport GeometryCollection from '../geom/GeometryCollection.js';\nimport GeometryLayout from '../geom/GeometryLayout.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport LineString from '../geom/LineString.js';\nimport MultiLineString from '../geom/MultiLineString.js';\nimport MultiPoint from '../geom/MultiPoint.js';\nimport MultiPolygon from '../geom/MultiPolygon.js';\nimport Point from '../geom/Point.js';\nimport Polygon from '../geom/Polygon.js';\nimport {toRadians} from '../math.js';\nimport {get as getProjection} from '../proj.js';\nimport Fill from '../style/Fill.js';\nimport Icon from '../style/Icon.js';\nimport IconAnchorUnits from '../style/IconAnchorUnits.js';\nimport IconOrigin from '../style/IconOrigin.js';\nimport Stroke from '../style/Stroke.js';\nimport Style from '../style/Style.js';\nimport Text from '../style/Text.js';\nimport {createElementNS, getAllTextContent, isDocument, isNode, makeArrayExtender,\n  makeArrayPusher, makeChildAppender, makeObjectPropertySetter,\n  makeReplacer, makeSequence, makeSimpleNodeFactory, makeStructureNS,\n  OBJECT_PROPERTY_NODE_FACTORY, parse, parseNode, pushParseAndPop,\n  pushSerializeAndPop, XML_SCHEMA_INSTANCE_URI} from '../xml.js';\n\n/**\n * @typedef {Object} Vec2\n * @property {number} x\n * @property {module:ol/style/IconAnchorUnits} xunits\n * @property {number} y\n * @property {module:ol/style/IconAnchorUnits} yunits\n * @property {module:ol/style/IconOrigin} origin\n */\n\n/**\n * @typedef {Object} GxTrackObject\n * @property {Array.<number>} flatCoordinates\n * @property {Array.<number>} whens\n */\n\n\n/**\n * @const\n * @type {Array.<string>}\n */\nconst GX_NAMESPACE_URIS = [\n  'http://www.google.com/kml/ext/2.2'\n];\n\n\n/**\n * @const\n * @type {Array.<null|string>}\n */\nconst NAMESPACE_URIS = [\n  null,\n  'http://earth.google.com/kml/2.0',\n  'http://earth.google.com/kml/2.1',\n  'http://earth.google.com/kml/2.2',\n  'http://www.opengis.net/kml/2.2'\n];\n\n\n/**\n * @const\n * @type {string}\n */\nconst SCHEMA_LOCATION = 'http://www.opengis.net/kml/2.2 ' +\n    'https://developers.google.com/kml/schema/kml22gx.xsd';\n\n\n/**\n * @type {Object.<string, module:ol/style/IconAnchorUnits>}\n */\nconst ICON_ANCHOR_UNITS_MAP = {\n  'fraction': IconAnchorUnits.FRACTION,\n  'pixels': IconAnchorUnits.PIXELS,\n  'insetPixels': IconAnchorUnits.PIXELS\n};\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst PLACEMARK_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'ExtendedData': extendedDataParser,\n    'Region': regionParser,\n    'MultiGeometry': makeObjectPropertySetter(\n      readMultiGeometry, 'geometry'),\n    'LineString': makeObjectPropertySetter(\n      readLineString, 'geometry'),\n    'LinearRing': makeObjectPropertySetter(\n      readLinearRing, 'geometry'),\n    'Point': makeObjectPropertySetter(\n      readPoint, 'geometry'),\n    'Polygon': makeObjectPropertySetter(\n      readPolygon, 'geometry'),\n    'Style': makeObjectPropertySetter(readStyle),\n    'StyleMap': placemarkStyleMapParser,\n    'address': makeObjectPropertySetter(readString),\n    'description': makeObjectPropertySetter(readString),\n    'name': makeObjectPropertySetter(readString),\n    'open': makeObjectPropertySetter(readBoolean),\n    'phoneNumber': makeObjectPropertySetter(readString),\n    'styleUrl': makeObjectPropertySetter(readURI),\n    'visibility': makeObjectPropertySetter(readBoolean)\n  }, makeStructureNS(\n    GX_NAMESPACE_URIS, {\n      'MultiTrack': makeObjectPropertySetter(\n        readGxMultiTrack, 'geometry'),\n      'Track': makeObjectPropertySetter(\n        readGxTrack, 'geometry')\n    }\n  ));\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst NETWORK_LINK_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'ExtendedData': extendedDataParser,\n    'Region': regionParser,\n    'Link': linkParser,\n    'address': makeObjectPropertySetter(readString),\n    'description': makeObjectPropertySetter(readString),\n    'name': makeObjectPropertySetter(readString),\n    'open': makeObjectPropertySetter(readBoolean),\n    'phoneNumber': makeObjectPropertySetter(readString),\n    'visibility': makeObjectPropertySetter(readBoolean)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst LINK_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'href': makeObjectPropertySetter(readURI)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst REGION_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'LatLonAltBox': latLonAltBoxParser,\n    'Lod': lodParser\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Array.<string>>}\n */\nconst KML_SEQUENCE = makeStructureNS(\n  NAMESPACE_URIS, [\n    'Document', 'Placemark'\n  ]);\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst KML_SERIALIZERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Document': makeChildAppender(writeDocument),\n    'Placemark': makeChildAppender(writePlacemark)\n  });\n\n\n/**\n * @type {module:ol/color~Color}\n */\nlet DEFAULT_COLOR;\n\n/**\n * @type {module:ol/style/Fill}\n */\nlet DEFAULT_FILL_STYLE = null;\n\n/**\n * Get the default fill style (or null if not yet set).\n * @return {module:ol/style/Fill} The default fill style.\n */\nexport function getDefaultFillStyle() {\n  return DEFAULT_FILL_STYLE;\n}\n\n/**\n * @type {module:ol/size~Size}\n */\nlet DEFAULT_IMAGE_STYLE_ANCHOR;\n\n/**\n * @type {module:ol/style/IconAnchorUnits}\n */\nlet DEFAULT_IMAGE_STYLE_ANCHOR_X_UNITS;\n\n/**\n * @type {module:ol/style/IconAnchorUnits}\n */\nlet DEFAULT_IMAGE_STYLE_ANCHOR_Y_UNITS;\n\n/**\n * @type {module:ol/size~Size}\n */\nlet DEFAULT_IMAGE_STYLE_SIZE;\n\n/**\n * @type {string}\n */\nlet DEFAULT_IMAGE_STYLE_SRC;\n\n/**\n * @type {number}\n */\nlet DEFAULT_IMAGE_SCALE_MULTIPLIER;\n\n/**\n * @type {module:ol/style/Image}\n */\nlet DEFAULT_IMAGE_STYLE = null;\n\n/**\n * Get the default image style (or null if not yet set).\n * @return {module:ol/style/Image} The default image style.\n */\nexport function getDefaultImageStyle() {\n  return DEFAULT_IMAGE_STYLE;\n}\n\n/**\n * @type {string}\n */\nlet DEFAULT_NO_IMAGE_STYLE;\n\n/**\n * @type {module:ol/style/Stroke}\n */\nlet DEFAULT_STROKE_STYLE = null;\n\n/**\n * Get the default stroke style (or null if not yet set).\n * @return {module:ol/style/Stroke} The default stroke style.\n */\nexport function getDefaultStrokeStyle() {\n  return DEFAULT_STROKE_STYLE;\n}\n\n/**\n * @type {module:ol/style/Stroke}\n */\nlet DEFAULT_TEXT_STROKE_STYLE;\n\n/**\n * @type {module:ol/style/Text}\n */\nlet DEFAULT_TEXT_STYLE = null;\n\n/**\n * Get the default text style (or null if not yet set).\n * @return {module:ol/style/Text} The default text style.\n */\nexport function getDefaultTextStyle() {\n  return DEFAULT_TEXT_STYLE;\n}\n\n/**\n * @type {module:ol/style/Style}\n */\nlet DEFAULT_STYLE = null;\n\n/**\n * Get the default style (or null if not yet set).\n * @return {module:ol/style/Style} The default style.\n */\nexport function getDefaultStyle() {\n  return DEFAULT_STYLE;\n}\n\n/**\n * @type {Array.<module:ol/style/Style>}\n */\nlet DEFAULT_STYLE_ARRAY = null;\n\n/**\n * Get the default style array (or null if not yet set).\n * @return {Array.<module:ol/style/Style>} The default style.\n */\nexport function getDefaultStyleArray() {\n  return DEFAULT_STYLE_ARRAY;\n}\n\n\nfunction createStyleDefaults() {\n\n  DEFAULT_COLOR = [255, 255, 255, 1];\n\n  DEFAULT_FILL_STYLE = new Fill({\n    color: DEFAULT_COLOR\n  });\n\n  DEFAULT_IMAGE_STYLE_ANCHOR = [20, 2]; // FIXME maybe [8, 32] ?\n\n  DEFAULT_IMAGE_STYLE_ANCHOR_X_UNITS = IconAnchorUnits.PIXELS;\n\n  DEFAULT_IMAGE_STYLE_ANCHOR_Y_UNITS = IconAnchorUnits.PIXELS;\n\n  DEFAULT_IMAGE_STYLE_SIZE = [64, 64];\n\n  DEFAULT_IMAGE_STYLE_SRC =\n      'https://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png';\n\n  DEFAULT_IMAGE_SCALE_MULTIPLIER = 0.5;\n\n  DEFAULT_IMAGE_STYLE = new Icon({\n    anchor: DEFAULT_IMAGE_STYLE_ANCHOR,\n    anchorOrigin: IconOrigin.BOTTOM_LEFT,\n    anchorXUnits: DEFAULT_IMAGE_STYLE_ANCHOR_X_UNITS,\n    anchorYUnits: DEFAULT_IMAGE_STYLE_ANCHOR_Y_UNITS,\n    crossOrigin: 'anonymous',\n    rotation: 0,\n    scale: DEFAULT_IMAGE_SCALE_MULTIPLIER,\n    size: DEFAULT_IMAGE_STYLE_SIZE,\n    src: DEFAULT_IMAGE_STYLE_SRC\n  });\n\n  DEFAULT_NO_IMAGE_STYLE = 'NO_IMAGE';\n\n  DEFAULT_STROKE_STYLE = new Stroke({\n    color: DEFAULT_COLOR,\n    width: 1\n  });\n\n  DEFAULT_TEXT_STROKE_STYLE = new Stroke({\n    color: [51, 51, 51, 1],\n    width: 2\n  });\n\n  DEFAULT_TEXT_STYLE = new Text({\n    font: 'bold 16px Helvetica',\n    fill: DEFAULT_FILL_STYLE,\n    stroke: DEFAULT_TEXT_STROKE_STYLE,\n    scale: 0.8\n  });\n\n  DEFAULT_STYLE = new Style({\n    fill: DEFAULT_FILL_STYLE,\n    image: DEFAULT_IMAGE_STYLE,\n    text: DEFAULT_TEXT_STYLE,\n    stroke: DEFAULT_STROKE_STYLE,\n    zIndex: 0\n  });\n\n  DEFAULT_STYLE_ARRAY = [DEFAULT_STYLE];\n\n}\n\n\n/**\n * @typedef {Object} Options\n * @property {boolean} [extractStyles=true] Extract styles from the KML.\n * @property {boolean} [showPointNames=true] Show names as labels for placemarks which contain points.\n * @property {Array.<module:ol/style/Style>} [defaultStyle] Default style. The\n * default default style is the same as Google Earth.\n * @property {boolean} [writeStyles=true] Write styles into KML.\n */\n\n\n/**\n * @classdesc\n * Feature format for reading and writing data in the KML format.\n *\n * {@link module:ol/format/KML~KML#readFeature} will read the first feature from\n * a KML source.\n *\n * MultiGeometries are converted into GeometryCollections if they are a mix of\n * geometry types, and into MultiPoint/MultiLineString/MultiPolygon if they are\n * all of the same type.\n *\n * Note that the KML format uses the URL() constructor. Older browsers such as IE\n * which do not support this will need a URL polyfill to be loaded before use.\n *\n * @api\n */\nclass KML extends XMLFeature {\n\n  /**\n   * @param {module:ol/format/KML~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n    super();\n\n    const options = opt_options ? opt_options : {};\n\n    if (!DEFAULT_STYLE_ARRAY) {\n      createStyleDefaults();\n    }\n\n    /**\n     * @inheritDoc\n     */\n    this.dataProjection = getProjection('EPSG:4326');\n\n    /**\n     * @private\n     * @type {Array.<module:ol/style/Style>}\n     */\n    this.defaultStyle_ = options.defaultStyle ?\n      options.defaultStyle : DEFAULT_STYLE_ARRAY;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.extractStyles_ = options.extractStyles !== undefined ?\n      options.extractStyles : true;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.writeStyles_ = options.writeStyles !== undefined ?\n      options.writeStyles : true;\n\n    /**\n     * @private\n     * @type {!Object.<string, (Array.<module:ol/style/Style>|string)>}\n     */\n    this.sharedStyles_ = {};\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.showPointNames_ = options.showPointNames !== undefined ?\n      options.showPointNames : true;\n\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   * @return {Array.<module:ol/Feature>|undefined} Features.\n   */\n  readDocumentOrFolder_(node, objectStack) {\n    // FIXME use scope somehow\n    const parsersNS = makeStructureNS(\n      NAMESPACE_URIS, {\n        'Document': makeArrayExtender(this.readDocumentOrFolder_, this),\n        'Folder': makeArrayExtender(this.readDocumentOrFolder_, this),\n        'Placemark': makeArrayPusher(this.readPlacemark_, this),\n        'Style': this.readSharedStyle_.bind(this),\n        'StyleMap': this.readSharedStyleMap_.bind(this)\n      });\n    /** @type {Array.<module:ol/Feature>} */\n    const features = pushParseAndPop([], parsersNS, node, objectStack, this);\n    if (features) {\n      return features;\n    } else {\n      return undefined;\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   * @return {module:ol/Feature|undefined} Feature.\n   */\n  readPlacemark_(node, objectStack) {\n    const object = pushParseAndPop({'geometry': null},\n      PLACEMARK_PARSERS, node, objectStack);\n    if (!object) {\n      return undefined;\n    }\n    const feature = new Feature();\n    const id = node.getAttribute('id');\n    if (id !== null) {\n      feature.setId(id);\n    }\n    const options = /** @type {module:ol/format/Feature~ReadOptions} */ (objectStack[0]);\n\n    const geometry = object['geometry'];\n    if (geometry) {\n      transformWithOptions(geometry, false, options);\n    }\n    feature.setGeometry(geometry);\n    delete object['geometry'];\n\n    if (this.extractStyles_) {\n      const style = object['Style'];\n      const styleUrl = object['styleUrl'];\n      const styleFunction = createFeatureStyleFunction(\n        style, styleUrl, this.defaultStyle_, this.sharedStyles_,\n        this.showPointNames_);\n      feature.setStyle(styleFunction);\n    }\n    delete object['Style'];\n    // we do not remove the styleUrl property from the object, so it\n    // gets stored on feature when setProperties is called\n\n    feature.setProperties(object);\n\n    return feature;\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   */\n  readSharedStyle_(node, objectStack) {\n    const id = node.getAttribute('id');\n    if (id !== null) {\n      const style = readStyle(node, objectStack);\n      if (style) {\n        let styleUri;\n        let baseURI = node.baseURI;\n        if (!baseURI || baseURI == 'about:blank') {\n          baseURI = window.location.href;\n        }\n        if (baseURI) {\n          const url = new URL('#' + id, baseURI);\n          styleUri = url.href;\n        } else {\n          styleUri = '#' + id;\n        }\n        this.sharedStyles_[styleUri] = style;\n      }\n    }\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @private\n   */\n  readSharedStyleMap_(node, objectStack) {\n    const id = node.getAttribute('id');\n    if (id === null) {\n      return;\n    }\n    const styleMapValue = readStyleMapValue(node, objectStack);\n    if (!styleMapValue) {\n      return;\n    }\n    let styleUri;\n    let baseURI = node.baseURI;\n    if (!baseURI || baseURI == 'about:blank') {\n      baseURI = window.location.href;\n    }\n    if (baseURI) {\n      const url = new URL('#' + id, baseURI);\n      styleUri = url.href;\n    } else {\n      styleUri = '#' + id;\n    }\n    this.sharedStyles_[styleUri] = styleMapValue;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFeatureFromNode(node, opt_options) {\n    if (!includes(NAMESPACE_URIS, node.namespaceURI)) {\n      return null;\n    }\n    const feature = this.readPlacemark_(\n      node, [this.getReadOptions(node, opt_options)]);\n    if (feature) {\n      return feature;\n    } else {\n      return null;\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFeaturesFromNode(node, opt_options) {\n    if (!includes(NAMESPACE_URIS, node.namespaceURI)) {\n      return [];\n    }\n    let features;\n    const localName = node.localName;\n    if (localName == 'Document' || localName == 'Folder') {\n      features = this.readDocumentOrFolder_(\n        node, [this.getReadOptions(node, opt_options)]);\n      if (features) {\n        return features;\n      } else {\n        return [];\n      }\n    } else if (localName == 'Placemark') {\n      const feature = this.readPlacemark_(\n        node, [this.getReadOptions(node, opt_options)]);\n      if (feature) {\n        return [feature];\n      } else {\n        return [];\n      }\n    } else if (localName == 'kml') {\n      features = [];\n      for (let n = node.firstElementChild; n; n = n.nextElementSibling) {\n        const fs = this.readFeaturesFromNode(n, opt_options);\n        if (fs) {\n          extend(features, fs);\n        }\n      }\n      return features;\n    } else {\n      return [];\n    }\n  }\n\n  /**\n   * Read the name of the KML.\n   *\n   * @param {Document|Node|string} source Source.\n   * @return {string|undefined} Name.\n   * @api\n   */\n  readName(source) {\n    if (isDocument(source)) {\n      return this.readNameFromDocument(/** @type {Document} */ (source));\n    } else if (isNode(source)) {\n      return this.readNameFromNode(/** @type {Node} */ (source));\n    } else if (typeof source === 'string') {\n      const doc = parse(source);\n      return this.readNameFromDocument(doc);\n    } else {\n      return undefined;\n    }\n  }\n\n  /**\n   * @param {Document} doc Document.\n   * @return {string|undefined} Name.\n   */\n  readNameFromDocument(doc) {\n    for (let n = doc.firstChild; n; n = n.nextSibling) {\n      if (n.nodeType == Node.ELEMENT_NODE) {\n        const name = this.readNameFromNode(n);\n        if (name) {\n          return name;\n        }\n      }\n    }\n    return undefined;\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @return {string|undefined} Name.\n   */\n  readNameFromNode(node) {\n    for (let n = node.firstElementChild; n; n = n.nextElementSibling) {\n      if (includes(NAMESPACE_URIS, n.namespaceURI) &&\n          n.localName == 'name') {\n        return readString(n);\n      }\n    }\n    for (let n = node.firstElementChild; n; n = n.nextElementSibling) {\n      const localName = n.localName;\n      if (includes(NAMESPACE_URIS, n.namespaceURI) &&\n          (localName == 'Document' ||\n           localName == 'Folder' ||\n           localName == 'Placemark' ||\n           localName == 'kml')) {\n        const name = this.readNameFromNode(n);\n        if (name) {\n          return name;\n        }\n      }\n    }\n    return undefined;\n  }\n\n  /**\n   * Read the network links of the KML.\n   *\n   * @param {Document|Node|string} source Source.\n   * @return {Array.<Object>} Network links.\n   * @api\n   */\n  readNetworkLinks(source) {\n    const networkLinks = [];\n    if (isDocument(source)) {\n      extend(networkLinks, this.readNetworkLinksFromDocument(\n        /** @type {Document} */ (source)));\n    } else if (isNode(source)) {\n      extend(networkLinks, this.readNetworkLinksFromNode(\n        /** @type {Node} */ (source)));\n    } else if (typeof source === 'string') {\n      const doc = parse(source);\n      extend(networkLinks, this.readNetworkLinksFromDocument(doc));\n    }\n    return networkLinks;\n  }\n\n  /**\n   * @param {Document} doc Document.\n   * @return {Array.<Object>} Network links.\n   */\n  readNetworkLinksFromDocument(doc) {\n    const networkLinks = [];\n    for (let n = doc.firstChild; n; n = n.nextSibling) {\n      if (n.nodeType == Node.ELEMENT_NODE) {\n        extend(networkLinks, this.readNetworkLinksFromNode(n));\n      }\n    }\n    return networkLinks;\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @return {Array.<Object>} Network links.\n   */\n  readNetworkLinksFromNode(node) {\n    const networkLinks = [];\n    for (let n = node.firstElementChild; n; n = n.nextElementSibling) {\n      if (includes(NAMESPACE_URIS, n.namespaceURI) &&\n          n.localName == 'NetworkLink') {\n        const obj = pushParseAndPop({}, NETWORK_LINK_PARSERS,\n          n, []);\n        networkLinks.push(obj);\n      }\n    }\n    for (let n = node.firstElementChild; n; n = n.nextElementSibling) {\n      const localName = n.localName;\n      if (includes(NAMESPACE_URIS, n.namespaceURI) &&\n          (localName == 'Document' ||\n           localName == 'Folder' ||\n           localName == 'kml')) {\n        extend(networkLinks, this.readNetworkLinksFromNode(n));\n      }\n    }\n    return networkLinks;\n  }\n\n  /**\n   * Read the regions of the KML.\n   *\n   * @param {Document|Node|string} source Source.\n   * @return {Array.<Object>} Regions.\n   * @api\n   */\n  readRegion(source) {\n    const regions = [];\n    if (isDocument(source)) {\n      extend(regions, this.readRegionFromDocument(\n        /** @type {Document} */ (source)));\n    } else if (isNode(source)) {\n      extend(regions, this.readRegionFromNode(\n        /** @type {Node} */ (source)));\n    } else if (typeof source === 'string') {\n      const doc = parse(source);\n      extend(regions, this.readRegionFromDocument(doc));\n    }\n    return regions;\n  }\n\n  /**\n   * @param {Document} doc Document.\n   * @return {Array.<Object>} Region.\n   */\n  readRegionFromDocument(doc) {\n    const regions = [];\n    for (let n = doc.firstChild; n; n = n.nextSibling) {\n      if (n.nodeType == Node.ELEMENT_NODE) {\n        extend(regions, this.readRegionFromNode(n));\n      }\n    }\n    return regions;\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @return {Array.<Object>} Region.\n   * @api\n   */\n  readRegionFromNode(node) {\n    const regions = [];\n    for (let n = node.firstElementChild; n; n = n.nextElementSibling) {\n      if (includes(NAMESPACE_URIS, n.namespaceURI) &&\n          n.localName == 'Region') {\n        const obj = pushParseAndPop({}, REGION_PARSERS,\n          n, []);\n        regions.push(obj);\n      }\n    }\n    for (let n = node.firstElementChild; n; n = n.nextElementSibling) {\n      const localName = n.localName;\n      if (includes(NAMESPACE_URIS, n.namespaceURI) &&\n          (localName == 'Document' ||\n           localName == 'Folder' ||\n           localName == 'kml')) {\n        extend(regions, this.readRegionFromNode(n));\n      }\n    }\n    return regions;\n  }\n\n  /**\n   * Encode an array of features in the KML format as an XML node. GeometryCollections,\n   * MultiPoints, MultiLineStrings, and MultiPolygons are output as MultiGeometries.\n   *\n   * @param {Array.<module:ol/Feature>} features Features.\n   * @param {module:ol/format/Feature~WriteOptions=} opt_options Options.\n   * @return {Node} Node.\n   * @override\n   * @api\n   */\n  writeFeaturesNode(features, opt_options) {\n    opt_options = this.adaptOptions(opt_options);\n    const kml = createElementNS(NAMESPACE_URIS[4], 'kml');\n    const xmlnsUri = 'http://www.w3.org/2000/xmlns/';\n    kml.setAttributeNS(xmlnsUri, 'xmlns:gx', GX_NAMESPACE_URIS[0]);\n    kml.setAttributeNS(xmlnsUri, 'xmlns:xsi', XML_SCHEMA_INSTANCE_URI);\n    kml.setAttributeNS(XML_SCHEMA_INSTANCE_URI, 'xsi:schemaLocation', SCHEMA_LOCATION);\n\n    const /** @type {module:ol/xml~NodeStackItem} */ context = {node: kml};\n    const properties = {};\n    if (features.length > 1) {\n      properties['Document'] = features;\n    } else if (features.length == 1) {\n      properties['Placemark'] = features[0];\n    }\n    const orderedKeys = KML_SEQUENCE[kml.namespaceURI];\n    const values = makeSequence(properties, orderedKeys);\n    pushSerializeAndPop(context, KML_SERIALIZERS,\n      OBJECT_PROPERTY_NODE_FACTORY, values, [opt_options], orderedKeys,\n      this);\n    return kml;\n  }\n}\n\n\n/**\n * @param {module:ol/style/Style|undefined} foundStyle Style.\n * @param {string} name Name.\n * @return {module:ol/style/Style} style Style.\n */\nfunction createNameStyleFunction(foundStyle, name) {\n  let textStyle = null;\n  const textOffset = [0, 0];\n  let textAlign = 'start';\n  if (foundStyle.getImage()) {\n    let imageSize = foundStyle.getImage().getImageSize();\n    if (imageSize === null) {\n      imageSize = DEFAULT_IMAGE_STYLE_SIZE;\n    }\n    if (imageSize.length == 2) {\n      const imageScale = foundStyle.getImage().getScale();\n      // Offset the label to be centered to the right of the icon, if there is\n      // one.\n      textOffset[0] = imageScale * imageSize[0] / 2;\n      textOffset[1] = -imageScale * imageSize[1] / 2;\n      textAlign = 'left';\n    }\n  }\n  if (foundStyle.getText() !== null) {\n    // clone the text style, customizing it with name, alignments and offset.\n    // Note that kml does not support many text options that OpenLayers does (rotation, textBaseline).\n    const foundText = foundStyle.getText();\n    textStyle = foundText.clone();\n    textStyle.setFont(foundText.getFont() || DEFAULT_TEXT_STYLE.getFont());\n    textStyle.setScale(foundText.getScale() || DEFAULT_TEXT_STYLE.getScale());\n    textStyle.setFill(foundText.getFill() || DEFAULT_TEXT_STYLE.getFill());\n    textStyle.setStroke(foundText.getStroke() || DEFAULT_TEXT_STROKE_STYLE);\n  } else {\n    textStyle = DEFAULT_TEXT_STYLE.clone();\n  }\n  textStyle.setText(name);\n  textStyle.setOffsetX(textOffset[0]);\n  textStyle.setOffsetY(textOffset[1]);\n  textStyle.setTextAlign(textAlign);\n\n  const nameStyle = new Style({\n    text: textStyle\n  });\n  return nameStyle;\n}\n\n\n/**\n * @param {Array.<module:ol/style/Style>|undefined} style Style.\n * @param {string} styleUrl Style URL.\n * @param {Array.<module:ol/style/Style>} defaultStyle Default style.\n * @param {!Object.<string, (Array.<module:ol/style/Style>|string)>} sharedStyles Shared styles.\n * @param {boolean|undefined} showPointNames true to show names for point placemarks.\n * @return {module:ol/style/Style~StyleFunction} Feature style function.\n */\nfunction createFeatureStyleFunction(style, styleUrl, defaultStyle, sharedStyles, showPointNames) {\n\n  return (\n    /**\n     * @param {module:ol/Feature} feature feature.\n     * @param {number} resolution Resolution.\n     * @return {Array.<module:ol/style/Style>} Style.\n     */\n    function(feature, resolution) {\n      let drawName = showPointNames;\n      /** @type {module:ol/style/Style|undefined} */\n      let nameStyle;\n      let name = '';\n      if (drawName) {\n        const geometry = feature.getGeometry();\n        if (geometry) {\n          drawName = geometry.getType() === GeometryType.POINT;\n        }\n      }\n\n      if (drawName) {\n        name = /** @type {string} */ (feature.get('name'));\n        drawName = drawName && name;\n      }\n\n      if (style) {\n        if (drawName) {\n          nameStyle = createNameStyleFunction(style[0], name);\n          return style.concat(nameStyle);\n        }\n        return style;\n      }\n      if (styleUrl) {\n        const foundStyle = findStyle(styleUrl, defaultStyle, sharedStyles);\n        if (drawName) {\n          nameStyle = createNameStyleFunction(foundStyle[0], name);\n          return foundStyle.concat(nameStyle);\n        }\n        return foundStyle;\n      }\n      if (drawName) {\n        nameStyle = createNameStyleFunction(defaultStyle[0], name);\n        return defaultStyle.concat(nameStyle);\n      }\n      return defaultStyle;\n    }\n  );\n}\n\n\n/**\n * @param {Array.<module:ol/style/Style>|string|undefined} styleValue Style value.\n * @param {Array.<module:ol/style/Style>} defaultStyle Default style.\n * @param {!Object.<string, (Array.<module:ol/style/Style>|string)>} sharedStyles\n * Shared styles.\n * @return {Array.<module:ol/style/Style>} Style.\n */\nfunction findStyle(styleValue, defaultStyle, sharedStyles) {\n  if (Array.isArray(styleValue)) {\n    return styleValue;\n  } else if (typeof styleValue === 'string') {\n    // KML files in the wild occasionally forget the leading `#` on styleUrls\n    // defined in the same document.  Add a leading `#` if it enables to find\n    // a style.\n    if (!(styleValue in sharedStyles) && ('#' + styleValue in sharedStyles)) {\n      styleValue = '#' + styleValue;\n    }\n    return findStyle(sharedStyles[styleValue], defaultStyle, sharedStyles);\n  } else {\n    return defaultStyle;\n  }\n}\n\n\n/**\n * @param {Node} node Node.\n * @return {module:ol/color~Color|undefined} Color.\n */\nfunction readColor(node) {\n  const s = getAllTextContent(node, false);\n  // The KML specification states that colors should not include a leading `#`\n  // but we tolerate them.\n  const m = /^\\s*#?\\s*([0-9A-Fa-f]{8})\\s*$/.exec(s);\n  if (m) {\n    const hexColor = m[1];\n    return [\n      parseInt(hexColor.substr(6, 2), 16),\n      parseInt(hexColor.substr(4, 2), 16),\n      parseInt(hexColor.substr(2, 2), 16),\n      parseInt(hexColor.substr(0, 2), 16) / 255\n    ];\n\n  } else {\n    return undefined;\n  }\n}\n\n\n/**\n * @param {Node} node Node.\n * @return {Array.<number>|undefined} Flat coordinates.\n */\nexport function readFlatCoordinates(node) {\n  let s = getAllTextContent(node, false);\n  const flatCoordinates = [];\n  // The KML specification states that coordinate tuples should not include\n  // spaces, but we tolerate them.\n  const re =\n      /^\\s*([+\\-]?\\d*\\.?\\d+(?:e[+\\-]?\\d+)?)\\s*,\\s*([+\\-]?\\d*\\.?\\d+(?:e[+\\-]?\\d+)?)(?:\\s*,\\s*([+\\-]?\\d*\\.?\\d+(?:e[+\\-]?\\d+)?))?\\s*/i;\n  let m;\n  while ((m = re.exec(s))) {\n    const x = parseFloat(m[1]);\n    const y = parseFloat(m[2]);\n    const z = m[3] ? parseFloat(m[3]) : 0;\n    flatCoordinates.push(x, y, z);\n    s = s.substr(m[0].length);\n  }\n  if (s !== '') {\n    return undefined;\n  }\n  return flatCoordinates;\n}\n\n\n/**\n * @param {Node} node Node.\n * @return {string} URI.\n */\nfunction readURI(node) {\n  const s = getAllTextContent(node, false).trim();\n  let baseURI = node.baseURI;\n  if (!baseURI || baseURI == 'about:blank') {\n    baseURI = window.location.href;\n  }\n  if (baseURI) {\n    const url = new URL(s, baseURI);\n    return url.href;\n  } else {\n    return s;\n  }\n}\n\n\n/**\n * @param {Node} node Node.\n * @return {module:ol/format/KML~Vec2} Vec2.\n */\nfunction readVec2(node) {\n  const xunits = node.getAttribute('xunits');\n  const yunits = node.getAttribute('yunits');\n  let origin;\n  if (xunits !== 'insetPixels') {\n    if (yunits !== 'insetPixels') {\n      origin = IconOrigin.BOTTOM_LEFT;\n    } else {\n      origin = IconOrigin.TOP_LEFT;\n    }\n  } else {\n    if (yunits !== 'insetPixels') {\n      origin = IconOrigin.BOTTOM_RIGHT;\n    } else {\n      origin = IconOrigin.TOP_RIGHT;\n    }\n  }\n  return {\n    x: parseFloat(node.getAttribute('x')),\n    xunits: ICON_ANCHOR_UNITS_MAP[xunits],\n    y: parseFloat(node.getAttribute('y')),\n    yunits: ICON_ANCHOR_UNITS_MAP[yunits],\n    origin: origin\n  };\n}\n\n\n/**\n * @param {Node} node Node.\n * @return {number|undefined} Scale.\n */\nfunction readScale(node) {\n  return readDecimal(node);\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst STYLE_MAP_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Pair': pairDataParser\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Array.<module:ol/style/Style>|string|undefined} StyleMap.\n */\nfunction readStyleMapValue(node, objectStack) {\n  return pushParseAndPop(undefined,\n    STYLE_MAP_PARSERS, node, objectStack);\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst ICON_STYLE_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Icon': makeObjectPropertySetter(readIcon),\n    'heading': makeObjectPropertySetter(readDecimal),\n    'hotSpot': makeObjectPropertySetter(readVec2),\n    'scale': makeObjectPropertySetter(readScale)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction iconStyleParser(node, objectStack) {\n  // FIXME refreshMode\n  // FIXME refreshInterval\n  // FIXME viewRefreshTime\n  // FIXME viewBoundScale\n  // FIXME viewFormat\n  // FIXME httpQuery\n  const object = pushParseAndPop(\n    {}, ICON_STYLE_PARSERS, node, objectStack);\n  if (!object) {\n    return;\n  }\n  const styleObject = /** @type {Object} */ (objectStack[objectStack.length - 1]);\n  const IconObject = 'Icon' in object ? object['Icon'] : {};\n  const drawIcon = (!('Icon' in object) || Object.keys(IconObject).length > 0);\n  let src;\n  const href = /** @type {string|undefined} */\n      (IconObject['href']);\n  if (href) {\n    src = href;\n  } else if (drawIcon) {\n    src = DEFAULT_IMAGE_STYLE_SRC;\n  }\n  let anchor, anchorXUnits, anchorYUnits;\n  let anchorOrigin = IconOrigin.BOTTOM_LEFT;\n  const hotSpot = /** @type {module:ol/format/KML~Vec2|undefined} */\n      (object['hotSpot']);\n  if (hotSpot) {\n    anchor = [hotSpot.x, hotSpot.y];\n    anchorXUnits = hotSpot.xunits;\n    anchorYUnits = hotSpot.yunits;\n    anchorOrigin = hotSpot.origin;\n  } else if (src === DEFAULT_IMAGE_STYLE_SRC) {\n    anchor = DEFAULT_IMAGE_STYLE_ANCHOR;\n    anchorXUnits = DEFAULT_IMAGE_STYLE_ANCHOR_X_UNITS;\n    anchorYUnits = DEFAULT_IMAGE_STYLE_ANCHOR_Y_UNITS;\n  } else if (/^http:\\/\\/maps\\.(?:google|gstatic)\\.com\\//.test(src)) {\n    anchor = [0.5, 0];\n    anchorXUnits = IconAnchorUnits.FRACTION;\n    anchorYUnits = IconAnchorUnits.FRACTION;\n  }\n\n  let offset;\n  const x = /** @type {number|undefined} */\n      (IconObject['x']);\n  const y = /** @type {number|undefined} */\n      (IconObject['y']);\n  if (x !== undefined && y !== undefined) {\n    offset = [x, y];\n  }\n\n  let size;\n  const w = /** @type {number|undefined} */\n      (IconObject['w']);\n  const h = /** @type {number|undefined} */\n      (IconObject['h']);\n  if (w !== undefined && h !== undefined) {\n    size = [w, h];\n  }\n\n  let rotation;\n  const heading = /** @type {number} */\n      (object['heading']);\n  if (heading !== undefined) {\n    rotation = toRadians(heading);\n  }\n\n  let scale = /** @type {number|undefined} */\n      (object['scale']);\n\n  if (drawIcon) {\n    if (src == DEFAULT_IMAGE_STYLE_SRC) {\n      size = DEFAULT_IMAGE_STYLE_SIZE;\n      if (scale === undefined) {\n        scale = DEFAULT_IMAGE_SCALE_MULTIPLIER;\n      }\n    }\n\n    const imageStyle = new Icon({\n      anchor: anchor,\n      anchorOrigin: anchorOrigin,\n      anchorXUnits: anchorXUnits,\n      anchorYUnits: anchorYUnits,\n      crossOrigin: 'anonymous', // FIXME should this be configurable?\n      offset: offset,\n      offsetOrigin: IconOrigin.BOTTOM_LEFT,\n      rotation: rotation,\n      scale: scale,\n      size: size,\n      src: src\n    });\n    styleObject['imageStyle'] = imageStyle;\n  } else {\n    // handle the case when we explicitly want to draw no icon.\n    styleObject['imageStyle'] = DEFAULT_NO_IMAGE_STYLE;\n  }\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst LABEL_STYLE_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'color': makeObjectPropertySetter(readColor),\n    'scale': makeObjectPropertySetter(readScale)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction labelStyleParser(node, objectStack) {\n  // FIXME colorMode\n  const object = pushParseAndPop(\n    {}, LABEL_STYLE_PARSERS, node, objectStack);\n  if (!object) {\n    return;\n  }\n  const styleObject = objectStack[objectStack.length - 1];\n  const textStyle = new Text({\n    fill: new Fill({\n      color: /** @type {module:ol/color~Color} */\n          ('color' in object ? object['color'] : DEFAULT_COLOR)\n    }),\n    scale: /** @type {number|undefined} */\n        (object['scale'])\n  });\n  styleObject['textStyle'] = textStyle;\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst LINE_STYLE_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'color': makeObjectPropertySetter(readColor),\n    'width': makeObjectPropertySetter(readDecimal)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction lineStyleParser(node, objectStack) {\n  // FIXME colorMode\n  // FIXME gx:outerColor\n  // FIXME gx:outerWidth\n  // FIXME gx:physicalWidth\n  // FIXME gx:labelVisibility\n  const object = pushParseAndPop(\n    {}, LINE_STYLE_PARSERS, node, objectStack);\n  if (!object) {\n    return;\n  }\n  const styleObject = objectStack[objectStack.length - 1];\n  const strokeStyle = new Stroke({\n    color: /** @type {module:ol/color~Color} */\n        ('color' in object ? object['color'] : DEFAULT_COLOR),\n    width: /** @type {number} */ ('width' in object ? object['width'] : 1)\n  });\n  styleObject['strokeStyle'] = strokeStyle;\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst POLY_STYLE_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'color': makeObjectPropertySetter(readColor),\n    'fill': makeObjectPropertySetter(readBoolean),\n    'outline': makeObjectPropertySetter(readBoolean)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction polyStyleParser(node, objectStack) {\n  // FIXME colorMode\n  const object = pushParseAndPop(\n    {}, POLY_STYLE_PARSERS, node, objectStack);\n  if (!object) {\n    return;\n  }\n  const styleObject = objectStack[objectStack.length - 1];\n  const fillStyle = new Fill({\n    color: /** @type {module:ol/color~Color} */\n        ('color' in object ? object['color'] : DEFAULT_COLOR)\n  });\n  styleObject['fillStyle'] = fillStyle;\n  const fill = /** @type {boolean|undefined} */ (object['fill']);\n  if (fill !== undefined) {\n    styleObject['fill'] = fill;\n  }\n  const outline = /** @type {boolean|undefined} */ (object['outline']);\n  if (outline !== undefined) {\n    styleObject['outline'] = outline;\n  }\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst FLAT_LINEAR_RING_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'coordinates': makeReplacer(readFlatCoordinates)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Array.<number>} LinearRing flat coordinates.\n */\nfunction readFlatLinearRing(node, objectStack) {\n  return pushParseAndPop(null,\n    FLAT_LINEAR_RING_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction gxCoordParser(node, objectStack) {\n  const gxTrackObject = /** @type {module:ol/format/KML~GxTrackObject} */\n      (objectStack[objectStack.length - 1]);\n  const flatCoordinates = gxTrackObject.flatCoordinates;\n  const s = getAllTextContent(node, false);\n  const re =\n      /^\\s*([+\\-]?\\d+(?:\\.\\d*)?(?:e[+\\-]?\\d*)?)\\s+([+\\-]?\\d+(?:\\.\\d*)?(?:e[+\\-]?\\d*)?)\\s+([+\\-]?\\d+(?:\\.\\d*)?(?:e[+\\-]?\\d*)?)\\s*$/i;\n  const m = re.exec(s);\n  if (m) {\n    const x = parseFloat(m[1]);\n    const y = parseFloat(m[2]);\n    const z = parseFloat(m[3]);\n    flatCoordinates.push(x, y, z, 0);\n  } else {\n    flatCoordinates.push(0, 0, 0, 0);\n  }\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst GX_MULTITRACK_GEOMETRY_PARSERS = makeStructureNS(\n  GX_NAMESPACE_URIS, {\n    'Track': makeArrayPusher(readGxTrack)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {module:ol/geom/MultiLineString|undefined} MultiLineString.\n */\nfunction readGxMultiTrack(node, objectStack) {\n  const lineStrings = pushParseAndPop([],\n    GX_MULTITRACK_GEOMETRY_PARSERS, node, objectStack);\n  if (!lineStrings) {\n    return undefined;\n  }\n  return new MultiLineString(lineStrings);\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst GX_TRACK_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'when': whenParser\n  }, makeStructureNS(\n    GX_NAMESPACE_URIS, {\n      'coord': gxCoordParser\n    }));\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {module:ol/geom/LineString|undefined} LineString.\n */\nfunction readGxTrack(node, objectStack) {\n  const gxTrackObject = pushParseAndPop(\n    /** @type {module:ol/format/KML~GxTrackObject} */ ({\n      flatCoordinates: [],\n      whens: []\n    }), GX_TRACK_PARSERS, node, objectStack);\n  if (!gxTrackObject) {\n    return undefined;\n  }\n  const flatCoordinates = gxTrackObject.flatCoordinates;\n  const whens = gxTrackObject.whens;\n  for (let i = 0, ii = Math.min(flatCoordinates.length, whens.length); i < ii; ++i) {\n    flatCoordinates[4 * i + 3] = whens[i];\n  }\n  return new LineString(flatCoordinates, GeometryLayout.XYZM);\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst ICON_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'href': makeObjectPropertySetter(readURI)\n  }, makeStructureNS(\n    GX_NAMESPACE_URIS, {\n      'x': makeObjectPropertySetter(readDecimal),\n      'y': makeObjectPropertySetter(readDecimal),\n      'w': makeObjectPropertySetter(readDecimal),\n      'h': makeObjectPropertySetter(readDecimal)\n    }));\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object} Icon object.\n */\nfunction readIcon(node, objectStack) {\n  const iconObject = pushParseAndPop(\n    {}, ICON_PARSERS, node, objectStack);\n  if (iconObject) {\n    return iconObject;\n  } else {\n    return null;\n  }\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst GEOMETRY_FLAT_COORDINATES_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'coordinates': makeReplacer(readFlatCoordinates)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Array.<number>} Flat coordinates.\n */\nfunction readFlatCoordinatesFromNode(node, objectStack) {\n  return pushParseAndPop(null,\n    GEOMETRY_FLAT_COORDINATES_PARSERS, node, objectStack);\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst EXTRUDE_AND_ALTITUDE_MODE_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'extrude': makeObjectPropertySetter(readBoolean),\n    'tessellate': makeObjectPropertySetter(readBoolean),\n    'altitudeMode': makeObjectPropertySetter(readString)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {module:ol/geom/LineString|undefined} LineString.\n */\nfunction readLineString(node, objectStack) {\n  const properties = pushParseAndPop({},\n    EXTRUDE_AND_ALTITUDE_MODE_PARSERS, node,\n    objectStack);\n  const flatCoordinates =\n      readFlatCoordinatesFromNode(node, objectStack);\n  if (flatCoordinates) {\n    const lineString = new LineString(flatCoordinates, GeometryLayout.XYZ);\n    lineString.setProperties(properties);\n    return lineString;\n  } else {\n    return undefined;\n  }\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {module:ol/geom/Polygon|undefined} Polygon.\n */\nfunction readLinearRing(node, objectStack) {\n  const properties = pushParseAndPop({},\n    EXTRUDE_AND_ALTITUDE_MODE_PARSERS, node,\n    objectStack);\n  const flatCoordinates =\n      readFlatCoordinatesFromNode(node, objectStack);\n  if (flatCoordinates) {\n    const polygon = new Polygon(flatCoordinates, GeometryLayout.XYZ, [flatCoordinates.length]);\n    polygon.setProperties(properties);\n    return polygon;\n  } else {\n    return undefined;\n  }\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst MULTI_GEOMETRY_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'LineString': makeArrayPusher(readLineString),\n    'LinearRing': makeArrayPusher(readLinearRing),\n    'MultiGeometry': makeArrayPusher(readMultiGeometry),\n    'Point': makeArrayPusher(readPoint),\n    'Polygon': makeArrayPusher(readPolygon)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {module:ol/geom/Geometry} Geometry.\n */\nfunction readMultiGeometry(node, objectStack) {\n  const geometries = pushParseAndPop([],\n    MULTI_GEOMETRY_PARSERS, node, objectStack);\n  if (!geometries) {\n    return null;\n  }\n  if (geometries.length === 0) {\n    return new GeometryCollection(geometries);\n  }\n  /** @type {module:ol/geom/Geometry} */\n  let multiGeometry;\n  let homogeneous = true;\n  const type = geometries[0].getType();\n  let geometry;\n  for (let i = 1, ii = geometries.length; i < ii; ++i) {\n    geometry = geometries[i];\n    if (geometry.getType() != type) {\n      homogeneous = false;\n      break;\n    }\n  }\n  if (homogeneous) {\n    let layout;\n    let flatCoordinates;\n    if (type == GeometryType.POINT) {\n      const point = geometries[0];\n      layout = point.getLayout();\n      flatCoordinates = point.getFlatCoordinates();\n      for (let i = 1, ii = geometries.length; i < ii; ++i) {\n        geometry = geometries[i];\n        extend(flatCoordinates, geometry.getFlatCoordinates());\n      }\n      multiGeometry = new MultiPoint(flatCoordinates, layout);\n      setCommonGeometryProperties(multiGeometry, geometries);\n    } else if (type == GeometryType.LINE_STRING) {\n      multiGeometry = new MultiLineString(geometries);\n      setCommonGeometryProperties(multiGeometry, geometries);\n    } else if (type == GeometryType.POLYGON) {\n      multiGeometry = new MultiPolygon(geometries);\n      setCommonGeometryProperties(multiGeometry, geometries);\n    } else if (type == GeometryType.GEOMETRY_COLLECTION) {\n      multiGeometry = new GeometryCollection(geometries);\n    } else {\n      assert(false, 37); // Unknown geometry type found\n    }\n  } else {\n    multiGeometry = new GeometryCollection(geometries);\n  }\n  return (\n    /** @type {module:ol/geom/Geometry} */ (multiGeometry)\n  );\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {module:ol/geom/Point|undefined} Point.\n */\nfunction readPoint(node, objectStack) {\n  const properties = pushParseAndPop({},\n    EXTRUDE_AND_ALTITUDE_MODE_PARSERS, node,\n    objectStack);\n  const flatCoordinates =\n      readFlatCoordinatesFromNode(node, objectStack);\n  if (flatCoordinates) {\n    const point = new Point(flatCoordinates, GeometryLayout.XYZ);\n    point.setProperties(properties);\n    return point;\n  } else {\n    return undefined;\n  }\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst FLAT_LINEAR_RINGS_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'innerBoundaryIs': innerBoundaryIsParser,\n    'outerBoundaryIs': outerBoundaryIsParser\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {module:ol/geom/Polygon|undefined} Polygon.\n */\nfunction readPolygon(node, objectStack) {\n  const properties = pushParseAndPop(/** @type {Object<string,*>} */ ({}),\n    EXTRUDE_AND_ALTITUDE_MODE_PARSERS, node,\n    objectStack);\n  const flatLinearRings = pushParseAndPop([null],\n    FLAT_LINEAR_RINGS_PARSERS, node, objectStack);\n  if (flatLinearRings && flatLinearRings[0]) {\n    const flatCoordinates = flatLinearRings[0];\n    const ends = [flatCoordinates.length];\n    for (let i = 1, ii = flatLinearRings.length; i < ii; ++i) {\n      extend(flatCoordinates, flatLinearRings[i]);\n      ends.push(flatCoordinates.length);\n    }\n    const polygon = new Polygon(flatCoordinates, GeometryLayout.XYZ, ends);\n    polygon.setProperties(properties);\n    return polygon;\n  } else {\n    return undefined;\n  }\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst STYLE_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'IconStyle': iconStyleParser,\n    'LabelStyle': labelStyleParser,\n    'LineStyle': lineStyleParser,\n    'PolyStyle': polyStyleParser\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Array.<module:ol/style/Style>} Style.\n */\nfunction readStyle(node, objectStack) {\n  const styleObject = pushParseAndPop(\n    {}, STYLE_PARSERS, node, objectStack);\n  if (!styleObject) {\n    return null;\n  }\n  let fillStyle = /** @type {module:ol/style/Fill} */\n      ('fillStyle' in styleObject ?\n        styleObject['fillStyle'] : DEFAULT_FILL_STYLE);\n  const fill = /** @type {boolean|undefined} */ (styleObject['fill']);\n  if (fill !== undefined && !fill) {\n    fillStyle = null;\n  }\n  let imageStyle = /** @type {module:ol/style/Image} */\n      ('imageStyle' in styleObject ?\n        styleObject['imageStyle'] : DEFAULT_IMAGE_STYLE);\n  if (imageStyle == DEFAULT_NO_IMAGE_STYLE) {\n    imageStyle = undefined;\n  }\n  const textStyle = /** @type {module:ol/style/Text} */\n      ('textStyle' in styleObject ?\n        styleObject['textStyle'] : DEFAULT_TEXT_STYLE);\n  let strokeStyle = /** @type {module:ol/style/Stroke} */\n      ('strokeStyle' in styleObject ?\n        styleObject['strokeStyle'] : DEFAULT_STROKE_STYLE);\n  const outline = /** @type {boolean|undefined} */\n      (styleObject['outline']);\n  if (outline !== undefined && !outline) {\n    strokeStyle = null;\n  }\n  return [new Style({\n    fill: fillStyle,\n    image: imageStyle,\n    stroke: strokeStyle,\n    text: textStyle,\n    zIndex: undefined // FIXME\n  })];\n}\n\n\n/**\n * Reads an array of geometries and creates arrays for common geometry\n * properties. Then sets them to the multi geometry.\n * @param {module:ol/geom/MultiPoint|module:ol/geom/MultiLineString|module:ol/geom/MultiPolygon}\n *     multiGeometry A multi-geometry.\n * @param {Array.<module:ol/geom/Geometry>} geometries List of geometries.\n */\nfunction setCommonGeometryProperties(multiGeometry, geometries) {\n  const ii = geometries.length;\n  const extrudes = new Array(geometries.length);\n  const tessellates = new Array(geometries.length);\n  const altitudeModes = new Array(geometries.length);\n  let hasExtrude, hasTessellate, hasAltitudeMode;\n  hasExtrude = hasTessellate = hasAltitudeMode = false;\n  for (let i = 0; i < ii; ++i) {\n    const geometry = geometries[i];\n    extrudes[i] = geometry.get('extrude');\n    tessellates[i] = geometry.get('tessellate');\n    altitudeModes[i] = geometry.get('altitudeMode');\n    hasExtrude = hasExtrude || extrudes[i] !== undefined;\n    hasTessellate = hasTessellate || tessellates[i] !== undefined;\n    hasAltitudeMode = hasAltitudeMode || altitudeModes[i];\n  }\n  if (hasExtrude) {\n    multiGeometry.set('extrude', extrudes);\n  }\n  if (hasTessellate) {\n    multiGeometry.set('tessellate', tessellates);\n  }\n  if (hasAltitudeMode) {\n    multiGeometry.set('altitudeMode', altitudeModes);\n  }\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst DATA_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'displayName': makeObjectPropertySetter(readString),\n    'value': makeObjectPropertySetter(readString)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction dataParser(node, objectStack) {\n  const name = node.getAttribute('name');\n  parseNode(DATA_PARSERS, node, objectStack);\n  const featureObject = /** @type {Object} */ (objectStack[objectStack.length - 1]);\n  if (name !== null) {\n    featureObject[name] = featureObject.value;\n  } else if (featureObject.displayName !== null) {\n    featureObject[featureObject.displayName] = featureObject.value;\n  }\n  delete featureObject['value'];\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst EXTENDED_DATA_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Data': dataParser,\n    'SchemaData': schemaDataParser\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction extendedDataParser(node, objectStack) {\n  parseNode(EXTENDED_DATA_PARSERS, node, objectStack);\n}\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction regionParser(node, objectStack) {\n  parseNode(REGION_PARSERS, node, objectStack);\n}\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst PAIR_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Style': makeObjectPropertySetter(readStyle),\n    'key': makeObjectPropertySetter(readString),\n    'styleUrl': makeObjectPropertySetter(readURI)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction pairDataParser(node, objectStack) {\n  const pairObject = pushParseAndPop(\n    {}, PAIR_PARSERS, node, objectStack);\n  if (!pairObject) {\n    return;\n  }\n  const key = /** @type {string|undefined} */\n      (pairObject['key']);\n  if (key && key == 'normal') {\n    const styleUrl = /** @type {string|undefined} */\n        (pairObject['styleUrl']);\n    if (styleUrl) {\n      objectStack[objectStack.length - 1] = styleUrl;\n    }\n    const Style = /** @type {module:ol/style/Style} */\n        (pairObject['Style']);\n    if (Style) {\n      objectStack[objectStack.length - 1] = Style;\n    }\n  }\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction placemarkStyleMapParser(node, objectStack) {\n  const styleMapValue = readStyleMapValue(node, objectStack);\n  if (!styleMapValue) {\n    return;\n  }\n  const placemarkObject = objectStack[objectStack.length - 1];\n  if (Array.isArray(styleMapValue)) {\n    placemarkObject['Style'] = styleMapValue;\n  } else if (typeof styleMapValue === 'string') {\n    placemarkObject['styleUrl'] = styleMapValue;\n  } else {\n    assert(false, 38); // `styleMapValue` has an unknown type\n  }\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst SCHEMA_DATA_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'SimpleData': simpleDataParser\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction schemaDataParser(node, objectStack) {\n  parseNode(SCHEMA_DATA_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction simpleDataParser(node, objectStack) {\n  const name = node.getAttribute('name');\n  if (name !== null) {\n    const data = readString(node);\n    const featureObject = /** @type {Object} */ (objectStack[objectStack.length - 1]);\n    featureObject[name] = data;\n  }\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst LAT_LON_ALT_BOX_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'altitudeMode': makeObjectPropertySetter(readString),\n    'minAltitude': makeObjectPropertySetter(readDecimal),\n    'maxAltitude': makeObjectPropertySetter(readDecimal),\n    'north': makeObjectPropertySetter(readDecimal),\n    'south': makeObjectPropertySetter(readDecimal),\n    'east': makeObjectPropertySetter(readDecimal),\n    'west': makeObjectPropertySetter(readDecimal)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction latLonAltBoxParser(node, objectStack) {\n  const object = pushParseAndPop({}, LAT_LON_ALT_BOX_PARSERS, node, objectStack);\n  if (!object) {\n    return;\n  }\n  const regionObject = /** @type {Object} */ (objectStack[objectStack.length - 1]);\n  const extent = [\n    parseFloat(object['west']),\n    parseFloat(object['south']),\n    parseFloat(object['east']),\n    parseFloat(object['north'])\n  ];\n  regionObject['extent'] = extent;\n  regionObject['altitudeMode'] = object['altitudeMode'];\n  regionObject['minAltitude'] = parseFloat(object['minAltitude']);\n  regionObject['maxAltitude'] = parseFloat(object['maxAltitude']);\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst LOD_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'minLodPixels': makeObjectPropertySetter(readDecimal),\n    'maxLodPixels': makeObjectPropertySetter(readDecimal),\n    'minFadeExtent': makeObjectPropertySetter(readDecimal),\n    'maxFadeExtent': makeObjectPropertySetter(readDecimal)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction lodParser(node, objectStack) {\n  const object = pushParseAndPop({}, LOD_PARSERS, node, objectStack);\n  if (!object) {\n    return;\n  }\n  const lodObject = /** @type {Object} */ (objectStack[objectStack.length - 1]);\n  lodObject['minLodPixels'] = parseFloat(object['minLodPixels']);\n  lodObject['maxLodPixels'] = parseFloat(object['maxLodPixels']);\n  lodObject['minFadeExtent'] = parseFloat(object['minFadeExtent']);\n  lodObject['maxFadeExtent'] = parseFloat(object['maxFadeExtent']);\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst INNER_BOUNDARY_IS_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'LinearRing': makeReplacer(readFlatLinearRing)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction innerBoundaryIsParser(node, objectStack) {\n  /** @type {Array.<number>|undefined} */\n  const flatLinearRing = pushParseAndPop(undefined,\n    INNER_BOUNDARY_IS_PARSERS, node, objectStack);\n  if (flatLinearRing) {\n    const flatLinearRings = /** @type {Array.<Array.<number>>} */\n        (objectStack[objectStack.length - 1]);\n    flatLinearRings.push(flatLinearRing);\n  }\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst OUTER_BOUNDARY_IS_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'LinearRing': makeReplacer(readFlatLinearRing)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction outerBoundaryIsParser(node, objectStack) {\n  /** @type {Array.<number>|undefined} */\n  const flatLinearRing = pushParseAndPop(undefined,\n    OUTER_BOUNDARY_IS_PARSERS, node, objectStack);\n  if (flatLinearRing) {\n    const flatLinearRings = /** @type {Array.<Array.<number>>} */\n        (objectStack[objectStack.length - 1]);\n    flatLinearRings[0] = flatLinearRing;\n  }\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction linkParser(node, objectStack) {\n  parseNode(LINK_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction whenParser(node, objectStack) {\n  const gxTrackObject = /** @type {module:ol/format/KML~GxTrackObject} */\n      (objectStack[objectStack.length - 1]);\n  const whens = gxTrackObject.whens;\n  const s = getAllTextContent(node, false);\n  const when = Date.parse(s);\n  whens.push(isNaN(when) ? 0 : when);\n}\n\n\n/**\n * @param {Node} node Node to append a TextNode with the color to.\n * @param {module:ol/color~Color|string} color Color.\n */\nfunction writeColorTextNode(node, color) {\n  const rgba = asArray(color);\n  const opacity = (rgba.length == 4) ? rgba[3] : 1;\n  const abgr = [opacity * 255, rgba[2], rgba[1], rgba[0]];\n  for (let i = 0; i < 4; ++i) {\n    const hex = parseInt(abgr[i], 10).toString(16);\n    abgr[i] = (hex.length == 1) ? '0' + hex : hex;\n  }\n  writeStringTextNode(node, abgr.join(''));\n}\n\n\n/**\n * @param {Node} node Node to append a TextNode with the coordinates to.\n * @param {Array.<number>} coordinates Coordinates.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction writeCoordinatesTextNode(node, coordinates, objectStack) {\n  const context = objectStack[objectStack.length - 1];\n\n  const layout = context['layout'];\n  const stride = context['stride'];\n\n  let dimension;\n  if (layout == GeometryLayout.XY ||\n      layout == GeometryLayout.XYM) {\n    dimension = 2;\n  } else if (layout == GeometryLayout.XYZ ||\n      layout == GeometryLayout.XYZM) {\n    dimension = 3;\n  } else {\n    assert(false, 34); // Invalid geometry layout\n  }\n\n  const ii = coordinates.length;\n  let text = '';\n  if (ii > 0) {\n    text += coordinates[0];\n    for (let d = 1; d < dimension; ++d) {\n      text += ',' + coordinates[d];\n    }\n    for (let i = stride; i < ii; i += stride) {\n      text += ' ' + coordinates[i];\n      for (let d = 1; d < dimension; ++d) {\n        text += ',' + coordinates[i + d];\n      }\n    }\n  }\n  writeStringTextNode(node, text);\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst EXTENDEDDATA_NODE_SERIALIZERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Data': makeChildAppender(writeDataNode),\n    'value': makeChildAppender(writeDataNodeValue),\n    'displayName': makeChildAppender(writeDataNodeName)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {{name: *, value: *}} pair Name value pair.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction writeDataNode(node, pair, objectStack) {\n  node.setAttribute('name', pair.name);\n  const /** @type {module:ol/xml~NodeStackItem} */ context = {node: node};\n  const value = pair.value;\n\n  if (typeof value == 'object') {\n    if (value !== null && value.displayName) {\n      pushSerializeAndPop(context, EXTENDEDDATA_NODE_SERIALIZERS,\n        OBJECT_PROPERTY_NODE_FACTORY, [value.displayName], objectStack, ['displayName']);\n    }\n\n    if (value !== null && value.value) {\n      pushSerializeAndPop(context, EXTENDEDDATA_NODE_SERIALIZERS,\n        OBJECT_PROPERTY_NODE_FACTORY, [value.value], objectStack, ['value']);\n    }\n  } else {\n    pushSerializeAndPop(context, EXTENDEDDATA_NODE_SERIALIZERS,\n      OBJECT_PROPERTY_NODE_FACTORY, [value], objectStack, ['value']);\n  }\n}\n\n\n/**\n * @param {Node} node Node to append a TextNode with the name to.\n * @param {string} name DisplayName.\n */\nfunction writeDataNodeName(node, name) {\n  writeCDATASection(node, name);\n}\n\n\n/**\n * @param {Node} node Node to append a CDATA Section with the value to.\n * @param {string} value Value.\n */\nfunction writeDataNodeValue(node, value) {\n  writeStringTextNode(node, value);\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst DOCUMENT_SERIALIZERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Placemark': makeChildAppender(writePlacemark)\n  });\n\n\n/**\n * @const\n * @param {*} value Value.\n * @param {Array.<*>} objectStack Object stack.\n * @param {string=} opt_nodeName Node name.\n * @return {Node|undefined} Node.\n */\nconst DOCUMENT_NODE_FACTORY = function(value, objectStack, opt_nodeName) {\n  const parentNode = objectStack[objectStack.length - 1].node;\n  return createElementNS(parentNode.namespaceURI, 'Placemark');\n};\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<module:ol/Feature>} features Features.\n * @param {Array.<*>} objectStack Object stack.\n * @this {module:ol/format/KML}\n */\nfunction writeDocument(node, features, objectStack) {\n  const /** @type {module:ol/xml~NodeStackItem} */ context = {node: node};\n  pushSerializeAndPop(context, DOCUMENT_SERIALIZERS,\n    DOCUMENT_NODE_FACTORY, features, objectStack, undefined,\n    this);\n}\n\n\n/**\n * A factory for creating Data nodes.\n * @const\n * @type {function(*, Array.<*>): (Node|undefined)}\n */\nconst DATA_NODE_FACTORY = makeSimpleNodeFactory('Data');\n\n\n/**\n * @param {Node} node Node.\n * @param {{names: Array<string>, values: (Array<*>)}} namesAndValues Names and values.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction writeExtendedData(node, namesAndValues, objectStack) {\n  const /** @type {module:ol/xml~NodeStackItem} */ context = {node: node};\n  const names = namesAndValues.names;\n  const values = namesAndValues.values;\n  const length = names.length;\n\n  for (let i = 0; i < length; i++) {\n    pushSerializeAndPop(context, EXTENDEDDATA_NODE_SERIALIZERS,\n      DATA_NODE_FACTORY, [{name: names[i], value: values[i]}], objectStack);\n  }\n}\n\n\n/**\n * @const\n * @type {Object.<string, Array.<string>>}\n */\nconst ICON_SEQUENCE = makeStructureNS(\n  NAMESPACE_URIS, [\n    'href'\n  ],\n  makeStructureNS(GX_NAMESPACE_URIS, [\n    'x', 'y', 'w', 'h'\n  ]));\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst ICON_SERIALIZERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'href': makeChildAppender(writeStringTextNode)\n  }, makeStructureNS(\n    GX_NAMESPACE_URIS, {\n      'x': makeChildAppender(writeDecimalTextNode),\n      'y': makeChildAppender(writeDecimalTextNode),\n      'w': makeChildAppender(writeDecimalTextNode),\n      'h': makeChildAppender(writeDecimalTextNode)\n    }));\n\n\n/**\n * @const\n * @param {*} value Value.\n * @param {Array.<*>} objectStack Object stack.\n * @param {string=} opt_nodeName Node name.\n * @return {Node|undefined} Node.\n */\nconst GX_NODE_FACTORY = function(value, objectStack, opt_nodeName) {\n  return createElementNS(GX_NAMESPACE_URIS[0],\n    'gx:' + opt_nodeName);\n};\n\n\n/**\n * @param {Node} node Node.\n * @param {Object} icon Icon object.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction writeIcon(node, icon, objectStack) {\n  const /** @type {module:ol/xml~NodeStackItem} */ context = {node: node};\n  const parentNode = objectStack[objectStack.length - 1].node;\n  let orderedKeys = ICON_SEQUENCE[parentNode.namespaceURI];\n  let values = makeSequence(icon, orderedKeys);\n  pushSerializeAndPop(context,\n    ICON_SERIALIZERS, OBJECT_PROPERTY_NODE_FACTORY,\n    values, objectStack, orderedKeys);\n  orderedKeys =\n      ICON_SEQUENCE[GX_NAMESPACE_URIS[0]];\n  values = makeSequence(icon, orderedKeys);\n  pushSerializeAndPop(context, ICON_SERIALIZERS,\n    GX_NODE_FACTORY, values, objectStack, orderedKeys);\n}\n\n\n/**\n * @const\n * @type {Object.<string, Array.<string>>}\n */\nconst ICON_STYLE_SEQUENCE = makeStructureNS(\n  NAMESPACE_URIS, [\n    'scale', 'heading', 'Icon', 'hotSpot'\n  ]);\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst ICON_STYLE_SERIALIZERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Icon': makeChildAppender(writeIcon),\n    'heading': makeChildAppender(writeDecimalTextNode),\n    'hotSpot': makeChildAppender(writeVec2),\n    'scale': makeChildAppender(writeScaleTextNode)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/style/Icon} style Icon style.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction writeIconStyle(node, style, objectStack) {\n  const /** @type {module:ol/xml~NodeStackItem} */ context = {node: node};\n  const properties = {};\n  const src = style.getSrc();\n  const size = style.getSize();\n  const iconImageSize = style.getImageSize();\n  const iconProperties = {\n    'href': src\n  };\n\n  if (size) {\n    iconProperties['w'] = size[0];\n    iconProperties['h'] = size[1];\n    const anchor = style.getAnchor(); // top-left\n    const origin = style.getOrigin(); // top-left\n\n    if (origin && iconImageSize && origin[0] !== 0 && origin[1] !== size[1]) {\n      iconProperties['x'] = origin[0];\n      iconProperties['y'] = iconImageSize[1] - (origin[1] + size[1]);\n    }\n\n    if (anchor && (anchor[0] !== size[0] / 2 || anchor[1] !== size[1] / 2)) {\n      const /** @type {module:ol/format/KML~Vec2} */ hotSpot = {\n        x: anchor[0],\n        xunits: IconAnchorUnits.PIXELS,\n        y: size[1] - anchor[1],\n        yunits: IconAnchorUnits.PIXELS\n      };\n      properties['hotSpot'] = hotSpot;\n    }\n  }\n\n  properties['Icon'] = iconProperties;\n\n  const scale = style.getScale();\n  if (scale !== 1) {\n    properties['scale'] = scale;\n  }\n\n  const rotation = style.getRotation();\n  if (rotation !== 0) {\n    properties['heading'] = rotation; // 0-360\n  }\n\n  const parentNode = objectStack[objectStack.length - 1].node;\n  const orderedKeys = ICON_STYLE_SEQUENCE[parentNode.namespaceURI];\n  const values = makeSequence(properties, orderedKeys);\n  pushSerializeAndPop(context, ICON_STYLE_SERIALIZERS,\n    OBJECT_PROPERTY_NODE_FACTORY, values, objectStack, orderedKeys);\n}\n\n\n/**\n * @const\n * @type {Object.<string, Array.<string>>}\n */\nconst LABEL_STYLE_SEQUENCE = makeStructureNS(\n  NAMESPACE_URIS, [\n    'color', 'scale'\n  ]);\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst LABEL_STYLE_SERIALIZERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'color': makeChildAppender(writeColorTextNode),\n    'scale': makeChildAppender(writeScaleTextNode)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/style/Text} style style.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction writeLabelStyle(node, style, objectStack) {\n  const /** @type {module:ol/xml~NodeStackItem} */ context = {node: node};\n  const properties = {};\n  const fill = style.getFill();\n  if (fill) {\n    properties['color'] = fill.getColor();\n  }\n  const scale = style.getScale();\n  if (scale && scale !== 1) {\n    properties['scale'] = scale;\n  }\n  const parentNode = objectStack[objectStack.length - 1].node;\n  const orderedKeys =\n      LABEL_STYLE_SEQUENCE[parentNode.namespaceURI];\n  const values = makeSequence(properties, orderedKeys);\n  pushSerializeAndPop(context, LABEL_STYLE_SERIALIZERS,\n    OBJECT_PROPERTY_NODE_FACTORY, values, objectStack, orderedKeys);\n}\n\n\n/**\n * @const\n * @type {Object.<string, Array.<string>>}\n */\nconst LINE_STYLE_SEQUENCE = makeStructureNS(\n  NAMESPACE_URIS, [\n    'color', 'width'\n  ]);\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst LINE_STYLE_SERIALIZERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'color': makeChildAppender(writeColorTextNode),\n    'width': makeChildAppender(writeDecimalTextNode)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/style/Stroke} style style.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction writeLineStyle(node, style, objectStack) {\n  const /** @type {module:ol/xml~NodeStackItem} */ context = {node: node};\n  const properties = {\n    'color': style.getColor(),\n    'width': style.getWidth()\n  };\n  const parentNode = objectStack[objectStack.length - 1].node;\n  const orderedKeys = LINE_STYLE_SEQUENCE[parentNode.namespaceURI];\n  const values = makeSequence(properties, orderedKeys);\n  pushSerializeAndPop(context, LINE_STYLE_SERIALIZERS,\n    OBJECT_PROPERTY_NODE_FACTORY, values, objectStack, orderedKeys);\n}\n\n\n/**\n * @const\n * @type {Object.<string, string>}\n */\nconst GEOMETRY_TYPE_TO_NODENAME = {\n  'Point': 'Point',\n  'LineString': 'LineString',\n  'LinearRing': 'LinearRing',\n  'Polygon': 'Polygon',\n  'MultiPoint': 'MultiGeometry',\n  'MultiLineString': 'MultiGeometry',\n  'MultiPolygon': 'MultiGeometry',\n  'GeometryCollection': 'MultiGeometry'\n};\n\n\n/**\n * @const\n * @param {*} value Value.\n * @param {Array.<*>} objectStack Object stack.\n * @param {string=} opt_nodeName Node name.\n * @return {Node|undefined} Node.\n */\nconst GEOMETRY_NODE_FACTORY = function(value, objectStack, opt_nodeName) {\n  if (value) {\n    const parentNode = objectStack[objectStack.length - 1].node;\n    return createElementNS(parentNode.namespaceURI,\n      GEOMETRY_TYPE_TO_NODENAME[/** @type {module:ol/geom/Geometry} */ (value).getType()]);\n  }\n};\n\n\n/**\n * A factory for creating Point nodes.\n * @const\n * @type {function(*, Array.<*>, string=): (Node|undefined)}\n */\nconst POINT_NODE_FACTORY = makeSimpleNodeFactory('Point');\n\n\n/**\n * A factory for creating LineString nodes.\n * @const\n * @type {function(*, Array.<*>, string=): (Node|undefined)}\n */\nconst LINE_STRING_NODE_FACTORY = makeSimpleNodeFactory('LineString');\n\n\n/**\n * A factory for creating LinearRing nodes.\n * @const\n * @type {function(*, Array.<*>, string=): (Node|undefined)}\n */\nconst LINEAR_RING_NODE_FACTORY = makeSimpleNodeFactory('LinearRing');\n\n\n/**\n * A factory for creating Polygon nodes.\n * @const\n * @type {function(*, Array.<*>, string=): (Node|undefined)}\n */\nconst POLYGON_NODE_FACTORY = makeSimpleNodeFactory('Polygon');\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst MULTI_GEOMETRY_SERIALIZERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'LineString': makeChildAppender(\n      writePrimitiveGeometry),\n    'Point': makeChildAppender(\n      writePrimitiveGeometry),\n    'Polygon': makeChildAppender(writePolygon),\n    'GeometryCollection': makeChildAppender(\n      writeMultiGeometry)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/geom/Geometry} geometry Geometry.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction writeMultiGeometry(node, geometry, objectStack) {\n  /** @type {module:ol/xml~NodeStackItem} */\n  const context = {node: node};\n  const type = geometry.getType();\n  /** @type {Array.<module:ol/geom/Geometry>} */\n  let geometries;\n  /** @type {function(*, Array.<*>, string=): (Node|undefined)} */\n  let factory;\n  if (type == GeometryType.GEOMETRY_COLLECTION) {\n    geometries = /** @type {module:ol/geom/GeometryCollection} */ (geometry).getGeometries();\n    factory = GEOMETRY_NODE_FACTORY;\n  } else if (type == GeometryType.MULTI_POINT) {\n    geometries = /** @type {module:ol/geom/MultiPoint} */ (geometry).getPoints();\n    factory = POINT_NODE_FACTORY;\n  } else if (type == GeometryType.MULTI_LINE_STRING) {\n    geometries =\n        (/** @type {module:ol/geom/MultiLineString} */ (geometry)).getLineStrings();\n    factory = LINE_STRING_NODE_FACTORY;\n  } else if (type == GeometryType.MULTI_POLYGON) {\n    geometries =\n        (/** @type {module:ol/geom/MultiPolygon} */ (geometry)).getPolygons();\n    factory = POLYGON_NODE_FACTORY;\n  } else {\n    assert(false, 39); // Unknown geometry type\n  }\n  pushSerializeAndPop(context,\n    MULTI_GEOMETRY_SERIALIZERS, factory,\n    geometries, objectStack);\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst BOUNDARY_IS_SERIALIZERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'LinearRing': makeChildAppender(\n      writePrimitiveGeometry)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/geom/LinearRing} linearRing Linear ring.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction writeBoundaryIs(node, linearRing, objectStack) {\n  const /** @type {module:ol/xml~NodeStackItem} */ context = {node: node};\n  pushSerializeAndPop(context,\n    BOUNDARY_IS_SERIALIZERS,\n    LINEAR_RING_NODE_FACTORY, [linearRing], objectStack);\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst PLACEMARK_SERIALIZERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'ExtendedData': makeChildAppender(writeExtendedData),\n    'MultiGeometry': makeChildAppender(writeMultiGeometry),\n    'LineString': makeChildAppender(writePrimitiveGeometry),\n    'LinearRing': makeChildAppender(writePrimitiveGeometry),\n    'Point': makeChildAppender(writePrimitiveGeometry),\n    'Polygon': makeChildAppender(writePolygon),\n    'Style': makeChildAppender(writeStyle),\n    'address': makeChildAppender(writeStringTextNode),\n    'description': makeChildAppender(writeStringTextNode),\n    'name': makeChildAppender(writeStringTextNode),\n    'open': makeChildAppender(writeBooleanTextNode),\n    'phoneNumber': makeChildAppender(writeStringTextNode),\n    'styleUrl': makeChildAppender(writeStringTextNode),\n    'visibility': makeChildAppender(writeBooleanTextNode)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Array.<string>>}\n */\nconst PLACEMARK_SEQUENCE = makeStructureNS(\n  NAMESPACE_URIS, [\n    'name', 'open', 'visibility', 'address', 'phoneNumber', 'description',\n    'styleUrl', 'Style'\n  ]);\n\n\n/**\n * A factory for creating ExtendedData nodes.\n * @const\n * @type {function(*, Array.<*>): (Node|undefined)}\n */\nconst EXTENDEDDATA_NODE_FACTORY = makeSimpleNodeFactory('ExtendedData');\n\n\n/**\n * FIXME currently we do serialize arbitrary/custom feature properties\n * (ExtendedData).\n * @param {Node} node Node.\n * @param {module:ol/Feature} feature Feature.\n * @param {Array.<*>} objectStack Object stack.\n * @this {module:ol/format/KML}\n */\nfunction writePlacemark(node, feature, objectStack) {\n  const /** @type {module:ol/xml~NodeStackItem} */ context = {node: node};\n\n  // set id\n  if (feature.getId()) {\n    node.setAttribute('id', feature.getId());\n  }\n\n  // serialize properties (properties unknown to KML are not serialized)\n  const properties = feature.getProperties();\n\n  // don't export these to ExtendedData\n  const filter = {'address': 1, 'description': 1, 'name': 1, 'open': 1,\n    'phoneNumber': 1, 'styleUrl': 1, 'visibility': 1};\n  filter[feature.getGeometryName()] = 1;\n  const keys = Object.keys(properties || {}).sort().filter(function(v) {\n    return !filter[v];\n  });\n\n  if (keys.length > 0) {\n    const sequence = makeSequence(properties, keys);\n    const namesAndValues = {names: keys, values: sequence};\n    pushSerializeAndPop(context, PLACEMARK_SERIALIZERS,\n      EXTENDEDDATA_NODE_FACTORY, [namesAndValues], objectStack);\n  }\n\n  const styleFunction = feature.getStyleFunction();\n  if (styleFunction) {\n    // FIXME the styles returned by the style function are supposed to be\n    // resolution-independent here\n    const styles = styleFunction(feature, 0);\n    if (styles) {\n      const style = Array.isArray(styles) ? styles[0] : styles;\n      if (this.writeStyles_) {\n        properties['Style'] = style;\n      }\n      const textStyle = style.getText();\n      if (textStyle) {\n        properties['name'] = textStyle.getText();\n      }\n    }\n  }\n  const parentNode = objectStack[objectStack.length - 1].node;\n  const orderedKeys = PLACEMARK_SEQUENCE[parentNode.namespaceURI];\n  const values = makeSequence(properties, orderedKeys);\n  pushSerializeAndPop(context, PLACEMARK_SERIALIZERS,\n    OBJECT_PROPERTY_NODE_FACTORY, values, objectStack, orderedKeys);\n\n  // serialize geometry\n  const options = /** @type {module:ol/format/Feature~WriteOptions} */ (objectStack[0]);\n  let geometry = feature.getGeometry();\n  if (geometry) {\n    geometry = transformWithOptions(geometry, true, options);\n  }\n  pushSerializeAndPop(context, PLACEMARK_SERIALIZERS,\n    GEOMETRY_NODE_FACTORY, [geometry], objectStack);\n}\n\n\n/**\n * @const\n * @type {Object.<string, Array.<string>>}\n */\nconst PRIMITIVE_GEOMETRY_SEQUENCE = makeStructureNS(\n  NAMESPACE_URIS, [\n    'extrude', 'tessellate', 'altitudeMode', 'coordinates'\n  ]);\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst PRIMITIVE_GEOMETRY_SERIALIZERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'extrude': makeChildAppender(writeBooleanTextNode),\n    'tessellate': makeChildAppender(writeBooleanTextNode),\n    'altitudeMode': makeChildAppender(writeStringTextNode),\n    'coordinates': makeChildAppender(writeCoordinatesTextNode)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/geom/SimpleGeometry} geometry Geometry.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction writePrimitiveGeometry(node, geometry, objectStack) {\n  const flatCoordinates = geometry.getFlatCoordinates();\n  const /** @type {module:ol/xml~NodeStackItem} */ context = {node: node};\n  context['layout'] = geometry.getLayout();\n  context['stride'] = geometry.getStride();\n\n  // serialize properties (properties unknown to KML are not serialized)\n  const properties = geometry.getProperties();\n  properties.coordinates = flatCoordinates;\n\n  const parentNode = objectStack[objectStack.length - 1].node;\n  const orderedKeys = PRIMITIVE_GEOMETRY_SEQUENCE[parentNode.namespaceURI];\n  const values = makeSequence(properties, orderedKeys);\n  pushSerializeAndPop(context, PRIMITIVE_GEOMETRY_SERIALIZERS,\n    OBJECT_PROPERTY_NODE_FACTORY, values, objectStack, orderedKeys);\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst POLYGON_SERIALIZERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'outerBoundaryIs': makeChildAppender(\n      writeBoundaryIs),\n    'innerBoundaryIs': makeChildAppender(\n      writeBoundaryIs)\n  });\n\n\n/**\n * A factory for creating innerBoundaryIs nodes.\n * @const\n * @type {function(*, Array.<*>, string=): (Node|undefined)}\n */\nconst INNER_BOUNDARY_NODE_FACTORY = makeSimpleNodeFactory('innerBoundaryIs');\n\n\n/**\n * A factory for creating outerBoundaryIs nodes.\n * @const\n * @type {function(*, Array.<*>, string=): (Node|undefined)}\n */\nconst OUTER_BOUNDARY_NODE_FACTORY = makeSimpleNodeFactory('outerBoundaryIs');\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/geom/Polygon} polygon Polygon.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction writePolygon(node, polygon, objectStack) {\n  const linearRings = polygon.getLinearRings();\n  const outerRing = linearRings.shift();\n  const /** @type {module:ol/xml~NodeStackItem} */ context = {node: node};\n  // inner rings\n  pushSerializeAndPop(context,\n    POLYGON_SERIALIZERS,\n    INNER_BOUNDARY_NODE_FACTORY,\n    linearRings, objectStack);\n  // outer ring\n  pushSerializeAndPop(context,\n    POLYGON_SERIALIZERS,\n    OUTER_BOUNDARY_NODE_FACTORY,\n    [outerRing], objectStack);\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst POLY_STYLE_SERIALIZERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'color': makeChildAppender(writeColorTextNode)\n  });\n\n\n/**\n * A factory for creating coordinates nodes.\n * @const\n * @type {function(*, Array.<*>, string=): (Node|undefined)}\n */\nconst COLOR_NODE_FACTORY = makeSimpleNodeFactory('color');\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/style/Fill} style Style.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction writePolyStyle(node, style, objectStack) {\n  const /** @type {module:ol/xml~NodeStackItem} */ context = {node: node};\n  pushSerializeAndPop(context, POLY_STYLE_SERIALIZERS,\n    COLOR_NODE_FACTORY, [style.getColor()], objectStack);\n}\n\n\n/**\n * @param {Node} node Node to append a TextNode with the scale to.\n * @param {number|undefined} scale Scale.\n */\nfunction writeScaleTextNode(node, scale) {\n  // the Math is to remove any excess decimals created by float arithmetic\n  writeDecimalTextNode(node,\n    Math.round(scale * 1e6) / 1e6);\n}\n\n\n/**\n * @const\n * @type {Object.<string, Array.<string>>}\n */\nconst STYLE_SEQUENCE = makeStructureNS(\n  NAMESPACE_URIS, [\n    'IconStyle', 'LabelStyle', 'LineStyle', 'PolyStyle'\n  ]);\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst STYLE_SERIALIZERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'IconStyle': makeChildAppender(writeIconStyle),\n    'LabelStyle': makeChildAppender(writeLabelStyle),\n    'LineStyle': makeChildAppender(writeLineStyle),\n    'PolyStyle': makeChildAppender(writePolyStyle)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/style/Style} style Style.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction writeStyle(node, style, objectStack) {\n  const /** @type {module:ol/xml~NodeStackItem} */ context = {node: node};\n  const properties = {};\n  const fillStyle = style.getFill();\n  const strokeStyle = style.getStroke();\n  const imageStyle = style.getImage();\n  const textStyle = style.getText();\n  if (imageStyle instanceof Icon) {\n    properties['IconStyle'] = imageStyle;\n  }\n  if (textStyle) {\n    properties['LabelStyle'] = textStyle;\n  }\n  if (strokeStyle) {\n    properties['LineStyle'] = strokeStyle;\n  }\n  if (fillStyle) {\n    properties['PolyStyle'] = fillStyle;\n  }\n  const parentNode = objectStack[objectStack.length - 1].node;\n  const orderedKeys = STYLE_SEQUENCE[parentNode.namespaceURI];\n  const values = makeSequence(properties, orderedKeys);\n  pushSerializeAndPop(context, STYLE_SERIALIZERS,\n    OBJECT_PROPERTY_NODE_FACTORY, values, objectStack, orderedKeys);\n}\n\n\n/**\n * @param {Node} node Node to append a TextNode with the Vec2 to.\n * @param {module:ol/format/KML~Vec2} vec2 Vec2.\n */\nfunction writeVec2(node, vec2) {\n  node.setAttribute('x', vec2.x);\n  node.setAttribute('y', vec2.y);\n  node.setAttribute('xunits', vec2.xunits);\n  node.setAttribute('yunits', vec2.yunits);\n}\n\n\nexport default KML;\n","/**\n * @module ol/style/IconOrigin\n */\n\n/**\n * Icon origin. One of 'bottom-left', 'bottom-right', 'top-left', 'top-right'.\n * @enum {string}\n */\nexport default {\n  BOTTOM_LEFT: 'bottom-left',\n  BOTTOM_RIGHT: 'bottom-right',\n  TOP_LEFT: 'top-left',\n  TOP_RIGHT: 'top-right'\n};\n","/**\n * @module ol/style/Icon\n */\nimport {getUid} from '../util.js';\nimport ImageState from '../ImageState.js';\nimport {assert} from '../asserts.js';\nimport {asArray} from '../color.js';\nimport {listen, unlisten} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport IconAnchorUnits from '../style/IconAnchorUnits.js';\nimport {get as getIconImage} from '../style/IconImage.js';\nimport IconOrigin from '../style/IconOrigin.js';\nimport ImageStyle from '../style/Image.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {Array.<number>} [anchor=[0.5, 0.5]] Anchor. Default value is the icon center.\n * @property {module:ol/style/IconOrigin} [anchorOrigin] Origin of the anchor: `bottom-left`, `bottom-right`,\n * `top-left` or `top-right`. Default is `top-left`.\n * @property {module:ol/style/IconAnchorUnits} [anchorXUnits] Units in which the anchor x value is\n * specified. A value of `'fraction'` indicates the x value is a fraction of the icon. A value of `'pixels'` indicates\n * the x value in pixels. Default is `'fraction'`.\n * @property {module:ol/style/IconAnchorUnits} [anchorYUnits] Units in which the anchor y value is\n * specified. A value of `'fraction'` indicates the y value is a fraction of the icon. A value of `'pixels'` indicates\n * the y value in pixels. Default is `'fraction'`.\n * @property {module:ol/color~Color|string} [color] Color to tint the icon. If not specified,\n * the icon will be left as is.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that you must provide a\n * `crossOrigin` value if you are using the WebGL renderer or if you want to access pixel data with the Canvas renderer.\n * See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {HTMLImageElement|HTMLCanvasElement} [img] Image object for the icon. If the `src` option is not provided then the\n * provided image must already be loaded. And in that case, it is required\n * to provide the size of the image, with the `imgSize` option.\n * @property {Array.<number>} [offset=[0, 0]] Offset, which, together with the size and the offset origin, define the\n * sub-rectangle to use from the original icon image.\n * @property {module:ol/style/IconOrigin} [offsetOrigin] Origin of the offset: `bottom-left`, `bottom-right`,\n * `top-left` or `top-right`. Default is `top-left`.\n * @property {number} [opacity=1] Opacity of the icon.\n * @property {number} [scale=1] Scale.\n * @property {boolean} [snapToPixel=true] If `true` integral numbers of pixels are used as the X and Y pixel coordinate\n * when drawing the icon in the output canvas. If `false` fractional numbers may be used. Using `true` allows for\n * \"sharp\" rendering (no blur), while using `false` allows for \"accurate\" rendering. Note that accuracy is important if\n * the icon's position is animated. Without it, the icon may jitter noticeably.\n * @property {boolean} [rotateWithView=false] Whether to rotate the icon with the view.\n * @property {number} [rotation=0] Rotation in radians (positive rotation clockwise).\n * @property {module:ol/size~Size} [size] Icon size in pixel. Can be used together with `offset` to define the\n * sub-rectangle to use from the origin (sprite) icon image.\n * @property {module:ol/size~Size} [imgSize] Image size in pixels. Only required if `img` is set and `src` is not, and\n * for SVG images in Internet Explorer 11. The provided `imgSize` needs to match the actual size of the image.\n * @property {string} [src] Image source URI.\n */\n\n\n/**\n * @classdesc\n * Set icon style for vector features.\n * @api\n */\nclass Icon extends ImageStyle {\n  /**\n   * @param {module:ol/style/Icon~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n    const options = opt_options || {};\n\n    /**\n     * @type {number}\n     */\n    const opacity = options.opacity !== undefined ? options.opacity : 1;\n\n    /**\n     * @type {number}\n     */\n    const rotation = options.rotation !== undefined ? options.rotation : 0;\n\n    /**\n     * @type {number}\n     */\n    const scale = options.scale !== undefined ? options.scale : 1;\n\n    /**\n     * @type {boolean}\n     */\n    const rotateWithView = options.rotateWithView !== undefined ?\n      options.rotateWithView : false;\n\n    /**\n     * @type {boolean}\n     */\n    const snapToPixel = options.snapToPixel !== undefined ?\n      options.snapToPixel : true;\n\n    super({\n      opacity: opacity,\n      rotation: rotation,\n      scale: scale,\n      snapToPixel: snapToPixel,\n      rotateWithView: rotateWithView\n    });\n\n    /**\n     * @private\n     * @type {Array.<number>}\n     */\n    this.anchor_ = options.anchor !== undefined ? options.anchor : [0.5, 0.5];\n\n    /**\n     * @private\n     * @type {Array.<number>}\n     */\n    this.normalizedAnchor_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/style/IconOrigin}\n     */\n    this.anchorOrigin_ = options.anchorOrigin !== undefined ?\n      options.anchorOrigin : IconOrigin.TOP_LEFT;\n\n    /**\n     * @private\n     * @type {module:ol/style/IconAnchorUnits}\n     */\n    this.anchorXUnits_ = options.anchorXUnits !== undefined ?\n      options.anchorXUnits : IconAnchorUnits.FRACTION;\n\n    /**\n     * @private\n     * @type {module:ol/style/IconAnchorUnits}\n     */\n    this.anchorYUnits_ = options.anchorYUnits !== undefined ?\n      options.anchorYUnits : IconAnchorUnits.FRACTION;\n\n    /**\n     * @private\n     * @type {?string}\n     */\n    this.crossOrigin_ =\n        options.crossOrigin !== undefined ? options.crossOrigin : null;\n\n    /**\n     * @type {HTMLImageElement|HTMLCanvasElement}\n     */\n    const image = options.img !== undefined ? options.img : null;\n\n    /**\n     * @type {module:ol/size~Size}\n     */\n    const imgSize = options.imgSize !== undefined ? options.imgSize : null;\n\n    /**\n     * @type {string|undefined}\n     */\n    let src = options.src;\n\n    assert(!(src !== undefined && image),\n      4); // `image` and `src` cannot be provided at the same time\n    assert(!image || (image && imgSize),\n      5); // `imgSize` must be set when `image` is provided\n\n    if ((src === undefined || src.length === 0) && image) {\n      src = image.src || getUid(image).toString();\n    }\n    assert(src !== undefined && src.length > 0,\n      6); // A defined and non-empty `src` or `image` must be provided\n\n    /**\n     * @type {module:ol/ImageState}\n     */\n    const imageState = options.src !== undefined ?\n      ImageState.IDLE : ImageState.LOADED;\n\n    /**\n     * @private\n     * @type {module:ol/color~Color}\n     */\n    this.color_ = options.color !== undefined ? asArray(options.color) : null;\n\n    /**\n     * @private\n     * @type {module:ol/style/IconImage}\n     */\n    this.iconImage_ = getIconImage(\n      image, /** @type {string} */ (src), imgSize, this.crossOrigin_, imageState, this.color_);\n\n    /**\n     * @private\n     * @type {Array.<number>}\n     */\n    this.offset_ = options.offset !== undefined ? options.offset : [0, 0];\n\n    /**\n     * @private\n     * @type {module:ol/style/IconOrigin}\n     */\n    this.offsetOrigin_ = options.offsetOrigin !== undefined ?\n      options.offsetOrigin : IconOrigin.TOP_LEFT;\n\n    /**\n     * @private\n     * @type {Array.<number>}\n     */\n    this.origin_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/size~Size}\n     */\n    this.size_ = options.size !== undefined ? options.size : null;\n\n  }\n\n  /**\n   * Clones the style. The underlying Image/HTMLCanvasElement is not cloned.\n   * @return {module:ol/style/Icon} The cloned style.\n   * @api\n   */\n  clone() {\n    return new Icon({\n      anchor: this.anchor_.slice(),\n      anchorOrigin: this.anchorOrigin_,\n      anchorXUnits: this.anchorXUnits_,\n      anchorYUnits: this.anchorYUnits_,\n      crossOrigin: this.crossOrigin_,\n      color: (this.color_ && this.color_.slice) ? this.color_.slice() : this.color_ || undefined,\n      src: this.getSrc(),\n      offset: this.offset_.slice(),\n      offsetOrigin: this.offsetOrigin_,\n      size: this.size_ !== null ? this.size_.slice() : undefined,\n      opacity: this.getOpacity(),\n      scale: this.getScale(),\n      snapToPixel: this.getSnapToPixel(),\n      rotation: this.getRotation(),\n      rotateWithView: this.getRotateWithView()\n    });\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  getAnchor() {\n    if (this.normalizedAnchor_) {\n      return this.normalizedAnchor_;\n    }\n    let anchor = this.anchor_;\n    const size = this.getSize();\n    if (this.anchorXUnits_ == IconAnchorUnits.FRACTION ||\n        this.anchorYUnits_ == IconAnchorUnits.FRACTION) {\n      if (!size) {\n        return null;\n      }\n      anchor = this.anchor_.slice();\n      if (this.anchorXUnits_ == IconAnchorUnits.FRACTION) {\n        anchor[0] *= size[0];\n      }\n      if (this.anchorYUnits_ == IconAnchorUnits.FRACTION) {\n        anchor[1] *= size[1];\n      }\n    }\n\n    if (this.anchorOrigin_ != IconOrigin.TOP_LEFT) {\n      if (!size) {\n        return null;\n      }\n      if (anchor === this.anchor_) {\n        anchor = this.anchor_.slice();\n      }\n      if (this.anchorOrigin_ == IconOrigin.TOP_RIGHT ||\n          this.anchorOrigin_ == IconOrigin.BOTTOM_RIGHT) {\n        anchor[0] = -anchor[0] + size[0];\n      }\n      if (this.anchorOrigin_ == IconOrigin.BOTTOM_LEFT ||\n          this.anchorOrigin_ == IconOrigin.BOTTOM_RIGHT) {\n        anchor[1] = -anchor[1] + size[1];\n      }\n    }\n    this.normalizedAnchor_ = anchor;\n    return this.normalizedAnchor_;\n  }\n\n  /**\n   * Set the anchor point. The anchor determines the center point for the\n   * symbolizer.\n   *\n   * @param {Array.<number>} anchor Anchor.\n   * @api\n   */\n  setAnchor(anchor) {\n    this.anchor_ = anchor;\n    this.normalizedAnchor_ = null;\n  }\n\n  /**\n   * Get the icon color.\n   * @return {module:ol/color~Color} Color.\n   * @api\n   */\n  getColor() {\n    return this.color_;\n  }\n\n  /**\n   * Get the image icon.\n   * @param {number} pixelRatio Pixel ratio.\n   * @return {HTMLImageElement|HTMLCanvasElement} Image or Canvas element.\n   * @override\n   * @api\n   */\n  getImage(pixelRatio) {\n    return this.iconImage_.getImage(pixelRatio);\n  }\n\n  /**\n   * @override\n   */\n  getImageSize() {\n    return this.iconImage_.getSize();\n  }\n\n  /**\n   * @override\n   */\n  getHitDetectionImageSize() {\n    return this.getImageSize();\n  }\n\n  /**\n   * @override\n   */\n  getImageState() {\n    return this.iconImage_.getImageState();\n  }\n\n  /**\n   * @override\n   */\n  getHitDetectionImage(pixelRatio) {\n    return this.iconImage_.getHitDetectionImage(pixelRatio);\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  getOrigin() {\n    if (this.origin_) {\n      return this.origin_;\n    }\n    let offset = this.offset_;\n\n    if (this.offsetOrigin_ != IconOrigin.TOP_LEFT) {\n      const size = this.getSize();\n      const iconImageSize = this.iconImage_.getSize();\n      if (!size || !iconImageSize) {\n        return null;\n      }\n      offset = offset.slice();\n      if (this.offsetOrigin_ == IconOrigin.TOP_RIGHT ||\n          this.offsetOrigin_ == IconOrigin.BOTTOM_RIGHT) {\n        offset[0] = iconImageSize[0] - size[0] - offset[0];\n      }\n      if (this.offsetOrigin_ == IconOrigin.BOTTOM_LEFT ||\n          this.offsetOrigin_ == IconOrigin.BOTTOM_RIGHT) {\n        offset[1] = iconImageSize[1] - size[1] - offset[1];\n      }\n    }\n    this.origin_ = offset;\n    return this.origin_;\n  }\n\n  /**\n   * Get the image URL.\n   * @return {string|undefined} Image src.\n   * @api\n   */\n  getSrc() {\n    return this.iconImage_.getSrc();\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  getSize() {\n    return !this.size_ ? this.iconImage_.getSize() : this.size_;\n  }\n\n  /**\n   * @override\n   */\n  listenImageChange(listener, thisArg) {\n    return listen(this.iconImage_, EventType.CHANGE,\n      listener, thisArg);\n  }\n\n  /**\n   * Load not yet loaded URI.\n   * When rendering a feature with an icon style, the vector renderer will\n   * automatically call this method. However, you might want to call this\n   * method yourself for preloading or other purposes.\n   * @override\n   * @api\n   */\n  load() {\n    this.iconImage_.load();\n  }\n\n  /**\n   * @override\n   */\n  unlistenImageChange(listener, thisArg) {\n    unlisten(this.iconImage_, EventType.CHANGE,\n      listener, thisArg);\n  }\n}\n\n\nexport default Icon;\n","exports.read = function (buffer, offset, isLE, mLen, nBytes) {\n  var e, m\n  var eLen = nBytes * 8 - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var nBits = -7\n  var i = isLE ? (nBytes - 1) : 0\n  var d = isLE ? -1 : 1\n  var s = buffer[offset + i]\n\n  i += d\n\n  e = s & ((1 << (-nBits)) - 1)\n  s >>= (-nBits)\n  nBits += eLen\n  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n  m = e & ((1 << (-nBits)) - 1)\n  e >>= (-nBits)\n  nBits += mLen\n  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n  if (e === 0) {\n    e = 1 - eBias\n  } else if (e === eMax) {\n    return m ? NaN : ((s ? -1 : 1) * Infinity)\n  } else {\n    m = m + Math.pow(2, mLen)\n    e = e - eBias\n  }\n  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n  var e, m, c\n  var eLen = nBytes * 8 - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n  var i = isLE ? 0 : (nBytes - 1)\n  var d = isLE ? 1 : -1\n  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n  value = Math.abs(value)\n\n  if (isNaN(value) || value === Infinity) {\n    m = isNaN(value) ? 1 : 0\n    e = eMax\n  } else {\n    e = Math.floor(Math.log(value) / Math.LN2)\n    if (value * (c = Math.pow(2, -e)) < 1) {\n      e--\n      c *= 2\n    }\n    if (e + eBias >= 1) {\n      value += rt / c\n    } else {\n      value += rt * Math.pow(2, 1 - eBias)\n    }\n    if (value * c >= 2) {\n      e++\n      c /= 2\n    }\n\n    if (e + eBias >= eMax) {\n      m = 0\n      e = eMax\n    } else if (e + eBias >= 1) {\n      m = (value * c - 1) * Math.pow(2, mLen)\n      e = e + eBias\n    } else {\n      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n      e = 0\n    }\n  }\n\n  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n  e = (e << mLen) | m\n  eLen += mLen\n  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n  buffer[offset + i - d] |= s * 128\n}\n","'use strict';\n\nmodule.exports = Pbf;\n\nvar ieee754 = require('ieee754');\n\nfunction Pbf(buf) {\n    this.buf = ArrayBuffer.isView && ArrayBuffer.isView(buf) ? buf : new Uint8Array(buf || 0);\n    this.pos = 0;\n    this.type = 0;\n    this.length = this.buf.length;\n}\n\nPbf.Varint  = 0; // varint: int32, int64, uint32, uint64, sint32, sint64, bool, enum\nPbf.Fixed64 = 1; // 64-bit: double, fixed64, sfixed64\nPbf.Bytes   = 2; // length-delimited: string, bytes, embedded messages, packed repeated fields\nPbf.Fixed32 = 5; // 32-bit: float, fixed32, sfixed32\n\nvar SHIFT_LEFT_32 = (1 << 16) * (1 << 16),\n    SHIFT_RIGHT_32 = 1 / SHIFT_LEFT_32;\n\nPbf.prototype = {\n\n    destroy: function() {\n        this.buf = null;\n    },\n\n    // === READING =================================================================\n\n    readFields: function(readField, result, end) {\n        end = end || this.length;\n\n        while (this.pos < end) {\n            var val = this.readVarint(),\n                tag = val >> 3,\n                startPos = this.pos;\n\n            this.type = val & 0x7;\n            readField(tag, result, this);\n\n            if (this.pos === startPos) this.skip(val);\n        }\n        return result;\n    },\n\n    readMessage: function(readField, result) {\n        return this.readFields(readField, result, this.readVarint() + this.pos);\n    },\n\n    readFixed32: function() {\n        var val = readUInt32(this.buf, this.pos);\n        this.pos += 4;\n        return val;\n    },\n\n    readSFixed32: function() {\n        var val = readInt32(this.buf, this.pos);\n        this.pos += 4;\n        return val;\n    },\n\n    // 64-bit int handling is based on github.com/dpw/node-buffer-more-ints (MIT-licensed)\n\n    readFixed64: function() {\n        var val = readUInt32(this.buf, this.pos) + readUInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32;\n        this.pos += 8;\n        return val;\n    },\n\n    readSFixed64: function() {\n        var val = readUInt32(this.buf, this.pos) + readInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32;\n        this.pos += 8;\n        return val;\n    },\n\n    readFloat: function() {\n        var val = ieee754.read(this.buf, this.pos, true, 23, 4);\n        this.pos += 4;\n        return val;\n    },\n\n    readDouble: function() {\n        var val = ieee754.read(this.buf, this.pos, true, 52, 8);\n        this.pos += 8;\n        return val;\n    },\n\n    readVarint: function(isSigned) {\n        var buf = this.buf,\n            val, b;\n\n        b = buf[this.pos++]; val  =  b & 0x7f;        if (b < 0x80) return val;\n        b = buf[this.pos++]; val |= (b & 0x7f) << 7;  if (b < 0x80) return val;\n        b = buf[this.pos++]; val |= (b & 0x7f) << 14; if (b < 0x80) return val;\n        b = buf[this.pos++]; val |= (b & 0x7f) << 21; if (b < 0x80) return val;\n        b = buf[this.pos];   val |= (b & 0x0f) << 28;\n\n        return readVarintRemainder(val, isSigned, this);\n    },\n\n    readVarint64: function() { // for compatibility with v2.0.1\n        return this.readVarint(true);\n    },\n\n    readSVarint: function() {\n        var num = this.readVarint();\n        return num % 2 === 1 ? (num + 1) / -2 : num / 2; // zigzag encoding\n    },\n\n    readBoolean: function() {\n        return Boolean(this.readVarint());\n    },\n\n    readString: function() {\n        var end = this.readVarint() + this.pos,\n            str = readUtf8(this.buf, this.pos, end);\n        this.pos = end;\n        return str;\n    },\n\n    readBytes: function() {\n        var end = this.readVarint() + this.pos,\n            buffer = this.buf.subarray(this.pos, end);\n        this.pos = end;\n        return buffer;\n    },\n\n    // verbose for performance reasons; doesn't affect gzipped size\n\n    readPackedVarint: function(arr, isSigned) {\n        var end = readPackedEnd(this);\n        arr = arr || [];\n        while (this.pos < end) arr.push(this.readVarint(isSigned));\n        return arr;\n    },\n    readPackedSVarint: function(arr) {\n        var end = readPackedEnd(this);\n        arr = arr || [];\n        while (this.pos < end) arr.push(this.readSVarint());\n        return arr;\n    },\n    readPackedBoolean: function(arr) {\n        var end = readPackedEnd(this);\n        arr = arr || [];\n        while (this.pos < end) arr.push(this.readBoolean());\n        return arr;\n    },\n    readPackedFloat: function(arr) {\n        var end = readPackedEnd(this);\n        arr = arr || [];\n        while (this.pos < end) arr.push(this.readFloat());\n        return arr;\n    },\n    readPackedDouble: function(arr) {\n        var end = readPackedEnd(this);\n        arr = arr || [];\n        while (this.pos < end) arr.push(this.readDouble());\n        return arr;\n    },\n    readPackedFixed32: function(arr) {\n        var end = readPackedEnd(this);\n        arr = arr || [];\n        while (this.pos < end) arr.push(this.readFixed32());\n        return arr;\n    },\n    readPackedSFixed32: function(arr) {\n        var end = readPackedEnd(this);\n        arr = arr || [];\n        while (this.pos < end) arr.push(this.readSFixed32());\n        return arr;\n    },\n    readPackedFixed64: function(arr) {\n        var end = readPackedEnd(this);\n        arr = arr || [];\n        while (this.pos < end) arr.push(this.readFixed64());\n        return arr;\n    },\n    readPackedSFixed64: function(arr) {\n        var end = readPackedEnd(this);\n        arr = arr || [];\n        while (this.pos < end) arr.push(this.readSFixed64());\n        return arr;\n    },\n\n    skip: function(val) {\n        var type = val & 0x7;\n        if (type === Pbf.Varint) while (this.buf[this.pos++] > 0x7f) {}\n        else if (type === Pbf.Bytes) this.pos = this.readVarint() + this.pos;\n        else if (type === Pbf.Fixed32) this.pos += 4;\n        else if (type === Pbf.Fixed64) this.pos += 8;\n        else throw new Error('Unimplemented type: ' + type);\n    },\n\n    // === WRITING =================================================================\n\n    writeTag: function(tag, type) {\n        this.writeVarint((tag << 3) | type);\n    },\n\n    realloc: function(min) {\n        var length = this.length || 16;\n\n        while (length < this.pos + min) length *= 2;\n\n        if (length !== this.length) {\n            var buf = new Uint8Array(length);\n            buf.set(this.buf);\n            this.buf = buf;\n            this.length = length;\n        }\n    },\n\n    finish: function() {\n        this.length = this.pos;\n        this.pos = 0;\n        return this.buf.subarray(0, this.length);\n    },\n\n    writeFixed32: function(val) {\n        this.realloc(4);\n        writeInt32(this.buf, val, this.pos);\n        this.pos += 4;\n    },\n\n    writeSFixed32: function(val) {\n        this.realloc(4);\n        writeInt32(this.buf, val, this.pos);\n        this.pos += 4;\n    },\n\n    writeFixed64: function(val) {\n        this.realloc(8);\n        writeInt32(this.buf, val & -1, this.pos);\n        writeInt32(this.buf, Math.floor(val * SHIFT_RIGHT_32), this.pos + 4);\n        this.pos += 8;\n    },\n\n    writeSFixed64: function(val) {\n        this.realloc(8);\n        writeInt32(this.buf, val & -1, this.pos);\n        writeInt32(this.buf, Math.floor(val * SHIFT_RIGHT_32), this.pos + 4);\n        this.pos += 8;\n    },\n\n    writeVarint: function(val) {\n        val = +val || 0;\n\n        if (val > 0xfffffff || val < 0) {\n            writeBigVarint(val, this);\n            return;\n        }\n\n        this.realloc(4);\n\n        this.buf[this.pos++] =           val & 0x7f  | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return;\n        this.buf[this.pos++] = ((val >>>= 7) & 0x7f) | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return;\n        this.buf[this.pos++] = ((val >>>= 7) & 0x7f) | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return;\n        this.buf[this.pos++] =   (val >>> 7) & 0x7f;\n    },\n\n    writeSVarint: function(val) {\n        this.writeVarint(val < 0 ? -val * 2 - 1 : val * 2);\n    },\n\n    writeBoolean: function(val) {\n        this.writeVarint(Boolean(val));\n    },\n\n    writeString: function(str) {\n        str = String(str);\n        this.realloc(str.length * 4);\n\n        this.pos++; // reserve 1 byte for short string length\n\n        var startPos = this.pos;\n        // write the string directly to the buffer and see how much was written\n        this.pos = writeUtf8(this.buf, str, this.pos);\n        var len = this.pos - startPos;\n\n        if (len >= 0x80) makeRoomForExtraLength(startPos, len, this);\n\n        // finally, write the message length in the reserved place and restore the position\n        this.pos = startPos - 1;\n        this.writeVarint(len);\n        this.pos += len;\n    },\n\n    writeFloat: function(val) {\n        this.realloc(4);\n        ieee754.write(this.buf, val, this.pos, true, 23, 4);\n        this.pos += 4;\n    },\n\n    writeDouble: function(val) {\n        this.realloc(8);\n        ieee754.write(this.buf, val, this.pos, true, 52, 8);\n        this.pos += 8;\n    },\n\n    writeBytes: function(buffer) {\n        var len = buffer.length;\n        this.writeVarint(len);\n        this.realloc(len);\n        for (var i = 0; i < len; i++) this.buf[this.pos++] = buffer[i];\n    },\n\n    writeRawMessage: function(fn, obj) {\n        this.pos++; // reserve 1 byte for short message length\n\n        // write the message directly to the buffer and see how much was written\n        var startPos = this.pos;\n        fn(obj, this);\n        var len = this.pos - startPos;\n\n        if (len >= 0x80) makeRoomForExtraLength(startPos, len, this);\n\n        // finally, write the message length in the reserved place and restore the position\n        this.pos = startPos - 1;\n        this.writeVarint(len);\n        this.pos += len;\n    },\n\n    writeMessage: function(tag, fn, obj) {\n        this.writeTag(tag, Pbf.Bytes);\n        this.writeRawMessage(fn, obj);\n    },\n\n    writePackedVarint:   function(tag, arr) { this.writeMessage(tag, writePackedVarint, arr);   },\n    writePackedSVarint:  function(tag, arr) { this.writeMessage(tag, writePackedSVarint, arr);  },\n    writePackedBoolean:  function(tag, arr) { this.writeMessage(tag, writePackedBoolean, arr);  },\n    writePackedFloat:    function(tag, arr) { this.writeMessage(tag, writePackedFloat, arr);    },\n    writePackedDouble:   function(tag, arr) { this.writeMessage(tag, writePackedDouble, arr);   },\n    writePackedFixed32:  function(tag, arr) { this.writeMessage(tag, writePackedFixed32, arr);  },\n    writePackedSFixed32: function(tag, arr) { this.writeMessage(tag, writePackedSFixed32, arr); },\n    writePackedFixed64:  function(tag, arr) { this.writeMessage(tag, writePackedFixed64, arr);  },\n    writePackedSFixed64: function(tag, arr) { this.writeMessage(tag, writePackedSFixed64, arr); },\n\n    writeBytesField: function(tag, buffer) {\n        this.writeTag(tag, Pbf.Bytes);\n        this.writeBytes(buffer);\n    },\n    writeFixed32Field: function(tag, val) {\n        this.writeTag(tag, Pbf.Fixed32);\n        this.writeFixed32(val);\n    },\n    writeSFixed32Field: function(tag, val) {\n        this.writeTag(tag, Pbf.Fixed32);\n        this.writeSFixed32(val);\n    },\n    writeFixed64Field: function(tag, val) {\n        this.writeTag(tag, Pbf.Fixed64);\n        this.writeFixed64(val);\n    },\n    writeSFixed64Field: function(tag, val) {\n        this.writeTag(tag, Pbf.Fixed64);\n        this.writeSFixed64(val);\n    },\n    writeVarintField: function(tag, val) {\n        this.writeTag(tag, Pbf.Varint);\n        this.writeVarint(val);\n    },\n    writeSVarintField: function(tag, val) {\n        this.writeTag(tag, Pbf.Varint);\n        this.writeSVarint(val);\n    },\n    writeStringField: function(tag, str) {\n        this.writeTag(tag, Pbf.Bytes);\n        this.writeString(str);\n    },\n    writeFloatField: function(tag, val) {\n        this.writeTag(tag, Pbf.Fixed32);\n        this.writeFloat(val);\n    },\n    writeDoubleField: function(tag, val) {\n        this.writeTag(tag, Pbf.Fixed64);\n        this.writeDouble(val);\n    },\n    writeBooleanField: function(tag, val) {\n        this.writeVarintField(tag, Boolean(val));\n    }\n};\n\nfunction readVarintRemainder(l, s, p) {\n    var buf = p.buf,\n        h, b;\n\n    b = buf[p.pos++]; h  = (b & 0x70) >> 4;  if (b < 0x80) return toNum(l, h, s);\n    b = buf[p.pos++]; h |= (b & 0x7f) << 3;  if (b < 0x80) return toNum(l, h, s);\n    b = buf[p.pos++]; h |= (b & 0x7f) << 10; if (b < 0x80) return toNum(l, h, s);\n    b = buf[p.pos++]; h |= (b & 0x7f) << 17; if (b < 0x80) return toNum(l, h, s);\n    b = buf[p.pos++]; h |= (b & 0x7f) << 24; if (b < 0x80) return toNum(l, h, s);\n    b = buf[p.pos++]; h |= (b & 0x01) << 31; if (b < 0x80) return toNum(l, h, s);\n\n    throw new Error('Expected varint not more than 10 bytes');\n}\n\nfunction readPackedEnd(pbf) {\n    return pbf.type === Pbf.Bytes ?\n        pbf.readVarint() + pbf.pos : pbf.pos + 1;\n}\n\nfunction toNum(low, high, isSigned) {\n    if (isSigned) {\n        return high * 0x100000000 + (low >>> 0);\n    }\n\n    return ((high >>> 0) * 0x100000000) + (low >>> 0);\n}\n\nfunction writeBigVarint(val, pbf) {\n    var low, high;\n\n    if (val >= 0) {\n        low  = (val % 0x100000000) | 0;\n        high = (val / 0x100000000) | 0;\n    } else {\n        low  = ~(-val % 0x100000000);\n        high = ~(-val / 0x100000000);\n\n        if (low ^ 0xffffffff) {\n            low = (low + 1) | 0;\n        } else {\n            low = 0;\n            high = (high + 1) | 0;\n        }\n    }\n\n    if (val >= 0x10000000000000000 || val < -0x10000000000000000) {\n        throw new Error('Given varint doesn\\'t fit into 10 bytes');\n    }\n\n    pbf.realloc(10);\n\n    writeBigVarintLow(low, high, pbf);\n    writeBigVarintHigh(high, pbf);\n}\n\nfunction writeBigVarintLow(low, high, pbf) {\n    pbf.buf[pbf.pos++] = low & 0x7f | 0x80; low >>>= 7;\n    pbf.buf[pbf.pos++] = low & 0x7f | 0x80; low >>>= 7;\n    pbf.buf[pbf.pos++] = low & 0x7f | 0x80; low >>>= 7;\n    pbf.buf[pbf.pos++] = low & 0x7f | 0x80; low >>>= 7;\n    pbf.buf[pbf.pos]   = low & 0x7f;\n}\n\nfunction writeBigVarintHigh(high, pbf) {\n    var lsb = (high & 0x07) << 4;\n\n    pbf.buf[pbf.pos++] |= lsb         | ((high >>>= 3) ? 0x80 : 0); if (!high) return;\n    pbf.buf[pbf.pos++]  = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); if (!high) return;\n    pbf.buf[pbf.pos++]  = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); if (!high) return;\n    pbf.buf[pbf.pos++]  = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); if (!high) return;\n    pbf.buf[pbf.pos++]  = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); if (!high) return;\n    pbf.buf[pbf.pos++]  = high & 0x7f;\n}\n\nfunction makeRoomForExtraLength(startPos, len, pbf) {\n    var extraLen =\n        len <= 0x3fff ? 1 :\n        len <= 0x1fffff ? 2 :\n        len <= 0xfffffff ? 3 : Math.ceil(Math.log(len) / (Math.LN2 * 7));\n\n    // if 1 byte isn't enough for encoding message length, shift the data to the right\n    pbf.realloc(extraLen);\n    for (var i = pbf.pos - 1; i >= startPos; i--) pbf.buf[i + extraLen] = pbf.buf[i];\n}\n\nfunction writePackedVarint(arr, pbf)   { for (var i = 0; i < arr.length; i++) pbf.writeVarint(arr[i]);   }\nfunction writePackedSVarint(arr, pbf)  { for (var i = 0; i < arr.length; i++) pbf.writeSVarint(arr[i]);  }\nfunction writePackedFloat(arr, pbf)    { for (var i = 0; i < arr.length; i++) pbf.writeFloat(arr[i]);    }\nfunction writePackedDouble(arr, pbf)   { for (var i = 0; i < arr.length; i++) pbf.writeDouble(arr[i]);   }\nfunction writePackedBoolean(arr, pbf)  { for (var i = 0; i < arr.length; i++) pbf.writeBoolean(arr[i]);  }\nfunction writePackedFixed32(arr, pbf)  { for (var i = 0; i < arr.length; i++) pbf.writeFixed32(arr[i]);  }\nfunction writePackedSFixed32(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeSFixed32(arr[i]); }\nfunction writePackedFixed64(arr, pbf)  { for (var i = 0; i < arr.length; i++) pbf.writeFixed64(arr[i]);  }\nfunction writePackedSFixed64(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeSFixed64(arr[i]); }\n\n// Buffer code below from https://github.com/feross/buffer, MIT-licensed\n\nfunction readUInt32(buf, pos) {\n    return ((buf[pos]) |\n        (buf[pos + 1] << 8) |\n        (buf[pos + 2] << 16)) +\n        (buf[pos + 3] * 0x1000000);\n}\n\nfunction writeInt32(buf, val, pos) {\n    buf[pos] = val;\n    buf[pos + 1] = (val >>> 8);\n    buf[pos + 2] = (val >>> 16);\n    buf[pos + 3] = (val >>> 24);\n}\n\nfunction readInt32(buf, pos) {\n    return ((buf[pos]) |\n        (buf[pos + 1] << 8) |\n        (buf[pos + 2] << 16)) +\n        (buf[pos + 3] << 24);\n}\n\nfunction readUtf8(buf, pos, end) {\n    var str = '';\n    var i = pos;\n\n    while (i < end) {\n        var b0 = buf[i];\n        var c = null; // codepoint\n        var bytesPerSequence =\n            b0 > 0xEF ? 4 :\n            b0 > 0xDF ? 3 :\n            b0 > 0xBF ? 2 : 1;\n\n        if (i + bytesPerSequence > end) break;\n\n        var b1, b2, b3;\n\n        if (bytesPerSequence === 1) {\n            if (b0 < 0x80) {\n                c = b0;\n            }\n        } else if (bytesPerSequence === 2) {\n            b1 = buf[i + 1];\n            if ((b1 & 0xC0) === 0x80) {\n                c = (b0 & 0x1F) << 0x6 | (b1 & 0x3F);\n                if (c <= 0x7F) {\n                    c = null;\n                }\n            }\n        } else if (bytesPerSequence === 3) {\n            b1 = buf[i + 1];\n            b2 = buf[i + 2];\n            if ((b1 & 0xC0) === 0x80 && (b2 & 0xC0) === 0x80) {\n                c = (b0 & 0xF) << 0xC | (b1 & 0x3F) << 0x6 | (b2 & 0x3F);\n                if (c <= 0x7FF || (c >= 0xD800 && c <= 0xDFFF)) {\n                    c = null;\n                }\n            }\n        } else if (bytesPerSequence === 4) {\n            b1 = buf[i + 1];\n            b2 = buf[i + 2];\n            b3 = buf[i + 3];\n            if ((b1 & 0xC0) === 0x80 && (b2 & 0xC0) === 0x80 && (b3 & 0xC0) === 0x80) {\n                c = (b0 & 0xF) << 0x12 | (b1 & 0x3F) << 0xC | (b2 & 0x3F) << 0x6 | (b3 & 0x3F);\n                if (c <= 0xFFFF || c >= 0x110000) {\n                    c = null;\n                }\n            }\n        }\n\n        if (c === null) {\n            c = 0xFFFD;\n            bytesPerSequence = 1;\n\n        } else if (c > 0xFFFF) {\n            c -= 0x10000;\n            str += String.fromCharCode(c >>> 10 & 0x3FF | 0xD800);\n            c = 0xDC00 | c & 0x3FF;\n        }\n\n        str += String.fromCharCode(c);\n        i += bytesPerSequence;\n    }\n\n    return str;\n}\n\nfunction writeUtf8(buf, str, pos) {\n    for (var i = 0, c, lead; i < str.length; i++) {\n        c = str.charCodeAt(i); // code point\n\n        if (c > 0xD7FF && c < 0xE000) {\n            if (lead) {\n                if (c < 0xDC00) {\n                    buf[pos++] = 0xEF;\n                    buf[pos++] = 0xBF;\n                    buf[pos++] = 0xBD;\n                    lead = c;\n                    continue;\n                } else {\n                    c = lead - 0xD800 << 10 | c - 0xDC00 | 0x10000;\n                    lead = null;\n                }\n            } else {\n                if (c > 0xDBFF || (i + 1 === str.length)) {\n                    buf[pos++] = 0xEF;\n                    buf[pos++] = 0xBF;\n                    buf[pos++] = 0xBD;\n                } else {\n                    lead = c;\n                }\n                continue;\n            }\n        } else if (lead) {\n            buf[pos++] = 0xEF;\n            buf[pos++] = 0xBF;\n            buf[pos++] = 0xBD;\n            lead = null;\n        }\n\n        if (c < 0x80) {\n            buf[pos++] = c;\n        } else {\n            if (c < 0x800) {\n                buf[pos++] = c >> 0x6 | 0xC0;\n            } else {\n                if (c < 0x10000) {\n                    buf[pos++] = c >> 0xC | 0xE0;\n                } else {\n                    buf[pos++] = c >> 0x12 | 0xF0;\n                    buf[pos++] = c >> 0xC & 0x3F | 0x80;\n                }\n                buf[pos++] = c >> 0x6 & 0x3F | 0x80;\n            }\n            buf[pos++] = c & 0x3F | 0x80;\n        }\n    }\n    return pos;\n}\n","/**\n * @module ol/render/Feature\n */\nimport {UNDEFINED} from '../functions.js';\nimport {extend} from '../array.js';\nimport {createOrUpdateFromCoordinate, createOrUpdateFromFlatCoordinates, getCenter, getHeight} from '../extent.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport {linearRingss as linearRingssCenter} from '../geom/flat/center.js';\nimport {getInteriorPointOfArray, getInteriorPointsOfMultiArray} from '../geom/flat/interiorpoint.js';\nimport {interpolatePoint} from '../geom/flat/interpolate.js';\nimport {get as getProjection} from '../proj.js';\nimport {transform2D} from '../geom/flat/transform.js';\nimport {create as createTransform, compose as composeTransform} from '../transform.js';\n\n\n/**\n * @type {module:ol/transform~Transform}\n */\nconst tmpTransform = createTransform();\n\n\n/**\n * Lightweight, read-only, {@link module:ol/Feature~Feature} and {@link module:ol/geom/Geometry~Geometry} like\n * structure, optimized for vector tile rendering and styling. Geometry access\n * through the API is limited to getting the type and extent of the geometry.\n *\n * @param {module:ol/geom/GeometryType} type Geometry type.\n * @param {Array.<number>} flatCoordinates Flat coordinates. These always need\n *     to be right-handed for polygons.\n * @param {Array.<number>|Array.<Array.<number>>} ends Ends or Endss.\n * @param {Object.<string, *>} properties Properties.\n * @param {number|string|undefined} id Feature id.\n */\nclass RenderFeature {\n  constructor(type, flatCoordinates, ends, properties, id) {\n    /**\n    * @private\n    * @type {module:ol/extent~Extent|undefined}\n    */\n    this.extent_;\n\n    /**\n    * @private\n    * @type {number|string|undefined}\n    */\n    this.id_ = id;\n\n    /**\n    * @private\n    * @type {module:ol/geom/GeometryType}\n    */\n    this.type_ = type;\n\n    /**\n    * @private\n    * @type {Array.<number>}\n    */\n    this.flatCoordinates_ = flatCoordinates;\n\n    /**\n    * @private\n    * @type {Array.<number>}\n    */\n    this.flatInteriorPoints_ = null;\n\n    /**\n    * @private\n    * @type {Array.<number>}\n    */\n    this.flatMidpoints_ = null;\n\n    /**\n    * @private\n    * @type {Array.<number>|Array.<Array.<number>>}\n    */\n    this.ends_ = ends;\n\n    /**\n    * @private\n    * @type {Object.<string, *>}\n    */\n    this.properties_ = properties;\n\n  }\n\n  /**\n  * Get a feature property by its key.\n  * @param {string} key Key\n  * @return {*} Value for the requested key.\n  * @api\n  */\n  get(key) {\n    return this.properties_[key];\n  }\n\n  /**\n  * Get the extent of this feature's geometry.\n  * @return {module:ol/extent~Extent} Extent.\n  * @api\n  */\n  getExtent() {\n    if (!this.extent_) {\n      this.extent_ = this.type_ === GeometryType.POINT ?\n        createOrUpdateFromCoordinate(this.flatCoordinates_) :\n        createOrUpdateFromFlatCoordinates(\n          this.flatCoordinates_, 0, this.flatCoordinates_.length, 2);\n\n    }\n    return this.extent_;\n  }\n\n  /**\n  * @return {Array.<number>} Flat interior points.\n  */\n  getFlatInteriorPoint() {\n    if (!this.flatInteriorPoints_) {\n      const flatCenter = getCenter(this.getExtent());\n      this.flatInteriorPoints_ = getInteriorPointOfArray(\n        this.flatCoordinates_, 0, this.ends_, 2, flatCenter, 0);\n    }\n    return this.flatInteriorPoints_;\n  }\n\n  /**\n  * @return {Array.<number>} Flat interior points.\n  */\n  getFlatInteriorPoints() {\n    if (!this.flatInteriorPoints_) {\n      const flatCenters = linearRingssCenter(\n        this.flatCoordinates_, 0, this.ends_, 2);\n      this.flatInteriorPoints_ = getInteriorPointsOfMultiArray(\n        this.flatCoordinates_, 0, this.ends_, 2, flatCenters);\n    }\n    return this.flatInteriorPoints_;\n  }\n\n  /**\n  * @return {Array.<number>} Flat midpoint.\n  */\n  getFlatMidpoint() {\n    if (!this.flatMidpoints_) {\n      this.flatMidpoints_ = interpolatePoint(\n        this.flatCoordinates_, 0, this.flatCoordinates_.length, 2, 0.5);\n    }\n    return this.flatMidpoints_;\n  }\n\n  /**\n  * @return {Array.<number>} Flat midpoints.\n  */\n  getFlatMidpoints() {\n    if (!this.flatMidpoints_) {\n      this.flatMidpoints_ = [];\n      const flatCoordinates = this.flatCoordinates_;\n      let offset = 0;\n      const ends = this.ends_;\n      for (let i = 0, ii = ends.length; i < ii; ++i) {\n        const end = ends[i];\n        const midpoint = interpolatePoint(\n          flatCoordinates, offset, end, 2, 0.5);\n        extend(this.flatMidpoints_, midpoint);\n        offset = end;\n      }\n    }\n    return this.flatMidpoints_;\n  }\n\n  /**\n  * Get the feature identifier.  This is a stable identifier for the feature and\n  * is set when reading data from a remote source.\n  * @return {number|string|undefined} Id.\n  * @api\n  */\n  getId() {\n    return this.id_;\n  }\n\n  /**\n  * @return {Array.<number>} Flat coordinates.\n  */\n  getOrientedFlatCoordinates() {\n    return this.flatCoordinates_;\n  }\n\n  /**\n  * For API compatibility with {@link module:ol/Feature~Feature}, this method is useful when\n  * determining the geometry type in style function (see {@link #getType}).\n  * @return {module:ol/render/Feature} Feature.\n  * @api\n  */\n  getGeometry() {\n    return this;\n  }\n\n  /**\n  * Get the feature properties.\n  * @return {Object.<string, *>} Feature properties.\n  * @api\n  */\n  getProperties() {\n    return this.properties_;\n  }\n\n  /**\n  * @return {number} Stride.\n  */\n  getStride() {\n    return 2;\n  }\n\n  /**\n  * Get the type of this feature's geometry.\n  * @return {module:ol/geom/GeometryType} Geometry type.\n  * @api\n  */\n  getType() {\n    return this.type_;\n  }\n\n  /**\n  * Transform geometry coordinates from tile pixel space to projected.\n  * The SRS of the source and destination are expected to be the same.\n  *\n  * @param {module:ol/proj~ProjectionLike} source The current projection\n  * @param {module:ol/proj~ProjectionLike} destination The desired projection.\n  */\n  transform(source, destination) {\n    source = getProjection(source);\n    const pixelExtent = source.getExtent();\n    const projectedExtent = source.getWorldExtent();\n    const scale = getHeight(projectedExtent) / getHeight(pixelExtent);\n    composeTransform(tmpTransform,\n      projectedExtent[0], projectedExtent[3],\n      scale, -scale, 0,\n      0, 0);\n    transform2D(this.flatCoordinates_, 0, this.flatCoordinates_.length, 2,\n      tmpTransform, this.flatCoordinates_);\n  }\n}\n\n\n/**\n * @return {Array.<number>|Array.<Array.<number>>} Ends or endss.\n */\nRenderFeature.prototype.getEnds =\nRenderFeature.prototype.getEndss = function() {\n  return this.ends_;\n};\n\n\n/**\n * @return {Array.<number>} Flat coordinates.\n */\nRenderFeature.prototype.getFlatCoordinates =\n    RenderFeature.prototype.getOrientedFlatCoordinates;\n\n\n/**\n * Get the feature for working with its geometry.\n * @return {module:ol/render/Feature} Feature.\n */\nRenderFeature.prototype.getSimplifiedGeometry =\n    RenderFeature.prototype.getGeometry;\n\n\n/**\n * @return {undefined}\n */\nRenderFeature.prototype.getStyleFunction = UNDEFINED;\n\n\nexport default RenderFeature;\n","/**\n * @module ol/format/MVT\n */\n//FIXME Implement projection handling\n\nimport {assert} from '../asserts.js';\nimport PBF from 'pbf';\nimport FeatureFormat, {transformWithOptions} from '../format/Feature.js';\nimport FormatType from '../format/FormatType.js';\nimport GeometryLayout from '../geom/GeometryLayout.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport LineString from '../geom/LineString.js';\nimport MultiLineString from '../geom/MultiLineString.js';\nimport MultiPoint from '../geom/MultiPoint.js';\nimport MultiPolygon from '../geom/MultiPolygon.js';\nimport Point from '../geom/Point.js';\nimport Polygon from '../geom/Polygon.js';\nimport {linearRingIsClockwise} from '../geom/flat/orient.js';\nimport Projection from '../proj/Projection.js';\nimport Units from '../proj/Units.js';\nimport RenderFeature from '../render/Feature.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {function((module:ol/geom/Geometry|Object.<string,*>)=)|function(module:ol/geom/GeometryType,Array.<number>,(Array.<number>|Array.<Array.<number>>),Object.<string,*>,number)} [featureClass]\n * Class for features returned by {@link module:ol/format/MVT#readFeatures}. Set to\n * {@link module:ol/Feature~Feature} to get full editing and geometry support at the cost of\n * decreased rendering performance. The default is {@link module:ol/render/Feature~RenderFeature},\n * which is optimized for rendering and hit detection.\n * @property {string} [geometryName='geometry'] Geometry name to use when creating\n * features.\n * @property {string} [layerName='layer'] Name of the feature attribute that\n * holds the layer name.\n * @property {Array.<string>} [layers] Layers to read features from. If not\n * provided, features will be read from all layers.\n */\n\n\n/**\n * @classdesc\n * Feature format for reading data in the Mapbox MVT format.\n *\n * @param {module:ol/format/MVT~Options=} opt_options Options.\n * @api\n */\nclass MVT extends FeatureFormat {\n\n  /**\n   * @param {module:ol/format/MVT~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n    super();\n\n    const options = opt_options ? opt_options : {};\n\n    /**\n     * @type {module:ol/proj/Projection}\n     */\n    this.dataProjection = new Projection({\n      code: '',\n      units: Units.TILE_PIXELS\n    });\n\n    /**\n     * @private\n     * @type {function((module:ol/geom/Geometry|Object.<string,*>)=)|\n     *     function(module:ol/geom/GeometryType,Array.<number>,\n     *         (Array.<number>|Array.<Array.<number>>),Object.<string,*>,number)}\n     */\n    this.featureClass_ = options.featureClass ?\n      options.featureClass : RenderFeature;\n\n    /**\n     * @private\n     * @type {string|undefined}\n     */\n    this.geometryName_ = options.geometryName;\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.layerName_ = options.layerName ? options.layerName : 'layer';\n\n    /**\n     * @private\n     * @type {Array.<string>}\n     */\n    this.layers_ = options.layers ? options.layers : null;\n\n    /**\n     * @private\n     * @type {module:ol/extent~Extent}\n     */\n    this.extent_ = null;\n\n  }\n\n  /**\n   * Read the raw geometry from the pbf offset stored in a raw feature's geometry\n   * property.\n   * @suppress {missingProperties}\n   * @param {Object} pbf PBF.\n   * @param {Object} feature Raw feature.\n   * @param {Array.<number>} flatCoordinates Array to store flat coordinates in.\n   * @param {Array.<number>} ends Array to store ends in.\n   * @private\n   */\n  readRawGeometry_(pbf, feature, flatCoordinates, ends) {\n    pbf.pos = feature.geometry;\n\n    const end = pbf.readVarint() + pbf.pos;\n    let cmd = 1;\n    let length = 0;\n    let x = 0;\n    let y = 0;\n    let coordsLen = 0;\n    let currentEnd = 0;\n\n    while (pbf.pos < end) {\n      if (!length) {\n        const cmdLen = pbf.readVarint();\n        cmd = cmdLen & 0x7;\n        length = cmdLen >> 3;\n      }\n\n      length--;\n\n      if (cmd === 1 || cmd === 2) {\n        x += pbf.readSVarint();\n        y += pbf.readSVarint();\n\n        if (cmd === 1) { // moveTo\n          if (coordsLen > currentEnd) {\n            ends.push(coordsLen);\n            currentEnd = coordsLen;\n          }\n        }\n\n        flatCoordinates.push(x, y);\n        coordsLen += 2;\n\n      } else if (cmd === 7) {\n\n        if (coordsLen > currentEnd) {\n          // close polygon\n          flatCoordinates.push(\n            flatCoordinates[currentEnd], flatCoordinates[currentEnd + 1]);\n          coordsLen += 2;\n        }\n\n      } else {\n        assert(false, 59); // Invalid command found in the PBF\n      }\n    }\n\n    if (coordsLen > currentEnd) {\n      ends.push(coordsLen);\n      currentEnd = coordsLen;\n    }\n\n  }\n\n  /**\n   * @private\n   * @param {Object} pbf PBF\n   * @param {Object} rawFeature Raw Mapbox feature.\n   * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n   * @return {module:ol/Feature|module:ol/render/Feature} Feature.\n   */\n  createFeature_(pbf, rawFeature, opt_options) {\n    const type = rawFeature.type;\n    if (type === 0) {\n      return null;\n    }\n\n    let feature;\n    const id = rawFeature.id;\n    const values = rawFeature.properties;\n    values[this.layerName_] = rawFeature.layer.name;\n\n    const flatCoordinates = [];\n    const ends = [];\n    this.readRawGeometry_(pbf, rawFeature, flatCoordinates, ends);\n\n    const geometryType = getGeometryType(type, ends.length);\n\n    if (this.featureClass_ === RenderFeature) {\n      feature = new this.featureClass_(geometryType, flatCoordinates, ends, values, id);\n    } else {\n      let geom;\n      if (geometryType == GeometryType.POLYGON) {\n        const endss = [];\n        let offset = 0;\n        let prevEndIndex = 0;\n        for (let i = 0, ii = ends.length; i < ii; ++i) {\n          const end = ends[i];\n          if (!linearRingIsClockwise(flatCoordinates, offset, end, 2)) {\n            endss.push(ends.slice(prevEndIndex, i));\n            prevEndIndex = i;\n          }\n          offset = end;\n        }\n        if (endss.length > 1) {\n          geom = new MultiPolygon(flatCoordinates, GeometryLayout.XY, endss);\n        } else {\n          geom = new Polygon(flatCoordinates, GeometryLayout.XY, ends);\n        }\n      } else {\n        geom = geometryType === GeometryType.POINT ? new Point(flatCoordinates, GeometryLayout.XY) :\n          geometryType === GeometryType.LINE_STRING ? new LineString(flatCoordinates, GeometryLayout.XY) :\n            geometryType === GeometryType.POLYGON ? new Polygon(flatCoordinates, GeometryLayout.XY, ends) :\n              geometryType === GeometryType.MULTI_POINT ? new MultiPoint(flatCoordinates, GeometryLayout.XY) :\n                geometryType === GeometryType.MULTI_LINE_STRING ? new MultiLineString(flatCoordinates, GeometryLayout.XY, ends) :\n                  null;\n      }\n      feature = new this.featureClass_();\n      if (this.geometryName_) {\n        feature.setGeometryName(this.geometryName_);\n      }\n      const geometry = transformWithOptions(geom, false, this.adaptOptions(opt_options));\n      feature.setGeometry(geometry);\n      feature.setId(id);\n      feature.setProperties(values);\n    }\n\n    return feature;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  getLastExtent() {\n    return this.extent_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getType() {\n    return FormatType.ARRAY_BUFFER;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  readFeatures(source, opt_options) {\n    const layers = this.layers_;\n\n    const pbf = new PBF(/** @type {ArrayBuffer} */ (source));\n    const pbfLayers = pbf.readFields(layersPBFReader, {});\n    /** @type {Array.<module:ol/Feature|module:ol/render/Feature>} */\n    const features = [];\n    for (const name in pbfLayers) {\n      if (layers && layers.indexOf(name) == -1) {\n        continue;\n      }\n      const pbfLayer = pbfLayers[name];\n\n      for (let i = 0, ii = pbfLayer.length; i < ii; ++i) {\n        const rawFeature = readRawFeature(pbf, pbfLayer, i);\n        features.push(this.createFeature_(pbf, rawFeature));\n      }\n      this.extent_ = pbfLayer ? [0, 0, pbfLayer.extent, pbfLayer.extent] : null;\n    }\n\n    return features;\n  }\n\n  /**\n   * @inheritDoc\n   * @api\n   */\n  readProjection(source) {\n    return this.dataProjection;\n  }\n\n  /**\n   * Sets the layers that features will be read from.\n   * @param {Array.<string>} layers Layers.\n   * @api\n   */\n  setLayers(layers) {\n    this.layers_ = layers;\n  }\n\n  /**\n   * Not implemented.\n   * @override\n   */\n  readFeature() {}\n\n  /**\n   * Not implemented.\n   * @override\n   */\n  readGeometry() {}\n\n  /**\n   * Not implemented.\n   * @override\n   */\n  writeFeature() {}\n\n  /**\n   * Not implemented.\n   * @override\n   */\n  writeGeometry() {}\n\n  /**\n   * Not implemented.\n   * @override\n   */\n  writeFeatures() {}\n}\n\n\n/**\n * Reader callback for parsing layers.\n * @param {number} tag The tag.\n * @param {Object} layers The layers object.\n * @param {Object} pbf The PBF.\n */\nfunction layersPBFReader(tag, layers, pbf) {\n  if (tag === 3) {\n    const layer = {\n      keys: [],\n      values: [],\n      features: []\n    };\n    const end = pbf.readVarint() + pbf.pos;\n    pbf.readFields(layerPBFReader, layer, end);\n    layer.length = layer.features.length;\n    if (layer.length) {\n      layers[layer.name] = layer;\n    }\n  }\n}\n\n/**\n * Reader callback for parsing layer.\n * @param {number} tag The tag.\n * @param {Object} layer The layer object.\n * @param {Object} pbf The PBF.\n */\nfunction layerPBFReader(tag, layer, pbf) {\n  if (tag === 15) {\n    layer.version = pbf.readVarint();\n  } else if (tag === 1) {\n    layer.name = pbf.readString();\n  } else if (tag === 5) {\n    layer.extent = pbf.readVarint();\n  } else if (tag === 2) {\n    layer.features.push(pbf.pos);\n  } else if (tag === 3) {\n    layer.keys.push(pbf.readString());\n  } else if (tag === 4) {\n    let value = null;\n    const end = pbf.readVarint() + pbf.pos;\n    while (pbf.pos < end) {\n      tag = pbf.readVarint() >> 3;\n      value = tag === 1 ? pbf.readString() :\n        tag === 2 ? pbf.readFloat() :\n          tag === 3 ? pbf.readDouble() :\n            tag === 4 ? pbf.readVarint64() :\n              tag === 5 ? pbf.readVarint() :\n                tag === 6 ? pbf.readSVarint() :\n                  tag === 7 ? pbf.readBoolean() : null;\n    }\n    layer.values.push(value);\n  }\n}\n\n/**\n * Reader callback for parsing feature.\n * @param {number} tag The tag.\n * @param {Object} feature The feature object.\n * @param {Object} pbf The PBF.\n */\nfunction featurePBFReader(tag, feature, pbf) {\n  if (tag == 1) {\n    feature.id = pbf.readVarint();\n  } else if (tag == 2) {\n    const end = pbf.readVarint() + pbf.pos;\n    while (pbf.pos < end) {\n      const key = feature.layer.keys[pbf.readVarint()];\n      const value = feature.layer.values[pbf.readVarint()];\n      feature.properties[key] = value;\n    }\n  } else if (tag == 3) {\n    feature.type = pbf.readVarint();\n  } else if (tag == 4) {\n    feature.geometry = pbf.pos;\n  }\n}\n\n\n/**\n * Read a raw feature from the pbf offset stored at index `i` in the raw layer.\n * @suppress {missingProperties}\n * @param {Object} pbf PBF.\n * @param {Object} layer Raw layer.\n * @param {number} i Index of the feature in the raw layer's `features` array.\n * @return {Object} Raw feature.\n */\nfunction readRawFeature(pbf, layer, i) {\n  pbf.pos = layer.features[i];\n  const end = pbf.readVarint() + pbf.pos;\n\n  const feature = {\n    layer: layer,\n    type: 0,\n    properties: {}\n  };\n  pbf.readFields(featurePBFReader, feature, end);\n  return feature;\n}\n\n\n/**\n * @suppress {missingProperties}\n * @param {number} type The raw feature's geometry type\n * @param {number} numEnds Number of ends of the flat coordinates of the\n * geometry.\n * @return {module:ol/geom/GeometryType} The geometry type.\n */\nfunction getGeometryType(type, numEnds) {\n  /** @type {module:ol/geom/GeometryType} */\n  let geometryType;\n  if (type === 1) {\n    geometryType = numEnds === 1 ?\n      GeometryType.POINT : GeometryType.MULTI_POINT;\n  } else if (type === 2) {\n    geometryType = numEnds === 1 ?\n      GeometryType.LINE_STRING :\n      GeometryType.MULTI_LINE_STRING;\n  } else if (type === 3) {\n    geometryType = GeometryType.POLYGON;\n    // MultiPolygon not relevant for rendering - winding order determines\n    // outer rings of polygons.\n  }\n  return geometryType;\n}\n\nexport default MVT;\n","/**\n * @module ol/format/OSMXML\n */\n// FIXME add typedef for stack state objects\nimport {extend} from '../array.js';\nimport Feature from '../Feature.js';\nimport {transformWithOptions} from '../format/Feature.js';\nimport XMLFeature from '../format/XMLFeature.js';\nimport GeometryLayout from '../geom/GeometryLayout.js';\nimport LineString from '../geom/LineString.js';\nimport Point from '../geom/Point.js';\nimport Polygon from '../geom/Polygon.js';\nimport {isEmpty} from '../obj.js';\nimport {get as getProjection} from '../proj.js';\nimport {pushParseAndPop, makeStructureNS} from '../xml.js';\n\n\n/**\n * @const\n * @type {Array.<null>}\n */\nconst NAMESPACE_URIS = [null];\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst WAY_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'nd': readNd,\n    'tag': readTag\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'node': readNode,\n    'way': readWay\n  });\n\n\n/**\n * @classdesc\n * Feature format for reading data in the\n * [OSMXML format](http://wiki.openstreetmap.org/wiki/OSM_XML).\n *\n * @api\n */\nclass OSMXML extends XMLFeature {\n  constructor() {\n    super();\n\n    /**\n     * @inheritDoc\n     */\n    this.dataProjection = getProjection('EPSG:4326');\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFeaturesFromNode(node, opt_options) {\n    const options = this.getReadOptions(node, opt_options);\n    if (node.localName == 'osm') {\n      const state = pushParseAndPop({\n        nodes: {},\n        ways: [],\n        features: []\n      }, PARSERS, node, [options]);\n      // parse nodes in ways\n      for (let j = 0; j < state.ways.length; j++) {\n        const values = /** @type {Object} */ (state.ways[j]);\n        /** @type {Array.<number>} */\n        const flatCoordinates = [];\n        for (let i = 0, ii = values.ndrefs.length; i < ii; i++) {\n          const point = state.nodes[values.ndrefs[i]];\n          extend(flatCoordinates, point);\n        }\n        let geometry;\n        if (values.ndrefs[0] == values.ndrefs[values.ndrefs.length - 1]) {\n          // closed way\n          geometry = new Polygon(flatCoordinates, GeometryLayout.XY, [flatCoordinates.length]);\n        } else {\n          geometry = new LineString(flatCoordinates, GeometryLayout.XY);\n        }\n        transformWithOptions(geometry, false, options);\n        const feature = new Feature(geometry);\n        feature.setId(values.id);\n        feature.setProperties(values.tags);\n        state.features.push(feature);\n      }\n      if (state.features) {\n        return state.features;\n      }\n    }\n    return [];\n  }\n\n  /**\n   * Not implemented.\n   * @inheritDoc\n   */\n  writeFeatureNode(feature, opt_options) {}\n\n  /**\n   * Not implemented.\n   * @inheritDoc\n   */\n  writeFeaturesNode(features, opt_options) {}\n\n  /**\n   * Not implemented.\n   * @inheritDoc\n   */\n  writeGeometryNode(geometry, opt_options) {}\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst NODE_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'tag': readTag\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction readNode(node, objectStack) {\n  const options = /** @type {module:ol/format/Feature~ReadOptions} */ (objectStack[0]);\n  const state = /** @type {Object} */ (objectStack[objectStack.length - 1]);\n  const id = node.getAttribute('id');\n  /** @type {module:ol/coordinate~Coordinate} */\n  const coordinates = [\n    parseFloat(node.getAttribute('lon')),\n    parseFloat(node.getAttribute('lat'))\n  ];\n  state.nodes[id] = coordinates;\n\n  const values = pushParseAndPop({\n    tags: {}\n  }, NODE_PARSERS, node, objectStack);\n  if (!isEmpty(values.tags)) {\n    const geometry = new Point(coordinates);\n    transformWithOptions(geometry, false, options);\n    const feature = new Feature(geometry);\n    feature.setId(id);\n    feature.setProperties(values.tags);\n    state.features.push(feature);\n  }\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction readWay(node, objectStack) {\n  const id = node.getAttribute('id');\n  const values = pushParseAndPop({\n    id: id,\n    ndrefs: [],\n    tags: {}\n  }, WAY_PARSERS, node, objectStack);\n  const state = /** @type {Object} */ (objectStack[objectStack.length - 1]);\n  state.ways.push(values);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction readNd(node, objectStack) {\n  const values = /** @type {Object} */ (objectStack[objectStack.length - 1]);\n  values.ndrefs.push(node.getAttribute('ref'));\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction readTag(node, objectStack) {\n  const values = /** @type {Object} */ (objectStack[objectStack.length - 1]);\n  values.tags[node.getAttribute('k')] = node.getAttribute('v');\n}\n\n\nexport default OSMXML;\n","/**\n * @module ol/geom/flat/flip\n */\n\n\n/**\n * @param {Array.<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {Array.<number>=} opt_dest Destination.\n * @param {number=} opt_destOffset Destination offset.\n * @return {Array.<number>} Flat coordinates.\n */\nexport function flipXY(flatCoordinates, offset, end, stride, opt_dest, opt_destOffset) {\n  let dest, destOffset;\n  if (opt_dest !== undefined) {\n    dest = opt_dest;\n    destOffset = opt_destOffset !== undefined ? opt_destOffset : 0;\n  } else {\n    dest = [];\n    destOffset = 0;\n  }\n  let j = offset;\n  while (j < end) {\n    const x = flatCoordinates[j++];\n    dest[destOffset++] = flatCoordinates[j++];\n    dest[destOffset++] = x;\n    for (let k = 2; k < stride; ++k) {\n      dest[destOffset++] = flatCoordinates[j++];\n    }\n  }\n  dest.length = destOffset;\n  return dest;\n}\n","/**\n * @module ol/format/Polyline\n */\nimport {assert} from '../asserts.js';\nimport Feature from '../Feature.js';\nimport {transformWithOptions} from '../format/Feature.js';\nimport TextFeature from '../format/TextFeature.js';\nimport GeometryLayout from '../geom/GeometryLayout.js';\nimport LineString from '../geom/LineString.js';\nimport {getStrideForLayout} from '../geom/SimpleGeometry.js';\nimport {flipXY} from '../geom/flat/flip.js';\nimport {inflateCoordinates} from '../geom/flat/inflate.js';\nimport {get as getProjection} from '../proj.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [factor=1e5] The factor by which the coordinates values will be scaled.\n * @property {module:ol/geom/GeometryLayout} [geometryLayout='XY'] Layout of the\n * feature geometries created by the format reader.\n */\n\n\n/**\n * @classdesc\n * Feature format for reading and writing data in the Encoded\n * Polyline Algorithm Format.\n *\n * When reading features, the coordinates are assumed to be in two dimensions\n * and in [latitude, longitude] order.\n *\n * As Polyline sources contain a single feature,\n * {@link module:ol/format/Polyline~Polyline#readFeatures} will return the\n * feature in an array.\n *\n * @api\n */\nclass Polyline extends TextFeature {\n\n  /**\n   * @param {module:ol/format/Polyline~Options=} opt_options Optional configuration object.\n   */\n  constructor(opt_options) {\n    super();\n\n    const options = opt_options ? opt_options : {};\n\n\n    /**\n     * @inheritDoc\n     */\n    this.dataProjection = getProjection('EPSG:4326');\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.factor_ = options.factor ? options.factor : 1e5;\n\n    /**\n     * @private\n     * @type {module:ol/geom/GeometryLayout}\n     */\n    this.geometryLayout_ = options.geometryLayout ?\n      options.geometryLayout : GeometryLayout.XY;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFeatureFromText(text, opt_options) {\n    const geometry = this.readGeometryFromText(text, opt_options);\n    return new Feature(geometry);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFeaturesFromText(text, opt_options) {\n    const feature = this.readFeatureFromText(text, opt_options);\n    return [feature];\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readGeometryFromText(text, opt_options) {\n    const stride = getStrideForLayout(this.geometryLayout_);\n    const flatCoordinates = decodeDeltas(text, stride, this.factor_);\n    flipXY(flatCoordinates, 0, flatCoordinates.length, stride, flatCoordinates);\n    const coordinates = inflateCoordinates(flatCoordinates, 0, flatCoordinates.length, stride);\n\n    return (\n      /** @type {module:ol/geom/Geometry} */ (transformWithOptions(\n        new LineString(coordinates, this.geometryLayout_),\n        false,\n        this.adaptOptions(opt_options)\n      ))\n    );\n  }\n\n  /**\n   * @inheritDoc\n   */\n  writeFeatureText(feature, opt_options) {\n    const geometry = feature.getGeometry();\n    if (geometry) {\n      return this.writeGeometryText(geometry, opt_options);\n    } else {\n      assert(false, 40); // Expected `feature` to have a geometry\n      return '';\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  writeFeaturesText(features, opt_options) {\n    return this.writeFeatureText(features[0], opt_options);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  writeGeometryText(geometry, opt_options) {\n    geometry = /** @type {module:ol/geom/LineString} */\n      (transformWithOptions(geometry, true, this.adaptOptions(opt_options)));\n    const flatCoordinates = geometry.getFlatCoordinates();\n    const stride = geometry.getStride();\n    flipXY(flatCoordinates, 0, flatCoordinates.length, stride, flatCoordinates);\n    return encodeDeltas(flatCoordinates, stride, this.factor_);\n  }\n}\n\n\n/**\n * Encode a list of n-dimensional points and return an encoded string\n *\n * Attention: This function will modify the passed array!\n *\n * @param {Array.<number>} numbers A list of n-dimensional points.\n * @param {number} stride The number of dimension of the points in the list.\n * @param {number=} opt_factor The factor by which the numbers will be\n *     multiplied. The remaining decimal places will get rounded away.\n *     Default is `1e5`.\n * @return {string} The encoded string.\n * @api\n */\nexport function encodeDeltas(numbers, stride, opt_factor) {\n  const factor = opt_factor ? opt_factor : 1e5;\n  let d;\n\n  const lastNumbers = new Array(stride);\n  for (d = 0; d < stride; ++d) {\n    lastNumbers[d] = 0;\n  }\n\n  for (let i = 0, ii = numbers.length; i < ii;) {\n    for (d = 0; d < stride; ++d, ++i) {\n      const num = numbers[i];\n      const delta = num - lastNumbers[d];\n      lastNumbers[d] = num;\n\n      numbers[i] = delta;\n    }\n  }\n\n  return encodeFloats(numbers, factor);\n}\n\n\n/**\n * Decode a list of n-dimensional points from an encoded string\n *\n * @param {string} encoded An encoded string.\n * @param {number} stride The number of dimension of the points in the\n *     encoded string.\n * @param {number=} opt_factor The factor by which the resulting numbers will\n *     be divided. Default is `1e5`.\n * @return {Array.<number>} A list of n-dimensional points.\n * @api\n */\nexport function decodeDeltas(encoded, stride, opt_factor) {\n  const factor = opt_factor ? opt_factor : 1e5;\n  let d;\n\n  /** @type {Array.<number>} */\n  const lastNumbers = new Array(stride);\n  for (d = 0; d < stride; ++d) {\n    lastNumbers[d] = 0;\n  }\n\n  const numbers = decodeFloats(encoded, factor);\n\n  for (let i = 0, ii = numbers.length; i < ii;) {\n    for (d = 0; d < stride; ++d, ++i) {\n      lastNumbers[d] += numbers[i];\n\n      numbers[i] = lastNumbers[d];\n    }\n  }\n\n  return numbers;\n}\n\n\n/**\n * Encode a list of floating point numbers and return an encoded string\n *\n * Attention: This function will modify the passed array!\n *\n * @param {Array.<number>} numbers A list of floating point numbers.\n * @param {number=} opt_factor The factor by which the numbers will be\n *     multiplied. The remaining decimal places will get rounded away.\n *     Default is `1e5`.\n * @return {string} The encoded string.\n * @api\n */\nexport function encodeFloats(numbers, opt_factor) {\n  const factor = opt_factor ? opt_factor : 1e5;\n  for (let i = 0, ii = numbers.length; i < ii; ++i) {\n    numbers[i] = Math.round(numbers[i] * factor);\n  }\n\n  return encodeSignedIntegers(numbers);\n}\n\n\n/**\n * Decode a list of floating point numbers from an encoded string\n *\n * @param {string} encoded An encoded string.\n * @param {number=} opt_factor The factor by which the result will be divided.\n *     Default is `1e5`.\n * @return {Array.<number>} A list of floating point numbers.\n * @api\n */\nexport function decodeFloats(encoded, opt_factor) {\n  const factor = opt_factor ? opt_factor : 1e5;\n  const numbers = decodeSignedIntegers(encoded);\n  for (let i = 0, ii = numbers.length; i < ii; ++i) {\n    numbers[i] /= factor;\n  }\n  return numbers;\n}\n\n\n/**\n * Encode a list of signed integers and return an encoded string\n *\n * Attention: This function will modify the passed array!\n *\n * @param {Array.<number>} numbers A list of signed integers.\n * @return {string} The encoded string.\n */\nexport function encodeSignedIntegers(numbers) {\n  for (let i = 0, ii = numbers.length; i < ii; ++i) {\n    const num = numbers[i];\n    numbers[i] = (num < 0) ? ~(num << 1) : (num << 1);\n  }\n  return encodeUnsignedIntegers(numbers);\n}\n\n\n/**\n * Decode a list of signed integers from an encoded string\n *\n * @param {string} encoded An encoded string.\n * @return {Array.<number>} A list of signed integers.\n */\nexport function decodeSignedIntegers(encoded) {\n  const numbers = decodeUnsignedIntegers(encoded);\n  for (let i = 0, ii = numbers.length; i < ii; ++i) {\n    const num = numbers[i];\n    numbers[i] = (num & 1) ? ~(num >> 1) : (num >> 1);\n  }\n  return numbers;\n}\n\n\n/**\n * Encode a list of unsigned integers and return an encoded string\n *\n * @param {Array.<number>} numbers A list of unsigned integers.\n * @return {string} The encoded string.\n */\nexport function encodeUnsignedIntegers(numbers) {\n  let encoded = '';\n  for (let i = 0, ii = numbers.length; i < ii; ++i) {\n    encoded += encodeUnsignedInteger(numbers[i]);\n  }\n  return encoded;\n}\n\n\n/**\n * Decode a list of unsigned integers from an encoded string\n *\n * @param {string} encoded An encoded string.\n * @return {Array.<number>} A list of unsigned integers.\n */\nexport function decodeUnsignedIntegers(encoded) {\n  const numbers = [];\n  let current = 0;\n  let shift = 0;\n  for (let i = 0, ii = encoded.length; i < ii; ++i) {\n    const b = encoded.charCodeAt(i) - 63;\n    current |= (b & 0x1f) << shift;\n    if (b < 0x20) {\n      numbers.push(current);\n      current = 0;\n      shift = 0;\n    } else {\n      shift += 5;\n    }\n  }\n  return numbers;\n}\n\n\n/**\n * Encode one single unsigned integer and return an encoded string\n *\n * @param {number} num Unsigned integer that should be encoded.\n * @return {string} The encoded string.\n */\nexport function encodeUnsignedInteger(num) {\n  let value, encoded = '';\n  while (num >= 0x20) {\n    value = (0x20 | (num & 0x1f)) + 63;\n    encoded += String.fromCharCode(value);\n    num >>= 5;\n  }\n  value = num + 63;\n  encoded += String.fromCharCode(value);\n  return encoded;\n}\n\n\nexport default Polyline;\n","/**\n * @module ol/format/TopoJSON\n */\nimport Feature from '../Feature.js';\nimport {transformWithOptions} from '../format/Feature.js';\nimport JSONFeature from '../format/JSONFeature.js';\nimport LineString from '../geom/LineString.js';\nimport MultiLineString from '../geom/MultiLineString.js';\nimport MultiPoint from '../geom/MultiPoint.js';\nimport MultiPolygon from '../geom/MultiPolygon.js';\nimport Point from '../geom/Point.js';\nimport Polygon from '../geom/Polygon.js';\nimport {get as getProjection} from '../proj.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/proj~ProjectionLike} [dataProjection='EPSG:4326'] Default data projection.\n * @property {string} [layerName] Set the name of the TopoJSON topology\n * `objects`'s children as feature property with the specified name. This means\n * that when set to `'layer'`, a topology like\n * ```\n * {\n *   \"type\": \"Topology\",\n *   \"objects\": {\n *     \"example\": {\n *       \"type\": \"GeometryCollection\",\n *       \"geometries\": []\n *     }\n *   }\n * }\n * ```\n * will result in features that have a property `'layer'` set to `'example'`.\n * When not set, no property will be added to features.\n * @property {Array.<string>} [layers] Names of the TopoJSON topology's\n * `objects`'s children to read features from.  If not provided, features will\n * be read from all children.\n */\n\n\n/**\n * @classdesc\n * Feature format for reading data in the TopoJSON format.\n *\n * @api\n */\nclass TopoJSON extends JSONFeature {\n\n  /**\n   * @param {module:ol/format/TopoJSON~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n    super();\n\n    const options = opt_options ? opt_options : {};\n\n    /**\n     * @private\n     * @type {string|undefined}\n     */\n    this.layerName_ = options.layerName;\n\n    /**\n     * @private\n     * @type {Array.<string>}\n     */\n    this.layers_ = options.layers ? options.layers : null;\n\n    /**\n     * @inheritDoc\n     */\n    this.dataProjection = getProjection(\n      options.dataProjection ?\n        options.dataProjection : 'EPSG:4326');\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFeaturesFromObject(object, opt_options) {\n    if (object.type == 'Topology') {\n      const topoJSONTopology = /** @type {TopoJSONTopology} */ (object);\n      let transform, scale = null, translate = null;\n      if (topoJSONTopology.transform) {\n        transform = topoJSONTopology.transform;\n        scale = transform.scale;\n        translate = transform.translate;\n      }\n      const arcs = topoJSONTopology.arcs;\n      if (transform) {\n        transformArcs(arcs, scale, translate);\n      }\n      /** @type {Array.<module:ol/Feature>} */\n      const features = [];\n      const topoJSONFeatures = topoJSONTopology.objects;\n      const property = this.layerName_;\n      let feature;\n      for (const objectName in topoJSONFeatures) {\n        if (this.layers_ && this.layers_.indexOf(objectName) == -1) {\n          continue;\n        }\n        if (topoJSONFeatures[objectName].type === 'GeometryCollection') {\n          feature = /** @type {TopoJSONGeometryCollection} */ (topoJSONFeatures[objectName]);\n          features.push.apply(features, readFeaturesFromGeometryCollection(\n            feature, arcs, scale, translate, property, objectName, opt_options));\n        } else {\n          feature = /** @type {TopoJSONGeometry} */ (topoJSONFeatures[objectName]);\n          features.push(readFeatureFromGeometry(\n            feature, arcs, scale, translate, property, objectName, opt_options));\n        }\n      }\n      return features;\n    } else {\n      return [];\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readProjectionFromObject(object) {\n    return this.dataProjection;\n  }\n\n  /**\n   * Not implemented.\n   * @inheritDoc\n   */\n  writeFeatureObject(feature, opt_options) {}\n\n  /**\n   * Not implemented.\n   * @inheritDoc\n   */\n  writeFeaturesObject(features, opt_options) {}\n\n  /**\n   * Not implemented.\n   * @inheritDoc\n   */\n  writeGeometryObject(geometry, opt_options) {}\n\n  /**\n   * Not implemented.\n   * @override\n   */\n  readGeometryFromObject() {}\n\n  /**\n   * Not implemented.\n   * @override\n   */\n  readFeatureFromObject() {}\n}\n\n\n/**\n * @const\n * @type {Object.<string, function(TopoJSONGeometry, Array, ...Array): module:ol/geom/Geometry>}\n */\nconst GEOMETRY_READERS = {\n  'Point': readPointGeometry,\n  'LineString': readLineStringGeometry,\n  'Polygon': readPolygonGeometry,\n  'MultiPoint': readMultiPointGeometry,\n  'MultiLineString': readMultiLineStringGeometry,\n  'MultiPolygon': readMultiPolygonGeometry\n};\n\n\n/**\n * Concatenate arcs into a coordinate array.\n * @param {Array.<number>} indices Indices of arcs to concatenate.  Negative\n *     values indicate arcs need to be reversed.\n * @param {Array.<Array.<module:ol/coordinate~Coordinate>>} arcs Array of arcs (already\n *     transformed).\n * @return {Array.<module:ol/coordinate~Coordinate>} Coordinates array.\n */\nfunction concatenateArcs(indices, arcs) {\n  /** @type {Array.<module:ol/coordinate~Coordinate>} */\n  const coordinates = [];\n  let index, arc;\n  for (let i = 0, ii = indices.length; i < ii; ++i) {\n    index = indices[i];\n    if (i > 0) {\n      // splicing together arcs, discard last point\n      coordinates.pop();\n    }\n    if (index >= 0) {\n      // forward arc\n      arc = arcs[index];\n    } else {\n      // reverse arc\n      arc = arcs[~index].slice().reverse();\n    }\n    coordinates.push.apply(coordinates, arc);\n  }\n  // provide fresh copies of coordinate arrays\n  for (let j = 0, jj = coordinates.length; j < jj; ++j) {\n    coordinates[j] = coordinates[j].slice();\n  }\n  return coordinates;\n}\n\n\n/**\n * Create a point from a TopoJSON geometry object.\n *\n * @param {TopoJSONGeometry} object TopoJSON object.\n * @param {Array.<number>} scale Scale for each dimension.\n * @param {Array.<number>} translate Translation for each dimension.\n * @return {module:ol/geom/Point} Geometry.\n */\nfunction readPointGeometry(object, scale, translate) {\n  const coordinates = object.coordinates;\n  if (scale && translate) {\n    transformVertex(coordinates, scale, translate);\n  }\n  return new Point(coordinates);\n}\n\n\n/**\n * Create a multi-point from a TopoJSON geometry object.\n *\n * @param {TopoJSONGeometry} object TopoJSON object.\n * @param {Array.<number>} scale Scale for each dimension.\n * @param {Array.<number>} translate Translation for each dimension.\n * @return {module:ol/geom/MultiPoint} Geometry.\n */\nfunction readMultiPointGeometry(object, scale, translate) {\n  const coordinates = object.coordinates;\n  if (scale && translate) {\n    for (let i = 0, ii = coordinates.length; i < ii; ++i) {\n      transformVertex(coordinates[i], scale, translate);\n    }\n  }\n  return new MultiPoint(coordinates);\n}\n\n\n/**\n * Create a linestring from a TopoJSON geometry object.\n *\n * @param {TopoJSONGeometry} object TopoJSON object.\n * @param {Array.<Array.<module:ol/coordinate~Coordinate>>} arcs Array of arcs.\n * @return {module:ol/geom/LineString} Geometry.\n */\nfunction readLineStringGeometry(object, arcs) {\n  const coordinates = concatenateArcs(object.arcs, arcs);\n  return new LineString(coordinates);\n}\n\n\n/**\n * Create a multi-linestring from a TopoJSON geometry object.\n *\n * @param {TopoJSONGeometry} object TopoJSON object.\n * @param {Array.<Array.<module:ol/coordinate~Coordinate>>} arcs Array of arcs.\n * @return {module:ol/geom/MultiLineString} Geometry.\n */\nfunction readMultiLineStringGeometry(object, arcs) {\n  const coordinates = [];\n  for (let i = 0, ii = object.arcs.length; i < ii; ++i) {\n    coordinates[i] = concatenateArcs(object.arcs[i], arcs);\n  }\n  return new MultiLineString(coordinates);\n}\n\n\n/**\n * Create a polygon from a TopoJSON geometry object.\n *\n * @param {TopoJSONGeometry} object TopoJSON object.\n * @param {Array.<Array.<module:ol/coordinate~Coordinate>>} arcs Array of arcs.\n * @return {module:ol/geom/Polygon} Geometry.\n */\nfunction readPolygonGeometry(object, arcs) {\n  const coordinates = [];\n  for (let i = 0, ii = object.arcs.length; i < ii; ++i) {\n    coordinates[i] = concatenateArcs(object.arcs[i], arcs);\n  }\n  return new Polygon(coordinates);\n}\n\n\n/**\n * Create a multi-polygon from a TopoJSON geometry object.\n *\n * @param {TopoJSONGeometry} object TopoJSON object.\n * @param {Array.<Array.<module:ol/coordinate~Coordinate>>} arcs Array of arcs.\n * @return {module:ol/geom/MultiPolygon} Geometry.\n */\nfunction readMultiPolygonGeometry(object, arcs) {\n  const coordinates = [];\n  for (let i = 0, ii = object.arcs.length; i < ii; ++i) {\n    // for each polygon\n    const polyArray = object.arcs[i];\n    const ringCoords = [];\n    for (let j = 0, jj = polyArray.length; j < jj; ++j) {\n      // for each ring\n      ringCoords[j] = concatenateArcs(polyArray[j], arcs);\n    }\n    coordinates[i] = ringCoords;\n  }\n  return new MultiPolygon(coordinates);\n}\n\n\n/**\n * Create features from a TopoJSON GeometryCollection object.\n *\n * @param {TopoJSONGeometryCollection} collection TopoJSON Geometry\n *     object.\n * @param {Array.<Array.<module:ol/coordinate~Coordinate>>} arcs Array of arcs.\n * @param {Array.<number>} scale Scale for each dimension.\n * @param {Array.<number>} translate Translation for each dimension.\n * @param {string|undefined} property Property to set the `GeometryCollection`'s parent\n *     object to.\n * @param {string} name Name of the `Topology`'s child object.\n * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n * @return {Array.<module:ol/Feature>} Array of features.\n */\nfunction readFeaturesFromGeometryCollection(collection, arcs, scale, translate, property, name, opt_options) {\n  const geometries = collection.geometries;\n  const features = [];\n  for (let i = 0, ii = geometries.length; i < ii; ++i) {\n    features[i] = readFeatureFromGeometry(\n      geometries[i], arcs, scale, translate, property, name, opt_options);\n  }\n  return features;\n}\n\n\n/**\n * Create a feature from a TopoJSON geometry object.\n *\n * @param {TopoJSONGeometry} object TopoJSON geometry object.\n * @param {Array.<Array.<module:ol/coordinate~Coordinate>>} arcs Array of arcs.\n * @param {Array.<number>} scale Scale for each dimension.\n * @param {Array.<number>} translate Translation for each dimension.\n * @param {string|undefined} property Property to set the `GeometryCollection`'s parent\n *     object to.\n * @param {string} name Name of the `Topology`'s child object.\n * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.\n * @return {module:ol/Feature} Feature.\n */\nfunction readFeatureFromGeometry(object, arcs, scale, translate, property, name, opt_options) {\n  let geometry;\n  const type = object.type;\n  const geometryReader = GEOMETRY_READERS[type];\n  if ((type === 'Point') || (type === 'MultiPoint')) {\n    geometry = geometryReader(object, scale, translate);\n  } else {\n    geometry = geometryReader(object, arcs);\n  }\n  const feature = new Feature();\n  feature.setGeometry(/** @type {module:ol/geom/Geometry} */ (\n    transformWithOptions(geometry, false, opt_options)));\n  if (object.id !== undefined) {\n    feature.setId(object.id);\n  }\n  let properties = object.properties;\n  if (property) {\n    if (!properties) {\n      properties = {};\n    }\n    properties[property] = name;\n  }\n  if (properties) {\n    feature.setProperties(properties);\n  }\n  return feature;\n}\n\n\n/**\n * Apply a linear transform to array of arcs.  The provided array of arcs is\n * modified in place.\n *\n * @param {Array.<Array.<module:ol/coordinate~Coordinate>>} arcs Array of arcs.\n * @param {Array.<number>} scale Scale for each dimension.\n * @param {Array.<number>} translate Translation for each dimension.\n */\nfunction transformArcs(arcs, scale, translate) {\n  for (let i = 0, ii = arcs.length; i < ii; ++i) {\n    transformArc(arcs[i], scale, translate);\n  }\n}\n\n\n/**\n * Apply a linear transform to an arc.  The provided arc is modified in place.\n *\n * @param {Array.<module:ol/coordinate~Coordinate>} arc Arc.\n * @param {Array.<number>} scale Scale for each dimension.\n * @param {Array.<number>} translate Translation for each dimension.\n */\nfunction transformArc(arc, scale, translate) {\n  let x = 0;\n  let y = 0;\n  for (let i = 0, ii = arc.length; i < ii; ++i) {\n    const vertex = arc[i];\n    x += vertex[0];\n    y += vertex[1];\n    vertex[0] = x;\n    vertex[1] = y;\n    transformVertex(vertex, scale, translate);\n  }\n}\n\n\n/**\n * Apply a linear transform to a vertex.  The provided vertex is modified in\n * place.\n *\n * @param {module:ol/coordinate~Coordinate} vertex Vertex.\n * @param {Array.<number>} scale Scale for each dimension.\n * @param {Array.<number>} translate Translation for each dimension.\n */\nfunction transformVertex(vertex, scale, translate) {\n  vertex[0] = vertex[0] * scale[0] + translate[0];\n  vertex[1] = vertex[1] * scale[1] + translate[1];\n}\n\n\nexport default TopoJSON;\n","/**\n * @module ol/format/filter/Filter\n */\n\n\n/**\n * @classdesc\n * Abstract class; normally only used for creating subclasses and not instantiated in apps.\n * Base class for WFS GetFeature filters.\n *\n * @abstract\n */\nclass Filter {\n  /**\n   * @param {!string} tagName The XML tag name for this filter.\n   */\n  constructor(tagName) {\n\n    /**\n     * @private\n     * @type {!string}\n     */\n    this.tagName_ = tagName;\n  }\n\n  /**\n   * The XML tag name for a filter.\n   * @returns {!string} Name.\n   */\n  getTagName() {\n    return this.tagName_;\n  }\n}\n\nexport default Filter;\n","/**\n * @module ol/format/filter/LogicalNary\n */\nimport {assert} from '../../asserts.js';\nimport Filter from '../filter/Filter.js';\n\n/**\n * @classdesc\n * Abstract class; normally only used for creating subclasses and not instantiated in apps.\n * Base class for WFS GetFeature n-ary logical filters.\n *\n * @abstract\n */\nclass LogicalNary extends Filter {\n\n  /**\n   * @param {!string} tagName The XML tag name for this filter.\n   * @param {...module:ol/format/filter/Filter} conditions Conditions.\n   */\n  constructor(tagName, conditions) {\n\n    super(tagName);\n\n    /**\n     * @type {Array.<module:ol/format/filter/Filter>}\n     */\n    this.conditions = Array.prototype.slice.call(arguments, 1);\n    assert(this.conditions.length >= 2, 57); // At least 2 conditions are required.\n  }\n\n}\n\nexport default LogicalNary;\n","/**\n * @module ol/format/filter/And\n */\nimport LogicalNary from '../filter/LogicalNary.js';\n\n/**\n * @classdesc\n * Represents a logical `<And>` operator between two or more filter conditions.\n *\n * @abstract\n */\nclass And extends LogicalNary {\n\n  /**\n   * @param {...module:ol/format/filter/Filter} conditions Conditions.\n   */\n  constructor(conditions) {\n    const params = ['And'].concat(Array.prototype.slice.call(arguments));\n    super(...params);\n  }\n\n}\n\nexport default And;\n","/**\n * @module ol/format/filter/Bbox\n */\nimport Filter from '../filter/Filter.js';\n\n/**\n * @classdesc\n * Represents a `<BBOX>` operator to test whether a geometry-valued property\n * intersects a fixed bounding box\n *\n * @api\n */\nclass Bbox extends Filter {\n\n  /**\n   * @param {!string} geometryName Geometry name to use.\n   * @param {!module:ol/extent~Extent} extent Extent.\n   * @param {string=} opt_srsName SRS name. No srsName attribute will be set\n   * on geometries when this is not provided.\n   */\n  constructor(geometryName, extent, opt_srsName) {\n\n    super('BBOX');\n\n    /**\n     * @type {!string}\n     */\n    this.geometryName = geometryName;\n\n    /**\n     * @type {module:ol/extent~Extent}\n     */\n    this.extent = extent;\n\n    /**\n     * @type {string|undefined}\n     */\n    this.srsName = opt_srsName;\n  }\n\n}\n\nexport default Bbox;\n","/**\n * @module ol/format/filter/Spatial\n */\nimport Filter from '../filter/Filter.js';\n\n/**\n * @classdesc\n * Abstract class; normally only used for creating subclasses and not instantiated in apps.\n * Represents a spatial operator to test whether a geometry-valued property\n * relates to a given geometry.\n *\n * @abstract\n */\nclass Spatial extends Filter {\n\n  /**\n   * @param {!string} tagName The XML tag name for this filter.\n   * @param {!string} geometryName Geometry name to use.\n   * @param {!module:ol/geom/Geometry} geometry Geometry.\n   * @param {string=} opt_srsName SRS name. No srsName attribute will be\n   *    set on geometries when this is not provided.\n   */\n  constructor(tagName, geometryName, geometry, opt_srsName) {\n\n    super(tagName);\n\n    /**\n     * @type {!string}\n     */\n    this.geometryName = geometryName || 'the_geom';\n\n    /**\n     * @type {module:ol/geom/Geometry}\n     */\n    this.geometry = geometry;\n\n    /**\n     * @type {string|undefined}\n     */\n    this.srsName = opt_srsName;\n  }\n\n}\n\nexport default Spatial;\n","/**\n * @module ol/format/filter/Contains\n */\nimport Spatial from '../filter/Spatial.js';\n\n/**\n * @classdesc\n * Represents a `<Contains>` operator to test whether a geometry-valued property\n * contains a given geometry.\n * @api\n */\nclass Contains extends Spatial {\n\n  /**\n   * @param {!string} geometryName Geometry name to use.\n   * @param {!module:ol/geom/Geometry} geometry Geometry.\n   * @param {string=} opt_srsName SRS name. No srsName attribute will be\n   *    set on geometries when this is not provided.\n   */\n  constructor(geometryName, geometry, opt_srsName) {\n\n    super('Contains', geometryName, geometry, opt_srsName);\n\n  }\n\n}\n\nexport default Contains;\n","/**\n * @module ol/format/filter/Comparison\n */\nimport Filter from '../filter/Filter.js';\n\n/**\n * @classdesc\n * Abstract class; normally only used for creating subclasses and not instantiated in apps.\n * Base class for WFS GetFeature property comparison filters.\n *\n * @abstract\n */\nclass Comparison extends Filter {\n\n  /**\n   * @param {!string} tagName The XML tag name for this filter.\n   * @param {!string} propertyName Name of the context property to compare.\n   */\n  constructor(tagName, propertyName) {\n\n    super(tagName);\n\n    /**\n     * @type {!string}\n     */\n    this.propertyName = propertyName;\n  }\n\n}\n\nexport default Comparison;\n","/**\n * @module ol/format/filter/During\n */\nimport Comparison from '../filter/Comparison.js';\n\n/**\n * @classdesc\n * Represents a `<During>` comparison operator.\n * @api\n */\nclass During extends Comparison {\n\n  /**\n   * @param {!string} propertyName Name of the context property to compare.\n   * @param {!string} begin The begin date in ISO-8601 format.\n   * @param {!string} end The end date in ISO-8601 format.\n   */\n  constructor(propertyName, begin, end) {\n    super('During', propertyName);\n\n    /**\n     * @type {!string}\n     */\n    this.begin = begin;\n\n    /**\n     * @type {!string}\n     */\n    this.end = end;\n  }\n\n}\n\nexport default During;\n","/**\n * @module ol/format/filter/ComparisonBinary\n */\nimport Comparison from '../filter/Comparison.js';\n\n/**\n * @classdesc\n * Abstract class; normally only used for creating subclasses and not instantiated in apps.\n * Base class for WFS GetFeature property binary comparison filters.\n *\n * @abstract\n */\nclass ComparisonBinary extends Comparison {\n\n  /**\n   * @param {!string} tagName The XML tag name for this filter.\n   * @param {!string} propertyName Name of the context property to compare.\n   * @param {!(string|number)} expression The value to compare.\n   * @param {boolean=} opt_matchCase Case-sensitive?\n   */\n  constructor(tagName, propertyName, expression, opt_matchCase) {\n\n    super(tagName, propertyName);\n\n    /**\n     * @type {!(string|number)}\n     */\n    this.expression = expression;\n\n    /**\n     * @type {boolean|undefined}\n     */\n    this.matchCase = opt_matchCase;\n  }\n\n}\n\nexport default ComparisonBinary;\n","/**\n * @module ol/format/filter/EqualTo\n */\nimport ComparisonBinary from '../filter/ComparisonBinary.js';\n\n/**\n * @classdesc\n * Represents a `<PropertyIsEqualTo>` comparison operator.\n * @api\n */\nclass EqualTo extends ComparisonBinary {\n\n  /**\n   * @param {!string} propertyName Name of the context property to compare.\n   * @param {!(string|number)} expression The value to compare.\n   * @param {boolean=} opt_matchCase Case-sensitive?\n   */\n  constructor(propertyName, expression, opt_matchCase) {\n    super('PropertyIsEqualTo', propertyName, expression, opt_matchCase);\n  }\n\n}\n\nexport default EqualTo;\n","/**\n * @module ol/format/filter/GreaterThan\n */\nimport ComparisonBinary from '../filter/ComparisonBinary.js';\n\n/**\n * @classdesc\n * Represents a `<PropertyIsGreaterThan>` comparison operator.\n * @api\n */\nclass GreaterThan extends ComparisonBinary {\n\n  /**\n   * @param {!string} propertyName Name of the context property to compare.\n   * @param {!number} expression The value to compare.\n   */\n  constructor(propertyName, expression) {\n    super('PropertyIsGreaterThan', propertyName, expression);\n  }\n\n}\n\nexport default GreaterThan;\n","/**\n * @module ol/format/filter/GreaterThanOrEqualTo\n */\nimport ComparisonBinary from '../filter/ComparisonBinary.js';\n\n/**\n * @classdesc\n * Represents a `<PropertyIsGreaterThanOrEqualTo>` comparison operator.\n * @api\n */\nclass GreaterThanOrEqualTo extends ComparisonBinary {\n\n  /**\n   * @param {!string} propertyName Name of the context property to compare.\n   * @param {!number} expression The value to compare.\n   */\n  constructor(propertyName, expression) {\n    super('PropertyIsGreaterThanOrEqualTo', propertyName, expression);\n  }\n\n}\n\nexport default GreaterThanOrEqualTo;\n","/**\n * @module ol/format/filter/Intersects\n */\nimport Spatial from '../filter/Spatial.js';\n\n/**\n * @classdesc\n * Represents a `<Intersects>` operator to test whether a geometry-valued property\n * intersects a given geometry.\n * @api\n */\nclass Intersects extends Spatial {\n\n  /**\n   * @param {!string} geometryName Geometry name to use.\n   * @param {!module:ol/geom/Geometry} geometry Geometry.\n   * @param {string=} opt_srsName SRS name. No srsName attribute will be\n   *    set on geometries when this is not provided.\n   */\n  constructor(geometryName, geometry, opt_srsName) {\n    super('Intersects', geometryName, geometry, opt_srsName);\n  }\n\n}\n\nexport default Intersects;\n","/**\n * @module ol/format/filter/IsBetween\n */\nimport Comparison from '../filter/Comparison.js';\n\n/**\n * @classdesc\n * Represents a `<PropertyIsBetween>` comparison operator.\n * @api\n */\nclass IsBetween extends Comparison {\n\n  /**\n   * @param {!string} propertyName Name of the context property to compare.\n   * @param {!number} lowerBoundary The lower bound of the range.\n   * @param {!number} upperBoundary The upper bound of the range.\n   */\n  constructor(propertyName, lowerBoundary, upperBoundary) {\n    super('PropertyIsBetween', propertyName);\n\n    /**\n     * @type {!number}\n     */\n    this.lowerBoundary = lowerBoundary;\n\n    /**\n     * @type {!number}\n     */\n    this.upperBoundary = upperBoundary;\n\n  }\n}\n\nexport default IsBetween;\n","/**\n * @module ol/format/filter/IsLike\n */\nimport Comparison from '../filter/Comparison.js';\n\n/**\n * @classdesc\n * Represents a `<PropertyIsLike>` comparison operator.\n * @api\n */\nclass IsLike extends Comparison {\n\n  /**\n   * [constructor description]\n   * @param {!string} propertyName Name of the context property to compare.\n   * @param {!string} pattern Text pattern.\n   * @param {string=} opt_wildCard Pattern character which matches any sequence of\n   *    zero or more string characters. Default is '*'.\n   * @param {string=} opt_singleChar pattern character which matches any single\n   *    string character. Default is '.'.\n   * @param {string=} opt_escapeChar Escape character which can be used to escape\n   *    the pattern characters. Default is '!'.\n   * @param {boolean=} opt_matchCase Case-sensitive?\n   */\n  constructor(propertyName, pattern, opt_wildCard, opt_singleChar, opt_escapeChar, opt_matchCase) {\n    super('PropertyIsLike', propertyName);\n\n    /**\n     * @type {!string}\n     */\n    this.pattern = pattern;\n\n    /**\n     * @type {!string}\n     */\n    this.wildCard = (opt_wildCard !== undefined) ? opt_wildCard : '*';\n\n    /**\n     * @type {!string}\n     */\n    this.singleChar = (opt_singleChar !== undefined) ? opt_singleChar : '.';\n\n    /**\n     * @type {!string}\n     */\n    this.escapeChar = (opt_escapeChar !== undefined) ? opt_escapeChar : '!';\n\n    /**\n     * @type {boolean|undefined}\n     */\n    this.matchCase = opt_matchCase;\n\n  }\n}\n\nexport default IsLike;\n","/**\n * @module ol/format/filter/IsNull\n */\nimport Comparison from '../filter/Comparison.js';\n\n/**\n * @classdesc\n * Represents a `<PropertyIsNull>` comparison operator.\n * @api\n */\nclass IsNull extends Comparison {\n\n  /**\n   * @param {!string} propertyName Name of the context property to compare.\n   */\n  constructor(propertyName) {\n    super('PropertyIsNull', propertyName);\n  }\n\n}\n\nexport default IsNull;\n","/**\n * @module ol/format/filter/LessThan\n */\nimport ComparisonBinary from '../filter/ComparisonBinary.js';\n\n/**\n * @classdesc\n * Represents a `<PropertyIsLessThan>` comparison operator.\n * @api\n */\nclass LessThan extends ComparisonBinary {\n\n  /**\n   * @param {!string} propertyName Name of the context property to compare.\n   * @param {!number} expression The value to compare.\n   */\n  constructor(propertyName, expression) {\n    super('PropertyIsLessThan', propertyName, expression);\n  }\n\n}\n\nexport default LessThan;\n","/**\n * @module ol/format/filter/LessThanOrEqualTo\n */\nimport ComparisonBinary from '../filter/ComparisonBinary.js';\n\n/**\n * @classdesc\n * Represents a `<PropertyIsLessThanOrEqualTo>` comparison operator.\n * @api\n */\nclass LessThanOrEqualTo extends ComparisonBinary {\n\n  /**\n   * @param {!string} propertyName Name of the context property to compare.\n   * @param {!number} expression The value to compare.\n   */\n  constructor(propertyName, expression) {\n    super('PropertyIsLessThanOrEqualTo', propertyName, expression);\n  }\n\n}\n\nexport default LessThanOrEqualTo;\n","/**\n * @module ol/format/filter/Not\n */\nimport Filter from '../filter/Filter.js';\n\n/**\n * @classdesc\n * Represents a logical `<Not>` operator for a filter condition.\n * @api\n */\nclass Not extends Filter {\n\n  /**\n   * @param {!module:ol/format/filter/Filter} condition Filter condition.\n   */\n  constructor(condition) {\n\n    super('Not');\n\n    /**\n     * @type {!module:ol/format/filter/Filter}\n     */\n    this.condition = condition;\n\n  }\n\n}\n\nexport default Not;\n","/**\n * @module ol/format/filter/NotEqualTo\n */\nimport ComparisonBinary from '../filter/ComparisonBinary.js';\n\n/**\n * @classdesc\n * Represents a `<PropertyIsNotEqualTo>` comparison operator.\n * @api\n */\nclass NotEqualTo extends ComparisonBinary {\n\n  /**\n   * @param {!string} propertyName Name of the context property to compare.\n   * @param {!(string|number)} expression The value to compare.\n   * @param {boolean=} opt_matchCase Case-sensitive?\n   */\n  constructor(propertyName, expression, opt_matchCase) {\n    super('PropertyIsNotEqualTo', propertyName, expression, opt_matchCase);\n  }\n\n}\n\nexport default NotEqualTo;\n","/**\n * @module ol/format/filter/Or\n */\nimport LogicalNary from '../filter/LogicalNary.js';\n\n/**\n * @classdesc\n * Represents a logical `<Or>` operator between two ore more filter conditions.\n * @api\n */\nclass Or extends LogicalNary {\n\n  /**\n   * @param {...module:ol/format/filter/Filter} conditions Conditions.\n   */\n  constructor(conditions) {\n    const params = ['Or'].concat(Array.prototype.slice.call(arguments));\n    super(...params);\n  }\n\n}\n\nexport default Or;\n","/**\n * @module ol/format/filter/Within\n */\nimport Spatial from '../filter/Spatial.js';\n\n/**\n * @classdesc\n * Represents a `<Within>` operator to test whether a geometry-valued property\n * is within a given geometry.\n * @api\n */\nclass Within extends Spatial {\n\n  /**\n   * @param {!string} geometryName Geometry name to use.\n   * @param {!module:ol/geom/Geometry} geometry Geometry.\n   * @param {string=} opt_srsName SRS name. No srsName attribute will be\n   *    set on geometries when this is not provided.\n   */\n  constructor(geometryName, geometry, opt_srsName) {\n    super('Within', geometryName, geometry, opt_srsName);\n  }\n\n}\n\nexport default Within;\n","/**\n * @module ol/format/filter\n */\nimport And from '../format/filter/And.js';\nimport Bbox from '../format/filter/Bbox.js';\nimport Contains from '../format/filter/Contains.js';\nimport During from '../format/filter/During.js';\nimport EqualTo from '../format/filter/EqualTo.js';\nimport GreaterThan from '../format/filter/GreaterThan.js';\nimport GreaterThanOrEqualTo from '../format/filter/GreaterThanOrEqualTo.js';\nimport Intersects from '../format/filter/Intersects.js';\nimport IsBetween from '../format/filter/IsBetween.js';\nimport IsLike from '../format/filter/IsLike.js';\nimport IsNull from '../format/filter/IsNull.js';\nimport LessThan from '../format/filter/LessThan.js';\nimport LessThanOrEqualTo from '../format/filter/LessThanOrEqualTo.js';\nimport Not from '../format/filter/Not.js';\nimport NotEqualTo from '../format/filter/NotEqualTo.js';\nimport Or from '../format/filter/Or.js';\nimport Within from '../format/filter/Within.js';\n\n\n/**\n * Create a logical `<And>` operator between two or more filter conditions.\n *\n * @param {...module:ol/format/filter/Filter} conditions Filter conditions.\n * @returns {!module:ol/format/filter/And} `<And>` operator.\n * @api\n */\nexport function and(conditions) {\n  const params = [null].concat(Array.prototype.slice.call(arguments));\n  return new (Function.prototype.bind.apply(And, params));\n}\n\n\n/**\n * Create a logical `<Or>` operator between two or more filter conditions.\n *\n * @param {...module:ol/format/filter/Filter} conditions Filter conditions.\n * @returns {!module:ol/format/filter/Or} `<Or>` operator.\n * @api\n */\nexport function or(conditions) {\n  const params = [null].concat(Array.prototype.slice.call(arguments));\n  return new (Function.prototype.bind.apply(Or, params));\n}\n\n\n/**\n * Represents a logical `<Not>` operator for a filter condition.\n *\n * @param {!module:ol/format/filter/Filter} condition Filter condition.\n * @returns {!module:ol/format/filter/Not} `<Not>` operator.\n * @api\n */\nexport function not(condition) {\n  return new Not(condition);\n}\n\n\n/**\n * Create a `<BBOX>` operator to test whether a geometry-valued property\n * intersects a fixed bounding box\n *\n * @param {!string} geometryName Geometry name to use.\n * @param {!module:ol/extent~Extent} extent Extent.\n * @param {string=} opt_srsName SRS name. No srsName attribute will be\n *    set on geometries when this is not provided.\n * @returns {!module:ol/format/filter/Bbox} `<BBOX>` operator.\n * @api\n */\nexport function bbox(geometryName, extent, opt_srsName) {\n  return new Bbox(geometryName, extent, opt_srsName);\n}\n\n/**\n * Create a `<Contains>` operator to test whether a geometry-valued property\n * contains a given geometry.\n *\n * @param {!string} geometryName Geometry name to use.\n * @param {!module:ol/geom/Geometry} geometry Geometry.\n * @param {string=} opt_srsName SRS name. No srsName attribute will be\n *    set on geometries when this is not provided.\n * @returns {!module:ol/format/filter/Contains} `<Contains>` operator.\n * @api\n */\nexport function contains(geometryName, geometry, opt_srsName) {\n  return new Contains(geometryName, geometry, opt_srsName);\n}\n\n/**\n * Create a `<Intersects>` operator to test whether a geometry-valued property\n * intersects a given geometry.\n *\n * @param {!string} geometryName Geometry name to use.\n * @param {!module:ol/geom/Geometry} geometry Geometry.\n * @param {string=} opt_srsName SRS name. No srsName attribute will be\n *    set on geometries when this is not provided.\n * @returns {!module:ol/format/filter/Intersects} `<Intersects>` operator.\n * @api\n */\nexport function intersects(geometryName, geometry, opt_srsName) {\n  return new Intersects(geometryName, geometry, opt_srsName);\n}\n\n/**\n * Create a `<Within>` operator to test whether a geometry-valued property\n * is within a given geometry.\n *\n * @param {!string} geometryName Geometry name to use.\n * @param {!module:ol/geom/Geometry} geometry Geometry.\n * @param {string=} opt_srsName SRS name. No srsName attribute will be\n *    set on geometries when this is not provided.\n * @returns {!module:ol/format/filter/Within} `<Within>` operator.\n * @api\n */\nexport function within(geometryName, geometry, opt_srsName) {\n  return new Within(geometryName, geometry, opt_srsName);\n}\n\n\n/**\n * Creates a `<PropertyIsEqualTo>` comparison operator.\n *\n * @param {!string} propertyName Name of the context property to compare.\n * @param {!(string|number)} expression The value to compare.\n * @param {boolean=} opt_matchCase Case-sensitive?\n * @returns {!module:ol/format/filter/EqualTo} `<PropertyIsEqualTo>` operator.\n * @api\n */\nexport function equalTo(propertyName, expression, opt_matchCase) {\n  return new EqualTo(propertyName, expression, opt_matchCase);\n}\n\n\n/**\n * Creates a `<PropertyIsNotEqualTo>` comparison operator.\n *\n * @param {!string} propertyName Name of the context property to compare.\n * @param {!(string|number)} expression The value to compare.\n * @param {boolean=} opt_matchCase Case-sensitive?\n * @returns {!module:ol/format/filter/NotEqualTo} `<PropertyIsNotEqualTo>` operator.\n * @api\n */\nexport function notEqualTo(propertyName, expression, opt_matchCase) {\n  return new NotEqualTo(propertyName, expression, opt_matchCase);\n}\n\n\n/**\n * Creates a `<PropertyIsLessThan>` comparison operator.\n *\n * @param {!string} propertyName Name of the context property to compare.\n * @param {!number} expression The value to compare.\n * @returns {!module:ol/format/filter/LessThan} `<PropertyIsLessThan>` operator.\n * @api\n */\nexport function lessThan(propertyName, expression) {\n  return new LessThan(propertyName, expression);\n}\n\n\n/**\n * Creates a `<PropertyIsLessThanOrEqualTo>` comparison operator.\n *\n * @param {!string} propertyName Name of the context property to compare.\n * @param {!number} expression The value to compare.\n * @returns {!module:ol/format/filter/LessThanOrEqualTo} `<PropertyIsLessThanOrEqualTo>` operator.\n * @api\n */\nexport function lessThanOrEqualTo(propertyName, expression) {\n  return new LessThanOrEqualTo(propertyName, expression);\n}\n\n\n/**\n * Creates a `<PropertyIsGreaterThan>` comparison operator.\n *\n * @param {!string} propertyName Name of the context property to compare.\n * @param {!number} expression The value to compare.\n * @returns {!module:ol/format/filter/GreaterThan} `<PropertyIsGreaterThan>` operator.\n * @api\n */\nexport function greaterThan(propertyName, expression) {\n  return new GreaterThan(propertyName, expression);\n}\n\n\n/**\n * Creates a `<PropertyIsGreaterThanOrEqualTo>` comparison operator.\n *\n * @param {!string} propertyName Name of the context property to compare.\n * @param {!number} expression The value to compare.\n * @returns {!module:ol/format/filter/GreaterThanOrEqualTo} `<PropertyIsGreaterThanOrEqualTo>` operator.\n * @api\n */\nexport function greaterThanOrEqualTo(propertyName, expression) {\n  return new GreaterThanOrEqualTo(propertyName, expression);\n}\n\n\n/**\n * Creates a `<PropertyIsNull>` comparison operator to test whether a property value\n * is null.\n *\n * @param {!string} propertyName Name of the context property to compare.\n * @returns {!module:ol/format/filter/IsNull} `<PropertyIsNull>` operator.\n * @api\n */\nexport function isNull(propertyName) {\n  return new IsNull(propertyName);\n}\n\n\n/**\n * Creates a `<PropertyIsBetween>` comparison operator to test whether an expression\n * value lies within a range given by a lower and upper bound (inclusive).\n *\n * @param {!string} propertyName Name of the context property to compare.\n * @param {!number} lowerBoundary The lower bound of the range.\n * @param {!number} upperBoundary The upper bound of the range.\n * @returns {!module:ol/format/filter/IsBetween} `<PropertyIsBetween>` operator.\n * @api\n */\nexport function between(propertyName, lowerBoundary, upperBoundary) {\n  return new IsBetween(propertyName, lowerBoundary, upperBoundary);\n}\n\n\n/**\n * Represents a `<PropertyIsLike>` comparison operator that matches a string property\n * value against a text pattern.\n *\n * @param {!string} propertyName Name of the context property to compare.\n * @param {!string} pattern Text pattern.\n * @param {string=} opt_wildCard Pattern character which matches any sequence of\n *    zero or more string characters. Default is '*'.\n * @param {string=} opt_singleChar pattern character which matches any single\n *    string character. Default is '.'.\n * @param {string=} opt_escapeChar Escape character which can be used to escape\n *    the pattern characters. Default is '!'.\n * @param {boolean=} opt_matchCase Case-sensitive?\n * @returns {!module:ol/format/filter/IsLike} `<PropertyIsLike>` operator.\n * @api\n */\nexport function like(propertyName, pattern,\n  opt_wildCard, opt_singleChar, opt_escapeChar, opt_matchCase) {\n  return new IsLike(propertyName, pattern,\n    opt_wildCard, opt_singleChar, opt_escapeChar, opt_matchCase);\n}\n\n\n/**\n * Create a `<During>` temporal operator.\n *\n * @param {!string} propertyName Name of the context property to compare.\n * @param {!string} begin The begin date in ISO-8601 format.\n * @param {!string} end The end date in ISO-8601 format.\n * @returns {!module:ol/format/filter/During} `<During>` operator.\n * @api\n */\nexport function during(propertyName, begin, end) {\n  return new During(propertyName, begin, end);\n}\n","/**\n * @module ol/format/WFS\n */\nimport {assert} from '../asserts.js';\nimport GML2 from '../format/GML2.js';\nimport GML3 from '../format/GML3.js';\nimport GMLBase, {GMLNS} from '../format/GMLBase.js';\nimport {and as andFilter, bbox as bboxFilter} from '../format/filter.js';\nimport XMLFeature from '../format/XMLFeature.js';\nimport {readNonNegativeIntegerString, readNonNegativeInteger, writeStringTextNode} from '../format/xsd.js';\nimport Geometry from '../geom/Geometry.js';\nimport {assign} from '../obj.js';\nimport {get as getProjection} from '../proj.js';\nimport {createElementNS, isDocument, isNode, makeArrayPusher, makeChildAppender,\n  makeObjectPropertySetter, makeSimpleNodeFactory, parse, parseNode,\n  pushParseAndPop, pushSerializeAndPop, XML_SCHEMA_INSTANCE_URI} from '../xml.js';\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst FEATURE_COLLECTION_PARSERS = {\n  'http://www.opengis.net/gml': {\n    'boundedBy': makeObjectPropertySetter(\n      GMLBase.prototype.readGeometryElement, 'bounds')\n  }\n};\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst TRANSACTION_SUMMARY_PARSERS = {\n  'http://www.opengis.net/wfs': {\n    'totalInserted': makeObjectPropertySetter(readNonNegativeInteger),\n    'totalUpdated': makeObjectPropertySetter(readNonNegativeInteger),\n    'totalDeleted': makeObjectPropertySetter(readNonNegativeInteger)\n  }\n};\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst TRANSACTION_RESPONSE_PARSERS = {\n  'http://www.opengis.net/wfs': {\n    'TransactionSummary': makeObjectPropertySetter(\n      readTransactionSummary, 'transactionSummary'),\n    'InsertResults': makeObjectPropertySetter(\n      readInsertResults, 'insertIds')\n  }\n};\n\n\n/**\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst QUERY_SERIALIZERS = {\n  'http://www.opengis.net/wfs': {\n    'PropertyName': makeChildAppender(writeStringTextNode)\n  }\n};\n\n\n/**\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst TRANSACTION_SERIALIZERS = {\n  'http://www.opengis.net/wfs': {\n    'Insert': makeChildAppender(writeFeature),\n    'Update': makeChildAppender(writeUpdate),\n    'Delete': makeChildAppender(writeDelete),\n    'Property': makeChildAppender(writeProperty),\n    'Native': makeChildAppender(writeNative)\n  }\n};\n\n\n/**\n * @typedef {Object} Options\n * @property {Object.<string, string>|string} [featureNS] The namespace URI used for features.\n * @property {Array.<string>|string} [featureType] The feature type to parse. Only used for read operations.\n * @property {module:ol/format/GMLBase} [gmlFormat] The GML format to use to parse the response. Default is `ol/format/GML3`.\n * @property {string} [schemaLocation] Optional schemaLocation to use for serialization, this will override the default.\n */\n\n\n/**\n * @typedef {Object} WriteGetFeatureOptions\n * @property {string} featureNS The namespace URI used for features.\n * @property {string} featurePrefix The prefix for the feature namespace.\n * @property {Array.<string>} featureTypes The feature type names.\n * @property {string} [srsName] SRS name. No srsName attribute will be set on\n * geometries when this is not provided.\n * @property {string} [handle] Handle.\n * @property {string} [outputFormat] Output format.\n * @property {number} [maxFeatures] Maximum number of features to fetch.\n * @property {string} [geometryName] Geometry name to use in a BBOX filter.\n * @property {Array.<string>} [propertyNames] Optional list of property names to serialize.\n * @property {number} [startIndex] Start index to use for WFS paging. This is a\n * WFS 2.0 feature backported to WFS 1.1.0 by some Web Feature Services.\n * @property {number} [count] Number of features to retrieve when paging. This is a\n * WFS 2.0 feature backported to WFS 1.1.0 by some Web Feature Services. Please note that some\n * Web Feature Services have repurposed `maxfeatures` instead.\n * @property {module:ol/extent~Extent} [bbox] Extent to use for the BBOX filter.\n * @property {module:ol/format/filter/Filter} [filter] Filter condition. See\n * {@link module:ol/format/Filter} for more information.\n * @property {string} [resultType] Indicates what response should be returned,\n * E.g. `hits` only includes the `numberOfFeatures` attribute in the response and no features.\n */\n\n\n/**\n * @typedef {Object} WriteTransactionOptions\n * @property {string} featureNS The namespace URI used for features.\n * @property {string} featurePrefix The prefix for the feature namespace.\n * @property {string} featureType The feature type name.\n * @property {string} [srsName] SRS name. No srsName attribute will be set on\n * geometries when this is not provided.\n * @property {string} [handle] Handle.\n * @property {boolean} [hasZ] Must be set to true if the transaction is for\n * a 3D layer. This will allow the Z coordinate to be included in the transaction.\n * @property {Array.<Object>} nativeElements Native elements. Currently not supported.\n * @property {module:ol/format/GMLBase~Options} [gmlOptions] GML options for the WFS transaction writer.\n * @property {string} [version='1.1.0'] WFS version to use for the transaction. Can be either `1.0.0` or `1.1.0`.\n */\n\n\n/**\n * Number of features; bounds/extent.\n * @typedef {Object} FeatureCollectionMetadata\n * @property {number} numberOfFeatures\n * @property {module:ol/extent~Extent} bounds\n */\n\n\n/**\n * Total deleted; total inserted; total updated; array of insert ids.\n * @typedef {Object} TransactionResponse\n * @property {number} totalDeleted\n * @property {number} totalInserted\n * @property {number} totalUpdated\n * @property {Array.<string>} insertIds\n */\n\n\n/**\n * @type {string}\n */\nconst FEATURE_PREFIX = 'feature';\n\n\n/**\n * @type {string}\n */\nconst XMLNS = 'http://www.w3.org/2000/xmlns/';\n\n\n/**\n * @type {string}\n */\nconst OGCNS = 'http://www.opengis.net/ogc';\n\n\n/**\n * @type {string}\n */\nconst WFSNS = 'http://www.opengis.net/wfs';\n\n\n/**\n * @type {string}\n */\nconst FESNS = 'http://www.opengis.net/fes';\n\n\n/**\n * @type {Object.<string, string>}\n */\nconst SCHEMA_LOCATIONS = {\n  '1.1.0': 'http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd',\n  '1.0.0': 'http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd'\n};\n\n\n/**\n * @const\n * @type {string}\n */\nconst DEFAULT_VERSION = '1.1.0';\n\n\n/**\n * @classdesc\n * Feature format for reading and writing data in the WFS format.\n * By default, supports WFS version 1.1.0. You can pass a GML format\n * as option if you want to read a WFS that contains GML2 (WFS 1.0.0).\n * Also see {@link module:ol/format/GMLBase~GMLBase} which is used by this format.\n *\n * @api\n */\nclass WFS extends XMLFeature {\n\n  /**\n   * @param {module:ol/format/WFS~Options=} opt_options Optional configuration object.\n   */\n  constructor(opt_options) {\n    super();\n\n    const options = opt_options ? opt_options : {};\n\n    /**\n     * @private\n     * @type {Array.<string>|string|undefined}\n     */\n    this.featureType_ = options.featureType;\n\n    /**\n     * @private\n     * @type {Object.<string, string>|string|undefined}\n     */\n    this.featureNS_ = options.featureNS;\n\n    /**\n     * @private\n     * @type {module:ol/format/GMLBase}\n     */\n    this.gmlFormat_ = options.gmlFormat ?\n      options.gmlFormat : new GML3();\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.schemaLocation_ = options.schemaLocation ?\n      options.schemaLocation : SCHEMA_LOCATIONS[DEFAULT_VERSION];\n  }\n\n  /**\n   * @return {Array.<string>|string|undefined} featureType\n   */\n  getFeatureType() {\n    return this.featureType_;\n  }\n\n  /**\n   * @param {Array.<string>|string|undefined} featureType Feature type(s) to parse.\n   */\n  setFeatureType(featureType) {\n    this.featureType_ = featureType;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFeaturesFromNode(node, opt_options) {\n    const context = /** @type {module:ol/xml~NodeStackItem} */ ({\n      'featureType': this.featureType_,\n      'featureNS': this.featureNS_\n    });\n    assign(context, this.getReadOptions(node, opt_options ? opt_options : {}));\n    const objectStack = [context];\n    this.gmlFormat_.FEATURE_COLLECTION_PARSERS[GMLNS][\n      'featureMember'] =\n        makeArrayPusher(GMLBase.prototype.readFeaturesInternal);\n    let features = pushParseAndPop([],\n      this.gmlFormat_.FEATURE_COLLECTION_PARSERS, node,\n      objectStack, this.gmlFormat_);\n    if (!features) {\n      features = [];\n    }\n    return features;\n  }\n\n  /**\n   * Read transaction response of the source.\n   *\n   * @param {Document|Node|Object|string} source Source.\n   * @return {module:ol/format/WFS~TransactionResponse|undefined} Transaction response.\n   * @api\n   */\n  readTransactionResponse(source) {\n    if (isDocument(source)) {\n      return this.readTransactionResponseFromDocument(\n        /** @type {Document} */ (source));\n    } else if (isNode(source)) {\n      return this.readTransactionResponseFromNode(/** @type {Node} */ (source));\n    } else if (typeof source === 'string') {\n      const doc = parse(source);\n      return this.readTransactionResponseFromDocument(doc);\n    } else {\n      return undefined;\n    }\n  }\n\n  /**\n   * Read feature collection metadata of the source.\n   *\n   * @param {Document|Node|Object|string} source Source.\n   * @return {module:ol/format/WFS~FeatureCollectionMetadata|undefined}\n   *     FeatureCollection metadata.\n   * @api\n   */\n  readFeatureCollectionMetadata(source) {\n    if (isDocument(source)) {\n      return this.readFeatureCollectionMetadataFromDocument(\n        /** @type {Document} */ (source));\n    } else if (isNode(source)) {\n      return this.readFeatureCollectionMetadataFromNode(\n        /** @type {Node} */ (source));\n    } else if (typeof source === 'string') {\n      const doc = parse(source);\n      return this.readFeatureCollectionMetadataFromDocument(doc);\n    } else {\n      return undefined;\n    }\n  }\n\n  /**\n   * @param {Document} doc Document.\n   * @return {module:ol/format/WFS~FeatureCollectionMetadata|undefined}\n   *     FeatureCollection metadata.\n   */\n  readFeatureCollectionMetadataFromDocument(doc) {\n    for (let n = doc.firstChild; n; n = n.nextSibling) {\n      if (n.nodeType == Node.ELEMENT_NODE) {\n        return this.readFeatureCollectionMetadataFromNode(n);\n      }\n    }\n    return undefined;\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @return {module:ol/format/WFS~FeatureCollectionMetadata|undefined}\n   *     FeatureCollection metadata.\n   */\n  readFeatureCollectionMetadataFromNode(node) {\n    const result = {};\n    const value = readNonNegativeIntegerString(\n      node.getAttribute('numberOfFeatures'));\n    result['numberOfFeatures'] = value;\n    return pushParseAndPop(\n      /** @type {module:ol/format/WFS~FeatureCollectionMetadata} */ (result),\n      FEATURE_COLLECTION_PARSERS, node, [], this.gmlFormat_);\n  }\n\n  /**\n   * @param {Document} doc Document.\n   * @return {module:ol/format/WFS~TransactionResponse|undefined} Transaction response.\n   */\n  readTransactionResponseFromDocument(doc) {\n    for (let n = doc.firstChild; n; n = n.nextSibling) {\n      if (n.nodeType == Node.ELEMENT_NODE) {\n        return this.readTransactionResponseFromNode(n);\n      }\n    }\n    return undefined;\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @return {module:ol/format/WFS~TransactionResponse|undefined} Transaction response.\n   */\n  readTransactionResponseFromNode(node) {\n    return pushParseAndPop(\n      /** @type {module:ol/format/WFS~TransactionResponse} */({}),\n      TRANSACTION_RESPONSE_PARSERS, node, []);\n  }\n\n  /**\n   * Encode format as WFS `GetFeature` and return the Node.\n   *\n   * @param {module:ol/format/WFS~WriteGetFeatureOptions} options Options.\n   * @return {Node} Result.\n   * @api\n   */\n  writeGetFeature(options) {\n    const node = createElementNS(WFSNS, 'GetFeature');\n    node.setAttribute('service', 'WFS');\n    node.setAttribute('version', '1.1.0');\n    let filter;\n    if (options) {\n      if (options.handle) {\n        node.setAttribute('handle', options.handle);\n      }\n      if (options.outputFormat) {\n        node.setAttribute('outputFormat', options.outputFormat);\n      }\n      if (options.maxFeatures !== undefined) {\n        node.setAttribute('maxFeatures', options.maxFeatures);\n      }\n      if (options.resultType) {\n        node.setAttribute('resultType', options.resultType);\n      }\n      if (options.startIndex !== undefined) {\n        node.setAttribute('startIndex', options.startIndex);\n      }\n      if (options.count !== undefined) {\n        node.setAttribute('count', options.count);\n      }\n      filter = options.filter;\n      if (options.bbox) {\n        assert(options.geometryName,\n          12); // `options.geometryName` must also be provided when `options.bbox` is set\n        const bbox = bboxFilter(\n          /** @type {string} */ (options.geometryName), options.bbox, options.srsName);\n        if (filter) {\n          // if bbox and filter are both set, combine the two into a single filter\n          filter = andFilter(filter, bbox);\n        } else {\n          filter = bbox;\n        }\n      }\n    }\n    node.setAttributeNS(XML_SCHEMA_INSTANCE_URI, 'xsi:schemaLocation', this.schemaLocation_);\n    /** @type {module:ol/xml~NodeStackItem} */\n    const context = {\n      node: node,\n      'srsName': options.srsName,\n      'featureNS': options.featureNS ? options.featureNS : this.featureNS_,\n      'featurePrefix': options.featurePrefix,\n      'geometryName': options.geometryName,\n      'filter': filter,\n      'propertyNames': options.propertyNames ? options.propertyNames : []\n    };\n    assert(Array.isArray(options.featureTypes),\n      11); // `options.featureTypes` should be an Array\n    writeGetFeature(node, /** @type {!Array.<string>} */ (options.featureTypes), [context]);\n    return node;\n  }\n\n  /**\n   * Encode format as WFS `Transaction` and return the Node.\n   *\n   * @param {Array.<module:ol/Feature>} inserts The features to insert.\n   * @param {Array.<module:ol/Feature>} updates The features to update.\n   * @param {Array.<module:ol/Feature>} deletes The features to delete.\n   * @param {module:ol/format/WFS~WriteTransactionOptions} options Write options.\n   * @return {Node} Result.\n   * @api\n   */\n  writeTransaction(inserts, updates, deletes, options) {\n    const objectStack = [];\n    const node = createElementNS(WFSNS, 'Transaction');\n    const version = options.version ? options.version : DEFAULT_VERSION;\n    const gmlVersion = version === '1.0.0' ? 2 : 3;\n    node.setAttribute('service', 'WFS');\n    node.setAttribute('version', version);\n    let baseObj;\n    /** @type {module:ol/xml~NodeStackItem} */\n    let obj;\n    if (options) {\n      baseObj = options.gmlOptions ? options.gmlOptions : {};\n      if (options.handle) {\n        node.setAttribute('handle', options.handle);\n      }\n    }\n    const schemaLocation = SCHEMA_LOCATIONS[version];\n    node.setAttributeNS(XML_SCHEMA_INSTANCE_URI, 'xsi:schemaLocation', schemaLocation);\n    const featurePrefix = options.featurePrefix ? options.featurePrefix : FEATURE_PREFIX;\n    if (inserts) {\n      obj = {node: node, 'featureNS': options.featureNS,\n        'featureType': options.featureType, 'featurePrefix': featurePrefix,\n        'gmlVersion': gmlVersion, 'hasZ': options.hasZ, 'srsName': options.srsName};\n      assign(obj, baseObj);\n      pushSerializeAndPop(obj,\n        TRANSACTION_SERIALIZERS,\n        makeSimpleNodeFactory('Insert'), inserts,\n        objectStack);\n    }\n    if (updates) {\n      obj = {node: node, 'featureNS': options.featureNS,\n        'featureType': options.featureType, 'featurePrefix': featurePrefix,\n        'gmlVersion': gmlVersion, 'hasZ': options.hasZ, 'srsName': options.srsName};\n      assign(obj, baseObj);\n      pushSerializeAndPop(obj,\n        TRANSACTION_SERIALIZERS,\n        makeSimpleNodeFactory('Update'), updates,\n        objectStack);\n    }\n    if (deletes) {\n      pushSerializeAndPop({node: node, 'featureNS': options.featureNS,\n        'featureType': options.featureType, 'featurePrefix': featurePrefix,\n        'gmlVersion': gmlVersion, 'srsName': options.srsName},\n      TRANSACTION_SERIALIZERS,\n      makeSimpleNodeFactory('Delete'), deletes,\n      objectStack);\n    }\n    if (options.nativeElements) {\n      pushSerializeAndPop({node: node, 'featureNS': options.featureNS,\n        'featureType': options.featureType, 'featurePrefix': featurePrefix,\n        'gmlVersion': gmlVersion, 'srsName': options.srsName},\n      TRANSACTION_SERIALIZERS,\n      makeSimpleNodeFactory('Native'), options.nativeElements,\n      objectStack);\n    }\n    return node;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readProjectionFromDocument(doc) {\n    for (let n = doc.firstChild; n; n = n.nextSibling) {\n      if (n.nodeType == Node.ELEMENT_NODE) {\n        return this.readProjectionFromNode(n);\n      }\n    }\n    return null;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readProjectionFromNode(node) {\n    if (node.firstElementChild &&\n        node.firstElementChild.firstElementChild) {\n      node = node.firstElementChild.firstElementChild;\n      for (let n = node.firstElementChild; n; n = n.nextElementSibling) {\n        if (!(n.childNodes.length === 0 ||\n            (n.childNodes.length === 1 &&\n            n.firstChild.nodeType === 3))) {\n          const objectStack = [{}];\n          this.gmlFormat_.readGeometryElement(n, objectStack);\n          return getProjection(objectStack.pop().srsName);\n        }\n      }\n    }\n\n    return null;\n  }\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Transaction Summary.\n */\nfunction readTransactionSummary(node, objectStack) {\n  return pushParseAndPop(\n    {}, TRANSACTION_SUMMARY_PARSERS, node, objectStack);\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst OGC_FID_PARSERS = {\n  'http://www.opengis.net/ogc': {\n    'FeatureId': makeArrayPusher(function(node, objectStack) {\n      return node.getAttribute('fid');\n    })\n  }\n};\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n */\nfunction fidParser(node, objectStack) {\n  parseNode(OGC_FID_PARSERS, node, objectStack);\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst INSERT_RESULTS_PARSERS = {\n  'http://www.opengis.net/wfs': {\n    'Feature': fidParser\n  }\n};\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Array.<string>|undefined} Insert results.\n */\nfunction readInsertResults(node, objectStack) {\n  return pushParseAndPop(\n    [], INSERT_RESULTS_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/Feature} feature Feature.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeFeature(node, feature, objectStack) {\n  const context = objectStack[objectStack.length - 1];\n  const featureType = context['featureType'];\n  const featureNS = context['featureNS'];\n  const gmlVersion = context['gmlVersion'];\n  const child = createElementNS(featureNS, featureType);\n  node.appendChild(child);\n  if (gmlVersion === 2) {\n    GML2.prototype.writeFeatureElement(child, feature, objectStack);\n  } else {\n    GML3.prototype.writeFeatureElement(child, feature, objectStack);\n  }\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {number|string} fid Feature identifier.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeOgcFidFilter(node, fid, objectStack) {\n  const filter = createElementNS(OGCNS, 'Filter');\n  const child = createElementNS(OGCNS, 'FeatureId');\n  filter.appendChild(child);\n  child.setAttribute('fid', fid);\n  node.appendChild(filter);\n}\n\n\n/**\n * @param {string|undefined} featurePrefix The prefix of the feature.\n * @param {string} featureType The type of the feature.\n * @returns {string} The value of the typeName property.\n */\nfunction getTypeName(featurePrefix, featureType) {\n  featurePrefix = featurePrefix ? featurePrefix : FEATURE_PREFIX;\n  const prefix = featurePrefix + ':';\n  // The featureType already contains the prefix.\n  if (featureType.indexOf(prefix) === 0) {\n    return featureType;\n  } else {\n    return prefix + featureType;\n  }\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/Feature} feature Feature.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeDelete(node, feature, objectStack) {\n  const context = objectStack[objectStack.length - 1];\n  assert(feature.getId() !== undefined, 26); // Features must have an id set\n  const featureType = context['featureType'];\n  const featurePrefix = context['featurePrefix'];\n  const featureNS = context['featureNS'];\n  const typeName = getTypeName(featurePrefix, featureType);\n  node.setAttribute('typeName', typeName);\n  node.setAttributeNS(XMLNS, 'xmlns:' + featurePrefix, featureNS);\n  const fid = feature.getId();\n  if (fid !== undefined) {\n    writeOgcFidFilter(node, fid, objectStack);\n  }\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/Feature} feature Feature.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeUpdate(node, feature, objectStack) {\n  const context = objectStack[objectStack.length - 1];\n  assert(feature.getId() !== undefined, 27); // Features must have an id set\n  const featureType = context['featureType'];\n  const featurePrefix = context['featurePrefix'];\n  const featureNS = context['featureNS'];\n  const typeName = getTypeName(featurePrefix, featureType);\n  const geometryName = feature.getGeometryName();\n  node.setAttribute('typeName', typeName);\n  node.setAttributeNS(XMLNS, 'xmlns:' + featurePrefix, featureNS);\n  const fid = feature.getId();\n  if (fid !== undefined) {\n    const keys = feature.getKeys();\n    const values = [];\n    for (let i = 0, ii = keys.length; i < ii; i++) {\n      const value = feature.get(keys[i]);\n      if (value !== undefined) {\n        let name = keys[i];\n        if (value instanceof Geometry) {\n          name = geometryName;\n        }\n        values.push({name: name, value: value});\n      }\n    }\n    pushSerializeAndPop(/** @type {module:ol/xml~NodeStackItem} */ (\n      {'gmlVersion': context['gmlVersion'], node: node,\n        'hasZ': context['hasZ'], 'srsName': context['srsName']}),\n    TRANSACTION_SERIALIZERS,\n    makeSimpleNodeFactory('Property'), values,\n    objectStack);\n    writeOgcFidFilter(node, fid, objectStack);\n  }\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Object} pair Property name and value.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeProperty(node, pair, objectStack) {\n  const name = createElementNS(WFSNS, 'Name');\n  const context = objectStack[objectStack.length - 1];\n  const gmlVersion = context['gmlVersion'];\n  node.appendChild(name);\n  writeStringTextNode(name, pair.name);\n  if (pair.value !== undefined && pair.value !== null) {\n    const value = createElementNS(WFSNS, 'Value');\n    node.appendChild(value);\n    if (pair.value instanceof Geometry) {\n      if (gmlVersion === 2) {\n        GML2.prototype.writeGeometryElement(value,\n          pair.value, objectStack);\n      } else {\n        GML3.prototype.writeGeometryElement(value,\n          pair.value, objectStack);\n      }\n    } else {\n      writeStringTextNode(value, pair.value);\n    }\n  }\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {{vendorId: string, safeToIgnore: boolean, value: string}}\n *     nativeElement The native element.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeNative(node, nativeElement, objectStack) {\n  if (nativeElement.vendorId) {\n    node.setAttribute('vendorId', nativeElement.vendorId);\n  }\n  if (nativeElement.safeToIgnore !== undefined) {\n    node.setAttribute('safeToIgnore', nativeElement.safeToIgnore);\n  }\n  if (nativeElement.value !== undefined) {\n    writeStringTextNode(node, nativeElement.value);\n  }\n}\n\n\n/**\n * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}\n */\nconst GETFEATURE_SERIALIZERS = {\n  'http://www.opengis.net/wfs': {\n    'Query': makeChildAppender(writeQuery)\n  },\n  'http://www.opengis.net/ogc': {\n    'During': makeChildAppender(writeDuringFilter),\n    'And': makeChildAppender(writeLogicalFilter),\n    'Or': makeChildAppender(writeLogicalFilter),\n    'Not': makeChildAppender(writeNotFilter),\n    'BBOX': makeChildAppender(writeBboxFilter),\n    'Contains': makeChildAppender(writeContainsFilter),\n    'Intersects': makeChildAppender(writeIntersectsFilter),\n    'Within': makeChildAppender(writeWithinFilter),\n    'PropertyIsEqualTo': makeChildAppender(writeComparisonFilter),\n    'PropertyIsNotEqualTo': makeChildAppender(writeComparisonFilter),\n    'PropertyIsLessThan': makeChildAppender(writeComparisonFilter),\n    'PropertyIsLessThanOrEqualTo': makeChildAppender(writeComparisonFilter),\n    'PropertyIsGreaterThan': makeChildAppender(writeComparisonFilter),\n    'PropertyIsGreaterThanOrEqualTo': makeChildAppender(writeComparisonFilter),\n    'PropertyIsNull': makeChildAppender(writeIsNullFilter),\n    'PropertyIsBetween': makeChildAppender(writeIsBetweenFilter),\n    'PropertyIsLike': makeChildAppender(writeIsLikeFilter)\n  }\n};\n\n\n/**\n * @param {Node} node Node.\n * @param {string} featureType Feature type.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeQuery(node, featureType, objectStack) {\n  const context = /** @type {Object} */ (objectStack[objectStack.length - 1]);\n  const featurePrefix = context['featurePrefix'];\n  const featureNS = context['featureNS'];\n  const propertyNames = context['propertyNames'];\n  const srsName = context['srsName'];\n  let typeName;\n  // If feature prefix is not defined, we must not use the default prefix.\n  if (featurePrefix) {\n    typeName = getTypeName(featurePrefix, featureType);\n  } else {\n    typeName = featureType;\n  }\n  node.setAttribute('typeName', typeName);\n  if (srsName) {\n    node.setAttribute('srsName', srsName);\n  }\n  if (featureNS) {\n    node.setAttributeNS(XMLNS, 'xmlns:' + featurePrefix, featureNS);\n  }\n  const item = /** @type {module:ol/xml~NodeStackItem} */ (assign({}, context));\n  item.node = node;\n  pushSerializeAndPop(item,\n    QUERY_SERIALIZERS,\n    makeSimpleNodeFactory('PropertyName'), propertyNames,\n    objectStack);\n  const filter = context['filter'];\n  if (filter) {\n    const child = createElementNS(OGCNS, 'Filter');\n    node.appendChild(child);\n    writeFilterCondition(child, filter, objectStack);\n  }\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/format/filter/Filter} filter Filter.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeFilterCondition(node, filter, objectStack) {\n  /** @type {module:ol/xml~NodeStackItem} */\n  const item = {node: node};\n  pushSerializeAndPop(item,\n    GETFEATURE_SERIALIZERS,\n    makeSimpleNodeFactory(filter.getTagName()),\n    [filter], objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/format/filter/Bbox} filter Filter.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeBboxFilter(node, filter, objectStack) {\n  const context = objectStack[objectStack.length - 1];\n  context['srsName'] = filter.srsName;\n\n  writeOgcPropertyName(node, filter.geometryName);\n  GML3.prototype.writeGeometryElement(node, filter.extent, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/format/filter/Contains} filter Filter.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeContainsFilter(node, filter, objectStack) {\n  const context = objectStack[objectStack.length - 1];\n  context['srsName'] = filter.srsName;\n\n  writeOgcPropertyName(node, filter.geometryName);\n  GML3.prototype.writeGeometryElement(node, filter.geometry, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/format/filter/Intersects} filter Filter.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeIntersectsFilter(node, filter, objectStack) {\n  const context = objectStack[objectStack.length - 1];\n  context['srsName'] = filter.srsName;\n\n  writeOgcPropertyName(node, filter.geometryName);\n  GML3.prototype.writeGeometryElement(node, filter.geometry, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/format/filter/Within} filter Filter.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeWithinFilter(node, filter, objectStack) {\n  const context = objectStack[objectStack.length - 1];\n  context['srsName'] = filter.srsName;\n\n  writeOgcPropertyName(node, filter.geometryName);\n  GML3.prototype.writeGeometryElement(node, filter.geometry, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/format/filter/During} filter Filter.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeDuringFilter(node, filter, objectStack) {\n\n  const valueReference = createElementNS(FESNS, 'ValueReference');\n  writeStringTextNode(valueReference, filter.propertyName);\n  node.appendChild(valueReference);\n\n  const timePeriod = createElementNS(GMLNS, 'TimePeriod');\n\n  node.appendChild(timePeriod);\n\n  const begin = createElementNS(GMLNS, 'begin');\n  timePeriod.appendChild(begin);\n  writeTimeInstant(begin, filter.begin);\n\n  const end = createElementNS(GMLNS, 'end');\n  timePeriod.appendChild(end);\n  writeTimeInstant(end, filter.end);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/format/filter/LogicalNary} filter Filter.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeLogicalFilter(node, filter, objectStack) {\n  /** @type {module:ol/xml~NodeStackItem} */\n  const item = {node: node};\n  const conditions = filter.conditions;\n  for (let i = 0, ii = conditions.length; i < ii; ++i) {\n    const condition = conditions[i];\n    pushSerializeAndPop(item,\n      GETFEATURE_SERIALIZERS,\n      makeSimpleNodeFactory(condition.getTagName()),\n      [condition], objectStack);\n  }\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/format/filter/Not} filter Filter.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeNotFilter(node, filter, objectStack) {\n  /** @type {module:ol/xml~NodeStackItem} */\n  const item = {node: node};\n  const condition = filter.condition;\n  pushSerializeAndPop(item,\n    GETFEATURE_SERIALIZERS,\n    makeSimpleNodeFactory(condition.getTagName()),\n    [condition], objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/format/filter/ComparisonBinary} filter Filter.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeComparisonFilter(node, filter, objectStack) {\n  if (filter.matchCase !== undefined) {\n    node.setAttribute('matchCase', filter.matchCase.toString());\n  }\n  writeOgcPropertyName(node, filter.propertyName);\n  writeOgcLiteral(node, '' + filter.expression);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/format/filter/IsNull} filter Filter.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeIsNullFilter(node, filter, objectStack) {\n  writeOgcPropertyName(node, filter.propertyName);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/format/filter/IsBetween} filter Filter.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeIsBetweenFilter(node, filter, objectStack) {\n  writeOgcPropertyName(node, filter.propertyName);\n\n  const lowerBoundary = createElementNS(OGCNS, 'LowerBoundary');\n  node.appendChild(lowerBoundary);\n  writeOgcLiteral(lowerBoundary, '' + filter.lowerBoundary);\n\n  const upperBoundary = createElementNS(OGCNS, 'UpperBoundary');\n  node.appendChild(upperBoundary);\n  writeOgcLiteral(upperBoundary, '' + filter.upperBoundary);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {module:ol/format/filter/IsLike} filter Filter.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeIsLikeFilter(node, filter, objectStack) {\n  node.setAttribute('wildCard', filter.wildCard);\n  node.setAttribute('singleChar', filter.singleChar);\n  node.setAttribute('escapeChar', filter.escapeChar);\n  if (filter.matchCase !== undefined) {\n    node.setAttribute('matchCase', filter.matchCase.toString());\n  }\n  writeOgcPropertyName(node, filter.propertyName);\n  writeOgcLiteral(node, '' + filter.pattern);\n}\n\n\n/**\n * @param {string} tagName Tag name.\n * @param {Node} node Node.\n * @param {string} value Value.\n */\nfunction writeOgcExpression(tagName, node, value) {\n  const property = createElementNS(OGCNS, tagName);\n  writeStringTextNode(property, value);\n  node.appendChild(property);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {string} value PropertyName value.\n */\nfunction writeOgcPropertyName(node, value) {\n  writeOgcExpression('PropertyName', node, value);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {string} value PropertyName value.\n */\nfunction writeOgcLiteral(node, value) {\n  writeOgcExpression('Literal', node, value);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {string} time PropertyName value.\n */\nfunction writeTimeInstant(node, time) {\n  const timeInstant = createElementNS(GMLNS, 'TimeInstant');\n  node.appendChild(timeInstant);\n\n  const timePosition = createElementNS(GMLNS, 'timePosition');\n  timeInstant.appendChild(timePosition);\n  writeStringTextNode(timePosition, time);\n}\n\n\n/**\n * Encode filter as WFS `Filter` and return the Node.\n *\n * @param {module:ol/format/filter/Filter} filter Filter.\n * @return {Node} Result.\n * @api\n */\nexport function writeFilter(filter) {\n  const child = createElementNS(OGCNS, 'Filter');\n  writeFilterCondition(child, filter, []);\n  return child;\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<string>} featureTypes Feature types.\n * @param {Array.<*>} objectStack Node stack.\n */\nfunction writeGetFeature(node, featureTypes, objectStack) {\n  const context = /** @type {Object} */ (objectStack[objectStack.length - 1]);\n  const item = /** @type {module:ol/xml~NodeStackItem} */ (assign({}, context));\n  item.node = node;\n  pushSerializeAndPop(item,\n    GETFEATURE_SERIALIZERS,\n    makeSimpleNodeFactory('Query'), featureTypes,\n    objectStack);\n}\n\n\nexport default WFS;\n","/**\n * @module ol/format/WKT\n */\nimport Feature from '../Feature.js';\nimport {transformWithOptions} from '../format/Feature.js';\nimport TextFeature from '../format/TextFeature.js';\nimport GeometryCollection from '../geom/GeometryCollection.js';\nimport GeometryType from '../geom/GeometryType.js';\nimport GeometryLayout from '../geom/GeometryLayout.js';\nimport LineString from '../geom/LineString.js';\nimport MultiLineString from '../geom/MultiLineString.js';\nimport MultiPoint from '../geom/MultiPoint.js';\nimport MultiPolygon from '../geom/MultiPolygon.js';\nimport Point from '../geom/Point.js';\nimport Polygon from '../geom/Polygon.js';\nimport SimpleGeometry from '../geom/SimpleGeometry.js';\n\n\n/**\n * @enum {function (new:module:ol/geom/Geometry, Array, module:ol/geom/GeometryLayout)}\n */\nconst GeometryConstructor = {\n  'POINT': Point,\n  'LINESTRING': LineString,\n  'POLYGON': Polygon,\n  'MULTIPOINT': MultiPoint,\n  'MULTILINESTRING': MultiLineString,\n  'MULTIPOLYGON': MultiPolygon\n};\n\n\n/**\n * @typedef {Object} Options\n * @property {boolean} [splitCollection=false] Whether to split GeometryCollections into\n * multiple features on reading.\n */\n\n/**\n * @typedef {Object} Token\n * @property {number} type\n * @property {number|string} [value]\n * @property {number} position\n */\n\n/**\n * @const\n * @type {string}\n */\nconst EMPTY = 'EMPTY';\n\n\n/**\n * @const\n * @type {string}\n */\nconst Z = 'Z';\n\n\n/**\n * @const\n * @type {string}\n */\nconst M = 'M';\n\n\n/**\n * @const\n * @type {string}\n */\nconst ZM = 'ZM';\n\n\n/**\n * @const\n * @enum {number}\n */\nconst TokenType = {\n  TEXT: 1,\n  LEFT_PAREN: 2,\n  RIGHT_PAREN: 3,\n  NUMBER: 4,\n  COMMA: 5,\n  EOF: 6\n};\n\n/**\n * @const\n * @type {Object.<string, string>}\n */\nconst WKTGeometryType = {};\nfor (const type in GeometryType) {\n  WKTGeometryType[type] = GeometryType[type].toUpperCase();\n}\n\n\n/**\n * Class to tokenize a WKT string.\n */\nclass Lexer {\n\n  /**\n   * @param {string} wkt WKT string.\n   */\n  constructor(wkt) {\n\n    /**\n     * @type {string}\n     */\n    this.wkt = wkt;\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.index_ = -1;\n  }\n\n  /**\n   * @param {string} c Character.\n   * @return {boolean} Whether the character is alphabetic.\n   * @private\n   */\n  isAlpha_(c) {\n    return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z';\n  }\n\n  /**\n   * @param {string} c Character.\n   * @param {boolean=} opt_decimal Whether the string number\n   *     contains a dot, i.e. is a decimal number.\n   * @return {boolean} Whether the character is numeric.\n   * @private\n   */\n  isNumeric_(c, opt_decimal) {\n    const decimal = opt_decimal !== undefined ? opt_decimal : false;\n    return c >= '0' && c <= '9' || c == '.' && !decimal;\n  }\n\n  /**\n   * @param {string} c Character.\n   * @return {boolean} Whether the character is whitespace.\n   * @private\n   */\n  isWhiteSpace_(c) {\n    return c == ' ' || c == '\\t' || c == '\\r' || c == '\\n';\n  }\n\n  /**\n   * @return {string} Next string character.\n   * @private\n   */\n  nextChar_() {\n    return this.wkt.charAt(++this.index_);\n  }\n\n  /**\n   * Fetch and return the next token.\n   * @return {!module:ol/format/WKT~Token} Next string token.\n   */\n  nextToken() {\n    const c = this.nextChar_();\n    const token = {position: this.index_, value: c};\n\n    if (c == '(') {\n      token.type = TokenType.LEFT_PAREN;\n    } else if (c == ',') {\n      token.type = TokenType.COMMA;\n    } else if (c == ')') {\n      token.type = TokenType.RIGHT_PAREN;\n    } else if (this.isNumeric_(c) || c == '-') {\n      token.type = TokenType.NUMBER;\n      token.value = this.readNumber_();\n    } else if (this.isAlpha_(c)) {\n      token.type = TokenType.TEXT;\n      token.value = this.readText_();\n    } else if (this.isWhiteSpace_(c)) {\n      return this.nextToken();\n    } else if (c === '') {\n      token.type = TokenType.EOF;\n    } else {\n      throw new Error('Unexpected character: ' + c);\n    }\n\n    return token;\n  }\n\n  /**\n   * @return {number} Numeric token value.\n   * @private\n   */\n  readNumber_() {\n    let c;\n    const index = this.index_;\n    let decimal = false;\n    let scientificNotation = false;\n    do {\n      if (c == '.') {\n        decimal = true;\n      } else if (c == 'e' || c == 'E') {\n        scientificNotation = true;\n      }\n      c = this.nextChar_();\n    } while (\n      this.isNumeric_(c, decimal) ||\n        // if we haven't detected a scientific number before, 'e' or 'E'\n        // hint that we should continue to read\n        !scientificNotation && (c == 'e' || c == 'E') ||\n        // once we know that we have a scientific number, both '-' and '+'\n        // are allowed\n        scientificNotation && (c == '-' || c == '+')\n    );\n    return parseFloat(this.wkt.substring(index, this.index_--));\n  }\n\n  /**\n   * @return {string} String token value.\n   * @private\n   */\n  readText_() {\n    let c;\n    const index = this.index_;\n    do {\n      c = this.nextChar_();\n    } while (this.isAlpha_(c));\n    return this.wkt.substring(index, this.index_--).toUpperCase();\n  }\n}\n\n/**\n * Class to parse the tokens from the WKT string.\n */\nclass Parser {\n\n  /**\n   * @param {module:ol/format/WKT~Lexer} lexer The lexer.\n   */\n  constructor(lexer) {\n\n    /**\n     * @type {module:ol/format/WKT~Lexer}\n     * @private\n     */\n    this.lexer_ = lexer;\n\n    /**\n     * @type {module:ol/format/WKT~Token}\n     * @private\n     */\n    this.token_;\n\n    /**\n     * @type {module:ol/geom/GeometryLayout}\n     * @private\n     */\n    this.layout_ = GeometryLayout.XY;\n  }\n\n  /**\n   * Fetch the next token form the lexer and replace the active token.\n   * @private\n   */\n  consume_() {\n    this.token_ = this.lexer_.nextToken();\n  }\n\n  /**\n   * Tests if the given type matches the type of the current token.\n   * @param {module:ol/format/WKT~TokenType} type Token type.\n   * @return {boolean} Whether the token matches the given type.\n   */\n  isTokenType(type) {\n    const isMatch = this.token_.type == type;\n    return isMatch;\n  }\n\n  /**\n   * If the given type matches the current token, consume it.\n   * @param {module:ol/format/WKT~TokenType} type Token type.\n   * @return {boolean} Whether the token matches the given type.\n   */\n  match(type) {\n    const isMatch = this.isTokenType(type);\n    if (isMatch) {\n      this.consume_();\n    }\n    return isMatch;\n  }\n\n  /**\n   * Try to parse the tokens provided by the lexer.\n   * @return {module:ol/geom/Geometry} The geometry.\n   */\n  parse() {\n    this.consume_();\n    const geometry = this.parseGeometry_();\n    return geometry;\n  }\n\n  /**\n   * Try to parse the dimensional info.\n   * @return {module:ol/geom/GeometryLayout} The layout.\n   * @private\n   */\n  parseGeometryLayout_() {\n    let layout = GeometryLayout.XY;\n    const dimToken = this.token_;\n    if (this.isTokenType(TokenType.TEXT)) {\n      const dimInfo = dimToken.value;\n      if (dimInfo === Z) {\n        layout = GeometryLayout.XYZ;\n      } else if (dimInfo === M) {\n        layout = GeometryLayout.XYM;\n      } else if (dimInfo === ZM) {\n        layout = GeometryLayout.XYZM;\n      }\n      if (layout !== GeometryLayout.XY) {\n        this.consume_();\n      }\n    }\n    return layout;\n  }\n\n  /**\n   * @return {!Array.<module:ol/geom/Geometry>} A collection of geometries.\n   * @private\n   */\n  parseGeometryCollectionText_() {\n    if (this.match(TokenType.LEFT_PAREN)) {\n      const geometries = [];\n      do {\n        geometries.push(this.parseGeometry_());\n      } while (this.match(TokenType.COMMA));\n      if (this.match(TokenType.RIGHT_PAREN)) {\n        return geometries;\n      }\n    } else if (this.isEmptyGeometry_()) {\n      return [];\n    }\n    throw new Error(this.formatErrorMessage_());\n  }\n\n  /**\n   * @return {Array.<number>} All values in a point.\n   * @private\n   */\n  parsePointText_() {\n    if (this.match(TokenType.LEFT_PAREN)) {\n      const coordinates = this.parsePoint_();\n      if (this.match(TokenType.RIGHT_PAREN)) {\n        return coordinates;\n      }\n    } else if (this.isEmptyGeometry_()) {\n      return null;\n    }\n    throw new Error(this.formatErrorMessage_());\n  }\n\n  /**\n   * @return {!Array.<!Array.<number>>} All points in a linestring.\n   * @private\n   */\n  parseLineStringText_() {\n    if (this.match(TokenType.LEFT_PAREN)) {\n      const coordinates = this.parsePointList_();\n      if (this.match(TokenType.RIGHT_PAREN)) {\n        return coordinates;\n      }\n    } else if (this.isEmptyGeometry_()) {\n      return [];\n    }\n    throw new Error(this.formatErrorMessage_());\n  }\n\n  /**\n   * @return {!Array.<!Array.<number>>} All points in a polygon.\n   * @private\n   */\n  parsePolygonText_() {\n    if (this.match(TokenType.LEFT_PAREN)) {\n      const coordinates = this.parseLineStringTextList_();\n      if (this.match(TokenType.RIGHT_PAREN)) {\n        return coordinates;\n      }\n    } else if (this.isEmptyGeometry_()) {\n      return [];\n    }\n    throw new Error(this.formatErrorMessage_());\n  }\n\n  /**\n   * @return {!Array.<!Array.<number>>} All points in a multipoint.\n   * @private\n   */\n  parseMultiPointText_() {\n    if (this.match(TokenType.LEFT_PAREN)) {\n      let coordinates;\n      if (this.token_.type == TokenType.LEFT_PAREN) {\n        coordinates = this.parsePointTextList_();\n      } else {\n        coordinates = this.parsePointList_();\n      }\n      if (this.match(TokenType.RIGHT_PAREN)) {\n        return coordinates;\n      }\n    } else if (this.isEmptyGeometry_()) {\n      return [];\n    }\n    throw new Error(this.formatErrorMessage_());\n  }\n\n  /**\n   * @return {!Array.<!Array.<number>>} All linestring points\n   *                                        in a multilinestring.\n   * @private\n   */\n  parseMultiLineStringText_() {\n    if (this.match(TokenType.LEFT_PAREN)) {\n      const coordinates = this.parseLineStringTextList_();\n      if (this.match(TokenType.RIGHT_PAREN)) {\n        return coordinates;\n      }\n    } else if (this.isEmptyGeometry_()) {\n      return [];\n    }\n    throw new Error(this.formatErrorMessage_());\n  }\n\n  /**\n   * @return {!Array.<!Array.<number>>} All polygon points in a multipolygon.\n   * @private\n   */\n  parseMultiPolygonText_() {\n    if (this.match(TokenType.LEFT_PAREN)) {\n      const coordinates = this.parsePolygonTextList_();\n      if (this.match(TokenType.RIGHT_PAREN)) {\n        return coordinates;\n      }\n    } else if (this.isEmptyGeometry_()) {\n      return [];\n    }\n    throw new Error(this.formatErrorMessage_());\n  }\n\n  /**\n   * @return {!Array.<number>} A point.\n   * @private\n   */\n  parsePoint_() {\n    const coordinates = [];\n    const dimensions = this.layout_.length;\n    for (let i = 0; i < dimensions; ++i) {\n      const token = this.token_;\n      if (this.match(TokenType.NUMBER)) {\n        coordinates.push(token.value);\n      } else {\n        break;\n      }\n    }\n    if (coordinates.length == dimensions) {\n      return coordinates;\n    }\n    throw new Error(this.formatErrorMessage_());\n  }\n\n  /**\n   * @return {!Array.<!Array.<number>>} An array of points.\n   * @private\n   */\n  parsePointList_() {\n    const coordinates = [this.parsePoint_()];\n    while (this.match(TokenType.COMMA)) {\n      coordinates.push(this.parsePoint_());\n    }\n    return coordinates;\n  }\n\n  /**\n   * @return {!Array.<!Array.<number>>} An array of points.\n   * @private\n   */\n  parsePointTextList_() {\n    const coordinates = [this.parsePointText_()];\n    while (this.match(TokenType.COMMA)) {\n      coordinates.push(this.parsePointText_());\n    }\n    return coordinates;\n  }\n\n  /**\n   * @return {!Array.<!Array.<number>>} An array of points.\n   * @private\n   */\n  parseLineStringTextList_() {\n    const coordinates = [this.parseLineStringText_()];\n    while (this.match(TokenType.COMMA)) {\n      coordinates.push(this.parseLineStringText_());\n    }\n    return coordinates;\n  }\n\n  /**\n   * @return {!Array.<!Array.<number>>} An array of points.\n   * @private\n   */\n  parsePolygonTextList_() {\n    const coordinates = [this.parsePolygonText_()];\n    while (this.match(TokenType.COMMA)) {\n      coordinates.push(this.parsePolygonText_());\n    }\n    return coordinates;\n  }\n\n  /**\n   * @return {boolean} Whether the token implies an empty geometry.\n   * @private\n   */\n  isEmptyGeometry_() {\n    const isEmpty = this.isTokenType(TokenType.TEXT) &&\n        this.token_.value == EMPTY;\n    if (isEmpty) {\n      this.consume_();\n    }\n    return isEmpty;\n  }\n\n  /**\n   * Create an error message for an unexpected token error.\n   * @return {string} Error message.\n   * @private\n   */\n  formatErrorMessage_() {\n    return 'Unexpected `' + this.token_.value + '` at position ' +\n        this.token_.position + ' in `' + this.lexer_.wkt + '`';\n  }\n\n  /**\n   * @return {!module:ol/geom/Geometry} The geometry.\n   * @private\n   */\n  parseGeometry_() {\n    const token = this.token_;\n    if (this.match(TokenType.TEXT)) {\n      const geomType = token.value;\n      this.layout_ = this.parseGeometryLayout_();\n      if (geomType == 'GEOMETRYCOLLECTION') {\n        const geometries = this.parseGeometryCollectionText_();\n        return new GeometryCollection(geometries);\n      } else {\n        const ctor = GeometryConstructor[geomType];\n        if (!ctor) {\n          throw new Error('Invalid geometry type: ' + geomType);\n        }\n\n        let coordinates;\n        switch (geomType) {\n          case 'POINT': {\n            coordinates = this.parsePointText_();\n            break;\n          }\n          case 'LINESTRING': {\n            coordinates = this.parseLineStringText_();\n            break;\n          }\n          case 'POLYGON': {\n            coordinates = this.parsePolygonText_();\n            break;\n          }\n          case 'MULTIPOINT': {\n            coordinates = this.parseMultiPointText_();\n            break;\n          }\n          case 'MULTILINESTRING': {\n            coordinates = this.parseMultiLineStringText_();\n            break;\n          }\n          case 'MULTIPOLYGON': {\n            coordinates = this.parseMultiPolygonText_();\n            break;\n          }\n          default: {\n            throw new Error('Invalid geometry type: ' + geomType);\n          }\n        }\n\n        if (!coordinates) {\n          if (ctor === GeometryConstructor['POINT']) {\n            coordinates = [NaN, NaN];\n          } else {\n            coordinates = [];\n          }\n        }\n        return new ctor(coordinates, this.layout_);\n      }\n    }\n    throw new Error(this.formatErrorMessage_());\n  }\n}\n\n\n/**\n * @classdesc\n * Geometry format for reading and writing data in the `WellKnownText` (WKT)\n * format.\n *\n * @api\n */\nclass WKT extends TextFeature {\n\n  /**\n   * @param {module:ol/format/WKT~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n    super();\n\n    const options = opt_options ? opt_options : {};\n\n\n    /**\n     * Split GeometryCollection into multiple features.\n     * @type {boolean}\n     * @private\n     */\n    this.splitCollection_ = options.splitCollection !== undefined ?\n      options.splitCollection : false;\n\n  }\n\n  /**\n   * Parse a WKT string.\n   * @param {string} wkt WKT string.\n   * @return {module:ol/geom/Geometry|undefined}\n   *     The geometry created.\n   * @private\n   */\n  parse_(wkt) {\n    const lexer = new Lexer(wkt);\n    const parser = new Parser(lexer);\n    return parser.parse();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFeatureFromText(text, opt_options) {\n    const geom = this.readGeometryFromText(text, opt_options);\n    if (geom) {\n      const feature = new Feature();\n      feature.setGeometry(geom);\n      return feature;\n    }\n    return null;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFeaturesFromText(text, opt_options) {\n    let geometries = [];\n    const geometry = this.readGeometryFromText(text, opt_options);\n    if (this.splitCollection_ &&\n        geometry.getType() == GeometryType.GEOMETRY_COLLECTION) {\n      geometries = (/** @type {module:ol/geom/GeometryCollection} */ (geometry))\n        .getGeometriesArray();\n    } else {\n      geometries = [geometry];\n    }\n    const features = [];\n    for (let i = 0, ii = geometries.length; i < ii; ++i) {\n      const feature = new Feature();\n      feature.setGeometry(geometries[i]);\n      features.push(feature);\n    }\n    return features;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readGeometryFromText(text, opt_options) {\n    const geometry = this.parse_(text);\n    if (geometry) {\n      return (\n        /** @type {module:ol/geom/Geometry} */ (transformWithOptions(geometry, false, opt_options))\n      );\n    } else {\n      return null;\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  writeFeatureText(feature, opt_options) {\n    const geometry = feature.getGeometry();\n    if (geometry) {\n      return this.writeGeometryText(geometry, opt_options);\n    }\n    return '';\n  }\n\n  /**\n   * @inheritDoc\n   */\n  writeFeaturesText(features, opt_options) {\n    if (features.length == 1) {\n      return this.writeFeatureText(features[0], opt_options);\n    }\n    const geometries = [];\n    for (let i = 0, ii = features.length; i < ii; ++i) {\n      geometries.push(features[i].getGeometry());\n    }\n    const collection = new GeometryCollection(geometries);\n    return this.writeGeometryText(collection, opt_options);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  writeGeometryText(geometry, opt_options) {\n    return encode(/** @type {module:ol/geom/Geometry} */ (\n      transformWithOptions(geometry, true, opt_options)));\n  }\n}\n\n\n/**\n * @param {module:ol/geom/Point} geom Point geometry.\n * @return {string} Coordinates part of Point as WKT.\n */\nfunction encodePointGeometry(geom) {\n  const coordinates = geom.getCoordinates();\n  if (coordinates.length === 0) {\n    return '';\n  }\n  return coordinates.join(' ');\n}\n\n\n/**\n * @param {module:ol/geom/MultiPoint} geom MultiPoint geometry.\n * @return {string} Coordinates part of MultiPoint as WKT.\n */\nfunction encodeMultiPointGeometry(geom) {\n  const array = [];\n  const components = geom.getPoints();\n  for (let i = 0, ii = components.length; i < ii; ++i) {\n    array.push('(' + encodePointGeometry(components[i]) + ')');\n  }\n  return array.join(',');\n}\n\n\n/**\n * @param {module:ol/geom/GeometryCollection} geom GeometryCollection geometry.\n * @return {string} Coordinates part of GeometryCollection as WKT.\n */\nfunction encodeGeometryCollectionGeometry(geom) {\n  const array = [];\n  const geoms = geom.getGeometries();\n  for (let i = 0, ii = geoms.length; i < ii; ++i) {\n    array.push(encode(geoms[i]));\n  }\n  return array.join(',');\n}\n\n\n/**\n * @param {module:ol/geom/LineString|module:ol/geom/LinearRing} geom LineString geometry.\n * @return {string} Coordinates part of LineString as WKT.\n */\nfunction encodeLineStringGeometry(geom) {\n  const coordinates = geom.getCoordinates();\n  const array = [];\n  for (let i = 0, ii = coordinates.length; i < ii; ++i) {\n    array.push(coordinates[i].join(' '));\n  }\n  return array.join(',');\n}\n\n\n/**\n * @param {module:ol/geom/MultiLineString} geom MultiLineString geometry.\n * @return {string} Coordinates part of MultiLineString as WKT.\n */\nfunction encodeMultiLineStringGeometry(geom) {\n  const array = [];\n  const components = geom.getLineStrings();\n  for (let i = 0, ii = components.length; i < ii; ++i) {\n    array.push('(' + encodeLineStringGeometry(components[i]) + ')');\n  }\n  return array.join(',');\n}\n\n\n/**\n * @param {module:ol/geom/Polygon} geom Polygon geometry.\n * @return {string} Coordinates part of Polygon as WKT.\n */\nfunction encodePolygonGeometry(geom) {\n  const array = [];\n  const rings = geom.getLinearRings();\n  for (let i = 0, ii = rings.length; i < ii; ++i) {\n    array.push('(' + encodeLineStringGeometry(rings[i]) + ')');\n  }\n  return array.join(',');\n}\n\n\n/**\n * @param {module:ol/geom/MultiPolygon} geom MultiPolygon geometry.\n * @return {string} Coordinates part of MultiPolygon as WKT.\n */\nfunction encodeMultiPolygonGeometry(geom) {\n  const array = [];\n  const components = geom.getPolygons();\n  for (let i = 0, ii = components.length; i < ii; ++i) {\n    array.push('(' + encodePolygonGeometry(components[i]) + ')');\n  }\n  return array.join(',');\n}\n\n/**\n * @param {module:ol/geom/SimpleGeometry} geom SimpleGeometry geometry.\n * @return {string} Potential dimensional information for WKT type.\n */\nfunction encodeGeometryLayout(geom) {\n  const layout = geom.getLayout();\n  let dimInfo = '';\n  if (layout === GeometryLayout.XYZ || layout === GeometryLayout.XYZM) {\n    dimInfo += Z;\n  }\n  if (layout === GeometryLayout.XYM || layout === GeometryLayout.XYZM) {\n    dimInfo += M;\n  }\n  return dimInfo;\n}\n\n\n/**\n * @const\n * @type {Object.<string, function(module:ol/geom/Geometry): string>}\n */\nconst GeometryEncoder = {\n  'Point': encodePointGeometry,\n  'LineString': encodeLineStringGeometry,\n  'Polygon': encodePolygonGeometry,\n  'MultiPoint': encodeMultiPointGeometry,\n  'MultiLineString': encodeMultiLineStringGeometry,\n  'MultiPolygon': encodeMultiPolygonGeometry,\n  'GeometryCollection': encodeGeometryCollectionGeometry\n};\n\n\n/**\n * Encode a geometry as WKT.\n * @param {module:ol/geom/Geometry} geom The geometry to encode.\n * @return {string} WKT string for the geometry.\n */\nfunction encode(geom) {\n  let type = geom.getType();\n  const geometryEncoder = GeometryEncoder[type];\n  const enc = geometryEncoder(geom);\n  type = type.toUpperCase();\n  if (geom instanceof SimpleGeometry) {\n    const dimInfo = encodeGeometryLayout(geom);\n    if (dimInfo.length > 0) {\n      type += ' ' + dimInfo;\n    }\n  }\n  if (enc.length === 0) {\n    return type + ' ' + EMPTY;\n  }\n  return type + '(' + enc + ')';\n}\n\n\nexport default WKT;\n","/**\n * @module ol/format/XLink\n */\n\n\n/**\n * @const\n * @type {string}\n */\nconst NAMESPACE_URI = 'http://www.w3.org/1999/xlink';\n\n\n/**\n * @param {Node} node Node.\n * @return {string|undefined} href.\n */\nexport function readHref(node) {\n  return node.getAttributeNS(NAMESPACE_URI, 'href');\n}\n","/**\n * @module ol/format/XML\n */\nimport {isDocument, isNode, parse} from '../xml.js';\n\n/**\n * @classdesc\n * Generic format for reading non-feature XML data\n *\n * @abstract\n */\nclass XML {\n  /**\n   * Read the source document.\n   *\n   * @param {Document|Node|string} source The XML source.\n   * @return {Object} An object representing the source.\n   * @api\n   */\n  read(source) {\n    if (isDocument(source)) {\n      return this.readFromDocument(/** @type {Document} */ (source));\n    } else if (isNode(source)) {\n      return this.readFromNode(/** @type {Node} */ (source));\n    } else if (typeof source === 'string') {\n      const doc = parse(source);\n      return this.readFromDocument(doc);\n    } else {\n      return null;\n    }\n  }\n\n  /**\n   * @abstract\n   * @param {Document} doc Document.\n   * @return {Object} Object\n   */\n  readFromDocument(doc) {}\n\n  /**\n   * @abstract\n   * @param {Node} node Node.\n   * @return {Object} Object\n   */\n  readFromNode(node) {}\n}\n\nexport default XML;\n","/**\n * @module ol/format/WMSCapabilities\n */\nimport {readHref} from '../format/XLink.js';\nimport XML from '../format/XML.js';\nimport {readDecimalString, readString, readNonNegativeInteger, readDecimal, readBooleanString, readNonNegativeIntegerString} from '../format/xsd.js';\nimport {makeArrayPusher, makeObjectPropertyPusher, makeObjectPropertySetter,\n  makeStructureNS, pushParseAndPop} from '../xml.js';\n\n\n/**\n * @const\n * @type {Array.<null|string>}\n */\nconst NAMESPACE_URIS = [\n  null,\n  'http://www.opengis.net/wms'\n];\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Service': makeObjectPropertySetter(readService),\n    'Capability': makeObjectPropertySetter(readCapability)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst CAPABILITY_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Request': makeObjectPropertySetter(readRequest),\n    'Exception': makeObjectPropertySetter(readException),\n    'Layer': makeObjectPropertySetter(readCapabilityLayer)\n  });\n\n\n/**\n * @classdesc\n * Format for reading WMS capabilities data\n *\n * @api\n */\nclass WMSCapabilities extends XML {\n  constructor() {\n    super();\n\n    /**\n     * @type {string|undefined}\n     */\n    this.version = undefined;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFromDocument(doc) {\n    for (let n = doc.firstChild; n; n = n.nextSibling) {\n      if (n.nodeType == Node.ELEMENT_NODE) {\n        return this.readFromNode(n);\n      }\n    }\n    return null;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFromNode(node) {\n    this.version = node.getAttribute('version').trim();\n    const wmsCapabilityObject = pushParseAndPop({\n      'version': this.version\n    }, PARSERS, node, []);\n    return wmsCapabilityObject ? wmsCapabilityObject : null;\n  }\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst SERVICE_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Name': makeObjectPropertySetter(readString),\n    'Title': makeObjectPropertySetter(readString),\n    'Abstract': makeObjectPropertySetter(readString),\n    'KeywordList': makeObjectPropertySetter(readKeywordList),\n    'OnlineResource': makeObjectPropertySetter(readHref),\n    'ContactInformation': makeObjectPropertySetter(readContactInformation),\n    'Fees': makeObjectPropertySetter(readString),\n    'AccessConstraints': makeObjectPropertySetter(readString),\n    'LayerLimit': makeObjectPropertySetter(readNonNegativeInteger),\n    'MaxWidth': makeObjectPropertySetter(readNonNegativeInteger),\n    'MaxHeight': makeObjectPropertySetter(readNonNegativeInteger)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst CONTACT_INFORMATION_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'ContactPersonPrimary': makeObjectPropertySetter(readContactPersonPrimary),\n    'ContactPosition': makeObjectPropertySetter(readString),\n    'ContactAddress': makeObjectPropertySetter(readContactAddress),\n    'ContactVoiceTelephone': makeObjectPropertySetter(readString),\n    'ContactFacsimileTelephone': makeObjectPropertySetter(readString),\n    'ContactElectronicMailAddress': makeObjectPropertySetter(readString)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst CONTACT_PERSON_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'ContactPerson': makeObjectPropertySetter(readString),\n    'ContactOrganization': makeObjectPropertySetter(readString)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst CONTACT_ADDRESS_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'AddressType': makeObjectPropertySetter(readString),\n    'Address': makeObjectPropertySetter(readString),\n    'City': makeObjectPropertySetter(readString),\n    'StateOrProvince': makeObjectPropertySetter(readString),\n    'PostCode': makeObjectPropertySetter(readString),\n    'Country': makeObjectPropertySetter(readString)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst EXCEPTION_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Format': makeArrayPusher(readString)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst LAYER_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Name': makeObjectPropertySetter(readString),\n    'Title': makeObjectPropertySetter(readString),\n    'Abstract': makeObjectPropertySetter(readString),\n    'KeywordList': makeObjectPropertySetter(readKeywordList),\n    'CRS': makeObjectPropertyPusher(readString),\n    'EX_GeographicBoundingBox': makeObjectPropertySetter(readEXGeographicBoundingBox),\n    'BoundingBox': makeObjectPropertyPusher(readBoundingBox),\n    'Dimension': makeObjectPropertyPusher(readDimension),\n    'Attribution': makeObjectPropertySetter(readAttribution),\n    'AuthorityURL': makeObjectPropertyPusher(readAuthorityURL),\n    'Identifier': makeObjectPropertyPusher(readString),\n    'MetadataURL': makeObjectPropertyPusher(readMetadataURL),\n    'DataURL': makeObjectPropertyPusher(readFormatOnlineresource),\n    'FeatureListURL': makeObjectPropertyPusher(readFormatOnlineresource),\n    'Style': makeObjectPropertyPusher(readStyle),\n    'MinScaleDenominator': makeObjectPropertySetter(readDecimal),\n    'MaxScaleDenominator': makeObjectPropertySetter(readDecimal),\n    'Layer': makeObjectPropertyPusher(readLayer)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst ATTRIBUTION_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Title': makeObjectPropertySetter(readString),\n    'OnlineResource': makeObjectPropertySetter(readHref),\n    'LogoURL': makeObjectPropertySetter(readSizedFormatOnlineresource)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst EX_GEOGRAPHIC_BOUNDING_BOX_PARSERS =\n    makeStructureNS(NAMESPACE_URIS, {\n      'westBoundLongitude': makeObjectPropertySetter(readDecimal),\n      'eastBoundLongitude': makeObjectPropertySetter(readDecimal),\n      'southBoundLatitude': makeObjectPropertySetter(readDecimal),\n      'northBoundLatitude': makeObjectPropertySetter(readDecimal)\n    });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst REQUEST_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'GetCapabilities': makeObjectPropertySetter(readOperationType),\n    'GetMap': makeObjectPropertySetter(readOperationType),\n    'GetFeatureInfo': makeObjectPropertySetter(readOperationType)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst OPERATIONTYPE_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Format': makeObjectPropertyPusher(readString),\n    'DCPType': makeObjectPropertyPusher(readDCPType)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst DCPTYPE_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'HTTP': makeObjectPropertySetter(readHTTP)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst HTTP_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Get': makeObjectPropertySetter(readFormatOnlineresource),\n    'Post': makeObjectPropertySetter(readFormatOnlineresource)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst STYLE_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Name': makeObjectPropertySetter(readString),\n    'Title': makeObjectPropertySetter(readString),\n    'Abstract': makeObjectPropertySetter(readString),\n    'LegendURL': makeObjectPropertyPusher(readSizedFormatOnlineresource),\n    'StyleSheetURL': makeObjectPropertySetter(readFormatOnlineresource),\n    'StyleURL': makeObjectPropertySetter(readFormatOnlineresource)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst FORMAT_ONLINERESOURCE_PARSERS =\n    makeStructureNS(NAMESPACE_URIS, {\n      'Format': makeObjectPropertySetter(readString),\n      'OnlineResource': makeObjectPropertySetter(readHref)\n    });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst KEYWORDLIST_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Keyword': makeArrayPusher(readString)\n  });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Attribution object.\n */\nfunction readAttribution(node, objectStack) {\n  return pushParseAndPop({}, ATTRIBUTION_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object} Bounding box object.\n */\nfunction readBoundingBox(node, objectStack) {\n  const extent = [\n    readDecimalString(node.getAttribute('minx')),\n    readDecimalString(node.getAttribute('miny')),\n    readDecimalString(node.getAttribute('maxx')),\n    readDecimalString(node.getAttribute('maxy'))\n  ];\n\n  const resolutions = [\n    readDecimalString(node.getAttribute('resx')),\n    readDecimalString(node.getAttribute('resy'))\n  ];\n\n  return {\n    'crs': node.getAttribute('CRS'),\n    'extent': extent,\n    'res': resolutions\n  };\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {module:ol/extent~Extent|undefined} Bounding box object.\n */\nfunction readEXGeographicBoundingBox(node, objectStack) {\n  const geographicBoundingBox = pushParseAndPop(\n    {},\n    EX_GEOGRAPHIC_BOUNDING_BOX_PARSERS,\n    node, objectStack);\n  if (!geographicBoundingBox) {\n    return undefined;\n  }\n  const westBoundLongitude = /** @type {number|undefined} */\n        (geographicBoundingBox['westBoundLongitude']);\n  const southBoundLatitude = /** @type {number|undefined} */\n        (geographicBoundingBox['southBoundLatitude']);\n  const eastBoundLongitude = /** @type {number|undefined} */\n        (geographicBoundingBox['eastBoundLongitude']);\n  const northBoundLatitude = /** @type {number|undefined} */\n        (geographicBoundingBox['northBoundLatitude']);\n  if (westBoundLongitude === undefined || southBoundLatitude === undefined ||\n        eastBoundLongitude === undefined || northBoundLatitude === undefined) {\n    return undefined;\n  }\n  return [\n    westBoundLongitude, southBoundLatitude,\n    eastBoundLongitude, northBoundLatitude\n  ];\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Capability object.\n */\nfunction readCapability(node, objectStack) {\n  return pushParseAndPop({}, CAPABILITY_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Service object.\n */\nfunction readService(node, objectStack) {\n  return pushParseAndPop({}, SERVICE_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Contact information object.\n */\nfunction readContactInformation(node, objectStack) {\n  return pushParseAndPop({}, CONTACT_INFORMATION_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Contact person object.\n */\nfunction readContactPersonPrimary(node, objectStack) {\n  return pushParseAndPop({}, CONTACT_PERSON_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Contact address object.\n */\nfunction readContactAddress(node, objectStack) {\n  return pushParseAndPop({}, CONTACT_ADDRESS_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Array.<string>|undefined} Format array.\n */\nfunction readException(node, objectStack) {\n  return pushParseAndPop([], EXCEPTION_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Layer object.\n */\nfunction readCapabilityLayer(node, objectStack) {\n  return pushParseAndPop({}, LAYER_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Layer object.\n */\nfunction readLayer(node, objectStack) {\n  const parentLayerObject = /**  @type {!Object.<string,*>} */ (objectStack[objectStack.length - 1]);\n\n  const layerObject = pushParseAndPop({}, LAYER_PARSERS, node, objectStack);\n\n  if (!layerObject) {\n    return undefined;\n  }\n  let queryable = readBooleanString(node.getAttribute('queryable'));\n  if (queryable === undefined) {\n    queryable = parentLayerObject['queryable'];\n  }\n  layerObject['queryable'] = queryable !== undefined ? queryable : false;\n\n  let cascaded = readNonNegativeIntegerString(\n    node.getAttribute('cascaded'));\n  if (cascaded === undefined) {\n    cascaded = parentLayerObject['cascaded'];\n  }\n  layerObject['cascaded'] = cascaded;\n\n  let opaque = readBooleanString(node.getAttribute('opaque'));\n  if (opaque === undefined) {\n    opaque = parentLayerObject['opaque'];\n  }\n  layerObject['opaque'] = opaque !== undefined ? opaque : false;\n\n  let noSubsets = readBooleanString(node.getAttribute('noSubsets'));\n  if (noSubsets === undefined) {\n    noSubsets = parentLayerObject['noSubsets'];\n  }\n  layerObject['noSubsets'] = noSubsets !== undefined ? noSubsets : false;\n\n  let fixedWidth = readDecimalString(node.getAttribute('fixedWidth'));\n  if (!fixedWidth) {\n    fixedWidth = parentLayerObject['fixedWidth'];\n  }\n  layerObject['fixedWidth'] = fixedWidth;\n\n  let fixedHeight = readDecimalString(node.getAttribute('fixedHeight'));\n  if (!fixedHeight) {\n    fixedHeight = parentLayerObject['fixedHeight'];\n  }\n  layerObject['fixedHeight'] = fixedHeight;\n\n  // See 7.2.4.8\n  const addKeys = ['Style', 'CRS', 'AuthorityURL'];\n  addKeys.forEach(function(key) {\n    if (key in parentLayerObject) {\n      const childValue = layerObject[key] || [];\n      layerObject[key] = childValue.concat(parentLayerObject[key]);\n    }\n  });\n\n  const replaceKeys = ['EX_GeographicBoundingBox', 'BoundingBox', 'Dimension',\n    'Attribution', 'MinScaleDenominator', 'MaxScaleDenominator'];\n  replaceKeys.forEach(function(key) {\n    if (!(key in layerObject)) {\n      const parentValue = parentLayerObject[key];\n      layerObject[key] = parentValue;\n    }\n  });\n\n  return layerObject;\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object} Dimension object.\n */\nfunction readDimension(node, objectStack) {\n  const dimensionObject = {\n    'name': node.getAttribute('name'),\n    'units': node.getAttribute('units'),\n    'unitSymbol': node.getAttribute('unitSymbol'),\n    'default': node.getAttribute('default'),\n    'multipleValues': readBooleanString(node.getAttribute('multipleValues')),\n    'nearestValue': readBooleanString(node.getAttribute('nearestValue')),\n    'current': readBooleanString(node.getAttribute('current')),\n    'values': readString(node)\n  };\n  return dimensionObject;\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Online resource object.\n */\nfunction readFormatOnlineresource(node, objectStack) {\n  return pushParseAndPop({}, FORMAT_ONLINERESOURCE_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Request object.\n */\nfunction readRequest(node, objectStack) {\n  return pushParseAndPop({}, REQUEST_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} DCP type object.\n */\nfunction readDCPType(node, objectStack) {\n  return pushParseAndPop({}, DCPTYPE_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} HTTP object.\n */\nfunction readHTTP(node, objectStack) {\n  return pushParseAndPop({}, HTTP_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Operation type object.\n */\nfunction readOperationType(node, objectStack) {\n  return pushParseAndPop({}, OPERATIONTYPE_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Online resource object.\n */\nfunction readSizedFormatOnlineresource(node, objectStack) {\n  const formatOnlineresource = readFormatOnlineresource(node, objectStack);\n  if (formatOnlineresource) {\n    const size = [\n      readNonNegativeIntegerString(node.getAttribute('width')),\n      readNonNegativeIntegerString(node.getAttribute('height'))\n    ];\n    formatOnlineresource['size'] = size;\n    return formatOnlineresource;\n  }\n  return undefined;\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Authority URL object.\n */\nfunction readAuthorityURL(node, objectStack) {\n  const authorityObject = readFormatOnlineresource(node, objectStack);\n  if (authorityObject) {\n    authorityObject['name'] = node.getAttribute('name');\n    return authorityObject;\n  }\n  return undefined;\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Metadata URL object.\n */\nfunction readMetadataURL(node, objectStack) {\n  const metadataObject = readFormatOnlineresource(node, objectStack);\n  if (metadataObject) {\n    metadataObject['type'] = node.getAttribute('type');\n    return metadataObject;\n  }\n  return undefined;\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Style object.\n */\nfunction readStyle(node, objectStack) {\n  return pushParseAndPop({}, STYLE_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Array.<string>|undefined} Keyword list.\n */\nfunction readKeywordList(node, objectStack) {\n  return pushParseAndPop([], KEYWORDLIST_PARSERS, node, objectStack);\n}\n\n\nexport default WMSCapabilities;\n","/**\n * @module ol/format/WMSGetFeatureInfo\n */\nimport {extend, includes} from '../array.js';\nimport GML2 from '../format/GML2.js';\nimport XMLFeature from '../format/XMLFeature.js';\nimport {assign} from '../obj.js';\nimport {makeArrayPusher, makeStructureNS, pushParseAndPop} from '../xml.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {Array.<string>} [layers] If set, only features of the given layers will be returned by the format when read.\n */\n\n\n/**\n * @const\n * @type {string}\n */\nconst featureIdentifier = '_feature';\n\n\n/**\n * @const\n * @type {string}\n */\nconst layerIdentifier = '_layer';\n\n\n/**\n * @classdesc\n * Format for reading WMSGetFeatureInfo format. It uses\n * {@link module:ol/format/GML2~GML2} to read features.\n *\n * @api\n */\nclass WMSGetFeatureInfo extends XMLFeature {\n\n  /**\n   * @param {module:ol/format/WMSGetFeatureInfo~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n    super();\n\n    const options = opt_options ? opt_options : {};\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.featureNS_ = 'http://mapserver.gis.umn.edu/mapserver';\n\n\n    /**\n     * @private\n     * @type {module:ol/format/GML2}\n     */\n    this.gmlFormat_ = new GML2();\n\n\n    /**\n     * @private\n     * @type {Array.<string>}\n     */\n    this.layers_ = options.layers ? options.layers : null;\n  }\n\n  /**\n   * @return {Array.<string>} layers\n   */\n  getLayers() {\n    return this.layers_;\n  }\n\n  /**\n   * @param {Array.<string>} layers Layers to parse.\n   */\n  setLayers(layers) {\n    this.layers_ = layers;\n  }\n\n  /**\n   * @param {Node} node Node.\n   * @param {Array.<*>} objectStack Object stack.\n   * @return {Array.<module:ol/Feature>} Features.\n   * @private\n   */\n  readFeatures_(node, objectStack) {\n    node.setAttribute('namespaceURI', this.featureNS_);\n    const localName = node.localName;\n    /** @type {Array.<module:ol/Feature>} */\n    let features = [];\n    if (node.childNodes.length === 0) {\n      return features;\n    }\n    if (localName == 'msGMLOutput') {\n      for (let i = 0, ii = node.childNodes.length; i < ii; i++) {\n        const layer = node.childNodes[i];\n        if (layer.nodeType !== Node.ELEMENT_NODE) {\n          continue;\n        }\n        const context = objectStack[0];\n\n        const toRemove = layerIdentifier;\n        const layerName = layer.localName.replace(toRemove, '');\n\n        if (this.layers_ && !includes(this.layers_, layerName)) {\n          continue;\n        }\n\n        const featureType = layerName +\n            featureIdentifier;\n\n        context['featureType'] = featureType;\n        context['featureNS'] = this.featureNS_;\n\n        const parsers = {};\n        parsers[featureType] = makeArrayPusher(\n          this.gmlFormat_.readFeatureElement, this.gmlFormat_);\n        const parsersNS = makeStructureNS(\n          [context['featureNS'], null], parsers);\n        layer.setAttribute('namespaceURI', this.featureNS_);\n        const layerFeatures = pushParseAndPop(\n          [], parsersNS, layer, objectStack, this.gmlFormat_);\n        if (layerFeatures) {\n          extend(features, layerFeatures);\n        }\n      }\n    }\n    if (localName == 'FeatureCollection') {\n      const gmlFeatures = pushParseAndPop([],\n        this.gmlFormat_.FEATURE_COLLECTION_PARSERS, node,\n        [{}], this.gmlFormat_);\n      if (gmlFeatures) {\n        features = gmlFeatures;\n      }\n    }\n    return features;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFeaturesFromNode(node, opt_options) {\n    const options = {};\n    if (opt_options) {\n      assign(options, this.getReadOptions(node, opt_options));\n    }\n    return this.readFeatures_(node, [options]);\n  }\n\n  /**\n   * Not implemented.\n   * @inheritDoc\n   */\n  writeFeatureNode(feature, opt_options) {}\n\n  /**\n   * Not implemented.\n   * @inheritDoc\n   */\n  writeFeaturesNode(features, opt_options) {}\n\n  /**\n   * Not implemented.\n   * @inheritDoc\n   */\n  writeGeometryNode(geometry, opt_options) {}\n}\n\n\nexport default WMSGetFeatureInfo;\n","/**\n * @module ol/format/OWS\n */\nimport {readHref} from '../format/XLink.js';\nimport XML from '../format/XML.js';\nimport {readString} from '../format/xsd.js';\nimport {makeObjectPropertyPusher, makeObjectPropertySetter, makeStructureNS, pushParseAndPop} from '../xml.js';\n\n\n/**\n * @const\n * @type {Array.<null|string>}\n */\nconst NAMESPACE_URIS = [null, 'http://www.opengis.net/ows/1.1'];\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'ServiceIdentification': makeObjectPropertySetter(readServiceIdentification),\n    'ServiceProvider': makeObjectPropertySetter(readServiceProvider),\n    'OperationsMetadata': makeObjectPropertySetter(readOperationsMetadata)\n  });\n\n\nclass OWS extends XML {\n  constructor() {\n    super();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFromDocument(doc) {\n    for (let n = doc.firstChild; n; n = n.nextSibling) {\n      if (n.nodeType == Node.ELEMENT_NODE) {\n        return this.readFromNode(n);\n      }\n    }\n    return null;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFromNode(node) {\n    const owsObject = pushParseAndPop({},\n      PARSERS, node, []);\n    return owsObject ? owsObject : null;\n  }\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst ADDRESS_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'DeliveryPoint': makeObjectPropertySetter(readString),\n    'City': makeObjectPropertySetter(readString),\n    'AdministrativeArea': makeObjectPropertySetter(readString),\n    'PostalCode': makeObjectPropertySetter(readString),\n    'Country': makeObjectPropertySetter(readString),\n    'ElectronicMailAddress': makeObjectPropertySetter(readString)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst ALLOWED_VALUES_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Value': makeObjectPropertyPusher(readValue)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst CONSTRAINT_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'AllowedValues': makeObjectPropertySetter(readAllowedValues)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst CONTACT_INFO_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Phone': makeObjectPropertySetter(readPhone),\n    'Address': makeObjectPropertySetter(readAddress)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst DCP_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'HTTP': makeObjectPropertySetter(readHttp)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst HTTP_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Get': makeObjectPropertyPusher(readGet),\n    'Post': undefined // TODO\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst OPERATION_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'DCP': makeObjectPropertySetter(readDcp)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst OPERATIONS_METADATA_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Operation': readOperation\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst PHONE_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Voice': makeObjectPropertySetter(readString),\n    'Facsimile': makeObjectPropertySetter(readString)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst REQUEST_METHOD_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Constraint': makeObjectPropertyPusher(readConstraint)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst SERVICE_CONTACT_PARSERS =\n    makeStructureNS(\n      NAMESPACE_URIS, {\n        'IndividualName': makeObjectPropertySetter(readString),\n        'PositionName': makeObjectPropertySetter(readString),\n        'ContactInfo': makeObjectPropertySetter(readContactInfo)\n      });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst SERVICE_IDENTIFICATION_PARSERS =\n    makeStructureNS(\n      NAMESPACE_URIS, {\n        'Abstract': makeObjectPropertySetter(readString),\n        'AccessConstraints': makeObjectPropertySetter(readString),\n        'Fees': makeObjectPropertySetter(readString),\n        'Title': makeObjectPropertySetter(readString),\n        'ServiceTypeVersion': makeObjectPropertySetter(readString),\n        'ServiceType': makeObjectPropertySetter(readString)\n      });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst SERVICE_PROVIDER_PARSERS =\n    makeStructureNS(\n      NAMESPACE_URIS, {\n        'ProviderName': makeObjectPropertySetter(readString),\n        'ProviderSite': makeObjectPropertySetter(readHref),\n        'ServiceContact': makeObjectPropertySetter(readServiceContact)\n      });\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} The address.\n */\nfunction readAddress(node, objectStack) {\n  return pushParseAndPop({},\n    ADDRESS_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} The values.\n */\nfunction readAllowedValues(node, objectStack) {\n  return pushParseAndPop({},\n    ALLOWED_VALUES_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} The constraint.\n */\nfunction readConstraint(node, objectStack) {\n  const name = node.getAttribute('name');\n  if (!name) {\n    return undefined;\n  }\n  return pushParseAndPop({'name': name},\n    CONSTRAINT_PARSERS, node,\n    objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} The contact info.\n */\nfunction readContactInfo(node, objectStack) {\n  return pushParseAndPop({},\n    CONTACT_INFO_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} The DCP.\n */\nfunction readDcp(node, objectStack) {\n  return pushParseAndPop({},\n    DCP_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} The GET object.\n */\nfunction readGet(node, objectStack) {\n  const href = readHref(node);\n  if (!href) {\n    return undefined;\n  }\n  return pushParseAndPop({'href': href},\n    REQUEST_METHOD_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} The HTTP object.\n */\nfunction readHttp(node, objectStack) {\n  return pushParseAndPop({}, HTTP_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} The operation.\n */\nfunction readOperation(node, objectStack) {\n  const name = node.getAttribute('name');\n  const value = pushParseAndPop({},\n    OPERATION_PARSERS, node, objectStack);\n  if (!value) {\n    return undefined;\n  }\n  const object = /** @type {Object} */\n      (objectStack[objectStack.length - 1]);\n  object[name] = value;\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} The operations metadata.\n */\nfunction readOperationsMetadata(node, objectStack) {\n  return pushParseAndPop({},\n    OPERATIONS_METADATA_PARSERS, node,\n    objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} The phone.\n */\nfunction readPhone(node, objectStack) {\n  return pushParseAndPop({},\n    PHONE_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} The service identification.\n */\nfunction readServiceIdentification(node, objectStack) {\n  return pushParseAndPop(\n    {}, SERVICE_IDENTIFICATION_PARSERS, node,\n    objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} The service contact.\n */\nfunction readServiceContact(node, objectStack) {\n  return pushParseAndPop(\n    {}, SERVICE_CONTACT_PARSERS, node,\n    objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} The service provider.\n */\nfunction readServiceProvider(node, objectStack) {\n  return pushParseAndPop(\n    {}, SERVICE_PROVIDER_PARSERS, node,\n    objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {string|undefined} The value.\n */\nfunction readValue(node, objectStack) {\n  return readString(node);\n}\n\n\nexport default OWS;\n","/**\n * @module ol/format/WMTSCapabilities\n */\nimport {boundingExtent} from '../extent.js';\nimport OWS from '../format/OWS.js';\nimport {readHref} from '../format/XLink.js';\nimport XML from '../format/XML.js';\nimport {readString, readNonNegativeInteger, readDecimal} from '../format/xsd.js';\nimport {pushParseAndPop, makeStructureNS,\n  makeObjectPropertySetter, makeObjectPropertyPusher, makeArrayPusher} from '../xml.js';\n\n\n/**\n * @const\n * @type {Array.<null|string>}\n */\nconst NAMESPACE_URIS = [\n  null,\n  'http://www.opengis.net/wmts/1.0'\n];\n\n\n/**\n * @const\n * @type {Array.<null|string>}\n */\nconst OWS_NAMESPACE_URIS = [\n  null,\n  'http://www.opengis.net/ows/1.1'\n];\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Contents': makeObjectPropertySetter(readContents)\n  });\n\n\n/**\n * @classdesc\n * Format for reading WMTS capabilities data.\n *\n  * @api\n */\nclass WMTSCapabilities extends XML {\n  constructor() {\n    super();\n\n    /**\n     * @type {module:ol/format/OWS}\n     * @private\n     */\n    this.owsParser_ = new OWS();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFromDocument(doc) {\n    for (let n = doc.firstChild; n; n = n.nextSibling) {\n      if (n.nodeType == Node.ELEMENT_NODE) {\n        return this.readFromNode(n);\n      }\n    }\n    return null;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  readFromNode(node) {\n    const version = node.getAttribute('version').trim();\n    let WMTSCapabilityObject = this.owsParser_.readFromNode(node);\n    if (!WMTSCapabilityObject) {\n      return null;\n    }\n    WMTSCapabilityObject['version'] = version;\n    WMTSCapabilityObject = pushParseAndPop(WMTSCapabilityObject, PARSERS, node, []);\n    return WMTSCapabilityObject ? WMTSCapabilityObject : null;\n  }\n}\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst CONTENTS_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Layer': makeObjectPropertyPusher(readLayer),\n    'TileMatrixSet': makeObjectPropertyPusher(readTileMatrixSet)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst LAYER_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Style': makeObjectPropertyPusher(readStyle),\n    'Format': makeObjectPropertyPusher(readString),\n    'TileMatrixSetLink': makeObjectPropertyPusher(readTileMatrixSetLink),\n    'Dimension': makeObjectPropertyPusher(readDimensions),\n    'ResourceURL': makeObjectPropertyPusher(readResourceUrl)\n  }, makeStructureNS(OWS_NAMESPACE_URIS, {\n    'Title': makeObjectPropertySetter(readString),\n    'Abstract': makeObjectPropertySetter(readString),\n    'WGS84BoundingBox': makeObjectPropertySetter(readWgs84BoundingBox),\n    'Identifier': makeObjectPropertySetter(readString)\n  }));\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst STYLE_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'LegendURL': makeObjectPropertyPusher(readLegendUrl)\n  }, makeStructureNS(OWS_NAMESPACE_URIS, {\n    'Title': makeObjectPropertySetter(readString),\n    'Identifier': makeObjectPropertySetter(readString)\n  }));\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst TMS_LINKS_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'TileMatrixSet': makeObjectPropertySetter(readString),\n    'TileMatrixSetLimits': makeObjectPropertySetter(readTileMatrixLimitsList)\n  });\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst TMS_LIMITS_LIST_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'TileMatrixLimits': makeArrayPusher(readTileMatrixLimits)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst TMS_LIMITS_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'TileMatrix': makeObjectPropertySetter(readString),\n    'MinTileRow': makeObjectPropertySetter(readNonNegativeInteger),\n    'MaxTileRow': makeObjectPropertySetter(readNonNegativeInteger),\n    'MinTileCol': makeObjectPropertySetter(readNonNegativeInteger),\n    'MaxTileCol': makeObjectPropertySetter(readNonNegativeInteger)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst DIMENSION_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'Default': makeObjectPropertySetter(readString),\n    'Value': makeObjectPropertyPusher(readString)\n  }, makeStructureNS(OWS_NAMESPACE_URIS, {\n    'Identifier': makeObjectPropertySetter(readString)\n  }));\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst WGS84_BBOX_READERS = makeStructureNS(\n  OWS_NAMESPACE_URIS, {\n    'LowerCorner': makeArrayPusher(readCoordinates),\n    'UpperCorner': makeArrayPusher(readCoordinates)\n  });\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst TMS_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'WellKnownScaleSet': makeObjectPropertySetter(readString),\n    'TileMatrix': makeObjectPropertyPusher(readTileMatrix)\n  }, makeStructureNS(OWS_NAMESPACE_URIS, {\n    'SupportedCRS': makeObjectPropertySetter(readString),\n    'Identifier': makeObjectPropertySetter(readString)\n  }));\n\n\n/**\n * @const\n * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}\n */\nconst TM_PARSERS = makeStructureNS(\n  NAMESPACE_URIS, {\n    'TopLeftCorner': makeObjectPropertySetter(readCoordinates),\n    'ScaleDenominator': makeObjectPropertySetter(readDecimal),\n    'TileWidth': makeObjectPropertySetter(readNonNegativeInteger),\n    'TileHeight': makeObjectPropertySetter(readNonNegativeInteger),\n    'MatrixWidth': makeObjectPropertySetter(readNonNegativeInteger),\n    'MatrixHeight': makeObjectPropertySetter(readNonNegativeInteger)\n  }, makeStructureNS(OWS_NAMESPACE_URIS, {\n    'Identifier': makeObjectPropertySetter(readString)\n  }));\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Attribution object.\n */\nfunction readContents(node, objectStack) {\n  return pushParseAndPop({}, CONTENTS_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Layers object.\n */\nfunction readLayer(node, objectStack) {\n  return pushParseAndPop({}, LAYER_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Tile Matrix Set object.\n */\nfunction readTileMatrixSet(node, objectStack) {\n  return pushParseAndPop({}, TMS_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Style object.\n */\nfunction readStyle(node, objectStack) {\n  const style = pushParseAndPop({}, STYLE_PARSERS, node, objectStack);\n  if (!style) {\n    return undefined;\n  }\n  const isDefault = node.getAttribute('isDefault') === 'true';\n  style['isDefault'] = isDefault;\n  return style;\n\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Tile Matrix Set Link object.\n */\nfunction readTileMatrixSetLink(node, objectStack) {\n  return pushParseAndPop({}, TMS_LINKS_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Dimension object.\n */\nfunction readDimensions(node, objectStack) {\n  return pushParseAndPop({}, DIMENSION_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Resource URL object.\n */\nfunction readResourceUrl(node, objectStack) {\n  const format = node.getAttribute('format');\n  const template = node.getAttribute('template');\n  const resourceType = node.getAttribute('resourceType');\n  const resource = {};\n  if (format) {\n    resource['format'] = format;\n  }\n  if (template) {\n    resource['template'] = template;\n  }\n  if (resourceType) {\n    resource['resourceType'] = resourceType;\n  }\n  return resource;\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} WGS84 BBox object.\n */\nfunction readWgs84BoundingBox(node, objectStack) {\n  const coordinates = pushParseAndPop([], WGS84_BBOX_READERS, node, objectStack);\n  if (coordinates.length != 2) {\n    return undefined;\n  }\n  return boundingExtent(coordinates);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Legend object.\n */\nfunction readLegendUrl(node, objectStack) {\n  const legend = {};\n  legend['format'] = node.getAttribute('format');\n  legend['href'] = readHref(node);\n  return legend;\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} Coordinates object.\n */\nfunction readCoordinates(node, objectStack) {\n  const coordinates = readString(node).split(' ');\n  if (!coordinates || coordinates.length != 2) {\n    return undefined;\n  }\n  const x = +coordinates[0];\n  const y = +coordinates[1];\n  if (isNaN(x) || isNaN(y)) {\n    return undefined;\n  }\n  return [x, y];\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} TileMatrix object.\n */\nfunction readTileMatrix(node, objectStack) {\n  return pushParseAndPop({}, TM_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} TileMatrixSetLimits Object.\n */\nfunction readTileMatrixLimitsList(node, objectStack) {\n  return pushParseAndPop([], TMS_LIMITS_LIST_PARSERS, node, objectStack);\n}\n\n\n/**\n * @param {Node} node Node.\n * @param {Array.<*>} objectStack Object stack.\n * @return {Object|undefined} TileMatrixLimits Array.\n */\nfunction readTileMatrixLimits(node, objectStack) {\n  return pushParseAndPop({}, TMS_LIMITS_PARSERS, node, objectStack);\n}\n\n\nexport default WMTSCapabilities;\n","/**\n * @module ol/layer/Heatmap\n */\nimport {listen} from '../events.js';\nimport {getChangeEventType} from '../Object.js';\nimport {createCanvasContext2D} from '../dom.js';\nimport VectorLayer from '../layer/Vector.js';\nimport {clamp} from '../math.js';\nimport {assign} from '../obj.js';\nimport RenderEventType from '../render/EventType.js';\nimport Icon from '../style/Icon.js';\nimport Style from '../style/Style.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {module:ol/extent~Extent} [extent] The bounding extent for layer rendering.  The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex=0] The z-index for layer rendering.  At rendering time, the layers\n * will be ordered, first by Z-index and then by position.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {Array.<string>} [gradient=['#00f', '#0ff', '#0f0', '#ff0', '#f00']] The color gradient\n * of the heatmap, specified as an array of CSS color strings.\n * @property {number} [radius=8] Radius size in pixels.\n * @property {number} [blur=15] Blur size in pixels.\n * @property {number} [shadow=250] Shadow size in pixels.\n * @property {string|function(module:ol/Feature):number} [weight='weight'] The feature\n * attribute to use for the weight or a function that returns a weight from a feature. Weight values\n * should range from 0 to 1 (and values outside will be clamped to that range).\n * @property {module:ol/layer/VectorRenderType|string} [renderMode='vector'] Render mode for vector layers:\n *  * `'image'`: Vector layers are rendered as images. Great performance, but point symbols and\n *    texts are always rotated with the view and pixels are scaled during zoom animations.\n *  * `'vector'`: Vector layers are rendered as vectors. Most accurate rendering even during\n *    animations, but slower performance.\n * @property {module:ol/source/Vector} [source] Source.\n */\n\n\n/**\n * @enum {string}\n * @private\n */\nconst Property = {\n  BLUR: 'blur',\n  GRADIENT: 'gradient',\n  RADIUS: 'radius'\n};\n\n\n/**\n * @const\n * @type {Array.<string>}\n */\nconst DEFAULT_GRADIENT = ['#00f', '#0ff', '#0f0', '#ff0', '#f00'];\n\n\n/**\n * @classdesc\n * Layer for rendering vector data as a heatmap.\n * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}\n * property on the layer object; for example, setting `title: 'My Title'` in the\n * options means that `title` is observable, and has get/set accessors.\n *\n * @fires module:ol/render/Event~RenderEvent\n * @api\n */\nclass Heatmap extends VectorLayer {\n  /**\n   * @param {module:ol/layer/Heatmap~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n    const options = opt_options ? opt_options : {};\n\n    const baseOptions = assign({}, options);\n\n    delete baseOptions.gradient;\n    delete baseOptions.radius;\n    delete baseOptions.blur;\n    delete baseOptions.shadow;\n    delete baseOptions.weight;\n    super(baseOptions);\n\n    /**\n     * @private\n     * @type {Uint8ClampedArray}\n     */\n    this.gradient_ = null;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.shadow_ = options.shadow !== undefined ? options.shadow : 250;\n\n    /**\n     * @private\n     * @type {string|undefined}\n     */\n    this.circleImage_ = undefined;\n\n    /**\n     * @private\n     * @type {Array.<Array.<module:ol/style/Style>>}\n     */\n    this.styleCache_ = null;\n\n    listen(this,\n      getChangeEventType(Property.GRADIENT),\n      this.handleGradientChanged_, this);\n\n    this.setGradient(options.gradient ? options.gradient : DEFAULT_GRADIENT);\n\n    this.setBlur(options.blur !== undefined ? options.blur : 15);\n\n    this.setRadius(options.radius !== undefined ? options.radius : 8);\n\n    listen(this,\n      getChangeEventType(Property.BLUR),\n      this.handleStyleChanged_, this);\n    listen(this,\n      getChangeEventType(Property.RADIUS),\n      this.handleStyleChanged_, this);\n\n    this.handleStyleChanged_();\n\n    const weight = options.weight ? options.weight : 'weight';\n    let weightFunction;\n    if (typeof weight === 'string') {\n      weightFunction = function(feature) {\n        return feature.get(weight);\n      };\n    } else {\n      weightFunction = weight;\n    }\n\n    this.setStyle(function(feature, resolution) {\n      const weight = weightFunction(feature);\n      const opacity = weight !== undefined ? clamp(weight, 0, 1) : 1;\n      // cast to 8 bits\n      const index = (255 * opacity) | 0;\n      let style = this.styleCache_[index];\n      if (!style) {\n        style = [\n          new Style({\n            image: new Icon({\n              opacity: opacity,\n              src: this.circleImage_\n            })\n          })\n        ];\n        this.styleCache_[index] = style;\n      }\n      return style;\n    }.bind(this));\n\n    // For performance reasons, don't sort the features before rendering.\n    // The render order is not relevant for a heatmap representation.\n    this.setRenderOrder(null);\n\n    listen(this, RenderEventType.RENDER, this.handleRender_, this);\n  }\n\n  /**\n   * @return {string} Data URL for a circle.\n   * @private\n   */\n  createCircle_() {\n    const radius = this.getRadius();\n    const blur = this.getBlur();\n    const halfSize = radius + blur + 1;\n    const size = 2 * halfSize;\n    const context = createCanvasContext2D(size, size);\n    context.shadowOffsetX = context.shadowOffsetY = this.shadow_;\n    context.shadowBlur = blur;\n    context.shadowColor = '#000';\n    context.beginPath();\n    const center = halfSize - this.shadow_;\n    context.arc(center, center, radius, 0, Math.PI * 2, true);\n    context.fill();\n    return context.canvas.toDataURL();\n  }\n\n  /**\n   * Return the blur size in pixels.\n   * @return {number} Blur size in pixels.\n   * @api\n   * @observable\n   */\n  getBlur() {\n    return /** @type {number} */ (this.get(Property.BLUR));\n  }\n\n  /**\n   * Return the gradient colors as array of strings.\n   * @return {Array.<string>} Colors.\n   * @api\n   * @observable\n   */\n  getGradient() {\n    return /** @type {Array.<string>} */ (this.get(Property.GRADIENT));\n  }\n\n  /**\n   * Return the size of the radius in pixels.\n   * @return {number} Radius size in pixel.\n   * @api\n   * @observable\n   */\n  getRadius() {\n    return /** @type {number} */ (this.get(Property.RADIUS));\n  }\n\n  /**\n   * @private\n   */\n  handleGradientChanged_() {\n    this.gradient_ = createGradient(this.getGradient());\n  }\n\n  /**\n   * @private\n   */\n  handleStyleChanged_() {\n    this.circleImage_ = this.createCircle_();\n    this.styleCache_ = new Array(256);\n    this.changed();\n  }\n\n  /**\n   * @param {module:ol/render/Event} event Post compose event\n   * @private\n   */\n  handleRender_(event) {\n    const context = event.context;\n    const canvas = context.canvas;\n    const image = context.getImageData(0, 0, canvas.width, canvas.height);\n    const view8 = image.data;\n    for (let i = 0, ii = view8.length; i < ii; i += 4) {\n      const alpha = view8[i + 3] * 4;\n      if (alpha) {\n        view8[i] = this.gradient_[alpha];\n        view8[i + 1] = this.gradient_[alpha + 1];\n        view8[i + 2] = this.gradient_[alpha + 2];\n      }\n    }\n    context.putImageData(image, 0, 0);\n  }\n\n  /**\n   * Set the blur size in pixels.\n   * @param {number} blur Blur size in pixels.\n   * @api\n   * @observable\n   */\n  setBlur(blur) {\n    this.set(Property.BLUR, blur);\n  }\n\n  /**\n   * Set the gradient colors as array of strings.\n   * @param {Array.<string>} colors Gradient.\n   * @api\n   * @observable\n   */\n  setGradient(colors) {\n    this.set(Property.GRADIENT, colors);\n  }\n\n  /**\n   * Set the size of the radius in pixels.\n   * @param {number} radius Radius size in pixel.\n   * @api\n   * @observable\n   */\n  setRadius(radius) {\n    this.set(Property.RADIUS, radius);\n  }\n}\n\n\n/**\n * @param {Array.<string>} colors A list of colored.\n * @return {Uint8ClampedArray} An array.\n */\nfunction createGradient(colors) {\n  const width = 1;\n  const height = 256;\n  const context = createCanvasContext2D(width, height);\n\n  const gradient = context.createLinearGradient(0, 0, width, height);\n  const step = 1 / (colors.length - 1);\n  for (let i = 0, ii = colors.length; i < ii; ++i) {\n    gradient.addColorStop(i * step, colors[i]);\n  }\n\n  context.fillStyle = gradient;\n  context.fillRect(0, 0, width, height);\n\n  return context.getImageData(0, 0, width, height).data;\n}\n\n\nexport default Heatmap;\n","/**\n * @module ol/layer/Image\n */\nimport LayerType from '../LayerType.js';\nimport Layer from '../layer/Layer.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {module:ol/extent~Extent} [extent] The bounding extent for layer rendering.  The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex=0] The z-index for layer rendering.  At rendering time, the layers\n * will be ordered, first by Z-index and then by position.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {module:ol/PluggableMap} [map] Sets the layer as overlay on a map. The map will not manage\n * this layer in its layers collection, and the layer will be rendered on top. This is useful for\n * temporary layers. The standard way to add a layer to a map and have it managed by the map is to\n * use {@link module:ol/Map#addLayer}.\n * @property {module:ol/source/Image} [source] Source for this layer.\n */\n\n\n/**\n * @classdesc\n * Server-rendered images that are available for arbitrary extents and\n * resolutions.\n * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}\n * property on the layer object; for example, setting `title: 'My Title'` in the\n * options means that `title` is observable, and has get/set accessors.\n *\n * @fires module:ol/render/Event~RenderEvent\n * @api\n */\nclass ImageLayer extends Layer {\n\n  /**\n   * @param {module:ol/layer/Image~Options=} opt_options Layer options.\n   */\n  constructor(opt_options) {\n    const options = opt_options ? opt_options : {};\n    super(options);\n\n    /**\n     * The layer type.\n     * @protected\n     * @type {module:ol/LayerType}\n     */\n    this.type = LayerType.IMAGE;\n\n  }\n\n}\n\n\n/**\n * Return the associated {@link module:ol/source/Image source} of the image layer.\n * @function\n * @return {module:ol/source/Image} Source.\n * @api\n */\nImageLayer.prototype.getSource;\nexport default ImageLayer;\n","/**\n * @module ol/layer/TileProperty\n */\n\n/**\n * @enum {string}\n */\nexport default {\n  PRELOAD: 'preload',\n  USE_INTERIM_TILES_ON_ERROR: 'useInterimTilesOnError'\n};\n","/**\n * @module ol/layer/Tile\n */\nimport LayerType from '../LayerType.js';\nimport Layer from '../layer/Layer.js';\nimport TileProperty from '../layer/TileProperty.js';\nimport {assign} from '../obj.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {module:ol/extent~Extent} [extent] The bounding extent for layer rendering.  The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex=0] The z-index for layer rendering.  At rendering time, the layers\n * will be ordered, first by Z-index and then by position.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [preload=0] Preload. Load low-resolution tiles up to `preload` levels. `0`\n * means no preloading.\n * @property {module:ol/source/Tile} [source] Source for this layer.\n * @property {module:ol/PluggableMap} [map] Sets the layer as overlay on a map. The map will not manage\n * this layer in its layers collection, and the layer will be rendered on top. This is useful for\n * temporary layers. The standard way to add a layer to a map and have it managed by the map is to\n * use {@link module:ol/Map#addLayer}.\n * @property {boolean} [useInterimTilesOnError=true] Use interim tiles on error.\n */\n\n/**\n * @classdesc\n * For layer sources that provide pre-rendered, tiled images in grids that are\n * organized by zoom levels for specific resolutions.\n * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}\n * property on the layer object; for example, setting `title: 'My Title'` in the\n * options means that `title` is observable, and has get/set accessors.\n *\n * @api\n */\nclass TileLayer extends Layer {\n  /**\n   * @param {module:ol/layer/Tile~Options=} opt_options Tile layer options.\n   */\n  constructor(opt_options) {\n    const options = opt_options ? opt_options : {};\n\n    const baseOptions = assign({}, options);\n\n    delete baseOptions.preload;\n    delete baseOptions.useInterimTilesOnError;\n    super(baseOptions);\n\n    this.setPreload(options.preload !== undefined ? options.preload : 0);\n    this.setUseInterimTilesOnError(options.useInterimTilesOnError !== undefined ?\n      options.useInterimTilesOnError : true);\n\n    /**\n    * The layer type.\n    * @protected\n    * @type {module:ol/LayerType}\n    */\n    this.type = LayerType.TILE;\n\n  }\n\n  /**\n  * Return the level as number to which we will preload tiles up to.\n  * @return {number} The level to preload tiles up to.\n  * @observable\n  * @api\n  */\n  getPreload() {\n    return /** @type {number} */ (this.get(TileProperty.PRELOAD));\n  }\n\n  /**\n  * Set the level as number to which we will preload tiles up to.\n  * @param {number} preload The level to preload tiles up to.\n  * @observable\n  * @api\n  */\n  setPreload(preload) {\n    this.set(TileProperty.PRELOAD, preload);\n  }\n\n  /**\n  * Whether we use interim tiles on error.\n  * @return {boolean} Use interim tiles on error.\n  * @observable\n  * @api\n  */\n  getUseInterimTilesOnError() {\n    return /** @type {boolean} */ (this.get(TileProperty.USE_INTERIM_TILES_ON_ERROR));\n  }\n\n  /**\n  * Set whether we use interim tiles on error.\n  * @param {boolean} useInterimTilesOnError Use interim tiles on error.\n  * @observable\n  * @api\n  */\n  setUseInterimTilesOnError(useInterimTilesOnError) {\n    this.set(TileProperty.USE_INTERIM_TILES_ON_ERROR, useInterimTilesOnError);\n  }\n}\n\n\n/**\n * Return the associated {@link module:ol/source/Tile tilesource} of the layer.\n * @function\n * @return {module:ol/source/Tile} Source.\n * @api\n */\nTileLayer.prototype.getSource;\n\n\nexport default TileLayer;\n","/**\n * @module ol/layer/VectorTile\n */\nimport LayerType from '../LayerType.js';\nimport {assert} from '../asserts.js';\nimport TileProperty from '../layer/TileProperty.js';\nimport VectorLayer from '../layer/Vector.js';\nimport VectorTileRenderType from '../layer/VectorTileRenderType.js';\nimport {assign} from '../obj.js';\n\n\n/**\n * @enum {string}\n * Render mode for vector tiles:\n *  * `'image'`: Vector tiles are rendered as images. Great performance, but\n *    point symbols and texts are always rotated with the view and pixels are\n *    scaled during zoom animations.\n *  * `'hybrid'`: Polygon and line elements are rendered as images, so pixels\n *    are scaled during zoom animations. Point symbols and texts are accurately\n *    rendered as vectors and can stay upright on rotated views.\n *  * `'vector'`: Vector tiles are rendered as vectors. Most accurate rendering\n *    even during animations, but slower performance than the other options.\n * @api\n */\nexport const RenderType = {\n  IMAGE: 'image',\n  HYBRID: 'hybrid',\n  VECTOR: 'vector'\n};\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {module:ol/extent~Extent} [extent] The bounding extent for layer rendering.  The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex=0] The z-index for layer rendering.  At rendering time, the layers\n * will be ordered, first by Z-index and then by position.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {module:ol/render~OrderFunction} [renderOrder] Render order. Function to be used when sorting\n * features before rendering. By default features are drawn in the order that they are created. Use\n * `null` to avoid the sort, but get an undefined draw order.\n * @property {number} [renderBuffer=100] The buffer in pixels around the tile extent used by the\n * renderer when getting features from the vector tile for the rendering or hit-detection.\n * Recommended value: Vector tiles are usually generated with a buffer, so this value should match\n * the largest possible buffer of the used tiles. It should be at least the size of the largest\n * point symbol or line width.\n * @property {module:ol/layer/VectorTileRenderType|string} [renderMode='hybrid'] Render mode for vector tiles:\n *  * `'image'`: Vector tiles are rendered as images. Great performance, but point symbols and texts\n *    are always rotated with the view and pixels are scaled during zoom animations.\n *  * `'hybrid'`: Polygon and line elements are rendered as images, so pixels are scaled during zoom\n *    animations. Point symbols and texts are accurately rendered as vectors and can stay upright on\n *    rotated views.\n *  * `'vector'`: Vector tiles are rendered as vectors. Most accurate rendering even during\n *    animations, but slower performance than the other options.\n *\n * When `declutter` is set to `true`, `'hybrid'` will be used instead of `'image'`.\n * @property {module:ol/source/VectorTile} [source] Source.\n * @property {module:ol/PluggableMap} [map] Sets the layer as overlay on a map. The map will not manage\n * this layer in its layers collection, and the layer will be rendered on top. This is useful for\n * temporary layers. The standard way to add a layer to a map and have it managed by the map is to\n * use {@link module:ol/Map#addLayer}.\n * @property {boolean} [declutter=false] Declutter images and text. Decluttering is applied to all\n * image and text styles, and the priority is defined by the z-index of the style. Lower z-index\n * means higher priority. When set to `true`, a `renderMode` of `'image'` will be overridden with\n * `'hybrid'`.\n * @property {module:ol/style/Style|Array.<module:ol/style/Style>|module:ol/style/Style~StyleFunction} [style] Layer style. See\n * {@link module:ol/style} for default style which will be used if this is not defined.\n * @property {boolean} [updateWhileAnimating=false] When set to `true`, feature batches will be\n * recreated during animations. This means that no vectors will be shown clipped, but the setting\n * will have a performance impact for large amounts of vector data. When set to `false`, batches\n * will be recreated when no animation is active.\n * @property {boolean} [updateWhileInteracting=false] When set to `true`, feature batches will be\n * recreated during interactions. See also `updateWhileAnimating`.\n * @property {number} [preload=0] Preload. Load low-resolution tiles up to `preload` levels. `0`\n * means no preloading.\n * @property {module:ol/render~OrderFunction} [renderOrder] Render order. Function to be used when sorting\n * features before rendering. By default features are drawn in the order that they are created.\n * @property {(module:ol/style/Style|Array.<module:ol/style/Style>|module:ol/style/Style~StyleFunction)} [style] Layer style. See\n * {@link module:ol/style} for default style which will be used if this is not defined.\n * @property {boolean} [useInterimTilesOnError=true] Use interim tiles on error.\n */\n\n\n/**\n * @classdesc\n * Layer for vector tile data that is rendered client-side.\n * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}\n * property on the layer object; for example, setting `title: 'My Title'` in the\n * options means that `title` is observable, and has get/set accessors.\n *\n * @param {module:ol/layer/VectorTile~Options=} opt_options Options.\n * @api\n */\nclass VectorTileLayer extends VectorLayer {\n  /**\n   * @param {module:ol/layer/VectorTile~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n    const options = opt_options ? opt_options : {};\n\n    let renderMode = options.renderMode || VectorTileRenderType.HYBRID;\n    assert(renderMode == undefined ||\n       renderMode == VectorTileRenderType.IMAGE ||\n       renderMode == VectorTileRenderType.HYBRID ||\n       renderMode == VectorTileRenderType.VECTOR,\n    28); // `renderMode` must be `'image'`, `'hybrid'` or `'vector'`\n    if (options.declutter && renderMode == VectorTileRenderType.IMAGE) {\n      renderMode = VectorTileRenderType.HYBRID;\n    }\n    options.renderMode = renderMode;\n\n    const baseOptions = assign({}, options);\n\n    delete baseOptions.preload;\n    delete baseOptions.useInterimTilesOnError;\n    super(baseOptions);\n\n    this.setPreload(options.preload ? options.preload : 0);\n    this.setUseInterimTilesOnError(options.useInterimTilesOnError !== undefined ?\n      options.useInterimTilesOnError : true);\n\n    /**\n    * The layer type.\n    * @protected\n    * @type {module:ol/LayerType}\n    */\n    this.type = LayerType.VECTOR_TILE;\n\n  }\n\n  /**\n  * Return the level as number to which we will preload tiles up to.\n  * @return {number} The level to preload tiles up to.\n  * @observable\n  * @api\n  */\n  getPreload() {\n    return /** @type {number} */ (this.get(TileProperty.PRELOAD));\n  }\n\n  /**\n  * Whether we use interim tiles on error.\n  * @return {boolean} Use interim tiles on error.\n  * @observable\n  * @api\n  */\n  getUseInterimTilesOnError() {\n    return /** @type {boolean} */ (this.get(TileProperty.USE_INTERIM_TILES_ON_ERROR));\n  }\n\n  /**\n  * Set the level as number to which we will preload tiles up to.\n  * @param {number} preload The level to preload tiles up to.\n  * @observable\n  * @api\n  */\n  setPreload(preload) {\n    this.set(TileProperty.PRELOAD, preload);\n  }\n\n  /**\n  * Set whether we use interim tiles on error.\n  * @param {boolean} useInterimTilesOnError Use interim tiles on error.\n  * @observable\n  * @api\n  */\n  setUseInterimTilesOnError(useInterimTilesOnError) {\n    this.set(TileProperty.USE_INTERIM_TILES_ON_ERROR, useInterimTilesOnError);\n  }\n}\n\n\n/**\n * Return the associated {@link module:ol/source/VectorTile vectortilesource} of the layer.\n * @function\n * @return {module:ol/source/VectorTile} Source.\n * @api\n */\nVectorTileLayer.prototype.getSource;\nexport default VectorTileLayer;\n","/**\n * @module ol/tilecoord\n */\n\n\n/**\n * An array of three numbers representing the location of a tile in a tile\n * grid. The order is `z`, `x`, and `y`. `z` is the zoom level.\n * @typedef {Array.<number>} TileCoord\n * @api\n */\n\n\n/**\n * @param {number} z Z.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {module:ol/tilecoord~TileCoord=} opt_tileCoord Tile coordinate.\n * @return {module:ol/tilecoord~TileCoord} Tile coordinate.\n */\nexport function createOrUpdate(z, x, y, opt_tileCoord) {\n  if (opt_tileCoord !== undefined) {\n    opt_tileCoord[0] = z;\n    opt_tileCoord[1] = x;\n    opt_tileCoord[2] = y;\n    return opt_tileCoord;\n  } else {\n    return [z, x, y];\n  }\n}\n\n\n/**\n * @param {number} z Z.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {string} Key.\n */\nexport function getKeyZXY(z, x, y) {\n  return z + '/' + x + '/' + y;\n}\n\n\n/**\n * Get the key for a tile coord.\n * @param {module:ol/tilecoord~TileCoord} tileCoord The tile coord.\n * @return {string} Key.\n */\nexport function getKey(tileCoord) {\n  return getKeyZXY(tileCoord[0], tileCoord[1], tileCoord[2]);\n}\n\n\n/**\n * Get a tile coord given a key.\n * @param {string} key The tile coord key.\n * @return {module:ol/tilecoord~TileCoord} The tile coord.\n */\nexport function fromKey(key) {\n  return key.split('/').map(Number);\n}\n\n\n/**\n * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coord.\n * @return {number} Hash.\n */\nexport function hash(tileCoord) {\n  return (tileCoord[1] << tileCoord[0]) + tileCoord[2];\n}\n\n\n/**\n * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coord.\n * @return {string} Quad key.\n */\nexport function quadKey(tileCoord) {\n  const z = tileCoord[0];\n  const digits = new Array(z);\n  let mask = 1 << (z - 1);\n  let i, charCode;\n  for (i = 0; i < z; ++i) {\n    // 48 is charCode for 0 - '0'.charCodeAt(0)\n    charCode = 48;\n    if (tileCoord[1] & mask) {\n      charCode += 1;\n    }\n    if (tileCoord[2] & mask) {\n      charCode += 2;\n    }\n    digits[i] = String.fromCharCode(charCode);\n    mask >>= 1;\n  }\n  return digits.join('');\n}\n\n\n/**\n * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n * @param {!module:ol/tilegrid/TileGrid} tileGrid Tile grid.\n * @return {boolean} Tile coordinate is within extent and zoom level range.\n */\nexport function withinExtentAndZ(tileCoord, tileGrid) {\n  const z = tileCoord[0];\n  const x = tileCoord[1];\n  const y = tileCoord[2];\n\n  if (tileGrid.getMinZoom() > z || z > tileGrid.getMaxZoom()) {\n    return false;\n  }\n  const extent = tileGrid.getExtent();\n  let tileRange;\n  if (!extent) {\n    tileRange = tileGrid.getFullTileRange(z);\n  } else {\n    tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);\n  }\n  if (!tileRange) {\n    return true;\n  } else {\n    return tileRange.containsXY(x, y);\n  }\n}\n","/**\n * @module ol/tileurlfunction\n */\nimport {assert} from './asserts.js';\nimport {modulo} from './math.js';\nimport {hash as tileCoordHash} from './tilecoord.js';\n\n\n/**\n * @param {string} template Template.\n * @param {module:ol/tilegrid/TileGrid} tileGrid Tile grid.\n * @return {module:ol/Tile~UrlFunction} Tile URL function.\n */\nexport function createFromTemplate(template, tileGrid) {\n  const zRegEx = /\\{z\\}/g;\n  const xRegEx = /\\{x\\}/g;\n  const yRegEx = /\\{y\\}/g;\n  const dashYRegEx = /\\{-y\\}/g;\n  return (\n    /**\n     * @param {module:ol/tilecoord~TileCoord} tileCoord Tile Coordinate.\n     * @param {number} pixelRatio Pixel ratio.\n     * @param {module:ol/proj/Projection} projection Projection.\n     * @return {string|undefined} Tile URL.\n     */\n    function(tileCoord, pixelRatio, projection) {\n      if (!tileCoord) {\n        return undefined;\n      } else {\n        return template.replace(zRegEx, tileCoord[0].toString())\n          .replace(xRegEx, tileCoord[1].toString())\n          .replace(yRegEx, function() {\n            const y = -tileCoord[2] - 1;\n            return y.toString();\n          })\n          .replace(dashYRegEx, function() {\n            const z = tileCoord[0];\n            const range = tileGrid.getFullTileRange(z);\n            assert(range, 55); // The {-y} placeholder requires a tile grid with extent\n            const y = range.getHeight() + tileCoord[2];\n            return y.toString();\n          });\n      }\n    }\n  );\n}\n\n\n/**\n * @param {Array.<string>} templates Templates.\n * @param {module:ol/tilegrid/TileGrid} tileGrid Tile grid.\n * @return {module:ol/Tile~UrlFunction} Tile URL function.\n */\nexport function createFromTemplates(templates, tileGrid) {\n  const len = templates.length;\n  const tileUrlFunctions = new Array(len);\n  for (let i = 0; i < len; ++i) {\n    tileUrlFunctions[i] = createFromTemplate(templates[i], tileGrid);\n  }\n  return createFromTileUrlFunctions(tileUrlFunctions);\n}\n\n\n/**\n * @param {Array.<module:ol/Tile~UrlFunction>} tileUrlFunctions Tile URL Functions.\n * @return {module:ol/Tile~UrlFunction} Tile URL function.\n */\nexport function createFromTileUrlFunctions(tileUrlFunctions) {\n  if (tileUrlFunctions.length === 1) {\n    return tileUrlFunctions[0];\n  }\n  return (\n    /**\n     * @param {module:ol/tilecoord~TileCoord} tileCoord Tile Coordinate.\n     * @param {number} pixelRatio Pixel ratio.\n     * @param {module:ol/proj/Projection} projection Projection.\n     * @return {string|undefined} Tile URL.\n     */\n    function(tileCoord, pixelRatio, projection) {\n      if (!tileCoord) {\n        return undefined;\n      } else {\n        const h = tileCoordHash(tileCoord);\n        const index = modulo(h, tileUrlFunctions.length);\n        return tileUrlFunctions[index](tileCoord, pixelRatio, projection);\n      }\n    }\n  );\n}\n\n\n/**\n * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n * @param {number} pixelRatio Pixel ratio.\n * @param {module:ol/proj/Projection} projection Projection.\n * @return {string|undefined} Tile URL.\n */\nexport function nullTileUrlFunction(tileCoord, pixelRatio, projection) {\n  return undefined;\n}\n\n\n/**\n * @param {string} url URL.\n * @return {Array.<string>} Array of urls.\n */\nexport function expandUrl(url) {\n  const urls = [];\n  let match = /\\{([a-z])-([a-z])\\}/.exec(url);\n  if (match) {\n    // char range\n    const startCharCode = match[1].charCodeAt(0);\n    const stopCharCode = match[2].charCodeAt(0);\n    let charCode;\n    for (charCode = startCharCode; charCode <= stopCharCode; ++charCode) {\n      urls.push(url.replace(match[0], String.fromCharCode(charCode)));\n    }\n    return urls;\n  }\n  match = match = /\\{(\\d+)-(\\d+)\\}/.exec(url);\n  if (match) {\n    // number range\n    const stop = parseInt(match[2], 10);\n    for (let i = parseInt(match[1], 10); i <= stop; i++) {\n      urls.push(url.replace(match[0], i.toString()));\n    }\n    return urls;\n  }\n  urls.push(url);\n  return urls;\n}\n","/**\n * @module ol/net\n */\nimport {getUid} from './util.js';\n\n\n/**\n * Simple JSONP helper. Supports error callbacks and a custom callback param.\n * The error callback will be called when no JSONP is executed after 10 seconds.\n *\n * @param {string} url Request url. A 'callback' query parameter will be\n *     appended.\n * @param {Function} callback Callback on success.\n * @param {function()=} opt_errback Callback on error.\n * @param {string=} opt_callbackParam Custom query parameter for the JSONP\n *     callback. Default is 'callback'.\n */\nexport function jsonp(url, callback, opt_errback, opt_callbackParam) {\n  const script = document.createElement('script');\n  const key = 'olc_' + getUid(callback);\n  function cleanup() {\n    delete window[key];\n    script.parentNode.removeChild(script);\n  }\n  script.async = true;\n  script.src = url + (url.indexOf('?') == -1 ? '?' : '&') +\n      (opt_callbackParam || 'callback') + '=' + key;\n  const timer = setTimeout(function() {\n    cleanup();\n    if (opt_errback) {\n      opt_errback();\n    }\n  }, 10000);\n  window[key] = function(data) {\n    clearTimeout(timer);\n    cleanup();\n    callback(data);\n  };\n  document.getElementsByTagName('head')[0].appendChild(script);\n}\n","/**\n * @module ol/TileCache\n */\nimport LRUCache from './structs/LRUCache.js';\nimport {fromKey, getKey} from './tilecoord.js';\n\nclass TileCache extends LRUCache {\n\n  /**\n   * @param {number=} opt_highWaterMark High water mark.\n   */\n  constructor(opt_highWaterMark) {\n\n    super(opt_highWaterMark);\n\n  }\n\n  /**\n   * @param {!Object.<string, module:ol/TileRange>} usedTiles Used tiles.\n   */\n  expireCache(usedTiles) {\n    while (this.canExpireCache()) {\n      const tile = this.peekLast();\n      const zKey = tile.tileCoord[0].toString();\n      if (zKey in usedTiles && usedTiles[zKey].contains(tile.tileCoord)) {\n        break;\n      } else {\n        this.pop().dispose();\n      }\n    }\n  }\n\n  /**\n   * Prune all tiles from the cache that don't have the same z as the newest tile.\n   */\n  pruneExceptNewestZ() {\n    if (this.getCount() === 0) {\n      return;\n    }\n    const key = this.peekFirstKey();\n    const tileCoord = fromKey(key);\n    const z = tileCoord[0];\n    this.forEach(function(tile) {\n      if (tile.tileCoord[0] !== z) {\n        this.remove(getKey(tile.tileCoord));\n        tile.dispose();\n      }\n    }, this);\n  }\n}\n\n\nexport default TileCache;\n","/**\n * @module ol/reproj\n */\nimport {createCanvasContext2D} from './dom.js';\nimport {containsCoordinate, createEmpty, extend, getHeight, getTopLeft, getWidth} from './extent.js';\nimport {solveLinearSystem} from './math.js';\nimport {getPointResolution, transform} from './proj.js';\n\n\n/**\n * Calculates ideal resolution to use from the source in order to achieve\n * pixel mapping as close as possible to 1:1 during reprojection.\n * The resolution is calculated regardless of what resolutions\n * are actually available in the dataset (TileGrid, Image, ...).\n *\n * @param {module:ol/proj/Projection} sourceProj Source projection.\n * @param {module:ol/proj/Projection} targetProj Target projection.\n * @param {module:ol/coordinate~Coordinate} targetCenter Target center.\n * @param {number} targetResolution Target resolution.\n * @return {number} The best resolution to use. Can be +-Infinity, NaN or 0.\n */\nexport function calculateSourceResolution(sourceProj, targetProj,\n  targetCenter, targetResolution) {\n\n  const sourceCenter = transform(targetCenter, targetProj, sourceProj);\n\n  // calculate the ideal resolution of the source data\n  let sourceResolution = getPointResolution(targetProj, targetResolution, targetCenter);\n\n  const targetMetersPerUnit = targetProj.getMetersPerUnit();\n  if (targetMetersPerUnit !== undefined) {\n    sourceResolution *= targetMetersPerUnit;\n  }\n  const sourceMetersPerUnit = sourceProj.getMetersPerUnit();\n  if (sourceMetersPerUnit !== undefined) {\n    sourceResolution /= sourceMetersPerUnit;\n  }\n\n  // Based on the projection properties, the point resolution at the specified\n  // coordinates may be slightly different. We need to reverse-compensate this\n  // in order to achieve optimal results.\n\n  const sourceExtent = sourceProj.getExtent();\n  if (!sourceExtent || containsCoordinate(sourceExtent, sourceCenter)) {\n    const compensationFactor = getPointResolution(sourceProj, sourceResolution, sourceCenter) /\n        sourceResolution;\n    if (isFinite(compensationFactor) && compensationFactor > 0) {\n      sourceResolution /= compensationFactor;\n    }\n  }\n\n  return sourceResolution;\n}\n\n\n/**\n * Enlarge the clipping triangle point by 1 pixel to ensure the edges overlap\n * in order to mask gaps caused by antialiasing.\n *\n * @param {number} centroidX Centroid of the triangle (x coordinate in pixels).\n * @param {number} centroidY Centroid of the triangle (y coordinate in pixels).\n * @param {number} x X coordinate of the point (in pixels).\n * @param {number} y Y coordinate of the point (in pixels).\n * @return {module:ol/coordinate~Coordinate} New point 1 px farther from the centroid.\n */\nfunction enlargeClipPoint(centroidX, centroidY, x, y) {\n  const dX = x - centroidX;\n  const dY = y - centroidY;\n  const distance = Math.sqrt(dX * dX + dY * dY);\n  return [Math.round(x + dX / distance), Math.round(y + dY / distance)];\n}\n\n\n/**\n * Renders the source data into new canvas based on the triangulation.\n *\n * @param {number} width Width of the canvas.\n * @param {number} height Height of the canvas.\n * @param {number} pixelRatio Pixel ratio.\n * @param {number} sourceResolution Source resolution.\n * @param {module:ol/extent~Extent} sourceExtent Extent of the data source.\n * @param {number} targetResolution Target resolution.\n * @param {module:ol/extent~Extent} targetExtent Target extent.\n * @param {module:ol/reproj/Triangulation} triangulation\n * Calculated triangulation.\n * @param {Array.<{extent: module:ol/extent~Extent,\n *                 image: (HTMLCanvasElement|HTMLImageElement|HTMLVideoElement)}>} sources\n * Array of sources.\n * @param {number} gutter Gutter of the sources.\n * @param {boolean=} opt_renderEdges Render reprojection edges.\n * @return {HTMLCanvasElement} Canvas with reprojected data.\n */\nexport function render(width, height, pixelRatio,\n  sourceResolution, sourceExtent, targetResolution, targetExtent,\n  triangulation, sources, gutter, opt_renderEdges) {\n\n  const context = createCanvasContext2D(Math.round(pixelRatio * width),\n    Math.round(pixelRatio * height));\n\n  if (sources.length === 0) {\n    return context.canvas;\n  }\n\n  context.scale(pixelRatio, pixelRatio);\n\n  const sourceDataExtent = createEmpty();\n  sources.forEach(function(src, i, arr) {\n    extend(sourceDataExtent, src.extent);\n  });\n\n  const canvasWidthInUnits = getWidth(sourceDataExtent);\n  const canvasHeightInUnits = getHeight(sourceDataExtent);\n  const stitchContext = createCanvasContext2D(\n    Math.round(pixelRatio * canvasWidthInUnits / sourceResolution),\n    Math.round(pixelRatio * canvasHeightInUnits / sourceResolution));\n\n  const stitchScale = pixelRatio / sourceResolution;\n\n  sources.forEach(function(src, i, arr) {\n    const xPos = src.extent[0] - sourceDataExtent[0];\n    const yPos = -(src.extent[3] - sourceDataExtent[3]);\n    const srcWidth = getWidth(src.extent);\n    const srcHeight = getHeight(src.extent);\n\n    stitchContext.drawImage(\n      src.image,\n      gutter, gutter,\n      src.image.width - 2 * gutter, src.image.height - 2 * gutter,\n      xPos * stitchScale, yPos * stitchScale,\n      srcWidth * stitchScale, srcHeight * stitchScale);\n  });\n\n  const targetTopLeft = getTopLeft(targetExtent);\n\n  triangulation.getTriangles().forEach(function(triangle, i, arr) {\n    /* Calculate affine transform (src -> dst)\n     * Resulting matrix can be used to transform coordinate\n     * from `sourceProjection` to destination pixels.\n     *\n     * To optimize number of context calls and increase numerical stability,\n     * we also do the following operations:\n     * trans(-topLeftExtentCorner), scale(1 / targetResolution), scale(1, -1)\n     * here before solving the linear system so [ui, vi] are pixel coordinates.\n     *\n     * Src points: xi, yi\n     * Dst points: ui, vi\n     * Affine coefficients: aij\n     *\n     * | x0 y0 1  0  0 0 |   |a00|   |u0|\n     * | x1 y1 1  0  0 0 |   |a01|   |u1|\n     * | x2 y2 1  0  0 0 | x |a02| = |u2|\n     * |  0  0 0 x0 y0 1 |   |a10|   |v0|\n     * |  0  0 0 x1 y1 1 |   |a11|   |v1|\n     * |  0  0 0 x2 y2 1 |   |a12|   |v2|\n     */\n    const source = triangle.source;\n    const target = triangle.target;\n    let x0 = source[0][0], y0 = source[0][1];\n    let x1 = source[1][0], y1 = source[1][1];\n    let x2 = source[2][0], y2 = source[2][1];\n    const u0 = (target[0][0] - targetTopLeft[0]) / targetResolution;\n    const v0 = -(target[0][1] - targetTopLeft[1]) / targetResolution;\n    const u1 = (target[1][0] - targetTopLeft[0]) / targetResolution;\n    const v1 = -(target[1][1] - targetTopLeft[1]) / targetResolution;\n    const u2 = (target[2][0] - targetTopLeft[0]) / targetResolution;\n    const v2 = -(target[2][1] - targetTopLeft[1]) / targetResolution;\n\n    // Shift all the source points to improve numerical stability\n    // of all the subsequent calculations. The [x0, y0] is used here.\n    // This is also used to simplify the linear system.\n    const sourceNumericalShiftX = x0;\n    const sourceNumericalShiftY = y0;\n    x0 = 0;\n    y0 = 0;\n    x1 -= sourceNumericalShiftX;\n    y1 -= sourceNumericalShiftY;\n    x2 -= sourceNumericalShiftX;\n    y2 -= sourceNumericalShiftY;\n\n    const augmentedMatrix = [\n      [x1, y1, 0, 0, u1 - u0],\n      [x2, y2, 0, 0, u2 - u0],\n      [0, 0, x1, y1, v1 - v0],\n      [0, 0, x2, y2, v2 - v0]\n    ];\n    const affineCoefs = solveLinearSystem(augmentedMatrix);\n    if (!affineCoefs) {\n      return;\n    }\n\n    context.save();\n    context.beginPath();\n    const centroidX = (u0 + u1 + u2) / 3;\n    const centroidY = (v0 + v1 + v2) / 3;\n    const p0 = enlargeClipPoint(centroidX, centroidY, u0, v0);\n    const p1 = enlargeClipPoint(centroidX, centroidY, u1, v1);\n    const p2 = enlargeClipPoint(centroidX, centroidY, u2, v2);\n\n    context.moveTo(p1[0], p1[1]);\n    context.lineTo(p0[0], p0[1]);\n    context.lineTo(p2[0], p2[1]);\n    context.clip();\n\n    context.transform(\n      affineCoefs[0], affineCoefs[2], affineCoefs[1], affineCoefs[3], u0, v0);\n\n    context.translate(sourceDataExtent[0] - sourceNumericalShiftX,\n      sourceDataExtent[3] - sourceNumericalShiftY);\n\n    context.scale(sourceResolution / pixelRatio,\n      -sourceResolution / pixelRatio);\n\n    context.drawImage(stitchContext.canvas, 0, 0);\n    context.restore();\n  });\n\n  if (opt_renderEdges) {\n    context.save();\n\n    context.strokeStyle = 'black';\n    context.lineWidth = 1;\n\n    triangulation.getTriangles().forEach(function(triangle, i, arr) {\n      const target = triangle.target;\n      const u0 = (target[0][0] - targetTopLeft[0]) / targetResolution;\n      const v0 = -(target[0][1] - targetTopLeft[1]) / targetResolution;\n      const u1 = (target[1][0] - targetTopLeft[0]) / targetResolution;\n      const v1 = -(target[1][1] - targetTopLeft[1]) / targetResolution;\n      const u2 = (target[2][0] - targetTopLeft[0]) / targetResolution;\n      const v2 = -(target[2][1] - targetTopLeft[1]) / targetResolution;\n\n      context.beginPath();\n      context.moveTo(u1, v1);\n      context.lineTo(u0, v0);\n      context.lineTo(u2, v2);\n      context.closePath();\n      context.stroke();\n    });\n\n    context.restore();\n  }\n  return context.canvas;\n}\n","/**\n * @module ol/reproj/Triangulation\n */\nimport {boundingExtent, createEmpty, extendCoordinate, getBottomLeft, getBottomRight,\n  getTopLeft, getTopRight, getWidth, intersects} from '../extent.js';\nimport {modulo} from '../math.js';\nimport {getTransform} from '../proj.js';\n\n\n/**\n * Single triangle; consists of 3 source points and 3 target points.\n * @typedef {Object} Triangle\n * @property {Array.<module:ol/coordinate~Coordinate>} source\n * @property {Array.<module:ol/coordinate~Coordinate>} target\n */\n\n\n/**\n * Maximum number of subdivision steps during raster reprojection triangulation.\n * Prevents high memory usage and large number of proj4 calls (for certain\n * transformations and areas). At most `2*(2^this)` triangles are created for\n * each triangulated extent (tile/image).\n * @type {number}\n */\nconst MAX_SUBDIVISION = 10;\n\n\n/**\n * Maximum allowed size of triangle relative to world width. When transforming\n * corners of world extent between certain projections, the resulting\n * triangulation seems to have zero error and no subdivision is performed. If\n * the triangle width is more than this (relative to world width; 0-1),\n * subdivison is forced (up to `MAX_SUBDIVISION`). Default is `0.25`.\n * @type {number}\n */\nconst MAX_TRIANGLE_WIDTH = 0.25;\n\n\n/**\n * @classdesc\n * Class containing triangulation of the given target extent.\n * Used for determining source data and the reprojection itself.\n */\nclass Triangulation {\n\n  /**\n   * @param {module:ol/proj/Projection} sourceProj Source projection.\n   * @param {module:ol/proj/Projection} targetProj Target projection.\n   * @param {module:ol/extent~Extent} targetExtent Target extent to triangulate.\n   * @param {module:ol/extent~Extent} maxSourceExtent Maximal source extent that can be used.\n   * @param {number} errorThreshold Acceptable error (in source units).\n   */\n  constructor(sourceProj, targetProj, targetExtent, maxSourceExtent, errorThreshold) {\n\n    /**\n     * @type {module:ol/proj/Projection}\n     * @private\n     */\n    this.sourceProj_ = sourceProj;\n\n    /**\n     * @type {module:ol/proj/Projection}\n     * @private\n     */\n    this.targetProj_ = targetProj;\n\n    /** @type {!Object.<string, module:ol/coordinate~Coordinate>} */\n    let transformInvCache = {};\n    const transformInv = getTransform(this.targetProj_, this.sourceProj_);\n\n    /**\n     * @param {module:ol/coordinate~Coordinate} c A coordinate.\n     * @return {module:ol/coordinate~Coordinate} Transformed coordinate.\n     * @private\n     */\n    this.transformInv_ = function(c) {\n      const key = c[0] + '/' + c[1];\n      if (!transformInvCache[key]) {\n        transformInvCache[key] = transformInv(c);\n      }\n      return transformInvCache[key];\n    };\n\n    /**\n     * @type {module:ol/extent~Extent}\n     * @private\n     */\n    this.maxSourceExtent_ = maxSourceExtent;\n\n    /**\n     * @type {number}\n     * @private\n     */\n    this.errorThresholdSquared_ = errorThreshold * errorThreshold;\n\n    /**\n     * @type {Array.<module:ol/reproj/Triangulation~Triangle>}\n     * @private\n     */\n    this.triangles_ = [];\n\n    /**\n     * Indicates that the triangulation crosses edge of the source projection.\n     * @type {boolean}\n     * @private\n     */\n    this.wrapsXInSource_ = false;\n\n    /**\n     * @type {boolean}\n     * @private\n     */\n    this.canWrapXInSource_ = this.sourceProj_.canWrapX() &&\n        !!maxSourceExtent &&\n        !!this.sourceProj_.getExtent() &&\n        (getWidth(maxSourceExtent) == getWidth(this.sourceProj_.getExtent()));\n\n    /**\n     * @type {?number}\n     * @private\n     */\n    this.sourceWorldWidth_ = this.sourceProj_.getExtent() ?\n      getWidth(this.sourceProj_.getExtent()) : null;\n\n    /**\n     * @type {?number}\n     * @private\n     */\n    this.targetWorldWidth_ = this.targetProj_.getExtent() ?\n      getWidth(this.targetProj_.getExtent()) : null;\n\n    const destinationTopLeft = getTopLeft(targetExtent);\n    const destinationTopRight = getTopRight(targetExtent);\n    const destinationBottomRight = getBottomRight(targetExtent);\n    const destinationBottomLeft = getBottomLeft(targetExtent);\n    const sourceTopLeft = this.transformInv_(destinationTopLeft);\n    const sourceTopRight = this.transformInv_(destinationTopRight);\n    const sourceBottomRight = this.transformInv_(destinationBottomRight);\n    const sourceBottomLeft = this.transformInv_(destinationBottomLeft);\n\n    this.addQuad_(\n      destinationTopLeft, destinationTopRight,\n      destinationBottomRight, destinationBottomLeft,\n      sourceTopLeft, sourceTopRight, sourceBottomRight, sourceBottomLeft,\n      MAX_SUBDIVISION);\n\n    if (this.wrapsXInSource_) {\n      let leftBound = Infinity;\n      this.triangles_.forEach(function(triangle, i, arr) {\n        leftBound = Math.min(leftBound,\n          triangle.source[0][0], triangle.source[1][0], triangle.source[2][0]);\n      });\n\n      // Shift triangles to be as close to `leftBound` as possible\n      // (if the distance is more than `worldWidth / 2` it can be closer.\n      this.triangles_.forEach(function(triangle) {\n        if (Math.max(triangle.source[0][0], triangle.source[1][0],\n          triangle.source[2][0]) - leftBound > this.sourceWorldWidth_ / 2) {\n          const newTriangle = [[triangle.source[0][0], triangle.source[0][1]],\n            [triangle.source[1][0], triangle.source[1][1]],\n            [triangle.source[2][0], triangle.source[2][1]]];\n          if ((newTriangle[0][0] - leftBound) > this.sourceWorldWidth_ / 2) {\n            newTriangle[0][0] -= this.sourceWorldWidth_;\n          }\n          if ((newTriangle[1][0] - leftBound) > this.sourceWorldWidth_ / 2) {\n            newTriangle[1][0] -= this.sourceWorldWidth_;\n          }\n          if ((newTriangle[2][0] - leftBound) > this.sourceWorldWidth_ / 2) {\n            newTriangle[2][0] -= this.sourceWorldWidth_;\n          }\n\n          // Rarely (if the extent contains both the dateline and prime meridian)\n          // the shift can in turn break some triangles.\n          // Detect this here and don't shift in such cases.\n          const minX = Math.min(\n            newTriangle[0][0], newTriangle[1][0], newTriangle[2][0]);\n          const maxX = Math.max(\n            newTriangle[0][0], newTriangle[1][0], newTriangle[2][0]);\n          if ((maxX - minX) < this.sourceWorldWidth_ / 2) {\n            triangle.source = newTriangle;\n          }\n        }\n      }.bind(this));\n    }\n\n    transformInvCache = {};\n  }\n\n  /**\n   * Adds triangle to the triangulation.\n   * @param {module:ol/coordinate~Coordinate} a The target a coordinate.\n   * @param {module:ol/coordinate~Coordinate} b The target b coordinate.\n   * @param {module:ol/coordinate~Coordinate} c The target c coordinate.\n   * @param {module:ol/coordinate~Coordinate} aSrc The source a coordinate.\n   * @param {module:ol/coordinate~Coordinate} bSrc The source b coordinate.\n   * @param {module:ol/coordinate~Coordinate} cSrc The source c coordinate.\n   * @private\n   */\n  addTriangle_(a, b, c, aSrc, bSrc, cSrc) {\n    this.triangles_.push({\n      source: [aSrc, bSrc, cSrc],\n      target: [a, b, c]\n    });\n  }\n\n  /**\n   * Adds quad (points in clock-wise order) to the triangulation\n   * (and reprojects the vertices) if valid.\n   * Performs quad subdivision if needed to increase precision.\n   *\n   * @param {module:ol/coordinate~Coordinate} a The target a coordinate.\n   * @param {module:ol/coordinate~Coordinate} b The target b coordinate.\n   * @param {module:ol/coordinate~Coordinate} c The target c coordinate.\n   * @param {module:ol/coordinate~Coordinate} d The target d coordinate.\n   * @param {module:ol/coordinate~Coordinate} aSrc The source a coordinate.\n   * @param {module:ol/coordinate~Coordinate} bSrc The source b coordinate.\n   * @param {module:ol/coordinate~Coordinate} cSrc The source c coordinate.\n   * @param {module:ol/coordinate~Coordinate} dSrc The source d coordinate.\n   * @param {number} maxSubdivision Maximal allowed subdivision of the quad.\n   * @private\n   */\n  addQuad_(a, b, c, d, aSrc, bSrc, cSrc, dSrc, maxSubdivision) {\n\n    const sourceQuadExtent = boundingExtent([aSrc, bSrc, cSrc, dSrc]);\n    const sourceCoverageX = this.sourceWorldWidth_ ?\n      getWidth(sourceQuadExtent) / this.sourceWorldWidth_ : null;\n    const sourceWorldWidth = /** @type {number} */ (this.sourceWorldWidth_);\n\n    // when the quad is wrapped in the source projection\n    // it covers most of the projection extent, but not fully\n    const wrapsX = this.sourceProj_.canWrapX() &&\n                 sourceCoverageX > 0.5 && sourceCoverageX < 1;\n\n    let needsSubdivision = false;\n\n    if (maxSubdivision > 0) {\n      if (this.targetProj_.isGlobal() && this.targetWorldWidth_) {\n        const targetQuadExtent = boundingExtent([a, b, c, d]);\n        const targetCoverageX = getWidth(targetQuadExtent) / this.targetWorldWidth_;\n        needsSubdivision |=\n            targetCoverageX > MAX_TRIANGLE_WIDTH;\n      }\n      if (!wrapsX && this.sourceProj_.isGlobal() && sourceCoverageX) {\n        needsSubdivision |=\n            sourceCoverageX > MAX_TRIANGLE_WIDTH;\n      }\n    }\n\n    if (!needsSubdivision && this.maxSourceExtent_) {\n      if (!intersects(sourceQuadExtent, this.maxSourceExtent_)) {\n        // whole quad outside source projection extent -> ignore\n        return;\n      }\n    }\n\n    if (!needsSubdivision) {\n      if (!isFinite(aSrc[0]) || !isFinite(aSrc[1]) ||\n          !isFinite(bSrc[0]) || !isFinite(bSrc[1]) ||\n          !isFinite(cSrc[0]) || !isFinite(cSrc[1]) ||\n          !isFinite(dSrc[0]) || !isFinite(dSrc[1])) {\n        if (maxSubdivision > 0) {\n          needsSubdivision = true;\n        } else {\n          return;\n        }\n      }\n    }\n\n    if (maxSubdivision > 0) {\n      if (!needsSubdivision) {\n        const center = [(a[0] + c[0]) / 2, (a[1] + c[1]) / 2];\n        const centerSrc = this.transformInv_(center);\n\n        let dx;\n        if (wrapsX) {\n          const centerSrcEstimX =\n              (modulo(aSrc[0], sourceWorldWidth) +\n               modulo(cSrc[0], sourceWorldWidth)) / 2;\n          dx = centerSrcEstimX -\n              modulo(centerSrc[0], sourceWorldWidth);\n        } else {\n          dx = (aSrc[0] + cSrc[0]) / 2 - centerSrc[0];\n        }\n        const dy = (aSrc[1] + cSrc[1]) / 2 - centerSrc[1];\n        const centerSrcErrorSquared = dx * dx + dy * dy;\n        needsSubdivision = centerSrcErrorSquared > this.errorThresholdSquared_;\n      }\n      if (needsSubdivision) {\n        if (Math.abs(a[0] - c[0]) <= Math.abs(a[1] - c[1])) {\n          // split horizontally (top & bottom)\n          const bc = [(b[0] + c[0]) / 2, (b[1] + c[1]) / 2];\n          const bcSrc = this.transformInv_(bc);\n          const da = [(d[0] + a[0]) / 2, (d[1] + a[1]) / 2];\n          const daSrc = this.transformInv_(da);\n\n          this.addQuad_(\n            a, b, bc, da, aSrc, bSrc, bcSrc, daSrc, maxSubdivision - 1);\n          this.addQuad_(\n            da, bc, c, d, daSrc, bcSrc, cSrc, dSrc, maxSubdivision - 1);\n        } else {\n          // split vertically (left & right)\n          const ab = [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2];\n          const abSrc = this.transformInv_(ab);\n          const cd = [(c[0] + d[0]) / 2, (c[1] + d[1]) / 2];\n          const cdSrc = this.transformInv_(cd);\n\n          this.addQuad_(\n            a, ab, cd, d, aSrc, abSrc, cdSrc, dSrc, maxSubdivision - 1);\n          this.addQuad_(\n            ab, b, c, cd, abSrc, bSrc, cSrc, cdSrc, maxSubdivision - 1);\n        }\n        return;\n      }\n    }\n\n    if (wrapsX) {\n      if (!this.canWrapXInSource_) {\n        return;\n      }\n      this.wrapsXInSource_ = true;\n    }\n\n    this.addTriangle_(a, c, d, aSrc, cSrc, dSrc);\n    this.addTriangle_(a, b, c, aSrc, bSrc, cSrc);\n  }\n\n  /**\n   * Calculates extent of the 'source' coordinates from all the triangles.\n   *\n   * @return {module:ol/extent~Extent} Calculated extent.\n   */\n  calculateSourceExtent() {\n    const extent = createEmpty();\n\n    this.triangles_.forEach(function(triangle, i, arr) {\n      const src = triangle.source;\n      extendCoordinate(extent, src[0]);\n      extendCoordinate(extent, src[1]);\n      extendCoordinate(extent, src[2]);\n    });\n\n    return extent;\n  }\n\n  /**\n   * @return {Array.<module:ol/reproj/Triangulation~Triangle>} Array of the calculated triangles.\n   */\n  getTriangles() {\n    return this.triangles_;\n  }\n}\n\nexport default Triangulation;\n","/**\n * @module ol/reproj/Tile\n */\nimport {ERROR_THRESHOLD} from './common.js';\n\nimport Tile from '../Tile.js';\nimport TileState from '../TileState.js';\nimport {listen, unlistenByKey} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport {getArea, getCenter, getIntersection} from '../extent.js';\nimport {clamp} from '../math.js';\nimport {calculateSourceResolution, render as renderReprojected} from '../reproj.js';\nimport Triangulation from '../reproj/Triangulation.js';\n\n\n/**\n * @typedef {function(number, number, number, number) : module:ol/Tile} FunctionType\n */\n\n\n/**\n * @classdesc\n * Class encapsulating single reprojected tile.\n * See {@link module:ol/source/TileImage~TileImage}.\n *\n */\nclass ReprojTile extends Tile {\n  /**\n   * @param {module:ol/proj/Projection} sourceProj Source projection.\n   * @param {module:ol/tilegrid/TileGrid} sourceTileGrid Source tile grid.\n   * @param {module:ol/proj/Projection} targetProj Target projection.\n   * @param {module:ol/tilegrid/TileGrid} targetTileGrid Target tile grid.\n   * @param {module:ol/tilecoord~TileCoord} tileCoord Coordinate of the tile.\n   * @param {module:ol/tilecoord~TileCoord} wrappedTileCoord Coordinate of the tile wrapped in X.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {number} gutter Gutter of the source tiles.\n   * @param {module:ol/reproj/Tile~FunctionType} getTileFunction\n   *     Function returning source tiles (z, x, y, pixelRatio).\n   * @param {number=} opt_errorThreshold Acceptable reprojection error (in px).\n   * @param {boolean=} opt_renderEdges Render reprojection edges.\n   */\n  constructor(\n    sourceProj,\n    sourceTileGrid,\n    targetProj,\n    targetTileGrid,\n    tileCoord,\n    wrappedTileCoord,\n    pixelRatio,\n    gutter,\n    getTileFunction,\n    opt_errorThreshold,\n    opt_renderEdges\n  ) {\n    super(tileCoord, TileState.IDLE);\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.renderEdges_ = opt_renderEdges !== undefined ? opt_renderEdges : false;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.pixelRatio_ = pixelRatio;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.gutter_ = gutter;\n\n    /**\n     * @private\n     * @type {HTMLCanvasElement}\n     */\n    this.canvas_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/tilegrid/TileGrid}\n     */\n    this.sourceTileGrid_ = sourceTileGrid;\n\n    /**\n     * @private\n     * @type {module:ol/tilegrid/TileGrid}\n     */\n    this.targetTileGrid_ = targetTileGrid;\n\n    /**\n     * @private\n     * @type {module:ol/tilecoord~TileCoord}\n     */\n    this.wrappedTileCoord_ = wrappedTileCoord ? wrappedTileCoord : tileCoord;\n\n    /**\n     * @private\n     * @type {!Array.<module:ol/Tile>}\n     */\n    this.sourceTiles_ = [];\n\n    /**\n     * @private\n     * @type {Array.<module:ol/events~EventsKey>}\n     */\n    this.sourcesListenerKeys_ = null;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.sourceZ_ = 0;\n\n    const targetExtent = targetTileGrid.getTileCoordExtent(this.wrappedTileCoord_);\n    const maxTargetExtent = this.targetTileGrid_.getExtent();\n    let maxSourceExtent = this.sourceTileGrid_.getExtent();\n\n    const limitedTargetExtent = maxTargetExtent ?\n      getIntersection(targetExtent, maxTargetExtent) : targetExtent;\n\n    if (getArea(limitedTargetExtent) === 0) {\n      // Tile is completely outside range -> EMPTY\n      // TODO: is it actually correct that the source even creates the tile ?\n      this.state = TileState.EMPTY;\n      return;\n    }\n\n    const sourceProjExtent = sourceProj.getExtent();\n    if (sourceProjExtent) {\n      if (!maxSourceExtent) {\n        maxSourceExtent = sourceProjExtent;\n      } else {\n        maxSourceExtent = getIntersection(maxSourceExtent, sourceProjExtent);\n      }\n    }\n\n    const targetResolution = targetTileGrid.getResolution(\n      this.wrappedTileCoord_[0]);\n\n    const targetCenter = getCenter(limitedTargetExtent);\n    const sourceResolution = calculateSourceResolution(\n      sourceProj, targetProj, targetCenter, targetResolution);\n\n    if (!isFinite(sourceResolution) || sourceResolution <= 0) {\n      // invalid sourceResolution -> EMPTY\n      // probably edges of the projections when no extent is defined\n      this.state = TileState.EMPTY;\n      return;\n    }\n\n    const errorThresholdInPixels = opt_errorThreshold !== undefined ?\n      opt_errorThreshold : ERROR_THRESHOLD;\n\n    /**\n     * @private\n     * @type {!module:ol/reproj/Triangulation}\n     */\n    this.triangulation_ = new Triangulation(\n      sourceProj, targetProj, limitedTargetExtent, maxSourceExtent,\n      sourceResolution * errorThresholdInPixels);\n\n    if (this.triangulation_.getTriangles().length === 0) {\n      // no valid triangles -> EMPTY\n      this.state = TileState.EMPTY;\n      return;\n    }\n\n    this.sourceZ_ = sourceTileGrid.getZForResolution(sourceResolution);\n    let sourceExtent = this.triangulation_.calculateSourceExtent();\n\n    if (maxSourceExtent) {\n      if (sourceProj.canWrapX()) {\n        sourceExtent[1] = clamp(\n          sourceExtent[1], maxSourceExtent[1], maxSourceExtent[3]);\n        sourceExtent[3] = clamp(\n          sourceExtent[3], maxSourceExtent[1], maxSourceExtent[3]);\n      } else {\n        sourceExtent = getIntersection(sourceExtent, maxSourceExtent);\n      }\n    }\n\n    if (!getArea(sourceExtent)) {\n      this.state = TileState.EMPTY;\n    } else {\n      const sourceRange = sourceTileGrid.getTileRangeForExtentAndZ(\n        sourceExtent, this.sourceZ_);\n\n      for (let srcX = sourceRange.minX; srcX <= sourceRange.maxX; srcX++) {\n        for (let srcY = sourceRange.minY; srcY <= sourceRange.maxY; srcY++) {\n          const tile = getTileFunction(this.sourceZ_, srcX, srcY, pixelRatio);\n          if (tile) {\n            this.sourceTiles_.push(tile);\n          }\n        }\n      }\n\n      if (this.sourceTiles_.length === 0) {\n        this.state = TileState.EMPTY;\n      }\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  disposeInternal() {\n    if (this.state == TileState.LOADING) {\n      this.unlistenSources_();\n    }\n    Tile.prototype.disposeInternal.call(this);\n  }\n\n  /**\n   * Get the HTML Canvas element for this tile.\n   * @return {HTMLCanvasElement} Canvas.\n   */\n  getImage() {\n    return this.canvas_;\n  }\n\n  /**\n   * @private\n   */\n  reproject_() {\n    const sources = [];\n    this.sourceTiles_.forEach(function(tile, i, arr) {\n      if (tile && tile.getState() == TileState.LOADED) {\n        sources.push({\n          extent: this.sourceTileGrid_.getTileCoordExtent(tile.tileCoord),\n          image: tile.getImage()\n        });\n      }\n    }.bind(this));\n    this.sourceTiles_.length = 0;\n\n    if (sources.length === 0) {\n      this.state = TileState.ERROR;\n    } else {\n      const z = this.wrappedTileCoord_[0];\n      const size = this.targetTileGrid_.getTileSize(z);\n      const width = typeof size === 'number' ? size : size[0];\n      const height = typeof size === 'number' ? size : size[1];\n      const targetResolution = this.targetTileGrid_.getResolution(z);\n      const sourceResolution = this.sourceTileGrid_.getResolution(this.sourceZ_);\n\n      const targetExtent = this.targetTileGrid_.getTileCoordExtent(\n        this.wrappedTileCoord_);\n      this.canvas_ = renderReprojected(width, height, this.pixelRatio_,\n        sourceResolution, this.sourceTileGrid_.getExtent(),\n        targetResolution, targetExtent, this.triangulation_, sources,\n        this.gutter_, this.renderEdges_);\n\n      this.state = TileState.LOADED;\n    }\n    this.changed();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  load() {\n    if (this.state == TileState.IDLE) {\n      this.state = TileState.LOADING;\n      this.changed();\n\n      let leftToLoad = 0;\n\n      this.sourcesListenerKeys_ = [];\n      this.sourceTiles_.forEach(function(tile, i, arr) {\n        const state = tile.getState();\n        if (state == TileState.IDLE || state == TileState.LOADING) {\n          leftToLoad++;\n\n          const sourceListenKey = listen(tile, EventType.CHANGE,\n            function(e) {\n              const state = tile.getState();\n              if (state == TileState.LOADED ||\n                    state == TileState.ERROR ||\n                    state == TileState.EMPTY) {\n                unlistenByKey(sourceListenKey);\n                leftToLoad--;\n                if (leftToLoad === 0) {\n                  this.unlistenSources_();\n                  this.reproject_();\n                }\n              }\n            }, this);\n          this.sourcesListenerKeys_.push(sourceListenKey);\n        }\n      }.bind(this));\n\n      this.sourceTiles_.forEach(function(tile, i, arr) {\n        const state = tile.getState();\n        if (state == TileState.IDLE) {\n          tile.load();\n        }\n      });\n\n      if (leftToLoad === 0) {\n        setTimeout(this.reproject_.bind(this), 0);\n      }\n    }\n  }\n\n  /**\n   * @private\n   */\n  unlistenSources_() {\n    this.sourcesListenerKeys_.forEach(unlistenByKey);\n    this.sourcesListenerKeys_ = null;\n  }\n}\n\n\nexport default ReprojTile;\n","/**\n * @module ol/tilegrid/TileGrid\n */\nimport {DEFAULT_TILE_SIZE} from './common.js';\nimport {assert} from '../asserts.js';\nimport TileRange, {createOrUpdate as createOrUpdateTileRange} from '../TileRange.js';\nimport {isSorted, linearFindNearest} from '../array.js';\nimport {createOrUpdate, getTopLeft} from '../extent.js';\nimport {clamp} from '../math.js';\nimport {toSize} from '../size.js';\nimport {createOrUpdate as createOrUpdateTileCoord} from '../tilecoord.js';\n\n\n/**\n * @private\n * @type {module:ol/tilecoord~TileCoord}\n */\nconst tmpTileCoord = [0, 0, 0];\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/extent~Extent} [extent] Extent for the tile grid. No tiles outside this\n * extent will be requested by {@link module:ol/source/Tile} sources. When no `origin` or\n * `origins` are configured, the `origin` will be set to the top-left corner of the extent.\n * @property {number} [minZoom=0] Minimum zoom.\n * @property {module:ol/coordinate~Coordinate} [origin] The tile grid origin, i.e. where the `x`\n * and `y` axes meet (`[z, 0, 0]`). Tile coordinates increase left to right and upwards. If not\n * specified, `extent` or `origins` must be provided.\n * @property {Array.<module:ol/coordinate~Coordinate>} [origins] Tile grid origins, i.e. where\n * the `x` and `y` axes meet (`[z, 0, 0]`), for each zoom level. If given, the array length\n * should match the length of the `resolutions` array, i.e. each resolution can have a different\n * origin. Tile coordinates increase left to right and upwards. If not specified, `extent` or\n * `origin` must be provided.\n * @property {!Array.<number>} resolutions Resolutions. The array index of each resolution needs\n * to match the zoom level. This means that even if a `minZoom` is configured, the resolutions\n * array will have a length of `maxZoom + 1`.\n * @property {Array.<module:ol/size~Size>} [sizes] Sizes.\n * @property {number|module:ol/size~Size} [tileSize] Tile size.\n * Default is `[256, 256]`.\n * @property {Array.<module:ol/size~Size>} [tileSizes] Tile sizes. If given, the array length\n * should match the length of the `resolutions` array, i.e. each resolution can have a different\n * tile size.\n */\n\n\n/**\n * @classdesc\n * Base class for setting the grid pattern for sources accessing tiled-image\n * servers.\n * @api\n */\nclass TileGrid {\n  /**\n   * @param {module:ol/tilegrid/TileGrid~Options} options Tile grid options.\n   */\n  constructor(options) {\n\n    /**\n     * @protected\n     * @type {number}\n     */\n    this.minZoom = options.minZoom !== undefined ? options.minZoom : 0;\n\n    /**\n     * @private\n     * @type {!Array.<number>}\n     */\n    this.resolutions_ = options.resolutions;\n    assert(isSorted(this.resolutions_, function(a, b) {\n      return b - a;\n    }, true), 17); // `resolutions` must be sorted in descending order\n\n\n    // check if we've got a consistent zoom factor and origin\n    let zoomFactor;\n    if (!options.origins) {\n      for (let i = 0, ii = this.resolutions_.length - 1; i < ii; ++i) {\n        if (!zoomFactor) {\n          zoomFactor = this.resolutions_[i] / this.resolutions_[i + 1];\n        } else {\n          if (this.resolutions_[i] / this.resolutions_[i + 1] !== zoomFactor) {\n            zoomFactor = undefined;\n            break;\n          }\n        }\n      }\n    }\n\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.zoomFactor_ = zoomFactor;\n\n\n    /**\n     * @protected\n     * @type {number}\n     */\n    this.maxZoom = this.resolutions_.length - 1;\n\n    /**\n     * @private\n     * @type {module:ol/coordinate~Coordinate}\n     */\n    this.origin_ = options.origin !== undefined ? options.origin : null;\n\n    /**\n     * @private\n     * @type {Array.<module:ol/coordinate~Coordinate>}\n     */\n    this.origins_ = null;\n    if (options.origins !== undefined) {\n      this.origins_ = options.origins;\n      assert(this.origins_.length == this.resolutions_.length,\n        20); // Number of `origins` and `resolutions` must be equal\n    }\n\n    const extent = options.extent;\n\n    if (extent !== undefined &&\n        !this.origin_ && !this.origins_) {\n      this.origin_ = getTopLeft(extent);\n    }\n\n    assert(\n      (!this.origin_ && this.origins_) || (this.origin_ && !this.origins_),\n      18); // Either `origin` or `origins` must be configured, never both\n\n    /**\n     * @private\n     * @type {Array.<number|module:ol/size~Size>}\n     */\n    this.tileSizes_ = null;\n    if (options.tileSizes !== undefined) {\n      this.tileSizes_ = options.tileSizes;\n      assert(this.tileSizes_.length == this.resolutions_.length,\n        19); // Number of `tileSizes` and `resolutions` must be equal\n    }\n\n    /**\n     * @private\n     * @type {number|module:ol/size~Size}\n     */\n    this.tileSize_ = options.tileSize !== undefined ?\n      options.tileSize :\n      !this.tileSizes_ ? DEFAULT_TILE_SIZE : null;\n    assert(\n      (!this.tileSize_ && this.tileSizes_) ||\n        (this.tileSize_ && !this.tileSizes_),\n      22); // Either `tileSize` or `tileSizes` must be configured, never both\n\n    /**\n     * @private\n     * @type {module:ol/extent~Extent}\n     */\n    this.extent_ = extent !== undefined ? extent : null;\n\n\n    /**\n     * @private\n     * @type {Array.<module:ol/TileRange>}\n     */\n    this.fullTileRanges_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/size~Size}\n     */\n    this.tmpSize_ = [0, 0];\n\n    if (options.sizes !== undefined) {\n      this.fullTileRanges_ = options.sizes.map(function(size, z) {\n        const tileRange = new TileRange(\n          Math.min(0, size[0]), Math.max(size[0] - 1, -1),\n          Math.min(0, size[1]), Math.max(size[1] - 1, -1));\n        return tileRange;\n      }, this);\n    } else if (extent) {\n      this.calculateTileRanges_(extent);\n    }\n\n  }\n\n  /**\n   * Call a function with each tile coordinate for a given extent and zoom level.\n   *\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {number} zoom Integer zoom level.\n   * @param {function(module:ol/tilecoord~TileCoord)} callback Function called with each tile coordinate.\n   * @api\n   */\n  forEachTileCoord(extent, zoom, callback) {\n    const tileRange = this.getTileRangeForExtentAndZ(extent, zoom);\n    for (let i = tileRange.minX, ii = tileRange.maxX; i <= ii; ++i) {\n      for (let j = tileRange.minY, jj = tileRange.maxY; j <= jj; ++j) {\n        callback([zoom, i, j]);\n      }\n    }\n  }\n\n  /**\n   * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n   * @param {function(this: T, number, module:ol/TileRange): boolean} callback Callback.\n   * @param {T=} opt_this The object to use as `this` in `callback`.\n   * @param {module:ol/TileRange=} opt_tileRange Temporary module:ol/TileRange object.\n   * @param {module:ol/extent~Extent=} opt_extent Temporary module:ol/extent~Extent object.\n   * @return {boolean} Callback succeeded.\n   * @template T\n   */\n  forEachTileCoordParentTileRange(tileCoord, callback, opt_this, opt_tileRange, opt_extent) {\n    let tileRange, x, y;\n    let tileCoordExtent = null;\n    let z = tileCoord[0] - 1;\n    if (this.zoomFactor_ === 2) {\n      x = tileCoord[1];\n      y = tileCoord[2];\n    } else {\n      tileCoordExtent = this.getTileCoordExtent(tileCoord, opt_extent);\n    }\n    while (z >= this.minZoom) {\n      if (this.zoomFactor_ === 2) {\n        x = Math.floor(x / 2);\n        y = Math.floor(y / 2);\n        tileRange = createOrUpdateTileRange(x, x, y, y, opt_tileRange);\n      } else {\n        tileRange = this.getTileRangeForExtentAndZ(tileCoordExtent, z, opt_tileRange);\n      }\n      if (callback.call(opt_this, z, tileRange)) {\n        return true;\n      }\n      --z;\n    }\n    return false;\n  }\n\n  /**\n   * Get the extent for this tile grid, if it was configured.\n   * @return {module:ol/extent~Extent} Extent.\n   */\n  getExtent() {\n    return this.extent_;\n  }\n\n  /**\n   * Get the maximum zoom level for the grid.\n   * @return {number} Max zoom.\n   * @api\n   */\n  getMaxZoom() {\n    return this.maxZoom;\n  }\n\n  /**\n   * Get the minimum zoom level for the grid.\n   * @return {number} Min zoom.\n   * @api\n   */\n  getMinZoom() {\n    return this.minZoom;\n  }\n\n  /**\n   * Get the origin for the grid at the given zoom level.\n   * @param {number} z Integer zoom level.\n   * @return {module:ol/coordinate~Coordinate} Origin.\n   * @api\n   */\n  getOrigin(z) {\n    if (this.origin_) {\n      return this.origin_;\n    } else {\n      return this.origins_[z];\n    }\n  }\n\n  /**\n   * Get the resolution for the given zoom level.\n   * @param {number} z Integer zoom level.\n   * @return {number} Resolution.\n   * @api\n   */\n  getResolution(z) {\n    return this.resolutions_[z];\n  }\n\n  /**\n   * Get the list of resolutions for the tile grid.\n   * @return {Array.<number>} Resolutions.\n   * @api\n   */\n  getResolutions() {\n    return this.resolutions_;\n  }\n\n  /**\n   * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n   * @param {module:ol/TileRange=} opt_tileRange Temporary module:ol/TileRange object.\n   * @param {module:ol/extent~Extent=} opt_extent Temporary module:ol/extent~Extent object.\n   * @return {module:ol/TileRange} Tile range.\n   */\n  getTileCoordChildTileRange(tileCoord, opt_tileRange, opt_extent) {\n    if (tileCoord[0] < this.maxZoom) {\n      if (this.zoomFactor_ === 2) {\n        const minX = tileCoord[1] * 2;\n        const minY = tileCoord[2] * 2;\n        return createOrUpdateTileRange(minX, minX + 1, minY, minY + 1, opt_tileRange);\n      }\n      const tileCoordExtent = this.getTileCoordExtent(tileCoord, opt_extent);\n      return this.getTileRangeForExtentAndZ(\n        tileCoordExtent, tileCoord[0] + 1, opt_tileRange);\n    }\n    return null;\n  }\n\n  /**\n   * Get the extent for a tile range.\n   * @param {number} z Integer zoom level.\n   * @param {module:ol/TileRange} tileRange Tile range.\n   * @param {module:ol/extent~Extent=} opt_extent Temporary module:ol/extent~Extent object.\n   * @return {module:ol/extent~Extent} Extent.\n   */\n  getTileRangeExtent(z, tileRange, opt_extent) {\n    const origin = this.getOrigin(z);\n    const resolution = this.getResolution(z);\n    const tileSize = toSize(this.getTileSize(z), this.tmpSize_);\n    const minX = origin[0] + tileRange.minX * tileSize[0] * resolution;\n    const maxX = origin[0] + (tileRange.maxX + 1) * tileSize[0] * resolution;\n    const minY = origin[1] + tileRange.minY * tileSize[1] * resolution;\n    const maxY = origin[1] + (tileRange.maxY + 1) * tileSize[1] * resolution;\n    return createOrUpdate(minX, minY, maxX, maxY, opt_extent);\n  }\n\n  /**\n   * Get a tile range for the given extent and integer zoom level.\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {number} z Integer zoom level.\n   * @param {module:ol/TileRange=} opt_tileRange Temporary tile range object.\n   * @return {module:ol/TileRange} Tile range.\n   */\n  getTileRangeForExtentAndZ(extent, z, opt_tileRange) {\n    const tileCoord = tmpTileCoord;\n    this.getTileCoordForXYAndZ_(extent[0], extent[1], z, false, tileCoord);\n    const minX = tileCoord[1];\n    const minY = tileCoord[2];\n    this.getTileCoordForXYAndZ_(extent[2], extent[3], z, true, tileCoord);\n    return createOrUpdateTileRange(minX, tileCoord[1], minY, tileCoord[2], opt_tileRange);\n  }\n\n  /**\n   * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n   * @return {module:ol/coordinate~Coordinate} Tile center.\n   */\n  getTileCoordCenter(tileCoord) {\n    const origin = this.getOrigin(tileCoord[0]);\n    const resolution = this.getResolution(tileCoord[0]);\n    const tileSize = toSize(this.getTileSize(tileCoord[0]), this.tmpSize_);\n    return [\n      origin[0] + (tileCoord[1] + 0.5) * tileSize[0] * resolution,\n      origin[1] + (tileCoord[2] + 0.5) * tileSize[1] * resolution\n    ];\n  }\n\n  /**\n   * Get the extent of a tile coordinate.\n   *\n   * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n   * @param {module:ol/extent~Extent=} opt_extent Temporary extent object.\n   * @return {module:ol/extent~Extent} Extent.\n   * @api\n   */\n  getTileCoordExtent(tileCoord, opt_extent) {\n    const origin = this.getOrigin(tileCoord[0]);\n    const resolution = this.getResolution(tileCoord[0]);\n    const tileSize = toSize(this.getTileSize(tileCoord[0]), this.tmpSize_);\n    const minX = origin[0] + tileCoord[1] * tileSize[0] * resolution;\n    const minY = origin[1] + tileCoord[2] * tileSize[1] * resolution;\n    const maxX = minX + tileSize[0] * resolution;\n    const maxY = minY + tileSize[1] * resolution;\n    return createOrUpdate(minX, minY, maxX, maxY, opt_extent);\n  }\n\n  /**\n   * Get the tile coordinate for the given map coordinate and resolution.  This\n   * method considers that coordinates that intersect tile boundaries should be\n   * assigned the higher tile coordinate.\n   *\n   * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n   * @param {number} resolution Resolution.\n   * @param {module:ol/tilecoord~TileCoord=} opt_tileCoord Destination module:ol/tilecoord~TileCoord object.\n   * @return {module:ol/tilecoord~TileCoord} Tile coordinate.\n   * @api\n   */\n  getTileCoordForCoordAndResolution(coordinate, resolution, opt_tileCoord) {\n    return this.getTileCoordForXYAndResolution_(\n      coordinate[0], coordinate[1], resolution, false, opt_tileCoord);\n  }\n\n  /**\n   * Note that this method should not be called for resolutions that correspond\n   * to an integer zoom level.  Instead call the `getTileCoordForXYAndZ_` method.\n   * @param {number} x X.\n   * @param {number} y Y.\n   * @param {number} resolution Resolution (for a non-integer zoom level).\n   * @param {boolean} reverseIntersectionPolicy Instead of letting edge\n   *     intersections go to the higher tile coordinate, let edge intersections\n   *     go to the lower tile coordinate.\n   * @param {module:ol/tilecoord~TileCoord=} opt_tileCoord Temporary module:ol/tilecoord~TileCoord object.\n   * @return {module:ol/tilecoord~TileCoord} Tile coordinate.\n   * @private\n   */\n  getTileCoordForXYAndResolution_(x, y, resolution, reverseIntersectionPolicy, opt_tileCoord) {\n    const z = this.getZForResolution(resolution);\n    const scale = resolution / this.getResolution(z);\n    const origin = this.getOrigin(z);\n    const tileSize = toSize(this.getTileSize(z), this.tmpSize_);\n\n    const adjustX = reverseIntersectionPolicy ? 0.5 : 0;\n    const adjustY = reverseIntersectionPolicy ? 0 : 0.5;\n    const xFromOrigin = Math.floor((x - origin[0]) / resolution + adjustX);\n    const yFromOrigin = Math.floor((y - origin[1]) / resolution + adjustY);\n    let tileCoordX = scale * xFromOrigin / tileSize[0];\n    let tileCoordY = scale * yFromOrigin / tileSize[1];\n\n    if (reverseIntersectionPolicy) {\n      tileCoordX = Math.ceil(tileCoordX) - 1;\n      tileCoordY = Math.ceil(tileCoordY) - 1;\n    } else {\n      tileCoordX = Math.floor(tileCoordX);\n      tileCoordY = Math.floor(tileCoordY);\n    }\n\n    return createOrUpdateTileCoord(z, tileCoordX, tileCoordY, opt_tileCoord);\n  }\n\n  /**\n   * Although there is repetition between this method and `getTileCoordForXYAndResolution_`,\n   * they should have separate implementations.  This method is for integer zoom\n   * levels.  The other method should only be called for resolutions corresponding\n   * to non-integer zoom levels.\n   * @param {number} x Map x coordinate.\n   * @param {number} y Map y coordinate.\n   * @param {number} z Integer zoom level.\n   * @param {boolean} reverseIntersectionPolicy Instead of letting edge\n   *     intersections go to the higher tile coordinate, let edge intersections\n   *     go to the lower tile coordinate.\n   * @param {module:ol/tilecoord~TileCoord=} opt_tileCoord Temporary module:ol/tilecoord~TileCoord object.\n   * @return {module:ol/tilecoord~TileCoord} Tile coordinate.\n   * @private\n   */\n  getTileCoordForXYAndZ_(x, y, z, reverseIntersectionPolicy, opt_tileCoord) {\n    const origin = this.getOrigin(z);\n    const resolution = this.getResolution(z);\n    const tileSize = toSize(this.getTileSize(z), this.tmpSize_);\n\n    const adjustX = reverseIntersectionPolicy ? 0.5 : 0;\n    const adjustY = reverseIntersectionPolicy ? 0 : 0.5;\n    const xFromOrigin = Math.floor((x - origin[0]) / resolution + adjustX);\n    const yFromOrigin = Math.floor((y - origin[1]) / resolution + adjustY);\n    let tileCoordX = xFromOrigin / tileSize[0];\n    let tileCoordY = yFromOrigin / tileSize[1];\n\n    if (reverseIntersectionPolicy) {\n      tileCoordX = Math.ceil(tileCoordX) - 1;\n      tileCoordY = Math.ceil(tileCoordY) - 1;\n    } else {\n      tileCoordX = Math.floor(tileCoordX);\n      tileCoordY = Math.floor(tileCoordY);\n    }\n\n    return createOrUpdateTileCoord(z, tileCoordX, tileCoordY, opt_tileCoord);\n  }\n\n  /**\n   * Get a tile coordinate given a map coordinate and zoom level.\n   * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n   * @param {number} z Zoom level.\n   * @param {module:ol/tilecoord~TileCoord=} opt_tileCoord Destination module:ol/tilecoord~TileCoord object.\n   * @return {module:ol/tilecoord~TileCoord} Tile coordinate.\n   * @api\n   */\n  getTileCoordForCoordAndZ(coordinate, z, opt_tileCoord) {\n    return this.getTileCoordForXYAndZ_(\n      coordinate[0], coordinate[1], z, false, opt_tileCoord);\n  }\n\n  /**\n   * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n   * @return {number} Tile resolution.\n   */\n  getTileCoordResolution(tileCoord) {\n    return this.resolutions_[tileCoord[0]];\n  }\n\n  /**\n   * Get the tile size for a zoom level. The type of the return value matches the\n   * `tileSize` or `tileSizes` that the tile grid was configured with. To always\n   * get an `module:ol/size~Size`, run the result through `module:ol/size~Size.toSize()`.\n   * @param {number} z Z.\n   * @return {number|module:ol/size~Size} Tile size.\n   * @api\n   */\n  getTileSize(z) {\n    if (this.tileSize_) {\n      return this.tileSize_;\n    } else {\n      return this.tileSizes_[z];\n    }\n  }\n\n  /**\n   * @param {number} z Zoom level.\n   * @return {module:ol/TileRange} Extent tile range for the specified zoom level.\n   */\n  getFullTileRange(z) {\n    if (!this.fullTileRanges_) {\n      return null;\n    } else {\n      return this.fullTileRanges_[z];\n    }\n  }\n\n  /**\n   * @param {number} resolution Resolution.\n   * @param {number=} opt_direction If 0, the nearest resolution will be used.\n   *     If 1, the nearest lower resolution will be used. If -1, the nearest\n   *     higher resolution will be used. Default is 0.\n   * @return {number} Z.\n   * @api\n   */\n  getZForResolution(resolution, opt_direction) {\n    const z = linearFindNearest(this.resolutions_, resolution, opt_direction || 0);\n    return clamp(z, this.minZoom, this.maxZoom);\n  }\n\n  /**\n   * @param {!module:ol/extent~Extent} extent Extent for this tile grid.\n   * @private\n   */\n  calculateTileRanges_(extent) {\n    const length = this.resolutions_.length;\n    const fullTileRanges = new Array(length);\n    for (let z = this.minZoom; z < length; ++z) {\n      fullTileRanges[z] = this.getTileRangeForExtentAndZ(extent, z);\n    }\n    this.fullTileRanges_ = fullTileRanges;\n  }\n}\n\n\nexport default TileGrid;\n","/**\n * @module ol/tilegrid\n */\nimport {DEFAULT_MAX_ZOOM, DEFAULT_TILE_SIZE} from './tilegrid/common.js';\nimport {toSize} from './size.js';\nimport {containsCoordinate, createOrUpdate, getCorner, getHeight, getWidth} from './extent.js';\nimport Corner from './extent/Corner.js';\nimport {assign} from './obj.js';\nimport {get as getProjection, METERS_PER_UNIT} from './proj.js';\nimport Units from './proj/Units.js';\nimport TileGrid from './tilegrid/TileGrid.js';\n\n\n/**\n * @param {module:ol/proj/Projection} projection Projection.\n * @return {!module:ol/tilegrid/TileGrid} Default tile grid for the\n * passed projection.\n */\nexport function getForProjection(projection) {\n  let tileGrid = projection.getDefaultTileGrid();\n  if (!tileGrid) {\n    tileGrid = createForProjection(projection);\n    projection.setDefaultTileGrid(tileGrid);\n  }\n  return tileGrid;\n}\n\n\n/**\n * @param {module:ol/tilegrid/TileGrid} tileGrid Tile grid.\n * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n * @param {module:ol/proj/Projection} projection Projection.\n * @return {module:ol/tilecoord~TileCoord} Tile coordinate.\n */\nexport function wrapX(tileGrid, tileCoord, projection) {\n  const z = tileCoord[0];\n  const center = tileGrid.getTileCoordCenter(tileCoord);\n  const projectionExtent = extentFromProjection(projection);\n  if (!containsCoordinate(projectionExtent, center)) {\n    const worldWidth = getWidth(projectionExtent);\n    const worldsAway = Math.ceil((projectionExtent[0] - center[0]) / worldWidth);\n    center[0] += worldWidth * worldsAway;\n    return tileGrid.getTileCoordForCoordAndZ(center, z);\n  } else {\n    return tileCoord;\n  }\n}\n\n\n/**\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {number=} opt_maxZoom Maximum zoom level (default is\n *     DEFAULT_MAX_ZOOM).\n * @param {number|module:ol/size~Size=} opt_tileSize Tile size (default uses\n *     DEFAULT_TILE_SIZE).\n * @param {module:ol/extent/Corner=} opt_corner Extent corner (default is `'top-left'`).\n * @return {!module:ol/tilegrid/TileGrid} TileGrid instance.\n */\nexport function createForExtent(extent, opt_maxZoom, opt_tileSize, opt_corner) {\n  const corner = opt_corner !== undefined ? opt_corner : Corner.TOP_LEFT;\n\n  const resolutions = resolutionsFromExtent(extent, opt_maxZoom, opt_tileSize);\n\n  return new TileGrid({\n    extent: extent,\n    origin: getCorner(extent, corner),\n    resolutions: resolutions,\n    tileSize: opt_tileSize\n  });\n}\n\n\n/**\n * @typedef {Object} XYZOptions\n * @property {module:ol/extent~Extent} [extent] Extent for the tile grid. The origin for an XYZ tile grid is the\n * top-left corner of the extent. The zero level of the grid is defined by the resolution at which one tile fits in the\n * provided extent. If not provided, the extent of the EPSG:3857 projection is used.\n * @property {number} [maxZoom] Maximum zoom. The default is `42`. This determines the number of levels\n * in the grid set. For example, a `maxZoom` of 21 means there are 22 levels in the grid set.\n * @property {number} [minZoom=0] Minimum zoom.\n * @property {number|module:ol/size~Size} [tileSize=[256, 256]] Tile size in pixels.\n */\n\n\n/**\n * Creates a tile grid with a standard XYZ tiling scheme.\n * @param {module:ol/tilegrid~XYZOptions=} opt_options Tile grid options.\n * @return {!module:ol/tilegrid/TileGrid} Tile grid instance.\n * @api\n */\nexport function createXYZ(opt_options) {\n  const options = /** @type {module:ol/tilegrid/TileGrid~Options} */ ({});\n  assign(options, opt_options !== undefined ?\n    opt_options : /** @type {module:ol/tilegrid~XYZOptions} */ ({}));\n  if (options.extent === undefined) {\n    options.extent = getProjection('EPSG:3857').getExtent();\n  }\n  options.resolutions = resolutionsFromExtent(\n    options.extent, options.maxZoom, options.tileSize);\n  delete options.maxZoom;\n\n  return new TileGrid(options);\n}\n\n\n/**\n * Create a resolutions array from an extent.  A zoom factor of 2 is assumed.\n * @param {module:ol/extent~Extent} extent Extent.\n * @param {number=} opt_maxZoom Maximum zoom level (default is\n *     DEFAULT_MAX_ZOOM).\n * @param {number|module:ol/size~Size=} opt_tileSize Tile size (default uses\n *     DEFAULT_TILE_SIZE).\n * @return {!Array.<number>} Resolutions array.\n */\nfunction resolutionsFromExtent(extent, opt_maxZoom, opt_tileSize) {\n  const maxZoom = opt_maxZoom !== undefined ?\n    opt_maxZoom : DEFAULT_MAX_ZOOM;\n\n  const height = getHeight(extent);\n  const width = getWidth(extent);\n\n  const tileSize = toSize(opt_tileSize !== undefined ?\n    opt_tileSize : DEFAULT_TILE_SIZE);\n  const maxResolution = Math.max(\n    width / tileSize[0], height / tileSize[1]);\n\n  const length = maxZoom + 1;\n  const resolutions = new Array(length);\n  for (let z = 0; z < length; ++z) {\n    resolutions[z] = maxResolution / Math.pow(2, z);\n  }\n  return resolutions;\n}\n\n\n/**\n * @param {module:ol/proj~ProjectionLike} projection Projection.\n * @param {number=} opt_maxZoom Maximum zoom level (default is\n *     DEFAULT_MAX_ZOOM).\n * @param {number|module:ol/size~Size=} opt_tileSize Tile size (default uses\n *     DEFAULT_TILE_SIZE).\n * @param {module:ol/extent/Corner=} opt_corner Extent corner (default is `'top-left'`).\n * @return {!module:ol/tilegrid/TileGrid} TileGrid instance.\n */\nexport function createForProjection(projection, opt_maxZoom, opt_tileSize, opt_corner) {\n  const extent = extentFromProjection(projection);\n  return createForExtent(extent, opt_maxZoom, opt_tileSize, opt_corner);\n}\n\n\n/**\n * Generate a tile grid extent from a projection.  If the projection has an\n * extent, it is used.  If not, a global extent is assumed.\n * @param {module:ol/proj~ProjectionLike} projection Projection.\n * @return {module:ol/extent~Extent} Extent.\n */\nexport function extentFromProjection(projection) {\n  projection = getProjection(projection);\n  let extent = projection.getExtent();\n  if (!extent) {\n    const half = 180 * METERS_PER_UNIT[Units.DEGREES] / projection.getMetersPerUnit();\n    extent = createOrUpdate(-half, -half, half, half);\n  }\n  return extent;\n}\n","/**\n * @module ol/source/Tile\n */\n\nimport {UNDEFINED} from '../functions.js';\nimport TileCache from '../TileCache.js';\nimport TileState from '../TileState.js';\nimport Event from '../events/Event.js';\nimport {equivalent} from '../proj.js';\nimport {toSize, scale as scaleSize} from '../size.js';\nimport Source from '../source/Source.js';\nimport {getKeyZXY, withinExtentAndZ} from '../tilecoord.js';\nimport {wrapX, getForProjection as getTileGridForProjection} from '../tilegrid.js';\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/source/Source~AttributionLike} [attributions]\n * @property {number} [cacheSize]\n * @property {module:ol/extent~Extent} [extent]\n * @property {boolean} [opaque]\n * @property {number} [tilePixelRatio]\n * @property {module:ol/proj~ProjectionLike} [projection]\n * @property {module:ol/source/State} [state]\n * @property {module:ol/tilegrid/TileGrid} [tileGrid]\n * @property {boolean} [wrapX=true]\n * @property {number} [transition]\n */\n\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Base class for sources providing images divided into a tile grid.\n * @api\n */\nclass TileSource extends Source {\n  /**\n   * @param {module:ol/source/Tile~Options=} options SourceTile source options.\n   */\n  constructor(options) {\n\n    super({\n      attributions: options.attributions,\n      extent: options.extent,\n      projection: options.projection,\n      state: options.state,\n      wrapX: options.wrapX\n    });\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.opaque_ = options.opaque !== undefined ? options.opaque : false;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.tilePixelRatio_ = options.tilePixelRatio !== undefined ?\n      options.tilePixelRatio : 1;\n\n    /**\n     * @protected\n     * @type {module:ol/tilegrid/TileGrid}\n     */\n    this.tileGrid = options.tileGrid !== undefined ? options.tileGrid : null;\n\n    /**\n     * @protected\n     * @type {module:ol/TileCache}\n     */\n    this.tileCache = new TileCache(options.cacheSize);\n\n    /**\n     * @protected\n     * @type {module:ol/size~Size}\n     */\n    this.tmpSize = [0, 0];\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.key_ = '';\n\n    /**\n     * @protected\n     * @type {module:ol/Tile~Options}\n     */\n    this.tileOptions = {transition: options.transition};\n\n  }\n\n  /**\n   * @return {boolean} Can expire cache.\n   */\n  canExpireCache() {\n    return this.tileCache.canExpireCache();\n  }\n\n  /**\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @param {!Object.<string, module:ol/TileRange>} usedTiles Used tiles.\n   */\n  expireCache(projection, usedTiles) {\n    const tileCache = this.getTileCacheForProjection(projection);\n    if (tileCache) {\n      tileCache.expireCache(usedTiles);\n    }\n  }\n\n  /**\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @param {number} z Zoom level.\n   * @param {module:ol/TileRange} tileRange Tile range.\n   * @param {function(module:ol/Tile):(boolean|undefined)} callback Called with each\n   *     loaded tile.  If the callback returns `false`, the tile will not be\n   *     considered loaded.\n   * @return {boolean} The tile range is fully covered with loaded tiles.\n   */\n  forEachLoadedTile(projection, z, tileRange, callback) {\n    const tileCache = this.getTileCacheForProjection(projection);\n    if (!tileCache) {\n      return false;\n    }\n\n    let covered = true;\n    let tile, tileCoordKey, loaded;\n    for (let x = tileRange.minX; x <= tileRange.maxX; ++x) {\n      for (let y = tileRange.minY; y <= tileRange.maxY; ++y) {\n        tileCoordKey = getKeyZXY(z, x, y);\n        loaded = false;\n        if (tileCache.containsKey(tileCoordKey)) {\n          tile = /** @type {!module:ol/Tile} */ (tileCache.get(tileCoordKey));\n          loaded = tile.getState() === TileState.LOADED;\n          if (loaded) {\n            loaded = (callback(tile) !== false);\n          }\n        }\n        if (!loaded) {\n          covered = false;\n        }\n      }\n    }\n    return covered;\n  }\n\n  /**\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @return {number} Gutter.\n   */\n  getGutter(projection) {\n    return 0;\n  }\n\n  /**\n   * Return the key to be used for all tiles in the source.\n   * @return {string} The key for all tiles.\n   * @protected\n   */\n  getKey() {\n    return this.key_;\n  }\n\n  /**\n   * Set the value to be used as the key for all tiles in the source.\n   * @param {string} key The key for tiles.\n   * @protected\n   */\n  setKey(key) {\n    if (this.key_ !== key) {\n      this.key_ = key;\n      this.changed();\n    }\n  }\n\n  /**\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @return {boolean} Opaque.\n   */\n  getOpaque(projection) {\n    return this.opaque_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getResolutions() {\n    return this.tileGrid.getResolutions();\n  }\n\n  /**\n   * @abstract\n   * @param {number} z Tile coordinate z.\n   * @param {number} x Tile coordinate x.\n   * @param {number} y Tile coordinate y.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @return {!module:ol/Tile} Tile.\n   */\n  getTile(z, x, y, pixelRatio, projection) {}\n\n  /**\n   * Return the tile grid of the tile source.\n   * @return {module:ol/tilegrid/TileGrid} Tile grid.\n   * @api\n   */\n  getTileGrid() {\n    return this.tileGrid;\n  }\n\n  /**\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @return {!module:ol/tilegrid/TileGrid} Tile grid.\n   */\n  getTileGridForProjection(projection) {\n    if (!this.tileGrid) {\n      return getTileGridForProjection(projection);\n    } else {\n      return this.tileGrid;\n    }\n  }\n\n  /**\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @return {module:ol/TileCache} Tile cache.\n   * @protected\n   */\n  getTileCacheForProjection(projection) {\n    const thisProj = this.getProjection();\n    if (thisProj && !equivalent(thisProj, projection)) {\n      return null;\n    } else {\n      return this.tileCache;\n    }\n  }\n\n  /**\n   * Get the tile pixel ratio for this source. Subclasses may override this\n   * method, which is meant to return a supported pixel ratio that matches the\n   * provided `pixelRatio` as close as possible.\n   * @param {number} pixelRatio Pixel ratio.\n   * @return {number} Tile pixel ratio.\n   */\n  getTilePixelRatio(pixelRatio) {\n    return this.tilePixelRatio_;\n  }\n\n  /**\n   * @param {number} z Z.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @return {module:ol/size~Size} Tile size.\n   */\n  getTilePixelSize(z, pixelRatio, projection) {\n    const tileGrid = this.getTileGridForProjection(projection);\n    const tilePixelRatio = this.getTilePixelRatio(pixelRatio);\n    const tileSize = toSize(tileGrid.getTileSize(z), this.tmpSize);\n    if (tilePixelRatio == 1) {\n      return tileSize;\n    } else {\n      return scaleSize(tileSize, tilePixelRatio, this.tmpSize);\n    }\n  }\n\n  /**\n   * Returns a tile coordinate wrapped around the x-axis. When the tile coordinate\n   * is outside the resolution and extent range of the tile grid, `null` will be\n   * returned.\n   * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n   * @param {module:ol/proj/Projection=} opt_projection Projection.\n   * @return {module:ol/tilecoord~TileCoord} Tile coordinate to be passed to the tileUrlFunction or\n   *     null if no tile URL should be created for the passed `tileCoord`.\n   */\n  getTileCoordForTileUrlFunction(tileCoord, opt_projection) {\n    const projection = opt_projection !== undefined ?\n      opt_projection : this.getProjection();\n    const tileGrid = this.getTileGridForProjection(projection);\n    if (this.getWrapX() && projection.isGlobal()) {\n      tileCoord = wrapX(tileGrid, tileCoord, projection);\n    }\n    return withinExtentAndZ(tileCoord, tileGrid) ? tileCoord : null;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  refresh() {\n    this.tileCache.clear();\n    this.changed();\n  }\n}\n\n\n/**\n * Marks a tile coord as being used, without triggering a load.\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {module:ol/proj/Projection} projection Projection.\n */\nTileSource.prototype.useTile = UNDEFINED;\n\n\n/**\n * @classdesc\n * Events emitted by {@link module:ol/source/Tile~TileSource} instances are instances of this\n * type.\n */\nexport class TileSourceEvent extends Event {\n  /**\n   * @param {string} type Type.\n   * @param {module:ol/Tile} tile The tile.\n   */\n  constructor(type, tile) {\n\n    super(type);\n\n    /**\n     * The tile related to the event.\n     * @type {module:ol/Tile}\n     * @api\n     */\n    this.tile = tile;\n\n  }\n\n}\n\nexport default TileSource;\n","/**\n * @module ol/source/TileEventType\n */\n\n/**\n * @enum {string}\n */\nexport default {\n\n  /**\n   * Triggered when a tile starts loading.\n   * @event module:ol/source/Tile~TileSourceEvent#tileloadstart\n   * @api\n   */\n  TILELOADSTART: 'tileloadstart',\n\n  /**\n   * Triggered when a tile finishes loading, either when its data is loaded,\n   * or when loading was aborted because the tile is no longer needed.\n   * @event module:ol/source/Tile~TileSourceEvent#tileloadend\n   * @api\n   */\n  TILELOADEND: 'tileloadend',\n\n  /**\n   * Triggered if tile loading results in an error.\n   * @event module:ol/source/Tile~TileSourceEvent#tileloaderror\n   * @api\n   */\n  TILELOADERROR: 'tileloaderror'\n\n};\n","/**\n * @module ol/source/UrlTile\n */\nimport {getUid} from '../util.js';\nimport TileState from '../TileState.js';\nimport {expandUrl, createFromTemplates, nullTileUrlFunction} from '../tileurlfunction.js';\nimport TileSource, {TileSourceEvent} from '../source/Tile.js';\nimport TileEventType from '../source/TileEventType.js';\nimport {getKeyZXY} from '../tilecoord.js';\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/source/Source~AttributionLike} [attributions]\n * @property {number} [cacheSize]\n * @property {module:ol/extent~Extent} [extent]\n * @property {boolean} [opaque]\n * @property {module:ol/proj~ProjectionLike} [projection]\n * @property {module:ol/source/State} [state]\n * @property {module:ol/tilegrid/TileGrid} [tileGrid]\n * @property {module:ol/Tile~LoadFunction} tileLoadFunction\n * @property {number} [tilePixelRatio]\n * @property {module:ol/Tile~UrlFunction} [tileUrlFunction]\n * @property {string} [url]\n * @property {Array.<string>} [urls]\n * @property {boolean} [wrapX=true]\n * @property {number} [transition]\n */\n\n\n/**\n * @classdesc\n * Base class for sources providing tiles divided into a tile grid over http.\n *\n * @fires module:ol/source/TileEvent\n */\nclass UrlTile extends TileSource {\n  /**\n   * @param {module:ol/source/UrlTile~Options=} options Image tile options.\n   */\n  constructor(options) {\n\n    super({\n      attributions: options.attributions,\n      cacheSize: options.cacheSize,\n      extent: options.extent,\n      opaque: options.opaque,\n      projection: options.projection,\n      state: options.state,\n      tileGrid: options.tileGrid,\n      tilePixelRatio: options.tilePixelRatio,\n      wrapX: options.wrapX,\n      transition: options.transition\n    });\n\n    /**\n     * @protected\n     * @type {module:ol/Tile~LoadFunction}\n     */\n    this.tileLoadFunction = options.tileLoadFunction;\n\n    /**\n     * @protected\n     * @type {module:ol/Tile~UrlFunction}\n     */\n    this.tileUrlFunction = this.fixedTileUrlFunction ?\n      this.fixedTileUrlFunction.bind(this) : nullTileUrlFunction;\n\n    /**\n     * @protected\n     * @type {!Array.<string>|null}\n     */\n    this.urls = null;\n\n    if (options.urls) {\n      this.setUrls(options.urls);\n    } else if (options.url) {\n      this.setUrl(options.url);\n    }\n    if (options.tileUrlFunction) {\n      this.setTileUrlFunction(options.tileUrlFunction);\n    }\n\n    /**\n     * @private\n     * @type {!Object.<number, boolean>}\n     */\n    this.tileLoadingKeys_ = {};\n\n  }\n\n  /**\n   * Return the tile load function of the source.\n   * @return {module:ol/Tile~LoadFunction} TileLoadFunction\n   * @api\n   */\n  getTileLoadFunction() {\n    return this.tileLoadFunction;\n  }\n\n  /**\n   * Return the tile URL function of the source.\n   * @return {module:ol/Tile~UrlFunction} TileUrlFunction\n   * @api\n   */\n  getTileUrlFunction() {\n    return this.tileUrlFunction;\n  }\n\n  /**\n   * Return the URLs used for this source.\n   * When a tileUrlFunction is used instead of url or urls,\n   * null will be returned.\n   * @return {!Array.<string>|null} URLs.\n   * @api\n   */\n  getUrls() {\n    return this.urls;\n  }\n\n  /**\n   * Handle tile change events.\n   * @param {module:ol/events/Event} event Event.\n   * @protected\n   */\n  handleTileChange(event) {\n    const tile = /** @type {module:ol/Tile} */ (event.target);\n    const uid = getUid(tile);\n    const tileState = tile.getState();\n    let type;\n    if (tileState == TileState.LOADING) {\n      this.tileLoadingKeys_[uid] = true;\n      type = TileEventType.TILELOADSTART;\n    } else if (uid in this.tileLoadingKeys_) {\n      delete this.tileLoadingKeys_[uid];\n      type = tileState == TileState.ERROR ? TileEventType.TILELOADERROR :\n        (tileState == TileState.LOADED || tileState == TileState.ABORT) ?\n          TileEventType.TILELOADEND : undefined;\n    }\n    if (type != undefined) {\n      this.dispatchEvent(new TileSourceEvent(type, tile));\n    }\n  }\n\n  /**\n   * Set the tile load function of the source.\n   * @param {module:ol/Tile~LoadFunction} tileLoadFunction Tile load function.\n   * @api\n   */\n  setTileLoadFunction(tileLoadFunction) {\n    this.tileCache.clear();\n    this.tileLoadFunction = tileLoadFunction;\n    this.changed();\n  }\n\n  /**\n   * Set the tile URL function of the source.\n   * @param {module:ol/Tile~UrlFunction} tileUrlFunction Tile URL function.\n   * @param {string=} opt_key Optional new tile key for the source.\n   * @api\n   */\n  setTileUrlFunction(tileUrlFunction, opt_key) {\n    this.tileUrlFunction = tileUrlFunction;\n    this.tileCache.pruneExceptNewestZ();\n    if (typeof opt_key !== 'undefined') {\n      this.setKey(opt_key);\n    } else {\n      this.changed();\n    }\n  }\n\n  /**\n   * Set the URL to use for requests.\n   * @param {string} url URL.\n   * @api\n   */\n  setUrl(url) {\n    const urls = this.urls = expandUrl(url);\n    this.setTileUrlFunction(this.fixedTileUrlFunction ?\n      this.fixedTileUrlFunction.bind(this) :\n      createFromTemplates(urls, this.tileGrid), url);\n  }\n\n  /**\n   * Set the URLs to use for requests.\n   * @param {Array.<string>} urls URLs.\n   * @api\n   */\n  setUrls(urls) {\n    this.urls = urls;\n    const key = urls.join('\\n');\n    this.setTileUrlFunction(this.fixedTileUrlFunction ?\n      this.fixedTileUrlFunction.bind(this) :\n      createFromTemplates(urls, this.tileGrid), key);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  useTile(z, x, y) {\n    const tileCoordKey = getKeyZXY(z, x, y);\n    if (this.tileCache.containsKey(tileCoordKey)) {\n      this.tileCache.get(tileCoordKey);\n    }\n  }\n}\n\n\n/**\n * @type {module:ol/Tile~UrlFunction|undefined}\n * @protected\n */\nUrlTile.prototype.fixedTileUrlFunction;\n\nexport default UrlTile;\n","/**\n * @module ol/source/TileImage\n */\nimport {ENABLE_RASTER_REPROJECTION} from '../reproj/common.js';\nimport {getUid} from '../util.js';\nimport ImageTile from '../ImageTile.js';\nimport TileCache from '../TileCache.js';\nimport TileState from '../TileState.js';\nimport {listen} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport {equivalent, get as getProjection} from '../proj.js';\nimport ReprojTile from '../reproj/Tile.js';\nimport UrlTile from '../source/UrlTile.js';\nimport {getKey, getKeyZXY} from '../tilecoord.js';\nimport {getForProjection as getTileGridForProjection} from '../tilegrid.js';\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/source/Source~AttributionLike} [attributions] Attributions.\n * @property {number} [cacheSize=2048] Cache size.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images.  Note that\n * you must provide a `crossOrigin` value if you are using the WebGL renderer or if you want to\n * access pixel data with the Canvas renderer.  See\n * https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {boolean} [opaque=true] Whether the layer is opaque.\n * @property {module:ol/proj~ProjectionLike} projection Projection.\n * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).\n * Higher values can increase reprojection performance, but decrease precision.\n * @property {module:ol/source/State} [state] Source state.\n * @property {module:ol/ImageTile~TileClass} [tileClass] Class used to instantiate image tiles.\n * Default is {@link module:ol/ImageTile~ImageTile}.\n * @property {module:ol/tilegrid/TileGrid} [tileGrid] Tile grid.\n * @property {module:ol/Tile~LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is\n * ```js\n * function(imageTile, src) {\n *   imageTile.getImage().src = src;\n * };\n * ```\n * @property {number} [tilePixelRatio=1] The pixel ratio used by the tile service. For example, if the tile\n * service advertizes 256px by 256px tiles but actually sends 512px\n * by 512px images (for retina/hidpi devices) then `tilePixelRatio`\n * should be set to `2`.\n * @property {module:ol/Tile~UrlFunction} [tileUrlFunction] Optional function to get tile URL given a tile coordinate and the projection.\n * @property {string} [url] URL template. Must include `{x}`, `{y}` or `{-y}`, and `{z}` placeholders.\n * A `{?-?}` template pattern, for example `subdomain{a-f}.domain.com`, may be\n * used instead of defining each one separately in the `urls` option.\n * @property {Array.<string>} [urls] An array of URL templates.\n * @property {boolean} [wrapX] Whether to wrap the world horizontally. The default, is to\n * request out-of-bounds tiles from the server. When set to `false`, only one\n * world will be rendered. When set to `true`, tiles will be requested for one\n * world only, but they will be wrapped horizontally to render multiple worlds.\n * @property {number} [transition] Duration of the opacity transition for rendering.\n * To disable the opacity transition, pass `transition: 0`.\n */\n\n\n/**\n * @classdesc\n * Base class for sources providing images divided into a tile grid.\n *\n * @fires module:ol/source/Tile~TileSourceEvent\n * @api\n */\nclass TileImage extends UrlTile {\n  /**\n   * @param {module:ol/source/TileImage~Options=} options Image tile options.\n   */\n  constructor(options) {\n\n    super({\n      attributions: options.attributions,\n      cacheSize: options.cacheSize,\n      extent: options.extent,\n      opaque: options.opaque,\n      projection: options.projection,\n      state: options.state,\n      tileGrid: options.tileGrid,\n      tileLoadFunction: options.tileLoadFunction ?\n        options.tileLoadFunction : defaultTileLoadFunction,\n      tilePixelRatio: options.tilePixelRatio,\n      tileUrlFunction: options.tileUrlFunction,\n      url: options.url,\n      urls: options.urls,\n      wrapX: options.wrapX,\n      transition: options.transition\n    });\n\n    /**\n     * @protected\n     * @type {?string}\n     */\n    this.crossOrigin =\n        options.crossOrigin !== undefined ? options.crossOrigin : null;\n\n    /**\n     * @protected\n     * @type {function(new: module:ol/ImageTile, module:ol/tilecoord~TileCoord, module:ol/TileState, string,\n     *        ?string, module:ol/Tile~LoadFunction, module:ol/Tile~Options=)}\n     */\n    this.tileClass = options.tileClass !== undefined ?\n      options.tileClass : ImageTile;\n\n    /**\n     * @protected\n     * @type {!Object.<string, module:ol/TileCache>}\n     */\n    this.tileCacheForProjection = {};\n\n    /**\n     * @protected\n     * @type {!Object.<string, module:ol/tilegrid/TileGrid>}\n     */\n    this.tileGridForProjection = {};\n\n    /**\n     * @private\n     * @type {number|undefined}\n     */\n    this.reprojectionErrorThreshold_ = options.reprojectionErrorThreshold;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.renderReprojectionEdges_ = false;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  canExpireCache() {\n    if (!ENABLE_RASTER_REPROJECTION) {\n      return UrlTile.prototype.canExpireCache.call(this);\n    }\n    if (this.tileCache.canExpireCache()) {\n      return true;\n    } else {\n      for (const key in this.tileCacheForProjection) {\n        if (this.tileCacheForProjection[key].canExpireCache()) {\n          return true;\n        }\n      }\n    }\n    return false;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  expireCache(projection, usedTiles) {\n    if (!ENABLE_RASTER_REPROJECTION) {\n      UrlTile.prototype.expireCache.call(this, projection, usedTiles);\n      return;\n    }\n    const usedTileCache = this.getTileCacheForProjection(projection);\n\n    this.tileCache.expireCache(this.tileCache == usedTileCache ? usedTiles : {});\n    for (const id in this.tileCacheForProjection) {\n      const tileCache = this.tileCacheForProjection[id];\n      tileCache.expireCache(tileCache == usedTileCache ? usedTiles : {});\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getGutter(projection) {\n    if (ENABLE_RASTER_REPROJECTION &&\n        this.getProjection() && projection && !equivalent(this.getProjection(), projection)) {\n      return 0;\n    } else {\n      return this.getGutterInternal();\n    }\n  }\n\n  /**\n   * @protected\n   * @return {number} Gutter.\n   */\n  getGutterInternal() {\n    return 0;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getOpaque(projection) {\n    if (ENABLE_RASTER_REPROJECTION &&\n        this.getProjection() && projection && !equivalent(this.getProjection(), projection)) {\n      return false;\n    } else {\n      return UrlTile.prototype.getOpaque.call(this, projection);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getTileGridForProjection(projection) {\n    if (!ENABLE_RASTER_REPROJECTION) {\n      return UrlTile.prototype.getTileGridForProjection.call(this, projection);\n    }\n    const thisProj = this.getProjection();\n    if (this.tileGrid && (!thisProj || equivalent(thisProj, projection))) {\n      return this.tileGrid;\n    } else {\n      const projKey = getUid(projection).toString();\n      if (!(projKey in this.tileGridForProjection)) {\n        this.tileGridForProjection[projKey] = getTileGridForProjection(projection);\n      }\n      return (\n        /** @type {!module:ol/tilegrid/TileGrid} */ (this.tileGridForProjection[projKey])\n      );\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getTileCacheForProjection(projection) {\n    if (!ENABLE_RASTER_REPROJECTION) {\n      return UrlTile.prototype.getTileCacheForProjection.call(this, projection);\n    }\n    const thisProj = this.getProjection(); if (!thisProj || equivalent(thisProj, projection)) {\n      return this.tileCache;\n    } else {\n      const projKey = getUid(projection).toString();\n      if (!(projKey in this.tileCacheForProjection)) {\n        this.tileCacheForProjection[projKey] = new TileCache(this.tileCache.highWaterMark);\n      }\n      return this.tileCacheForProjection[projKey];\n    }\n  }\n\n  /**\n   * @param {number} z Tile coordinate z.\n   * @param {number} x Tile coordinate x.\n   * @param {number} y Tile coordinate y.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @param {string} key The key set on the tile.\n   * @return {!module:ol/Tile} Tile.\n   * @private\n   */\n  createTile_(z, x, y, pixelRatio, projection, key) {\n    const tileCoord = [z, x, y];\n    const urlTileCoord = this.getTileCoordForTileUrlFunction(\n      tileCoord, projection);\n    const tileUrl = urlTileCoord ?\n      this.tileUrlFunction(urlTileCoord, pixelRatio, projection) : undefined;\n    const tile = new this.tileClass(\n      tileCoord,\n      tileUrl !== undefined ? TileState.IDLE : TileState.EMPTY,\n      tileUrl !== undefined ? tileUrl : '',\n      this.crossOrigin,\n      this.tileLoadFunction,\n      this.tileOptions);\n    tile.key = key;\n    listen(tile, EventType.CHANGE,\n      this.handleTileChange, this);\n    return tile;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getTile(z, x, y, pixelRatio, projection) {\n    const sourceProjection = /** @type {!module:ol/proj/Projection} */ (this.getProjection());\n    if (!ENABLE_RASTER_REPROJECTION ||\n        !sourceProjection || !projection || equivalent(sourceProjection, projection)) {\n      return this.getTileInternal(z, x, y, pixelRatio, sourceProjection || projection);\n    } else {\n      const cache = this.getTileCacheForProjection(projection);\n      const tileCoord = [z, x, y];\n      let tile;\n      const tileCoordKey = getKey(tileCoord);\n      if (cache.containsKey(tileCoordKey)) {\n        tile = /** @type {!module:ol/Tile} */ (cache.get(tileCoordKey));\n      }\n      const key = this.getKey();\n      if (tile && tile.key == key) {\n        return tile;\n      } else {\n        const sourceTileGrid = this.getTileGridForProjection(sourceProjection);\n        const targetTileGrid = this.getTileGridForProjection(projection);\n        const wrappedTileCoord =\n            this.getTileCoordForTileUrlFunction(tileCoord, projection);\n        const newTile = new ReprojTile(\n          sourceProjection, sourceTileGrid,\n          projection, targetTileGrid,\n          tileCoord, wrappedTileCoord, this.getTilePixelRatio(pixelRatio),\n          this.getGutterInternal(),\n          function(z, x, y, pixelRatio) {\n            return this.getTileInternal(z, x, y, pixelRatio, sourceProjection);\n          }.bind(this), this.reprojectionErrorThreshold_,\n          this.renderReprojectionEdges_);\n        newTile.key = key;\n\n        if (tile) {\n          newTile.interimTile = tile;\n          newTile.refreshInterimChain();\n          cache.replace(tileCoordKey, newTile);\n        } else {\n          cache.set(tileCoordKey, newTile);\n        }\n        return newTile;\n      }\n    }\n  }\n\n  /**\n   * @param {number} z Tile coordinate z.\n   * @param {number} x Tile coordinate x.\n   * @param {number} y Tile coordinate y.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {!module:ol/proj/Projection} projection Projection.\n   * @return {!module:ol/Tile} Tile.\n   * @protected\n   */\n  getTileInternal(z, x, y, pixelRatio, projection) {\n    let tile = null;\n    const tileCoordKey = getKeyZXY(z, x, y);\n    const key = this.getKey();\n    if (!this.tileCache.containsKey(tileCoordKey)) {\n      tile = this.createTile_(z, x, y, pixelRatio, projection, key);\n      this.tileCache.set(tileCoordKey, tile);\n    } else {\n      tile = this.tileCache.get(tileCoordKey);\n      if (tile.key != key) {\n        // The source's params changed. If the tile has an interim tile and if we\n        // can use it then we use it. Otherwise we create a new tile.  In both\n        // cases we attempt to assign an interim tile to the new tile.\n        const interimTile = tile;\n        tile = this.createTile_(z, x, y, pixelRatio, projection, key);\n\n        //make the new tile the head of the list,\n        if (interimTile.getState() == TileState.IDLE) {\n          //the old tile hasn't begun loading yet, and is now outdated, so we can simply discard it\n          tile.interimTile = interimTile.interimTile;\n        } else {\n          tile.interimTile = interimTile;\n        }\n        tile.refreshInterimChain();\n        this.tileCache.replace(tileCoordKey, tile);\n      }\n    }\n    return tile;\n  }\n\n  /**\n   * Sets whether to render reprojection edges or not (usually for debugging).\n   * @param {boolean} render Render the edges.\n   * @api\n   */\n  setRenderReprojectionEdges(render) {\n    if (!ENABLE_RASTER_REPROJECTION ||\n        this.renderReprojectionEdges_ == render) {\n      return;\n    }\n    this.renderReprojectionEdges_ = render;\n    for (const id in this.tileCacheForProjection) {\n      this.tileCacheForProjection[id].clear();\n    }\n    this.changed();\n  }\n\n  /**\n   * Sets the tile grid to use when reprojecting the tiles to the given\n   * projection instead of the default tile grid for the projection.\n   *\n   * This can be useful when the default tile grid cannot be created\n   * (e.g. projection has no extent defined) or\n   * for optimization reasons (custom tile size, resolutions, ...).\n   *\n   * @param {module:ol/proj~ProjectionLike} projection Projection.\n   * @param {module:ol/tilegrid/TileGrid} tilegrid Tile grid to use for the projection.\n   * @api\n   */\n  setTileGridForProjection(projection, tilegrid) {\n    if (ENABLE_RASTER_REPROJECTION) {\n      const proj = getProjection(projection);\n      if (proj) {\n        const projKey = getUid(proj).toString();\n        if (!(projKey in this.tileGridForProjection)) {\n          this.tileGridForProjection[projKey] = tilegrid;\n        }\n      }\n    }\n  }\n}\n\n\n/**\n * @param {module:ol/ImageTile} imageTile Image tile.\n * @param {string} src Source.\n */\nfunction defaultTileLoadFunction(imageTile, src) {\n  imageTile.getImage().src = src;\n}\n\nexport default TileImage;\n","/**\n * @module ol/source/BingMaps\n */\n\nimport {createFromTileUrlFunctions} from '../tileurlfunction.js';\nimport {applyTransform, intersects} from '../extent.js';\nimport {jsonp as requestJSONP} from '../net.js';\nimport {get as getProjection, getTransformFromProjections} from '../proj.js';\nimport SourceState from '../source/State.js';\nimport TileImage from '../source/TileImage.js';\nimport {createOrUpdate, quadKey} from '../tilecoord.js';\nimport {createXYZ, extentFromProjection} from '../tilegrid.js';\n\n\n/**\n * The attribution containing a link to the Microsoft® Bing™ Maps Platform APIs’\n * Terms Of Use.\n * @const\n * @type {string}\n */\nconst TOS_ATTRIBUTION = '<a class=\"ol-attribution-bing-tos\" ' +\n      'href=\"https://www.microsoft.com/maps/product/terms.html\">' +\n      'Terms of Use</a>';\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [cacheSize=2048] Cache size.\n * @property {boolean} [hidpi=false] If `true` hidpi tiles will be requested.\n * @property {string} [culture='en-us'] Culture code.\n * @property {string} key Bing Maps API key. Get yours at http://www.bingmapsportal.com/.\n * @property {string} imagerySet Type of imagery.\n * @property {number} [maxZoom=21] Max zoom. Default is what's advertized by the BingMaps service.\n * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).\n * Higher values can increase reprojection performance, but decrease precision.\n * @property {module:ol/Tile~LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is\n * ```js\n * function(imageTile, src) {\n *   imageTile.getImage().src = src;\n * };\n * ```\n * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.\n * @property {number} [transition] Duration of the opacity transition for rendering.\n * To disable the opacity transition, pass `transition: 0`.\n */\n\n\n/**\n * @classdesc\n * Layer source for Bing Maps tile data.\n * @api\n */\nclass BingMaps extends TileImage {\n  /**\n   * @param {module:ol/source/BingMaps~Options=} options Bing Maps options.\n   */\n  constructor(options) {\n\n    const hidpi = options.hidpi !== undefined ? options.hidpi : false;\n\n    super({\n      cacheSize: options.cacheSize,\n      crossOrigin: 'anonymous',\n      opaque: true,\n      projection: getProjection('EPSG:3857'),\n      reprojectionErrorThreshold: options.reprojectionErrorThreshold,\n      state: SourceState.LOADING,\n      tileLoadFunction: options.tileLoadFunction,\n      tilePixelRatio: hidpi ? 2 : 1,\n      wrapX: options.wrapX !== undefined ? options.wrapX : true,\n      transition: options.transition\n    });\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.hidpi_ = hidpi;\n\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.culture_ = options.culture !== undefined ? options.culture : 'en-us';\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.maxZoom_ = options.maxZoom !== undefined ? options.maxZoom : -1;\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.apiKey_ = options.key;\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.imagerySet_ = options.imagerySet;\n\n    const url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/' +\n        this.imagerySet_ +\n        '?uriScheme=https&include=ImageryProviders&key=' + this.apiKey_ +\n        '&c=' + this.culture_;\n\n    requestJSONP(url, this.handleImageryMetadataResponse.bind(this), undefined,\n      'jsonp');\n\n  }\n\n  /**\n   * Get the api key used for this source.\n   *\n   * @return {string} The api key.\n   * @api\n   */\n  getApiKey() {\n    return this.apiKey_;\n  }\n\n  /**\n   * Get the imagery set associated with this source.\n   *\n   * @return {string} The imagery set.\n   * @api\n   */\n  getImagerySet() {\n    return this.imagerySet_;\n  }\n\n  /**\n   * @param {BingMapsImageryMetadataResponse} response Response.\n   */\n  handleImageryMetadataResponse(response) {\n    if (response.statusCode != 200 ||\n        response.statusDescription != 'OK' ||\n        response.authenticationResultCode != 'ValidCredentials' ||\n        response.resourceSets.length != 1 ||\n        response.resourceSets[0].resources.length != 1) {\n      this.setState(SourceState.ERROR);\n      return;\n    }\n\n    const resource = response.resourceSets[0].resources[0];\n    const maxZoom = this.maxZoom_ == -1 ? resource.zoomMax : this.maxZoom_;\n\n    const sourceProjection = this.getProjection();\n    const extent = extentFromProjection(sourceProjection);\n    const tileSize = resource.imageWidth == resource.imageHeight ?\n      resource.imageWidth : [resource.imageWidth, resource.imageHeight];\n    const tileGrid = createXYZ({\n      extent: extent,\n      minZoom: resource.zoomMin,\n      maxZoom: maxZoom,\n      tileSize: tileSize / (this.hidpi_ ? 2 : 1)\n    });\n    this.tileGrid = tileGrid;\n\n    const culture = this.culture_;\n    const hidpi = this.hidpi_;\n    this.tileUrlFunction = createFromTileUrlFunctions(\n      resource.imageUrlSubdomains.map(function(subdomain) {\n        const quadKeyTileCoord = [0, 0, 0];\n        const imageUrl = resource.imageUrl\n          .replace('{subdomain}', subdomain)\n          .replace('{culture}', culture);\n        return (\n          /**\n           * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n           * @param {number} pixelRatio Pixel ratio.\n           * @param {module:ol/proj/Projection} projection Projection.\n           * @return {string|undefined} Tile URL.\n           */\n          function(tileCoord, pixelRatio, projection) {\n            if (!tileCoord) {\n              return undefined;\n            } else {\n              createOrUpdate(tileCoord[0], tileCoord[1], -tileCoord[2] - 1, quadKeyTileCoord);\n              let url = imageUrl;\n              if (hidpi) {\n                url += '&dpi=d1&device=mobile';\n              }\n              return url.replace('{quadkey}', quadKey(quadKeyTileCoord));\n            }\n          }\n        );\n      }));\n\n    if (resource.imageryProviders) {\n      const transform = getTransformFromProjections(\n        getProjection('EPSG:4326'), this.getProjection());\n\n      this.setAttributions(function(frameState) {\n        const attributions = [];\n        const zoom = frameState.viewState.zoom;\n        resource.imageryProviders.map(function(imageryProvider) {\n          let intersecting = false;\n          const coverageAreas = imageryProvider.coverageAreas;\n          for (let i = 0, ii = coverageAreas.length; i < ii; ++i) {\n            const coverageArea = coverageAreas[i];\n            if (zoom >= coverageArea.zoomMin && zoom <= coverageArea.zoomMax) {\n              const bbox = coverageArea.bbox;\n              const epsg4326Extent = [bbox[1], bbox[0], bbox[3], bbox[2]];\n              const extent = applyTransform(epsg4326Extent, transform);\n              if (intersects(extent, frameState.extent)) {\n                intersecting = true;\n                break;\n              }\n            }\n          }\n          if (intersecting) {\n            attributions.push(imageryProvider.attribution);\n          }\n        });\n\n        attributions.push(TOS_ATTRIBUTION);\n        return attributions;\n      });\n    }\n\n    this.setState(SourceState.READY);\n  }\n}\n\nexport default BingMaps;\n","/**\n * @module ol/source/XYZ\n */\n\nimport TileImage from '../source/TileImage.js';\nimport {createXYZ, extentFromProjection} from '../tilegrid.js';\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/source/Source~AttributionLike} [attributions] Attributions.\n * @property {number} [cacheSize=2048] Cache size.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images.  Note that\n * you must provide a `crossOrigin` value if you are using the WebGL renderer or if you want to\n * access pixel data with the Canvas renderer.  See\n * https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {boolean} [opaque=true] Whether the layer is opaque.\n * @property {module:ol/proj~ProjectionLike} [projection='EPSG:3857'] Projection.\n * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).\n * Higher values can increase reprojection performance, but decrease precision.\n * @property {number} [maxZoom=18] Optional max zoom level.\n * @property {number} [minZoom=0] Optional min zoom level.\n * @property {module:ol/tilegrid/TileGrid} [tileGrid] Tile grid.\n * @property {module:ol/Tile~LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is\n * ```js\n * function(imageTile, src) {\n *   imageTile.getImage().src = src;\n * };\n * ```\n * @property {number} [tilePixelRatio=1] The pixel ratio used by the tile service.\n * For example, if the tile service advertizes 256px by 256px tiles but actually sends 512px\n * by 512px images (for retina/hidpi devices) then `tilePixelRatio`\n * should be set to `2`.\n * @property {number|module:ol/size~Size} [tileSize=[256, 256]] The tile size used by the tile service.\n * @property {module:ol/Tile~UrlFunction} [tileUrlFunction] Optional function to get\n * tile URL given a tile coordinate and the projection.\n * Required if url or urls are not provided.\n * @property {string} [url] URL template. Must include `{x}`, `{y}` or `{-y}`,\n * and `{z}` placeholders. A `{?-?}` template pattern, for example `subdomain{a-f}.domain.com`,\n * may be used instead of defining each one separately in the `urls` option.\n * @property {Array.<string>} [urls] An array of URL templates.\n * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.\n * @property {number} [transition] Duration of the opacity transition for rendering.\n * To disable the opacity transition, pass `transition: 0`.\n */\n\n\n/**\n * @classdesc\n * Layer source for tile data with URLs in a set XYZ format that are\n * defined in a URL template. By default, this follows the widely-used\n * Google grid where `x` 0 and `y` 0 are in the top left. Grids like\n * TMS where `x` 0 and `y` 0 are in the bottom left can be used by\n * using the `{-y}` placeholder in the URL template, so long as the\n * source does not have a custom tile grid. In this case,\n * {@link module:ol/source/TileImage} can be used with a `tileUrlFunction`\n * such as:\n *\n *  tileUrlFunction: function(coordinate) {\n *    return 'http://mapserver.com/' + coordinate[0] + '/' +\n *        coordinate[1] + '/' + coordinate[2] + '.png';\n *    }\n *\n * @api\n */\nclass XYZ extends TileImage {\n  /**\n   * @param {module:ol/source/XYZ~Options=} opt_options XYZ options.\n   */\n  constructor(opt_options) {\n    const options = opt_options || {};\n    const projection = options.projection !== undefined ?\n      options.projection : 'EPSG:3857';\n\n    const tileGrid = options.tileGrid !== undefined ? options.tileGrid :\n      createXYZ({\n        extent: extentFromProjection(projection),\n        maxZoom: options.maxZoom,\n        minZoom: options.minZoom,\n        tileSize: options.tileSize\n      });\n\n    super({\n      attributions: options.attributions,\n      cacheSize: options.cacheSize,\n      crossOrigin: options.crossOrigin,\n      opaque: options.opaque,\n      projection: projection,\n      reprojectionErrorThreshold: options.reprojectionErrorThreshold,\n      tileGrid: tileGrid,\n      tileLoadFunction: options.tileLoadFunction,\n      tilePixelRatio: options.tilePixelRatio,\n      tileUrlFunction: options.tileUrlFunction,\n      url: options.url,\n      urls: options.urls,\n      wrapX: options.wrapX !== undefined ? options.wrapX : true,\n      transition: options.transition\n    });\n\n  }\n\n}\n\nexport default XYZ;\n","/**\n * @module ol/source/CartoDB\n */\n\nimport {assign} from '../obj.js';\nimport SourceState from '../source/State.js';\nimport XYZ from '../source/XYZ.js';\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/source/Source~AttributionLike} [attributions] Attributions.\n * @property {number} [cacheSize=2048] Cache size.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images.  Note that\n * you must provide a `crossOrigin` value if you are using the WebGL renderer or if you want to\n * access pixel data with the Canvas renderer.  See\n * https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {module:ol/proj~ProjectionLike} [projection='EPSG:3857'] Projection.\n * @property {number} [maxZoom=18] Max zoom.\n * @property {number} [minZoom] Minimum zoom.\n * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.\n * @property {Object} [config] If using anonymous maps, the CartoDB config to use. See\n * http://docs.cartodb.com/cartodb-platform/maps-api/anonymous-maps/\n * for more detail.\n * If using named maps, a key-value lookup with the template parameters.\n * See http://docs.cartodb.com/cartodb-platform/maps-api/named-maps/\n * for more detail.\n * @property {string} [map] If using named maps, this will be the name of the template to load.\n * See http://docs.cartodb.com/cartodb-platform/maps-api/named-maps/\n * for more detail.\n * @property {string} account If using named maps, this will be the name of the template to load.\n */\n\n\n/**\n * @classdesc\n * Layer source for the CartoDB Maps API.\n * @api\n */\nclass CartoDB extends XYZ {\n  /**\n   * @param {module:ol/source/CartoDB~Options=} options CartoDB options.\n   */\n  constructor(options) {\n    super({\n      attributions: options.attributions,\n      cacheSize: options.cacheSize,\n      crossOrigin: options.crossOrigin,\n      maxZoom: options.maxZoom !== undefined ? options.maxZoom : 18,\n      minZoom: options.minZoom,\n      projection: options.projection,\n      state: SourceState.LOADING,\n      wrapX: options.wrapX\n    });\n\n    /**\n     * @type {string}\n     * @private\n     */\n    this.account_ = options.account;\n\n    /**\n     * @type {string}\n     * @private\n     */\n    this.mapId_ = options.map || '';\n\n    /**\n     * @type {!Object}\n     * @private\n     */\n    this.config_ = options.config || {};\n\n    /**\n     * @type {!Object.<string, CartoDBLayerInfo>}\n     * @private\n     */\n    this.templateCache_ = {};\n\n    this.initializeMap_();\n  }\n\n  /**\n   * Returns the current config.\n   * @return {!Object} The current configuration.\n   * @api\n   */\n  getConfig() {\n    return this.config_;\n  }\n\n  /**\n   * Updates the carto db config.\n   * @param {Object} config a key-value lookup. Values will replace current values\n   *     in the config.\n   * @api\n   */\n  updateConfig(config) {\n    assign(this.config_, config);\n    this.initializeMap_();\n  }\n\n  /**\n   * Sets the CartoDB config\n   * @param {Object} config In the case of anonymous maps, a CartoDB configuration\n   *     object.\n   * If using named maps, a key-value lookup with the template parameters.\n   * @api\n   */\n  setConfig(config) {\n    this.config_ = config || {};\n    this.initializeMap_();\n  }\n\n  /**\n   * Issue a request to initialize the CartoDB map.\n   * @private\n   */\n  initializeMap_() {\n    const paramHash = JSON.stringify(this.config_);\n    if (this.templateCache_[paramHash]) {\n      this.applyTemplate_(this.templateCache_[paramHash]);\n      return;\n    }\n    let mapUrl = 'https://' + this.account_ + '.carto.com/api/v1/map';\n\n    if (this.mapId_) {\n      mapUrl += '/named/' + this.mapId_;\n    }\n\n    const client = new XMLHttpRequest();\n    client.addEventListener('load', this.handleInitResponse_.bind(this, paramHash));\n    client.addEventListener('error', this.handleInitError_.bind(this));\n    client.open('POST', mapUrl);\n    client.setRequestHeader('Content-type', 'application/json');\n    client.send(JSON.stringify(this.config_));\n  }\n\n  /**\n   * Handle map initialization response.\n   * @param {string} paramHash a hash representing the parameter set that was used\n   *     for the request\n   * @param {Event} event Event.\n   * @private\n   */\n  handleInitResponse_(paramHash, event) {\n    const client = /** @type {XMLHttpRequest} */ (event.target);\n    // status will be 0 for file:// urls\n    if (!client.status || client.status >= 200 && client.status < 300) {\n      let response;\n      try {\n        response = /** @type {CartoDBLayerInfo} */(JSON.parse(client.responseText));\n      } catch (err) {\n        this.setState(SourceState.ERROR);\n        return;\n      }\n      this.applyTemplate_(response);\n      this.templateCache_[paramHash] = response;\n      this.setState(SourceState.READY);\n    } else {\n      this.setState(SourceState.ERROR);\n    }\n  }\n\n  /**\n   * @private\n   * @param {Event} event Event.\n   */\n  handleInitError_(event) {\n    this.setState(SourceState.ERROR);\n  }\n\n  /**\n   * Apply the new tile urls returned by carto db\n   * @param {CartoDBLayerInfo} data Result of carto db call.\n   * @private\n   */\n  applyTemplate_(data) {\n    const tilesUrl = 'https://' + data.cdn_url.https + '/' + this.account_ +\n        '/api/v1/map/' + data.layergroupid + '/{z}/{x}/{y}.png';\n    this.setUrl(tilesUrl);\n  }\n}\n\n\nexport default CartoDB;\n","/**\n * @module ol/source/Cluster\n */\n\nimport {getUid} from '../util.js';\nimport {assert} from '../asserts.js';\nimport Feature from '../Feature.js';\nimport {scale as scaleCoordinate, add as addCoordinate} from '../coordinate.js';\nimport {listen} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport {buffer, createEmpty, createOrUpdateFromCoordinate} from '../extent.js';\nimport Point from '../geom/Point.js';\nimport VectorSource from '../source/Vector.js';\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/source/Source~AttributionLike} [attributions] Attributions.\n * @property {number} [distance=20] Minimum distance in pixels between clusters.\n * @property {module:ol/extent~Extent} [extent] Extent.\n * @property {function(module:ol/Feature):module:ol/geom/Point} [geometryFunction]\n * Function that takes an {@link module:ol/Feature} as argument and returns an\n * {@link module:ol/geom/Point} as cluster calculation point for the feature. When a\n * feature should not be considered for clustering, the function should return\n * `null`. The default, which works when the underyling source contains point\n * features only, is\n * ```js\n * function(feature) {\n *   return feature.getGeometry();\n * }\n * ```\n * See {@link module:ol/geom/Polygon~Polygon#getInteriorPoint} for a way to get a cluster\n * calculation point for polygons.\n * @property {module:ol/proj~ProjectionLike} projection Projection.\n * @property {module:ol/source/Vector} source Source.\n * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.\n */\n\n\n/**\n * @classdesc\n * Layer source to cluster vector data. Works out of the box with point\n * geometries. For other geometry types, or if not all geometries should be\n * considered for clustering, a custom `geometryFunction` can be defined.\n * @api\n */\nclass Cluster extends VectorSource {\n  /**\n   * @param {module:ol/source/Cluster~Options=} options Cluster options.\n   */\n  constructor(options) {\n    super({\n      attributions: options.attributions,\n      extent: options.extent,\n      projection: options.projection,\n      wrapX: options.wrapX\n    });\n\n    /**\n     * @type {number|undefined}\n     * @protected\n     */\n    this.resolution = undefined;\n\n    /**\n     * @type {number}\n     * @protected\n     */\n    this.distance = options.distance !== undefined ? options.distance : 20;\n\n    /**\n     * @type {Array.<module:ol/Feature>}\n     * @protected\n     */\n    this.features = [];\n\n    /**\n     * @param {module:ol/Feature} feature Feature.\n     * @return {module:ol/geom/Point} Cluster calculation point.\n     * @protected\n     */\n    this.geometryFunction = options.geometryFunction || function(feature) {\n      const geometry = /** @type {module:ol/geom/Point} */ (feature.getGeometry());\n      assert(geometry instanceof Point,\n        10); // The default `geometryFunction` can only handle `module:ol/geom/Point~Point` geometries\n      return geometry;\n    };\n\n    /**\n     * @type {module:ol/source/Vector}\n     * @protected\n     */\n    this.source = options.source;\n\n    listen(this.source, EventType.CHANGE, this.refresh, this);\n  }\n\n  /**\n   * Get the distance in pixels between clusters.\n   * @return {number} Distance.\n   * @api\n   */\n  getDistance() {\n    return this.distance;\n  }\n\n  /**\n   * Get a reference to the wrapped source.\n   * @return {module:ol/source/Vector} Source.\n   * @api\n   */\n  getSource() {\n    return this.source;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  loadFeatures(extent, resolution, projection) {\n    this.source.loadFeatures(extent, resolution, projection);\n    if (resolution !== this.resolution) {\n      this.clear();\n      this.resolution = resolution;\n      this.cluster();\n      this.addFeatures(this.features);\n    }\n  }\n\n  /**\n   * Set the distance in pixels between clusters.\n   * @param {number} distance The distance in pixels.\n   * @api\n   */\n  setDistance(distance) {\n    this.distance = distance;\n    this.refresh();\n  }\n\n  /**\n   * handle the source changing\n   * @override\n   */\n  refresh() {\n    this.clear();\n    this.cluster();\n    this.addFeatures(this.features);\n    VectorSource.prototype.refresh.call(this);\n  }\n\n  /**\n   * @protected\n   */\n  cluster() {\n    if (this.resolution === undefined) {\n      return;\n    }\n    this.features.length = 0;\n    const extent = createEmpty();\n    const mapDistance = this.distance * this.resolution;\n    const features = this.source.getFeatures();\n\n    /**\n     * @type {!Object.<string, boolean>}\n     */\n    const clustered = {};\n\n    for (let i = 0, ii = features.length; i < ii; i++) {\n      const feature = features[i];\n      if (!(getUid(feature).toString() in clustered)) {\n        const geometry = this.geometryFunction(feature);\n        if (geometry) {\n          const coordinates = geometry.getCoordinates();\n          createOrUpdateFromCoordinate(coordinates, extent);\n          buffer(extent, mapDistance, extent);\n\n          let neighbors = this.source.getFeaturesInExtent(extent);\n          neighbors = neighbors.filter(function(neighbor) {\n            const uid = getUid(neighbor).toString();\n            if (!(uid in clustered)) {\n              clustered[uid] = true;\n              return true;\n            } else {\n              return false;\n            }\n          });\n          this.features.push(this.createCluster(neighbors));\n        }\n      }\n    }\n  }\n\n  /**\n   * @param {Array.<module:ol/Feature>} features Features\n   * @return {module:ol/Feature} The cluster feature.\n   * @protected\n   */\n  createCluster(features) {\n    const centroid = [0, 0];\n    for (let i = features.length - 1; i >= 0; --i) {\n      const geometry = this.geometryFunction(features[i]);\n      if (geometry) {\n        addCoordinate(centroid, geometry.getCoordinates());\n      } else {\n        features.splice(i, 1);\n      }\n    }\n    scaleCoordinate(centroid, 1 / features.length);\n\n    const cluster = new Feature(new Point(centroid));\n    cluster.set('features', features);\n    return cluster;\n  }\n}\n\n\nexport default Cluster;\n","/**\n * @module ol/reproj/Image\n */\nimport {ERROR_THRESHOLD} from './common.js';\n\nimport ImageBase from '../ImageBase.js';\nimport ImageState from '../ImageState.js';\nimport {listen, unlistenByKey} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport {getCenter, getIntersection, getHeight, getWidth} from '../extent.js';\nimport {calculateSourceResolution, render as renderReprojected} from '../reproj.js';\nimport Triangulation from '../reproj/Triangulation.js';\n\n\n/**\n * @typedef {function(module:ol/extent~Extent, number, number) : module:ol/ImageBase} FunctionType\n */\n\n\n/**\n * @classdesc\n * Class encapsulating single reprojected image.\n * See {@link module:ol/source/Image~ImageSource}.\n */\nclass ReprojImage extends ImageBase {\n  /**\n   * @param {module:ol/proj/Projection} sourceProj Source projection (of the data).\n   * @param {module:ol/proj/Projection} targetProj Target projection.\n   * @param {module:ol/extent~Extent} targetExtent Target extent.\n   * @param {number} targetResolution Target resolution.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {module:ol/reproj/Image~FunctionType} getImageFunction\n   *     Function returning source images (extent, resolution, pixelRatio).\n   */\n  constructor(sourceProj, targetProj, targetExtent, targetResolution, pixelRatio, getImageFunction) {\n    const maxSourceExtent = sourceProj.getExtent();\n    const maxTargetExtent = targetProj.getExtent();\n\n    const limitedTargetExtent = maxTargetExtent ?\n      getIntersection(targetExtent, maxTargetExtent) : targetExtent;\n\n    const targetCenter = getCenter(limitedTargetExtent);\n    const sourceResolution = calculateSourceResolution(\n      sourceProj, targetProj, targetCenter, targetResolution);\n\n    const errorThresholdInPixels = ERROR_THRESHOLD;\n\n    const triangulation = new Triangulation(\n      sourceProj, targetProj, limitedTargetExtent, maxSourceExtent,\n      sourceResolution * errorThresholdInPixels);\n\n    const sourceExtent = triangulation.calculateSourceExtent();\n    const sourceImage = getImageFunction(sourceExtent, sourceResolution, pixelRatio);\n    let state = ImageState.LOADED;\n    if (sourceImage) {\n      state = ImageState.IDLE;\n    }\n    const sourcePixelRatio = sourceImage ? sourceImage.getPixelRatio() : 1;\n\n    super(targetExtent, targetResolution, sourcePixelRatio, state);\n\n    /**\n     * @private\n     * @type {module:ol/proj/Projection}\n     */\n    this.targetProj_ = targetProj;\n\n    /**\n     * @private\n     * @type {module:ol/extent~Extent}\n     */\n    this.maxSourceExtent_ = maxSourceExtent;\n\n    /**\n     * @private\n     * @type {!module:ol/reproj/Triangulation}\n     */\n    this.triangulation_ = triangulation;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.targetResolution_ = targetResolution;\n\n    /**\n     * @private\n     * @type {module:ol/extent~Extent}\n     */\n    this.targetExtent_ = targetExtent;\n\n    /**\n     * @private\n     * @type {module:ol/ImageBase}\n     */\n    this.sourceImage_ = sourceImage;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.sourcePixelRatio_ = sourcePixelRatio;\n\n    /**\n     * @private\n     * @type {HTMLCanvasElement}\n     */\n    this.canvas_ = null;\n\n    /**\n     * @private\n     * @type {?module:ol/events~EventsKey}\n     */\n    this.sourceListenerKey_ = null;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  disposeInternal() {\n    if (this.state == ImageState.LOADING) {\n      this.unlistenSource_();\n    }\n    ImageBase.prototype.disposeInternal.call(this);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getImage() {\n    return this.canvas_;\n  }\n\n  /**\n   * @return {module:ol/proj/Projection} Projection.\n   */\n  getProjection() {\n    return this.targetProj_;\n  }\n\n  /**\n   * @private\n   */\n  reproject_() {\n    const sourceState = this.sourceImage_.getState();\n    if (sourceState == ImageState.LOADED) {\n      const width = getWidth(this.targetExtent_) / this.targetResolution_;\n      const height = getHeight(this.targetExtent_) / this.targetResolution_;\n\n      this.canvas_ = renderReprojected(width, height, this.sourcePixelRatio_,\n        this.sourceImage_.getResolution(), this.maxSourceExtent_,\n        this.targetResolution_, this.targetExtent_, this.triangulation_, [{\n          extent: this.sourceImage_.getExtent(),\n          image: this.sourceImage_.getImage()\n        }], 0);\n    }\n    this.state = sourceState;\n    this.changed();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  load() {\n    if (this.state == ImageState.IDLE) {\n      this.state = ImageState.LOADING;\n      this.changed();\n\n      const sourceState = this.sourceImage_.getState();\n      if (sourceState == ImageState.LOADED || sourceState == ImageState.ERROR) {\n        this.reproject_();\n      } else {\n        this.sourceListenerKey_ = listen(this.sourceImage_,\n          EventType.CHANGE, function(e) {\n            const sourceState = this.sourceImage_.getState();\n            if (sourceState == ImageState.LOADED || sourceState == ImageState.ERROR) {\n              this.unlistenSource_();\n              this.reproject_();\n            }\n          }, this);\n        this.sourceImage_.load();\n      }\n    }\n  }\n\n  /**\n   * @private\n   */\n  unlistenSource_() {\n    unlistenByKey(/** @type {!module:ol/events~EventsKey} */ (this.sourceListenerKey_));\n    this.sourceListenerKey_ = null;\n  }\n}\n\n\nexport default ReprojImage;\n","/**\n * @module ol/source/Image\n */\nimport {ENABLE_RASTER_REPROJECTION} from '../reproj/common.js';\n\nimport ImageState from '../ImageState.js';\nimport {linearFindNearest} from '../array.js';\nimport Event from '../events/Event.js';\nimport {equals} from '../extent.js';\nimport {equivalent} from '../proj.js';\nimport ReprojImage from '../reproj/Image.js';\nimport Source from '../source/Source.js';\n\n\n/**\n * @enum {string}\n */\nconst ImageSourceEventType = {\n\n  /**\n   * Triggered when an image starts loading.\n   * @event ol/source/Image~ImageSourceEvent#imageloadstart\n   * @api\n   */\n  IMAGELOADSTART: 'imageloadstart',\n\n  /**\n   * Triggered when an image finishes loading.\n   * @event ol/source/Image~ImageSourceEvent#imageloadend\n   * @api\n   */\n  IMAGELOADEND: 'imageloadend',\n\n  /**\n   * Triggered if image loading results in an error.\n   * @event ol/source/Image~ImageSourceEvent#imageloaderror\n   * @api\n   */\n  IMAGELOADERROR: 'imageloaderror'\n\n};\n\n\n/**\n * @classdesc\n * Events emitted by {@link module:ol/source/Image~ImageSource} instances are instances of this\n * type.\n */\nclass ImageSourceEvent extends Event {\n  /**\n   * @param {string} type Type.\n   * @param {module:ol/Image} image The image.\n   */\n  constructor(type, image) {\n\n    super(type);\n\n    /**\n     * The image related to the event.\n     * @type {module:ol/Image}\n     * @api\n     */\n    this.image = image;\n\n  }\n\n}\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/source/Source~AttributionLike} [attributions]\n * @property {module:ol/extent~Extent} [extent]\n * @property {module:ol/proj~ProjectionLike} projection\n * @property {Array.<number>} [resolutions]\n * @property {module:ol/source/State} [state]\n */\n\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Base class for sources providing a single image.\n * @api\n */\nclass ImageSource extends Source {\n  /**\n   * @param {module:ol/source/Image~Options} options Single image source options.\n   */\n  constructor(options) {\n    super({\n      attributions: options.attributions,\n      extent: options.extent,\n      projection: options.projection,\n      state: options.state\n    });\n\n    /**\n     * @private\n     * @type {Array.<number>}\n     */\n    this.resolutions_ = options.resolutions !== undefined ?\n      options.resolutions : null;\n\n\n    /**\n     * @private\n     * @type {module:ol/reproj/Image}\n     */\n    this.reprojectedImage_ = null;\n\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.reprojectedRevision_ = 0;\n  }\n\n  /**\n   * @return {Array.<number>} Resolutions.\n   * @override\n   */\n  getResolutions() {\n    return this.resolutions_;\n  }\n\n  /**\n   * @protected\n   * @param {number} resolution Resolution.\n   * @return {number} Resolution.\n   */\n  findNearestResolution(resolution) {\n    if (this.resolutions_) {\n      const idx = linearFindNearest(this.resolutions_, resolution, 0);\n      resolution = this.resolutions_[idx];\n    }\n    return resolution;\n  }\n\n  /**\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {number} resolution Resolution.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @return {module:ol/ImageBase} Single image.\n   */\n  getImage(extent, resolution, pixelRatio, projection) {\n    const sourceProjection = this.getProjection();\n    if (!ENABLE_RASTER_REPROJECTION ||\n        !sourceProjection ||\n        !projection ||\n        equivalent(sourceProjection, projection)) {\n      if (sourceProjection) {\n        projection = sourceProjection;\n      }\n      return this.getImageInternal(extent, resolution, pixelRatio, projection);\n    } else {\n      if (this.reprojectedImage_) {\n        if (this.reprojectedRevision_ == this.getRevision() &&\n            equivalent(\n              this.reprojectedImage_.getProjection(), projection) &&\n            this.reprojectedImage_.getResolution() == resolution &&\n            equals(this.reprojectedImage_.getExtent(), extent)) {\n          return this.reprojectedImage_;\n        }\n        this.reprojectedImage_.dispose();\n        this.reprojectedImage_ = null;\n      }\n\n      this.reprojectedImage_ = new ReprojImage(\n        sourceProjection, projection, extent, resolution, pixelRatio,\n        function(extent, resolution, pixelRatio) {\n          return this.getImageInternal(extent, resolution,\n            pixelRatio, sourceProjection);\n        }.bind(this));\n      this.reprojectedRevision_ = this.getRevision();\n\n      return this.reprojectedImage_;\n    }\n  }\n\n  /**\n   * @abstract\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {number} resolution Resolution.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @return {module:ol/ImageBase} Single image.\n   * @protected\n   */\n  getImageInternal(extent, resolution, pixelRatio, projection) {}\n\n  /**\n   * Handle image change events.\n   * @param {module:ol/events/Event} event Event.\n   * @protected\n   */\n  handleImageChange(event) {\n    const image = /** @type {module:ol/Image} */ (event.target);\n    switch (image.getState()) {\n      case ImageState.LOADING:\n        this.dispatchEvent(\n          new ImageSourceEvent(ImageSourceEventType.IMAGELOADSTART,\n            image));\n        break;\n      case ImageState.LOADED:\n        this.dispatchEvent(\n          new ImageSourceEvent(ImageSourceEventType.IMAGELOADEND,\n            image));\n        break;\n      case ImageState.ERROR:\n        this.dispatchEvent(\n          new ImageSourceEvent(ImageSourceEventType.IMAGELOADERROR,\n            image));\n        break;\n      default:\n        // pass\n    }\n  }\n}\n\n\n/**\n * Default image load function for image sources that use module:ol/Image~Image image\n * instances.\n * @param {module:ol/Image} image Image.\n * @param {string} src Source.\n */\nexport function defaultImageLoadFunction(image, src) {\n  image.getImage().src = src;\n}\n\n\nexport default ImageSource;\n","/**\n * @module ol/uri\n */\n\n\n/**\n * Appends query parameters to a URI.\n *\n * @param {string} uri The original URI, which may already have query data.\n * @param {!Object} params An object where keys are URI-encoded parameter keys,\n *     and the values are arbitrary types or arrays.\n * @return {string} The new URI.\n */\nexport function appendParams(uri, params) {\n  const keyParams = [];\n  // Skip any null or undefined parameter values\n  Object.keys(params).forEach(function(k) {\n    if (params[k] !== null && params[k] !== undefined) {\n      keyParams.push(k + '=' + encodeURIComponent(params[k]));\n    }\n  });\n  const qs = keyParams.join('&');\n  // remove any trailing ? or &\n  uri = uri.replace(/[?&]$/, '');\n  // append ? or & depending on whether uri has existing parameters\n  uri = uri.indexOf('?') === -1 ? uri + '?' : uri + '&';\n  return uri + qs;\n}\n","/**\n * @module ol/source/ImageArcGISRest\n */\n\nimport ImageWrapper from '../Image.js';\nimport {assert} from '../asserts.js';\nimport {listen} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport {containsExtent, getHeight, getWidth} from '../extent.js';\nimport {assign} from '../obj.js';\nimport ImageSource, {defaultImageLoadFunction} from '../source/Image.js';\nimport {appendParams} from '../uri.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/source/Source~AttributionLike} [attributions] Attributions.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images.  Note that\n * you must provide a `crossOrigin` value if you are using the WebGL renderer or if you want to\n * access pixel data with the Canvas renderer.  See\n * https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {boolean} [hidpi=true] Use the `ol/Map#pixelRatio` value when requesting the image from\n * the remote server.\n * @property {module:ol/Image~LoadFunction} [imageLoadFunction] Optional function to load an image given\n * a URL.\n * @property {Object.<string,*>} params ArcGIS Rest parameters. This field is optional. Service\n * defaults will be used for any fields not specified. `FORMAT` is `PNG32` by default. `F` is\n * `IMAGE` by default. `TRANSPARENT` is `true` by default.  `BBOX, `SIZE`, `BBOXSR`, and `IMAGESR`\n * will be set dynamically. Set `LAYERS` to override the default service layer visibility. See\n * http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#/Export_Map/02r3000000v7000000/\n * for further reference.\n * @property {module:ol/proj~ProjectionLike} projection Projection.\n * @property {number} [ratio=1.5] Ratio. `1` means image requests are the size of the map viewport,\n * `2` means twice the size of the map viewport, and so on.\n * @property {Array.<number>} [resolutions] Resolutions. If specified, requests will be made for\n * these resolutions only.\n * @property {string} [url] ArcGIS Rest service URL for a Map Service or Image Service. The url\n * should include /MapServer or /ImageServer.\n */\n\n\n/**\n * @classdesc\n * Source for data from ArcGIS Rest services providing single, untiled images.\n * Useful when underlying map service has labels.\n *\n * If underlying map service is not using labels,\n * take advantage of ol image caching and use\n * {@link module:ol/source/TileArcGISRest} data source.\n *\n * @fires ol/source/Image~ImageSourceEvent\n * @api\n */\nclass ImageArcGISRest extends ImageSource {\n  /**\n   * @param {module:ol/source/ImageArcGISRest~Options=} opt_options Image ArcGIS Rest Options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options || {};\n\n    super({\n      attributions: options.attributions,\n      projection: options.projection,\n      resolutions: options.resolutions\n    });\n\n    /**\n     * @private\n     * @type {?string}\n     */\n    this.crossOrigin_ =\n        options.crossOrigin !== undefined ? options.crossOrigin : null;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.hidpi_ = options.hidpi !== undefined ? options.hidpi : true;\n\n    /**\n     * @private\n     * @type {string|undefined}\n     */\n    this.url_ = options.url;\n\n    /**\n     * @private\n     * @type {module:ol/Image~LoadFunction}\n     */\n    this.imageLoadFunction_ = options.imageLoadFunction !== undefined ?\n      options.imageLoadFunction : defaultImageLoadFunction;\n\n\n    /**\n     * @private\n     * @type {!Object}\n     */\n    this.params_ = options.params || {};\n\n    /**\n     * @private\n     * @type {module:ol/Image}\n     */\n    this.image_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/size~Size}\n     */\n    this.imageSize_ = [0, 0];\n\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.renderedRevision_ = 0;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.ratio_ = options.ratio !== undefined ? options.ratio : 1.5;\n\n  }\n\n  /**\n   * Get the user-provided params, i.e. those passed to the constructor through\n   * the \"params\" option, and possibly updated using the updateParams method.\n   * @return {Object} Params.\n   * @api\n   */\n  getParams() {\n    return this.params_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getImageInternal(extent, resolution, pixelRatio, projection) {\n\n    if (this.url_ === undefined) {\n      return null;\n    }\n\n    resolution = this.findNearestResolution(resolution);\n    pixelRatio = this.hidpi_ ? pixelRatio : 1;\n\n    const image = this.image_;\n    if (image &&\n        this.renderedRevision_ == this.getRevision() &&\n        image.getResolution() == resolution &&\n        image.getPixelRatio() == pixelRatio &&\n        containsExtent(image.getExtent(), extent)) {\n      return image;\n    }\n\n    const params = {\n      'F': 'image',\n      'FORMAT': 'PNG32',\n      'TRANSPARENT': true\n    };\n    assign(params, this.params_);\n\n    extent = extent.slice();\n    const centerX = (extent[0] + extent[2]) / 2;\n    const centerY = (extent[1] + extent[3]) / 2;\n    if (this.ratio_ != 1) {\n      const halfWidth = this.ratio_ * getWidth(extent) / 2;\n      const halfHeight = this.ratio_ * getHeight(extent) / 2;\n      extent[0] = centerX - halfWidth;\n      extent[1] = centerY - halfHeight;\n      extent[2] = centerX + halfWidth;\n      extent[3] = centerY + halfHeight;\n    }\n\n    const imageResolution = resolution / pixelRatio;\n\n    // Compute an integer width and height.\n    const width = Math.ceil(getWidth(extent) / imageResolution);\n    const height = Math.ceil(getHeight(extent) / imageResolution);\n\n    // Modify the extent to match the integer width and height.\n    extent[0] = centerX - imageResolution * width / 2;\n    extent[2] = centerX + imageResolution * width / 2;\n    extent[1] = centerY - imageResolution * height / 2;\n    extent[3] = centerY + imageResolution * height / 2;\n\n    this.imageSize_[0] = width;\n    this.imageSize_[1] = height;\n\n    const url = this.getRequestUrl_(extent, this.imageSize_, pixelRatio,\n      projection, params);\n\n    this.image_ = new ImageWrapper(extent, resolution, pixelRatio,\n      url, this.crossOrigin_, this.imageLoadFunction_);\n\n    this.renderedRevision_ = this.getRevision();\n\n    listen(this.image_, EventType.CHANGE,\n      this.handleImageChange, this);\n\n    return this.image_;\n\n  }\n\n  /**\n   * Return the image load function of the source.\n   * @return {module:ol/Image~LoadFunction} The image load function.\n   * @api\n   */\n  getImageLoadFunction() {\n    return this.imageLoadFunction_;\n  }\n\n  /**\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {module:ol/size~Size} size Size.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @param {Object} params Params.\n   * @return {string} Request URL.\n   * @private\n   */\n  getRequestUrl_(extent, size, pixelRatio, projection, params) {\n    // ArcGIS Server only wants the numeric portion of the projection ID.\n    const srid = projection.getCode().split(':').pop();\n\n    params['SIZE'] = size[0] + ',' + size[1];\n    params['BBOX'] = extent.join(',');\n    params['BBOXSR'] = srid;\n    params['IMAGESR'] = srid;\n    params['DPI'] = Math.round(90 * pixelRatio);\n\n    const url = this.url_;\n\n    const modifiedUrl = url\n      .replace(/MapServer\\/?$/, 'MapServer/export')\n      .replace(/ImageServer\\/?$/, 'ImageServer/exportImage');\n    if (modifiedUrl == url) {\n      assert(false, 50); // `options.featureTypes` should be an Array\n    }\n    return appendParams(modifiedUrl, params);\n  }\n\n  /**\n   * Return the URL used for this ArcGIS source.\n   * @return {string|undefined} URL.\n   * @api\n   */\n  getUrl() {\n    return this.url_;\n  }\n\n  /**\n   * Set the image load function of the source.\n   * @param {module:ol/Image~LoadFunction} imageLoadFunction Image load function.\n   * @api\n   */\n  setImageLoadFunction(imageLoadFunction) {\n    this.image_ = null;\n    this.imageLoadFunction_ = imageLoadFunction;\n    this.changed();\n  }\n\n  /**\n   * Set the URL to use for requests.\n   * @param {string|undefined} url URL.\n   * @api\n   */\n  setUrl(url) {\n    if (url != this.url_) {\n      this.url_ = url;\n      this.image_ = null;\n      this.changed();\n    }\n  }\n\n  /**\n   * Update the user-provided params.\n   * @param {Object} params Params.\n   * @api\n   */\n  updateParams(params) {\n    assign(this.params_, params);\n    this.image_ = null;\n    this.changed();\n  }\n}\n\n\nexport default ImageArcGISRest;\n","/**\n * @module ol/source/ImageCanvas\n */\n\nimport ImageCanvas from '../ImageCanvas.js';\nimport {containsExtent, getHeight, getWidth, scaleFromCenter} from '../extent.js';\nimport ImageSource from '../source/Image.js';\n\n\n/**\n * A function returning the canvas element (`{HTMLCanvasElement}`)\n * used by the source as an image. The arguments passed to the function are:\n * {@link module:ol/extent~Extent} the image extent, `{number}` the image resolution,\n * `{number}` the device pixel ratio, {@link module:ol/size~Size} the image size, and\n * {@link module:ol/proj/Projection} the image projection. The canvas returned by\n * this function is cached by the source. The this keyword inside the function\n * references the {@link module:ol/source/ImageCanvas}.\n *\n * @typedef {function(this:module:ol/ImageCanvas, module:ol/extent~Extent, number,\n *     number, module:ol/size~Size, module:ol/proj/Projection): HTMLCanvasElement} FunctionType\n */\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/source/Source~AttributionLike} [attributions] Attributions.\n * @property {module:ol/source/ImageCanvas~FunctionType} [canvasFunction] Canvas function.\n * The function returning the canvas element used by the source\n * as an image. The arguments passed to the function are: `{module:ol/extent~Extent}` the\n * image extent, `{number}` the image resolution, `{number}` the device pixel\n * ratio, `{module:ol/size~Size}` the image size, and `{module:ol/proj/Projection~Projection}` the image\n * projection. The canvas returned by this function is cached by the source. If\n * the value returned by the function is later changed then\n * `changed` should be called on the source for the source to\n * invalidate the current cached image. See @link: {@link module:ol/Observable~Observable#changed}\n * @property {module:ol/proj~ProjectionLike} projection Projection.\n * @property {number} [ratio=1.5] Ratio. 1 means canvases are the size of the map viewport, 2 means twice the\n * width and height of the map viewport, and so on. Must be `1` or higher.\n * @property {Array.<number>} [resolutions] Resolutions.\n * If specified, new canvases will be created for these resolutions\n * @property {module:ol/source/State} [state] Source state.\n */\n\n\n/**\n * @classdesc\n * Base class for image sources where a canvas element is the image.\n * @api\n */\nclass ImageCanvasSource extends ImageSource {\n  /**\n   * @param {module:ol/source/ImageCanvas~Options=} options ImageCanvas options.\n   */\n  constructor(options) {\n\n    super({\n      attributions: options.attributions,\n      projection: options.projection,\n      resolutions: options.resolutions,\n      state: options.state\n    });\n\n    /**\n    * @private\n    * @type {module:ol/source/ImageCanvas~FunctionType}\n    */\n    this.canvasFunction_ = options.canvasFunction;\n\n    /**\n    * @private\n    * @type {module:ol/ImageCanvas}\n    */\n    this.canvas_ = null;\n\n    /**\n    * @private\n    * @type {number}\n    */\n    this.renderedRevision_ = 0;\n\n    /**\n    * @private\n    * @type {number}\n    */\n    this.ratio_ = options.ratio !== undefined ?\n      options.ratio : 1.5;\n\n  }\n\n  /**\n  * @inheritDoc\n  */\n  getImageInternal(extent, resolution, pixelRatio, projection) {\n    resolution = this.findNearestResolution(resolution);\n\n    let canvas = this.canvas_;\n    if (canvas &&\n       this.renderedRevision_ == this.getRevision() &&\n       canvas.getResolution() == resolution &&\n       canvas.getPixelRatio() == pixelRatio &&\n       containsExtent(canvas.getExtent(), extent)) {\n      return canvas;\n    }\n\n    extent = extent.slice();\n    scaleFromCenter(extent, this.ratio_);\n    const width = getWidth(extent) / resolution;\n    const height = getHeight(extent) / resolution;\n    const size = [width * pixelRatio, height * pixelRatio];\n\n    const canvasElement = this.canvasFunction_(\n      extent, resolution, pixelRatio, size, projection);\n    if (canvasElement) {\n      canvas = new ImageCanvas(extent, resolution, pixelRatio, canvasElement);\n    }\n    this.canvas_ = canvas;\n    this.renderedRevision_ = this.getRevision();\n\n    return canvas;\n  }\n}\n\n\nexport default ImageCanvasSource;\n","/**\n * @module ol/source/ImageMapGuide\n */\n\nimport ImageWrapper from '../Image.js';\nimport {listen} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport {containsExtent, getCenter, getHeight, getWidth, scaleFromCenter} from '../extent.js';\nimport {assign} from '../obj.js';\nimport ImageSource, {defaultImageLoadFunction} from '../source/Image.js';\nimport {appendParams} from '../uri.js';\n\n/**\n * @typedef {Object} Options\n * @property {string} [url] The mapagent url.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images.  Note that\n * you must provide a `crossOrigin` value if you are using the WebGL renderer or if you want to\n * access pixel data with the Canvas renderer.  See\n * https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {number} [displayDpi=96] The display resolution.\n * @property {number} [metersPerUnit=1] The meters-per-unit value.\n * @property {boolean} [hidpi=true] Use the `ol/Map#pixelRatio` value when requesting\n * the image from the remote server.\n * @property {boolean} [useOverlay] If `true`, will use `GETDYNAMICMAPOVERLAYIMAGE`.\n * @property {module:ol/proj~ProjectionLike} projection Projection.\n * @property {number} [ratio=1] Ratio. `1` means image requests are the size of the map viewport, `2` means\n * twice the width and height of the map viewport, and so on. Must be `1` or higher.\n * @property {Array.<number>} [resolutions] Resolutions.\n * If specified, requests will be made for these resolutions only.\n * @property {module:ol/Image~LoadFunction} [imageLoadFunction] Optional function to load an image given a URL.\n * @property {Object} [params] Additional parameters.\n */\n\n\n/**\n * @classdesc\n * Source for images from Mapguide servers\n *\n * @fires ol/source/Image~ImageSourceEvent\n * @api\n */\nclass ImageMapGuide extends ImageSource {\n  /**\n   * @param {module:ol/source/ImageMapGuide~Options=} options ImageMapGuide options.\n   */\n  constructor(options) {\n\n    super({\n      projection: options.projection,\n      resolutions: options.resolutions\n    });\n\n    /**\n     * @private\n     * @type {?string}\n     */\n    this.crossOrigin_ =\n        options.crossOrigin !== undefined ? options.crossOrigin : null;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.displayDpi_ = options.displayDpi !== undefined ?\n      options.displayDpi : 96;\n\n    /**\n     * @private\n     * @type {!Object}\n     */\n    this.params_ = options.params || {};\n\n    /**\n     * @private\n     * @type {string|undefined}\n     */\n    this.url_ = options.url;\n\n    /**\n     * @private\n     * @type {module:ol/Image~LoadFunction}\n     */\n    this.imageLoadFunction_ = options.imageLoadFunction !== undefined ?\n      options.imageLoadFunction : defaultImageLoadFunction;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.hidpi_ = options.hidpi !== undefined ? options.hidpi : true;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.metersPerUnit_ = options.metersPerUnit !== undefined ?\n      options.metersPerUnit : 1;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.ratio_ = options.ratio !== undefined ? options.ratio : 1;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.useOverlay_ = options.useOverlay !== undefined ?\n      options.useOverlay : false;\n\n    /**\n     * @private\n     * @type {module:ol/Image}\n     */\n    this.image_ = null;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.renderedRevision_ = 0;\n\n  }\n\n  /**\n   * Get the user-provided params, i.e. those passed to the constructor through\n   * the \"params\" option, and possibly updated using the updateParams method.\n   * @return {Object} Params.\n   * @api\n   */\n  getParams() {\n    return this.params_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getImageInternal(extent, resolution, pixelRatio, projection) {\n    resolution = this.findNearestResolution(resolution);\n    pixelRatio = this.hidpi_ ? pixelRatio : 1;\n\n    let image = this.image_;\n    if (image &&\n        this.renderedRevision_ == this.getRevision() &&\n        image.getResolution() == resolution &&\n        image.getPixelRatio() == pixelRatio &&\n        containsExtent(image.getExtent(), extent)) {\n      return image;\n    }\n\n    if (this.ratio_ != 1) {\n      extent = extent.slice();\n      scaleFromCenter(extent, this.ratio_);\n    }\n    const width = getWidth(extent) / resolution;\n    const height = getHeight(extent) / resolution;\n    const size = [width * pixelRatio, height * pixelRatio];\n\n    if (this.url_ !== undefined) {\n      const imageUrl = this.getUrl(this.url_, this.params_, extent, size,\n        projection);\n      image = new ImageWrapper(extent, resolution, pixelRatio,\n        imageUrl, this.crossOrigin_,\n        this.imageLoadFunction_);\n      listen(image, EventType.CHANGE,\n        this.handleImageChange, this);\n    } else {\n      image = null;\n    }\n    this.image_ = image;\n    this.renderedRevision_ = this.getRevision();\n\n    return image;\n  }\n\n  /**\n   * Return the image load function of the source.\n   * @return {module:ol/Image~LoadFunction} The image load function.\n   * @api\n   */\n  getImageLoadFunction() {\n    return this.imageLoadFunction_;\n  }\n\n  /**\n   * Update the user-provided params.\n   * @param {Object} params Params.\n   * @api\n   */\n  updateParams(params) {\n    assign(this.params_, params);\n    this.changed();\n  }\n\n  /**\n   * @param {string} baseUrl The mapagent url.\n   * @param {Object.<string, string|number>} params Request parameters.\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {module:ol/size~Size} size Size.\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @return {string} The mapagent map image request URL.\n   */\n  getUrl(baseUrl, params, extent, size, projection) {\n    const scale = getScale(extent, size,\n      this.metersPerUnit_, this.displayDpi_);\n    const center = getCenter(extent);\n    const baseParams = {\n      'OPERATION': this.useOverlay_ ? 'GETDYNAMICMAPOVERLAYIMAGE' : 'GETMAPIMAGE',\n      'VERSION': '2.0.0',\n      'LOCALE': 'en',\n      'CLIENTAGENT': 'ol/source/ImageMapGuide source',\n      'CLIP': '1',\n      'SETDISPLAYDPI': this.displayDpi_,\n      'SETDISPLAYWIDTH': Math.round(size[0]),\n      'SETDISPLAYHEIGHT': Math.round(size[1]),\n      'SETVIEWSCALE': scale,\n      'SETVIEWCENTERX': center[0],\n      'SETVIEWCENTERY': center[1]\n    };\n    assign(baseParams, params);\n    return appendParams(baseUrl, baseParams);\n  }\n\n  /**\n   * Set the image load function of the MapGuide source.\n   * @param {module:ol/Image~LoadFunction} imageLoadFunction Image load function.\n   * @api\n   */\n  setImageLoadFunction(imageLoadFunction) {\n    this.image_ = null;\n    this.imageLoadFunction_ = imageLoadFunction;\n    this.changed();\n  }\n}\n\n\n/**\n * @param {module:ol/extent~Extent} extent The map extents.\n * @param {module:ol/size~Size} size The viewport size.\n * @param {number} metersPerUnit The meters-per-unit value.\n * @param {number} dpi The display resolution.\n * @return {number} The computed map scale.\n */\nfunction getScale(extent, size, metersPerUnit, dpi) {\n  const mcsW = getWidth(extent);\n  const mcsH = getHeight(extent);\n  const devW = size[0];\n  const devH = size[1];\n  const mpp = 0.0254 / dpi;\n  if (devH * mcsW > devW * mcsH) {\n    return mcsW * metersPerUnit / (devW * mpp); // width limited\n  } else {\n    return mcsH * metersPerUnit / (devH * mpp); // height limited\n  }\n}\n\n\nexport default ImageMapGuide;\n","/**\n * @module ol/source/ImageStatic\n */\n\nimport ImageWrapper from '../Image.js';\nimport ImageState from '../ImageState.js';\nimport {createCanvasContext2D} from '../dom.js';\nimport {listen} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport {intersects, getHeight, getWidth} from '../extent.js';\nimport {get as getProjection} from '../proj.js';\nimport ImageSource, {defaultImageLoadFunction} from '../source/Image.js';\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/source/Source~AttributionLike} [attributions] Attributions.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images.  Note that\n * you must provide a `crossOrigin` value if you are using the WebGL renderer or if you want to\n * access pixel data with the Canvas renderer.  See\n * https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {module:ol/extent~Extent} [imageExtent] Extent of the image in map coordinates.\n * This is the [left, bottom, right, top] map coordinates of your image.\n * @property {module:ol/Image~LoadFunction} [imageLoadFunction] Optional function to load an image given a URL.\n * @property {module:ol/proj~ProjectionLike} projection Projection.\n * @property {module:ol/size~Size} [imageSize] Size of the image in pixels. Usually the image size is auto-detected, so this\n * only needs to be set if auto-detection fails for some reason.\n * @property {string} url Image URL.\n */\n\n\n/**\n * @classdesc\n * A layer source for displaying a single, static image.\n * @api\n */\nclass Static extends ImageSource {\n  /**\n   * @param {module:ol/source/ImageStatic~Options=} options ImageStatic options.\n   */\n  constructor(options) {\n    const imageExtent = options.imageExtent;\n\n    const crossOrigin = options.crossOrigin !== undefined ?\n      options.crossOrigin : null;\n\n    const /** @type {module:ol/Image~LoadFunction} */ imageLoadFunction =\n        options.imageLoadFunction !== undefined ?\n          options.imageLoadFunction : defaultImageLoadFunction;\n\n    super({\n      attributions: options.attributions,\n      projection: getProjection(options.projection)\n    });\n\n    /**\n     * @private\n     * @type {module:ol/Image}\n     */\n    this.image_ = new ImageWrapper(imageExtent, undefined, 1, options.url, crossOrigin, imageLoadFunction);\n\n    /**\n     * @private\n     * @type {module:ol/size~Size}\n     */\n    this.imageSize_ = options.imageSize ? options.imageSize : null;\n\n    listen(this.image_, EventType.CHANGE,\n      this.handleImageChange, this);\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getImageInternal(extent, resolution, pixelRatio, projection) {\n    if (intersects(extent, this.image_.getExtent())) {\n      return this.image_;\n    }\n    return null;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  handleImageChange(evt) {\n    if (this.image_.getState() == ImageState.LOADED) {\n      const imageExtent = this.image_.getExtent();\n      const image = this.image_.getImage();\n      let imageWidth, imageHeight;\n      if (this.imageSize_) {\n        imageWidth = this.imageSize_[0];\n        imageHeight = this.imageSize_[1];\n      } else {\n        imageWidth = image.width;\n        imageHeight = image.height;\n      }\n      const resolution = getHeight(imageExtent) / imageHeight;\n      const targetWidth = Math.ceil(getWidth(imageExtent) / resolution);\n      if (targetWidth != imageWidth) {\n        const context = createCanvasContext2D(targetWidth, imageHeight);\n        const canvas = context.canvas;\n        context.drawImage(image, 0, 0, imageWidth, imageHeight,\n          0, 0, canvas.width, canvas.height);\n        this.image_.setImage(canvas);\n      }\n    }\n    ImageSource.prototype.handleImageChange.call(this, evt);\n  }\n}\n\n\nexport default Static;\n","/**\n * Default WMS version.\n * @type {string}\n */\nexport const DEFAULT_WMS_VERSION = '1.3.0';\n","/**\n * @module ol/source/WMSServerType\n */\n\n/**\n * Available server types: `'carmentaserver'`, `'geoserver'`, `'mapserver'`,\n *     `'qgis'`. These are servers that have vendor parameters beyond the WMS\n *     specification that OpenLayers can make use of.\n * @enum {string}\n */\nexport default {\n  CARMENTA_SERVER: 'carmentaserver',\n  GEOSERVER: 'geoserver',\n  MAPSERVER: 'mapserver',\n  QGIS: 'qgis'\n};\n","/**\n * @module ol/source/ImageWMS\n */\n\nimport {DEFAULT_WMS_VERSION} from './common.js';\n\nimport ImageWrapper from '../Image.js';\nimport {assert} from '../asserts.js';\nimport {listen} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport {containsExtent, getCenter, getForViewAndSize, getHeight, getWidth} from '../extent.js';\nimport {assign} from '../obj.js';\nimport {get as getProjection, transform} from '../proj.js';\nimport {calculateSourceResolution} from '../reproj.js';\nimport ImageSource, {defaultImageLoadFunction} from '../source/Image.js';\nimport WMSServerType from '../source/WMSServerType.js';\nimport {compareVersions} from '../string.js';\nimport {appendParams} from '../uri.js';\n\n\n/**\n * @const\n * @type {module:ol/size~Size}\n */\nconst GETFEATUREINFO_IMAGE_SIZE = [101, 101];\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/source/Source~AttributionLike} [attributions] Attributions.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images.  Note that\n * you must provide a `crossOrigin` value if you are using the WebGL renderer or if you want to\n * access pixel data with the Canvas renderer.  See\n * https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {boolean} [hidpi=true] Use the `ol/Map#pixelRatio` value when requesting\n * the image from the remote server.\n * @property {module:ol/source/WMSServerType|string} [serverType] The type of\n * the remote WMS server: `mapserver`, `geoserver` or `qgis`. Only needed if `hidpi` is `true`.\n * @property {module:ol/Image~LoadFunction} [imageLoadFunction] Optional function to load an image given a URL.\n * @property {Object.<string,*>} params WMS request parameters.\n * At least a `LAYERS` param is required. `STYLES` is\n * `''` by default. `VERSION` is `1.3.0` by default. `WIDTH`, `HEIGHT`, `BBOX`\n * and `CRS` (`SRS` for WMS version < 1.3.0) will be set dynamically.\n * @property {module:ol/proj~ProjectionLike} projection Projection.\n * @property {number} [ratio=1.5] Ratio. `1` means image requests are the size of the map viewport, `2` means\n * twice the width and height of the map viewport, and so on. Must be `1` or\n * higher.\n * @property {Array.<number>} [resolutions] Resolutions.\n * If specified, requests will be made for these resolutions only.\n * @property {string} url WMS service URL.\n */\n\n\n/**\n * @classdesc\n * Source for WMS servers providing single, untiled images.\n *\n * @fires ol/source/Image~ImageSourceEvent\n * @api\n */\nclass ImageWMS extends ImageSource {\n  /**\n   * @param {module:ol/source/ImageWMS~Options=} [opt_options] ImageWMS options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options || {};\n\n    super({\n      attributions: options.attributions,\n      projection: options.projection,\n      resolutions: options.resolutions\n    });\n\n    /**\n     * @private\n     * @type {?string}\n     */\n    this.crossOrigin_ =\n        options.crossOrigin !== undefined ? options.crossOrigin : null;\n\n    /**\n     * @private\n     * @type {string|undefined}\n     */\n    this.url_ = options.url;\n\n    /**\n     * @private\n     * @type {module:ol/Image~LoadFunction}\n     */\n    this.imageLoadFunction_ = options.imageLoadFunction !== undefined ?\n      options.imageLoadFunction : defaultImageLoadFunction;\n\n    /**\n     * @private\n     * @type {!Object}\n     */\n    this.params_ = options.params || {};\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.v13_ = true;\n    this.updateV13_();\n\n    /**\n     * @private\n     * @type {module:ol/source/WMSServerType|undefined}\n     */\n    this.serverType_ = /** @type {module:ol/source/WMSServerType|undefined} */ (options.serverType);\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.hidpi_ = options.hidpi !== undefined ? options.hidpi : true;\n\n    /**\n     * @private\n     * @type {module:ol/Image}\n     */\n    this.image_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/size~Size}\n     */\n    this.imageSize_ = [0, 0];\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.renderedRevision_ = 0;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.ratio_ = options.ratio !== undefined ? options.ratio : 1.5;\n\n  }\n\n  /**\n   * Return the GetFeatureInfo URL for the passed coordinate, resolution, and\n   * projection. Return `undefined` if the GetFeatureInfo URL cannot be\n   * constructed.\n   * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n   * @param {number} resolution Resolution.\n   * @param {module:ol/proj~ProjectionLike} projection Projection.\n   * @param {!Object} params GetFeatureInfo params. `INFO_FORMAT` at least should\n   *     be provided. If `QUERY_LAYERS` is not provided then the layers specified\n   *     in the `LAYERS` parameter will be used. `VERSION` should not be\n   *     specified here.\n   * @return {string|undefined} GetFeatureInfo URL.\n   * @api\n   */\n  getGetFeatureInfoUrl(coordinate, resolution, projection, params) {\n    if (this.url_ === undefined) {\n      return undefined;\n    }\n    const projectionObj = getProjection(projection);\n    const sourceProjectionObj = this.getProjection();\n\n    if (sourceProjectionObj && sourceProjectionObj !== projectionObj) {\n      resolution = calculateSourceResolution(sourceProjectionObj, projectionObj, coordinate, resolution);\n      coordinate = transform(coordinate, projectionObj, sourceProjectionObj);\n    }\n\n    const extent = getForViewAndSize(coordinate, resolution, 0,\n      GETFEATUREINFO_IMAGE_SIZE);\n\n    const baseParams = {\n      'SERVICE': 'WMS',\n      'VERSION': DEFAULT_WMS_VERSION,\n      'REQUEST': 'GetFeatureInfo',\n      'FORMAT': 'image/png',\n      'TRANSPARENT': true,\n      'QUERY_LAYERS': this.params_['LAYERS']\n    };\n    assign(baseParams, this.params_, params);\n\n    const x = Math.floor((coordinate[0] - extent[0]) / resolution);\n    const y = Math.floor((extent[3] - coordinate[1]) / resolution);\n    baseParams[this.v13_ ? 'I' : 'X'] = x;\n    baseParams[this.v13_ ? 'J' : 'Y'] = y;\n\n    return this.getRequestUrl_(\n      extent, GETFEATUREINFO_IMAGE_SIZE,\n      1, sourceProjectionObj || projectionObj, baseParams);\n  }\n\n  /**\n   * Get the user-provided params, i.e. those passed to the constructor through\n   * the \"params\" option, and possibly updated using the updateParams method.\n   * @return {Object} Params.\n   * @api\n   */\n  getParams() {\n    return this.params_;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getImageInternal(extent, resolution, pixelRatio, projection) {\n\n    if (this.url_ === undefined) {\n      return null;\n    }\n\n    resolution = this.findNearestResolution(resolution);\n\n    if (pixelRatio != 1 && (!this.hidpi_ || this.serverType_ === undefined)) {\n      pixelRatio = 1;\n    }\n\n    const imageResolution = resolution / pixelRatio;\n\n    const center = getCenter(extent);\n    const viewWidth = Math.ceil(getWidth(extent) / imageResolution);\n    const viewHeight = Math.ceil(getHeight(extent) / imageResolution);\n    const viewExtent = getForViewAndSize(center, imageResolution, 0,\n      [viewWidth, viewHeight]);\n    const requestWidth = Math.ceil(this.ratio_ * getWidth(extent) / imageResolution);\n    const requestHeight = Math.ceil(this.ratio_ * getHeight(extent) / imageResolution);\n    const requestExtent = getForViewAndSize(center, imageResolution, 0,\n      [requestWidth, requestHeight]);\n\n    const image = this.image_;\n    if (image &&\n        this.renderedRevision_ == this.getRevision() &&\n        image.getResolution() == resolution &&\n        image.getPixelRatio() == pixelRatio &&\n        containsExtent(image.getExtent(), viewExtent)) {\n      return image;\n    }\n\n    const params = {\n      'SERVICE': 'WMS',\n      'VERSION': DEFAULT_WMS_VERSION,\n      'REQUEST': 'GetMap',\n      'FORMAT': 'image/png',\n      'TRANSPARENT': true\n    };\n    assign(params, this.params_);\n\n    this.imageSize_[0] = Math.round(getWidth(requestExtent) / imageResolution);\n    this.imageSize_[1] = Math.round(getHeight(requestExtent) / imageResolution);\n\n    const url = this.getRequestUrl_(requestExtent, this.imageSize_, pixelRatio,\n      projection, params);\n\n    this.image_ = new ImageWrapper(requestExtent, resolution, pixelRatio,\n      url, this.crossOrigin_, this.imageLoadFunction_);\n\n    this.renderedRevision_ = this.getRevision();\n\n    listen(this.image_, EventType.CHANGE,\n      this.handleImageChange, this);\n\n    return this.image_;\n\n  }\n\n  /**\n   * Return the image load function of the source.\n   * @return {module:ol/Image~LoadFunction} The image load function.\n   * @api\n   */\n  getImageLoadFunction() {\n    return this.imageLoadFunction_;\n  }\n\n  /**\n   * @param {module:ol/extent~Extent} extent Extent.\n   * @param {module:ol/size~Size} size Size.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @param {Object} params Params.\n   * @return {string} Request URL.\n   * @private\n   */\n  getRequestUrl_(extent, size, pixelRatio, projection, params) {\n\n    assert(this.url_ !== undefined, 9); // `url` must be configured or set using `#setUrl()`\n\n    params[this.v13_ ? 'CRS' : 'SRS'] = projection.getCode();\n\n    if (!('STYLES' in this.params_)) {\n      params['STYLES'] = '';\n    }\n\n    if (pixelRatio != 1) {\n      switch (this.serverType_) {\n        case WMSServerType.GEOSERVER:\n          const dpi = (90 * pixelRatio + 0.5) | 0;\n          if ('FORMAT_OPTIONS' in params) {\n            params['FORMAT_OPTIONS'] += ';dpi:' + dpi;\n          } else {\n            params['FORMAT_OPTIONS'] = 'dpi:' + dpi;\n          }\n          break;\n        case WMSServerType.MAPSERVER:\n          params['MAP_RESOLUTION'] = 90 * pixelRatio;\n          break;\n        case WMSServerType.CARMENTA_SERVER:\n        case WMSServerType.QGIS:\n          params['DPI'] = 90 * pixelRatio;\n          break;\n        default:\n          assert(false, 8); // Unknown `serverType` configured\n          break;\n      }\n    }\n\n    params['WIDTH'] = size[0];\n    params['HEIGHT'] = size[1];\n\n    const axisOrientation = projection.getAxisOrientation();\n    let bbox;\n    if (this.v13_ && axisOrientation.substr(0, 2) == 'ne') {\n      bbox = [extent[1], extent[0], extent[3], extent[2]];\n    } else {\n      bbox = extent;\n    }\n    params['BBOX'] = bbox.join(',');\n\n    return appendParams(/** @type {string} */ (this.url_), params);\n  }\n\n  /**\n   * Return the URL used for this WMS source.\n   * @return {string|undefined} URL.\n   * @api\n   */\n  getUrl() {\n    return this.url_;\n  }\n\n  /**\n   * Set the image load function of the source.\n   * @param {module:ol/Image~LoadFunction} imageLoadFunction Image load function.\n   * @api\n   */\n  setImageLoadFunction(imageLoadFunction) {\n    this.image_ = null;\n    this.imageLoadFunction_ = imageLoadFunction;\n    this.changed();\n  }\n\n  /**\n   * Set the URL to use for requests.\n   * @param {string|undefined} url URL.\n   * @api\n   */\n  setUrl(url) {\n    if (url != this.url_) {\n      this.url_ = url;\n      this.image_ = null;\n      this.changed();\n    }\n  }\n\n  /**\n   * Update the user-provided params.\n   * @param {Object} params Params.\n   * @api\n   */\n  updateParams(params) {\n    assign(this.params_, params);\n    this.updateV13_();\n    this.image_ = null;\n    this.changed();\n  }\n\n  /**\n   * @private\n   */\n  updateV13_() {\n    const version = this.params_['VERSION'] || DEFAULT_WMS_VERSION;\n    this.v13_ = compareVersions(version, '1.3') >= 0;\n  }\n}\n\n\nexport default ImageWMS;\n","/**\n * @module ol/source/OSM\n */\n\nimport XYZ from '../source/XYZ.js';\n\n\n/**\n * The attribution containing a link to the OpenStreetMap Copyright and License\n * page.\n * @const\n * @type {string}\n * @api\n */\nexport const ATTRIBUTION = '&copy; ' +\n      '<a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> ' +\n      'contributors.';\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/source/Source~AttributionLike} [attributions] Attributions.\n * @property {number} [cacheSize=2048] Cache size.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images.  Note that\n * you must provide a `crossOrigin` value if you are using the WebGL renderer or if you want to\n * access pixel data with the Canvas renderer.  See\n * https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {number} [maxZoom=19] Max zoom.\n * @property {boolean} [opaque=true] Whether the layer is opaque.\n * @property {number} [reprojectionErrorThreshold=1.5] Maximum allowed reprojection error (in pixels).\n * Higher values can increase reprojection performance, but decrease precision.\n * @property {module:ol/Tile~LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is\n * ```js\n * function(imageTile, src) {\n *   imageTile.getImage().src = src;\n * };\n * ```\n * @property {string} [url='https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png'] URL template.\n * Must include `{x}`, `{y}` or `{-y}`, and `{z}` placeholders.\n * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.\n */\n\n\n/**\n * @classdesc\n * Layer source for the OpenStreetMap tile server.\n * @api\n */\nclass OSM extends XYZ {\n  /**\n   * @param {module:ol/source/OSM~Options=} [opt_options] Open Street Map options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options || {};\n\n    let attributions;\n    if (options.attributions !== undefined) {\n      attributions = options.attributions;\n    } else {\n      attributions = [ATTRIBUTION];\n    }\n\n    const crossOrigin = options.crossOrigin !== undefined ?\n      options.crossOrigin : 'anonymous';\n\n    const url = options.url !== undefined ?\n      options.url : 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png';\n\n    super({\n      attributions: attributions,\n      cacheSize: options.cacheSize,\n      crossOrigin: crossOrigin,\n      opaque: options.opaque !== undefined ? options.opaque : true,\n      maxZoom: options.maxZoom !== undefined ? options.maxZoom : 19,\n      reprojectionErrorThreshold: options.reprojectionErrorThreshold,\n      tileLoadFunction: options.tileLoadFunction,\n      url: url,\n      wrapX: options.wrapX\n    });\n\n  }\n\n}\n\nexport default OSM;\n","var hasImageData = true;\ntry {\n  new ImageData(10, 10);\n} catch (_) {\n  hasImageData = false;\n}\n\nvar context = document.createElement('canvas').getContext('2d');\n\nfunction newImageData(data, width, height) {\n  if (hasImageData) {\n    return new ImageData(data, width, height);\n  } else {\n    var imageData = context.createImageData(width, height);\n    imageData.data.set(data);\n    return imageData;\n  }\n}\n\nexports.newImageData = newImageData;\n","var newImageData = require('./util').newImageData;\n\n/**\n * Create a function for running operations.  This function is serialized for\n * use in a worker.\n * @param {function(Array, Object):*} operation The operation.\n * @return {function(Object):ArrayBuffer} A function that takes an object with\n * buffers, meta, imageOps, width, and height properties and returns an array\n * buffer.\n */\nfunction createMinion(operation) {\n  var workerHasImageData = true;\n  try {\n    new ImageData(10, 10);\n  } catch (_) {\n    workerHasImageData = false;\n  }\n\n  function newWorkerImageData(data, width, height) {\n    if (workerHasImageData) {\n      return new ImageData(data, width, height);\n    } else {\n      return {data: data, width: width, height: height};\n    }\n  }\n\n  return function(data) {\n    // bracket notation for minification support\n    var buffers = data['buffers'];\n    var meta = data['meta'];\n    var imageOps = data['imageOps'];\n    var width = data['width'];\n    var height = data['height'];\n\n    var numBuffers = buffers.length;\n    var numBytes = buffers[0].byteLength;\n    var output, b;\n\n    if (imageOps) {\n      var images = new Array(numBuffers);\n      for (b = 0; b < numBuffers; ++b) {\n        images[b] = newWorkerImageData(\n            new Uint8ClampedArray(buffers[b]), width, height);\n      }\n      output = operation(images, meta).data;\n    } else {\n      output = new Uint8ClampedArray(numBytes);\n      var arrays = new Array(numBuffers);\n      var pixels = new Array(numBuffers);\n      for (b = 0; b < numBuffers; ++b) {\n        arrays[b] = new Uint8ClampedArray(buffers[b]);\n        pixels[b] = [0, 0, 0, 0];\n      }\n      for (var i = 0; i < numBytes; i += 4) {\n        for (var j = 0; j < numBuffers; ++j) {\n          var array = arrays[j];\n          pixels[j][0] = array[i];\n          pixels[j][1] = array[i + 1];\n          pixels[j][2] = array[i + 2];\n          pixels[j][3] = array[i + 3];\n        }\n        var pixel = operation(pixels, meta);\n        output[i] = pixel[0];\n        output[i + 1] = pixel[1];\n        output[i + 2] = pixel[2];\n        output[i + 3] = pixel[3];\n      }\n    }\n    return output.buffer;\n  };\n}\n\n/**\n * Create a worker for running operations.\n * @param {Object} config Configuration.\n * @param {function(MessageEvent)} onMessage Called with a message event.\n * @return {Worker} The worker.\n */\nfunction createWorker(config, onMessage) {\n  var lib = Object.keys(config.lib || {}).map(function(name) {\n    return 'var ' + name + ' = ' + config.lib[name].toString() + ';';\n  });\n\n  var lines = lib.concat([\n    'var __minion__ = (' + createMinion.toString() + ')(', config.operation.toString(), ');',\n    'self.addEventListener(\"message\", function(event) {',\n    '  var buffer = __minion__(event.data);',\n    '  self.postMessage({buffer: buffer, meta: event.data.meta}, [buffer]);',\n    '});'\n  ]);\n\n  var blob = new Blob(lines, {type: 'text/javascript'});\n  var source = URL.createObjectURL(blob);\n  var worker = new Worker(source);\n  worker.addEventListener('message', onMessage);\n  return worker;\n}\n\n/**\n * Create a faux worker for running operations.\n * @param {Object} config Configuration.\n * @param {function(MessageEvent)} onMessage Called with a message event.\n * @return {Object} The faux worker.\n */\nfunction createFauxWorker(config, onMessage) {\n  var minion = createMinion(config.operation);\n  return {\n    postMessage: function(data) {\n      setTimeout(function() {\n        onMessage({'data': {'buffer': minion(data), 'meta': data['meta']}});\n      }, 0);\n    }\n  };\n}\n\n/**\n * A processor runs pixel or image operations in workers.\n * @param {Object} config Configuration.\n */\nfunction Processor(config) {\n  this._imageOps = !!config.imageOps;\n  var threads;\n  if (config.threads === 0) {\n    threads = 0;\n  } else if (this._imageOps) {\n    threads = 1;\n  } else {\n    threads = config.threads || 1;\n  }\n  var workers = [];\n  if (threads) {\n    for (var i = 0; i < threads; ++i) {\n      workers[i] = createWorker(config, this._onWorkerMessage.bind(this, i));\n    }\n  } else {\n    workers[0] = createFauxWorker(config, this._onWorkerMessage.bind(this, 0));\n  }\n  this._workers = workers;\n  this._queue = [];\n  this._maxQueueLength = config.queue || Infinity;\n  this._running = 0;\n  this._dataLookup = {};\n  this._job = null;\n}\n\n/**\n * Run operation on input data.\n * @param {Array.<Array|ImageData>} inputs Array of pixels or image data\n *     (depending on the operation type).\n * @param {Object} meta A user data object.  This is passed to all operations\n *     and must be serializable.\n * @param {function(Error, ImageData, Object)} callback Called when work\n *     completes.  The first argument is any error.  The second is the ImageData\n *     generated by operations.  The third is the user data object.\n */\nProcessor.prototype.process = function(inputs, meta, callback) {\n  this._enqueue({\n    inputs: inputs,\n    meta: meta,\n    callback: callback\n  });\n  this._dispatch();\n};\n\n/**\n * Stop responding to any completed work and destroy the processor.\n */\nProcessor.prototype.destroy = function() {\n  for (var key in this) {\n    this[key] = null;\n  }\n  this._destroyed = true;\n};\n\n/**\n * Add a job to the queue.\n * @param {Object} job The job.\n */\nProcessor.prototype._enqueue = function(job) {\n  this._queue.push(job);\n  while (this._queue.length > this._maxQueueLength) {\n    this._queue.shift().callback(null, null);\n  }\n};\n\n/**\n * Dispatch a job.\n */\nProcessor.prototype._dispatch = function() {\n  if (this._running === 0 && this._queue.length > 0) {\n    var job = this._job = this._queue.shift();\n    var width = job.inputs[0].width;\n    var height = job.inputs[0].height;\n    var buffers = job.inputs.map(function(input) {\n      return input.data.buffer;\n    });\n    var threads = this._workers.length;\n    this._running = threads;\n    if (threads === 1) {\n      this._workers[0].postMessage({\n        'buffers': buffers,\n        'meta': job.meta,\n        'imageOps': this._imageOps,\n        'width': width,\n        'height': height\n      }, buffers);\n    } else {\n      var length = job.inputs[0].data.length;\n      var segmentLength = 4 * Math.ceil(length / 4 / threads);\n      for (var i = 0; i < threads; ++i) {\n        var offset = i * segmentLength;\n        var slices = [];\n        for (var j = 0, jj = buffers.length; j < jj; ++j) {\n          slices.push(buffers[i].slice(offset, offset + segmentLength));\n        }\n        this._workers[i].postMessage({\n          'buffers': slices,\n          'meta': job.meta,\n          'imageOps': this._imageOps,\n          'width': width,\n          'height': height\n        }, slices);\n      }\n    }\n  }\n};\n\n/**\n * Handle messages from the worker.\n * @param {number} index The worker index.\n * @param {MessageEvent} event The message event.\n */\nProcessor.prototype._onWorkerMessage = function(index, event) {\n  if (this._destroyed) {\n    return;\n  }\n  this._dataLookup[index] = event.data;\n  --this._running;\n  if (this._running === 0) {\n    this._resolveJob();\n  }\n};\n\n/**\n * Resolve a job.  If there are no more worker threads, the processor callback\n * will be called.\n */\nProcessor.prototype._resolveJob = function() {\n  var job = this._job;\n  var threads = this._workers.length;\n  var data, meta;\n  if (threads === 1) {\n    data = new Uint8ClampedArray(this._dataLookup[0]['buffer']);\n    meta = this._dataLookup[0]['meta'];\n  } else {\n    var length = job.inputs[0].data.length;\n    data = new Uint8ClampedArray(length);\n    meta = new Array(length);\n    var segmentLength = 4 * Math.ceil(length / 4 / threads);\n    for (var i = 0; i < threads; ++i) {\n      var buffer = this._dataLookup[i]['buffer'];\n      var offset = i * segmentLength;\n      data.set(new Uint8ClampedArray(buffer), offset);\n      meta[i] = this._dataLookup[i]['meta'];\n    }\n  }\n  this._job = null;\n  this._dataLookup = {};\n  job.callback(null,\n      newImageData(data, job.inputs[0].width, job.inputs[0].height), meta);\n  this._dispatch();\n};\n\nmodule.exports = Processor;\n","/**\n * @module ol/source/Raster\n */\nimport {getUid} from '../util.js';\nimport ImageCanvas from '../ImageCanvas.js';\nimport TileQueue from '../TileQueue.js';\nimport {createCanvasContext2D} from '../dom.js';\nimport {listen} from '../events.js';\nimport Event from '../events/Event.js';\nimport EventType from '../events/EventType.js';\nimport {Processor} from 'pixelworks/lib/index';\nimport {equals, getCenter, getHeight, getWidth} from '../extent.js';\nimport LayerType from '../LayerType.js';\nimport Layer from '../layer/Layer.js';\nimport ImageLayer from '../layer/Image.js';\nimport TileLayer from '../layer/Tile.js';\nimport {assign} from '../obj.js';\nimport CanvasImageLayerRenderer from '../renderer/canvas/ImageLayer.js';\nimport CanvasTileLayerRenderer from '../renderer/canvas/TileLayer.js';\nimport ImageSource from '../source/Image.js';\nimport SourceState from '../source/State.js';\nimport TileSource from '../source/Tile.js';\nimport {create as createTransform} from '../transform.js';\n\n\n/**\n * A function that takes an array of input data, performs some operation, and\n * returns an array of output data.\n * For `pixel` type operations, the function will be called with an array of\n * pixels, where each pixel is an array of four numbers (`[r, g, b, a]`) in the\n * range of 0 - 255. It should return a single pixel array.\n * For `'image'` type operations, functions will be called with an array of\n * {@link ImageData https://developer.mozilla.org/en-US/docs/Web/API/ImageData}\n * and should return a single {@link ImageData\n * https://developer.mozilla.org/en-US/docs/Web/API/ImageData}.  The operations\n * are called with a second \"data\" argument, which can be used for storage.  The\n * data object is accessible from raster events, where it can be initialized in\n * \"beforeoperations\" and accessed again in \"afteroperations\".\n *\n * @typedef {function((Array.<Array.<number>>|Array.<ImageData>), Object):\n *     (Array.<number>|ImageData)} Operation\n */\n\n\n/**\n * @enum {string}\n */\nconst RasterEventType = {\n  /**\n   * Triggered before operations are run.\n   * @event ol/source/Raster~RasterSourceEvent#beforeoperations\n   * @api\n   */\n  BEFOREOPERATIONS: 'beforeoperations',\n\n  /**\n   * Triggered after operations are run.\n   * @event ol/source/Raster~RasterSourceEvent#afteroperations\n   * @api\n   */\n  AFTEROPERATIONS: 'afteroperations'\n};\n\n\n/**\n * Raster operation type. Supported values are `'pixel'` and `'image'`.\n * @enum {string}\n */\nconst RasterOperationType = {\n  PIXEL: 'pixel',\n  IMAGE: 'image'\n};\n\n\n/**\n * @classdesc\n * Events emitted by {@link module:ol/source/Raster} instances are instances of this\n * type.\n */\nclass RasterSourceEvent extends Event {\n  /**\n   * @param {string} type Type.\n   * @param {module:ol/PluggableMap~FrameState} frameState The frame state.\n   * @param {Object} data An object made available to operations.\n   */\n  constructor(type, frameState, data) {\n    super(type);\n\n    /**\n     * The raster extent.\n     * @type {module:ol/extent~Extent}\n     * @api\n     */\n    this.extent = frameState.extent;\n\n    /**\n     * The pixel resolution (map units per pixel).\n     * @type {number}\n     * @api\n     */\n    this.resolution = frameState.viewState.resolution / frameState.pixelRatio;\n\n    /**\n     * An object made available to all operations.  This can be used by operations\n     * as a storage object (e.g. for calculating statistics).\n     * @type {Object}\n     * @api\n     */\n    this.data = data;\n\n  }\n\n}\n\n/**\n * @typedef {Object} Options\n * @property {Array.<module:ol/source/Source|module:ol/layer/Layer>} sources Input\n * sources or layers. Vector layers must be configured with `renderMode: 'image'`.\n * @property {module:ol/source/Raster~Operation} [operation] Raster operation.\n * The operation will be called with data from input sources\n * and the output will be assigned to the raster source.\n * @property {Object} [lib] Functions that will be made available to operations run in a worker.\n * @property {number} [threads] By default, operations will be run in a single worker thread.\n * To avoid using workers altogether, set `threads: 0`.  For pixel operations, operations can\n * be run in multiple worker threads.  Note that there is additional overhead in\n * transferring data to multiple workers, and that depending on the user's\n * system, it may not be possible to parallelize the work.\n * @property {module:ol/source/Raster~RasterOperationType} [operationType='pixel'] Operation type.\n * Supported values are `'pixel'` and `'image'`.  By default,\n * `'pixel'` operations are assumed, and operations will be called with an\n * array of pixels from input sources.  If set to `'image'`, operations will\n * be called with an array of ImageData objects from input sources.\n */\n\n\n/**\n * @classdesc\n * A source that transforms data from any number of input sources using an\n * {@link module:ol/source/Raster~Operation} function to transform input pixel values into\n * output pixel values.\n *\n * @fires ol/source/Raster~RasterSourceEvent\n * @api\n */\nclass RasterSource extends ImageSource {\n  /**\n   * @param {module:ol/source/Raster~Options=} options Options.\n   */\n  constructor(options) {\n    super({});\n\n    /**\n     * @private\n     * @type {*}\n     */\n    this.worker_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/source/Raster~RasterOperationType}\n     */\n    this.operationType_ = options.operationType !== undefined ?\n      options.operationType : RasterOperationType.PIXEL;\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.threads_ = options.threads !== undefined ? options.threads : 1;\n\n    /**\n     * @private\n     * @type {Array.<module:ol/renderer/canvas/Layer>}\n     */\n    this.renderers_ = createRenderers(options.sources);\n\n    for (let r = 0, rr = this.renderers_.length; r < rr; ++r) {\n      listen(this.renderers_[r], EventType.CHANGE,\n        this.changed, this);\n    }\n\n    /**\n     * @private\n     * @type {module:ol/TileQueue}\n     */\n    this.tileQueue_ = new TileQueue(\n      function() {\n        return 1;\n      },\n      this.changed.bind(this));\n\n    const layerStatesArray = getLayerStatesArray(this.renderers_);\n    const layerStates = {};\n    for (let i = 0, ii = layerStatesArray.length; i < ii; ++i) {\n      layerStates[getUid(layerStatesArray[i].layer)] = layerStatesArray[i];\n    }\n\n    /**\n     * The most recently requested frame state.\n     * @type {module:ol/PluggableMap~FrameState}\n     * @private\n     */\n    this.requestedFrameState_;\n\n    /**\n     * The most recently rendered image canvas.\n     * @type {module:ol/ImageCanvas}\n     * @private\n     */\n    this.renderedImageCanvas_ = null;\n\n    /**\n     * The most recently rendered revision.\n     * @type {number}\n     */\n    this.renderedRevision_;\n\n    /**\n     * @private\n     * @type {module:ol/PluggableMap~FrameState}\n     */\n    this.frameState_ = {\n      animate: false,\n      coordinateToPixelTransform: createTransform(),\n      extent: null,\n      focus: null,\n      index: 0,\n      layerStates: layerStates,\n      layerStatesArray: layerStatesArray,\n      pixelRatio: 1,\n      pixelToCoordinateTransform: createTransform(),\n      postRenderFunctions: [],\n      size: [0, 0],\n      skippedFeatureUids: {},\n      tileQueue: this.tileQueue_,\n      time: Date.now(),\n      usedTiles: {},\n      viewState: /** @type {module:ol/View~State} */ ({\n        rotation: 0\n      }),\n      viewHints: [],\n      wantedTiles: {}\n    };\n\n    if (options.operation !== undefined) {\n      this.setOperation(options.operation, options.lib);\n    }\n\n  }\n\n  /**\n   * Set the operation.\n   * @param {module:ol/source/Raster~Operation} operation New operation.\n   * @param {Object=} opt_lib Functions that will be available to operations run\n   *     in a worker.\n   * @api\n   */\n  setOperation(operation, opt_lib) {\n    this.worker_ = new Processor({\n      operation: operation,\n      imageOps: this.operationType_ === RasterOperationType.IMAGE,\n      queue: 1,\n      lib: opt_lib,\n      threads: this.threads_\n    });\n    this.changed();\n  }\n\n  /**\n   * Update the stored frame state.\n   * @param {module:ol/extent~Extent} extent The view extent (in map units).\n   * @param {number} resolution The view resolution.\n   * @param {module:ol/proj/Projection} projection The view projection.\n   * @return {module:ol/PluggableMap~FrameState} The updated frame state.\n   * @private\n   */\n  updateFrameState_(extent, resolution, projection) {\n\n    const frameState = /** @type {module:ol/PluggableMap~FrameState} */ (assign({}, this.frameState_));\n\n    frameState.viewState = /** @type {module:ol/View~State} */ (assign({}, frameState.viewState));\n\n    const center = getCenter(extent);\n\n    frameState.extent = extent.slice();\n    frameState.focus = center;\n    frameState.size[0] = Math.round(getWidth(extent) / resolution);\n    frameState.size[1] = Math.round(getHeight(extent) / resolution);\n    frameState.time = Date.now();\n    frameState.animate = false;\n\n    const viewState = frameState.viewState;\n    viewState.center = center;\n    viewState.projection = projection;\n    viewState.resolution = resolution;\n    return frameState;\n  }\n\n  /**\n   * Determine if all sources are ready.\n   * @return {boolean} All sources are ready.\n   * @private\n   */\n  allSourcesReady_() {\n    let ready = true;\n    let source;\n    for (let i = 0, ii = this.renderers_.length; i < ii; ++i) {\n      source = this.renderers_[i].getLayer().getSource();\n      if (source.getState() !== SourceState.READY) {\n        ready = false;\n        break;\n      }\n    }\n    return ready;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getImage(extent, resolution, pixelRatio, projection) {\n    if (!this.allSourcesReady_()) {\n      return null;\n    }\n\n    const frameState = this.updateFrameState_(extent, resolution, projection);\n    this.requestedFrameState_ = frameState;\n\n    // check if we can't reuse the existing ol/ImageCanvas\n    if (this.renderedImageCanvas_) {\n      const renderedResolution = this.renderedImageCanvas_.getResolution();\n      const renderedExtent = this.renderedImageCanvas_.getExtent();\n      if (resolution !== renderedResolution || !equals(extent, renderedExtent)) {\n        this.renderedImageCanvas_ = null;\n      }\n    }\n\n    if (!this.renderedImageCanvas_ || this.getRevision() !== this.renderedRevision_) {\n      this.processSources_();\n    }\n\n    frameState.tileQueue.loadMoreTiles(16, 16);\n\n    if (frameState.animate) {\n      requestAnimationFrame(this.changed.bind(this));\n    }\n\n    return this.renderedImageCanvas_;\n  }\n\n  /**\n   * Start processing source data.\n   * @private\n   */\n  processSources_() {\n    const frameState = this.requestedFrameState_;\n    const len = this.renderers_.length;\n    const imageDatas = new Array(len);\n    for (let i = 0; i < len; ++i) {\n      const imageData = getImageData(\n        this.renderers_[i], frameState, frameState.layerStatesArray[i]);\n      if (imageData) {\n        imageDatas[i] = imageData;\n      } else {\n        return;\n      }\n    }\n\n    const data = {};\n    this.dispatchEvent(new RasterSourceEvent(RasterEventType.BEFOREOPERATIONS, frameState, data));\n    this.worker_.process(imageDatas, data, this.onWorkerComplete_.bind(this, frameState));\n  }\n\n  /**\n   * Called when pixel processing is complete.\n   * @param {module:ol/PluggableMap~FrameState} frameState The frame state.\n   * @param {Error} err Any error during processing.\n   * @param {ImageData} output The output image data.\n   * @param {Object} data The user data.\n   * @private\n   */\n  onWorkerComplete_(frameState, err, output, data) {\n    if (err || !output) {\n      return;\n    }\n\n    // do nothing if extent or resolution changed\n    const extent = frameState.extent;\n    const resolution = frameState.viewState.resolution;\n    if (resolution !== this.requestedFrameState_.viewState.resolution ||\n        !equals(extent, this.requestedFrameState_.extent)) {\n      return;\n    }\n\n    let context;\n    if (this.renderedImageCanvas_) {\n      context = this.renderedImageCanvas_.getImage().getContext('2d');\n    } else {\n      const width = Math.round(getWidth(extent) / resolution);\n      const height = Math.round(getHeight(extent) / resolution);\n      context = createCanvasContext2D(width, height);\n      this.renderedImageCanvas_ = new ImageCanvas(extent, resolution, 1, context.canvas);\n    }\n    context.putImageData(output, 0, 0);\n\n    this.changed();\n    this.renderedRevision_ = this.getRevision();\n\n    this.dispatchEvent(new RasterSourceEvent(RasterEventType.AFTEROPERATIONS, frameState, data));\n  }\n\n  /**\n   * @override\n   */\n  getImageInternal() {\n    return null; // not implemented\n  }\n}\n\n\n/**\n * A reusable canvas context.\n * @type {CanvasRenderingContext2D}\n * @private\n */\nlet sharedContext = null;\n\n\n/**\n * Get image data from a renderer.\n * @param {module:ol/renderer/canvas/Layer} renderer Layer renderer.\n * @param {module:ol/PluggableMap~FrameState} frameState The frame state.\n * @param {module:ol/layer/Layer~State} layerState The layer state.\n * @return {ImageData} The image data.\n */\nfunction getImageData(renderer, frameState, layerState) {\n  if (!renderer.prepareFrame(frameState, layerState)) {\n    return null;\n  }\n  const width = frameState.size[0];\n  const height = frameState.size[1];\n  if (!sharedContext) {\n    sharedContext = createCanvasContext2D(width, height);\n  } else {\n    const canvas = sharedContext.canvas;\n    if (canvas.width !== width || canvas.height !== height) {\n      sharedContext = createCanvasContext2D(width, height);\n    } else {\n      sharedContext.clearRect(0, 0, width, height);\n    }\n  }\n  renderer.composeFrame(frameState, layerState, sharedContext);\n  return sharedContext.getImageData(0, 0, width, height);\n}\n\n\n/**\n * Get a list of layer states from a list of renderers.\n * @param {Array.<module:ol/renderer/canvas/Layer>} renderers Layer renderers.\n * @return {Array.<module:ol/layer/Layer~State>} The layer states.\n */\nfunction getLayerStatesArray(renderers) {\n  return renderers.map(function(renderer) {\n    return renderer.getLayer().getLayerState();\n  });\n}\n\n\n/**\n * Create renderers for all sources.\n * @param {Array.<module:ol/source/Source>} sources The sources.\n * @return {Array.<module:ol/renderer/canvas/Layer>} Array of layer renderers.\n */\nfunction createRenderers(sources) {\n  const len = sources.length;\n  const renderers = new Array(len);\n  for (let i = 0; i < len; ++i) {\n    renderers[i] = createRenderer(sources[i]);\n  }\n  return renderers;\n}\n\n\n/**\n * Create a renderer for the provided source.\n * @param {module:ol/source/Source} source The source.\n * @return {module:ol/renderer/canvas/Layer} The renderer.\n */\nfunction createRenderer(source) {\n  let renderer = null;\n  if (source instanceof TileSource) {\n    renderer = createTileRenderer(source);\n  } else if (source instanceof ImageSource) {\n    renderer = createImageRenderer(source);\n  } else if (source instanceof TileLayer) {\n    renderer = new CanvasTileLayerRenderer(source);\n  } else if (source instanceof Layer &&\n      (source.getType() == LayerType.IMAGE || source.getType() == LayerType.VECTOR)) {\n    renderer = new CanvasImageLayerRenderer(source);\n  }\n  return renderer;\n}\n\n\n/**\n * Create an image renderer for the provided source.\n * @param {module:ol/source/Image} source The source.\n * @return {module:ol/renderer/canvas/Layer} The renderer.\n */\nfunction createImageRenderer(source) {\n  const layer = new ImageLayer({source: source});\n  return new CanvasImageLayerRenderer(layer);\n}\n\n\n/**\n * Create a tile renderer for the provided source.\n * @param {module:ol/source/Tile} source The source.\n * @return {module:ol/renderer/canvas/Layer} The renderer.\n */\nfunction createTileRenderer(source) {\n  const layer = new TileLayer({source: source});\n  return new CanvasTileLayerRenderer(layer);\n}\n\n\nexport default RasterSource;\n","/**\n * @module ol/source/Stamen\n */\n\nimport {ATTRIBUTION as OSM_ATTRIBUTION} from '../source/OSM.js';\nimport XYZ from '../source/XYZ.js';\n\n\n/**\n * @const\n * @type {Array.<string>}\n */\nconst ATTRIBUTIONS = [\n  'Map tiles by <a href=\"https://stamen.com/\">Stamen Design</a>, ' +\n        'under <a href=\"https://creativecommons.org/licenses/by/3.0/\">CC BY' +\n        ' 3.0</a>.',\n  OSM_ATTRIBUTION\n];\n\n\n/**\n * @type {Object.<string, {extension: string, opaque: boolean}>}\n */\nconst LayerConfig = {\n  'terrain': {\n    extension: 'jpg',\n    opaque: true\n  },\n  'terrain-background': {\n    extension: 'jpg',\n    opaque: true\n  },\n  'terrain-labels': {\n    extension: 'png',\n    opaque: false\n  },\n  'terrain-lines': {\n    extension: 'png',\n    opaque: false\n  },\n  'toner-background': {\n    extension: 'png',\n    opaque: true\n  },\n  'toner': {\n    extension: 'png',\n    opaque: true\n  },\n  'toner-hybrid': {\n    extension: 'png',\n    opaque: false\n  },\n  'toner-labels': {\n    extension: 'png',\n    opaque: false\n  },\n  'toner-lines': {\n    extension: 'png',\n    opaque: false\n  },\n  'toner-lite': {\n    extension: 'png',\n    opaque: true\n  },\n  'watercolor': {\n    extension: 'jpg',\n    opaque: true\n  }\n};\n\n\n/**\n * @type {Object.<string, {minZoom: number, maxZoom: number}>}\n */\nconst ProviderConfig = {\n  'terrain': {\n    minZoom: 4,\n    maxZoom: 18\n  },\n  'toner': {\n    minZoom: 0,\n    maxZoom: 20\n  },\n  'watercolor': {\n    minZoom: 1,\n    maxZoom: 16\n  }\n};\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [cacheSize=2048] Cache size.\n * @property {string} [layer] Layer.\n * @property {number} [minZoom] Minimum zoom.\n * @property {number} [maxZoom] Maximum zoom.\n * @property {boolean} [opaque] Whether the layer is opaque.\n * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).\n * Higher values can increase reprojection performance, but decrease precision.\n * @property {module:ol/Tile~LoadFunction} [tileLoadFunction]\n * Optional function to load a tile given a URL. The default is\n * ```js\n * function(imageTile, src) {\n *   imageTile.getImage().src = src;\n * };\n * ```\n * @property {string} [url] URL template. Must include `{x}`, `{y}` or `{-y}`, and `{z}` placeholders.\n * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.\n */\n\n\n/**\n * @classdesc\n * Layer source for the Stamen tile server.\n * @api\n */\nclass Stamen extends XYZ {\n  /**\n   * @param {module:ol/source/Stamen~Options=} options Stamen options.\n   */\n  constructor(options) {\n    const i = options.layer.indexOf('-');\n    const provider = i == -1 ? options.layer : options.layer.slice(0, i);\n    const providerConfig = ProviderConfig[provider];\n\n    const layerConfig = LayerConfig[options.layer];\n\n    const url = options.url !== undefined ? options.url :\n      'https://stamen-tiles-{a-d}.a.ssl.fastly.net/' + options.layer +\n        '/{z}/{x}/{y}.' + layerConfig.extension;\n\n    super({\n      attributions: ATTRIBUTIONS,\n      cacheSize: options.cacheSize,\n      crossOrigin: 'anonymous',\n      maxZoom: options.maxZoom != undefined ? options.maxZoom : providerConfig.maxZoom,\n      minZoom: options.minZoom != undefined ? options.minZoom : providerConfig.minZoom,\n      opaque: layerConfig.opaque,\n      reprojectionErrorThreshold: options.reprojectionErrorThreshold,\n      tileLoadFunction: options.tileLoadFunction,\n      url: url,\n      wrapX: options.wrapX\n    });\n\n  }\n\n}\n\nexport default Stamen;\n","/**\n * @module ol/source/TileArcGISRest\n */\n\nimport {createEmpty} from '../extent.js';\nimport {modulo} from '../math.js';\nimport {assign} from '../obj.js';\nimport {toSize, scale as scaleSize} from '../size.js';\nimport TileImage from '../source/TileImage.js';\nimport {hash as tileCoordHash} from '../tilecoord.js';\nimport {appendParams} from '../uri.js';\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/source/Source~AttributionLike} [attributions] Attributions.\n * @property {number} [cacheSize=2048] Cache size.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images.\n * Note that you must provide a `crossOrigin` value if you are using the WebGL renderer\n * or if you want to access pixel data with the Canvas renderer.  See\n * https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image\n * for more detail.\n * @property {Object.<string,*>} [params] ArcGIS Rest parameters. This field is optional. Service defaults will be\n * used for any fields not specified. `FORMAT` is `PNG32` by default. `F` is `IMAGE` by\n * default. `TRANSPARENT` is `true` by default.  `BBOX, `SIZE`, `BBOXSR`,\n * and `IMAGESR` will be set dynamically. Set `LAYERS` to\n * override the default service layer visibility. See\n * http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#/Export_Map/02r3000000v7000000/\n * for further reference.\n * @property {module:ol/tilegrid/TileGrid} [tileGrid] Tile grid. Base this on the resolutions,\n * tilesize and extent supported by the server.\n * If this is not defined, a default grid will be used: if there is a projection\n * extent, the grid will be based on that; if not, a grid based on a global\n * extent with origin at 0,0 will be used.\n * @property {module:ol/proj~ProjectionLike} projection Projection.\n * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).\n * Higher values can increase reprojection performance, but decrease precision.\n * @property {module:ol/Tile~LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL.\n * The default is\n * ```js\n * function(imageTile, src) {\n *   imageTile.getImage().src = src;\n * };\n * ```\n * @property {string} [url] ArcGIS Rest service URL for a Map Service or Image Service. The\n * url should include /MapServer or /ImageServer.\n * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.\n * @property {number} [transition] Duration of the opacity transition for rendering.  To disable the opacity\n * transition, pass `transition: 0`.\n * @property {Array.<string>} urls ArcGIS Rest service urls. Use this instead of `url` when the ArcGIS\n * Service supports multiple urls for export requests.\n */\n\n\n/**\n * @classdesc\n * Layer source for tile data from ArcGIS Rest services. Map and Image\n * Services are supported.\n *\n * For cached ArcGIS services, better performance is available using the\n * {@link module:ol/source/XYZ~XYZ} data source.\n * @api\n */\nclass TileArcGISRest extends TileImage {\n  /**\n   * @param {module:ol/source/TileArcGISRest~Options=} opt_options Tile ArcGIS Rest options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options || {};\n\n    super({\n      attributions: options.attributions,\n      cacheSize: options.cacheSize,\n      crossOrigin: options.crossOrigin,\n      projection: options.projection,\n      reprojectionErrorThreshold: options.reprojectionErrorThreshold,\n      tileGrid: options.tileGrid,\n      tileLoadFunction: options.tileLoadFunction,\n      url: options.url,\n      urls: options.urls,\n      wrapX: options.wrapX !== undefined ? options.wrapX : true,\n      transition: options.transition\n    });\n\n    /**\n     * @private\n     * @type {!Object}\n     */\n    this.params_ = options.params || {};\n\n    /**\n     * @private\n     * @type {module:ol/extent~Extent}\n     */\n    this.tmpExtent_ = createEmpty();\n\n    this.setKey(this.getKeyForParams_());\n  }\n\n  /**\n   * @private\n   * @return {string} The key for the current params.\n   */\n  getKeyForParams_() {\n    let i = 0;\n    const res = [];\n    for (const key in this.params_) {\n      res[i++] = key + '-' + this.params_[key];\n    }\n    return res.join('/');\n  }\n\n  /**\n   * Get the user-provided params, i.e. those passed to the constructor through\n   * the \"params\" option, and possibly updated using the updateParams method.\n   * @return {Object} Params.\n   * @api\n   */\n  getParams() {\n    return this.params_;\n  }\n\n  /**\n   * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n   * @param {module:ol/size~Size} tileSize Tile size.\n   * @param {module:ol/extent~Extent} tileExtent Tile extent.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @param {Object} params Params.\n   * @return {string|undefined} Request URL.\n   * @private\n   */\n  getRequestUrl_(tileCoord, tileSize, tileExtent, pixelRatio, projection, params) {\n\n    const urls = this.urls;\n    if (!urls) {\n      return undefined;\n    }\n\n    // ArcGIS Server only wants the numeric portion of the projection ID.\n    const srid = projection.getCode().split(':').pop();\n\n    params['SIZE'] = tileSize[0] + ',' + tileSize[1];\n    params['BBOX'] = tileExtent.join(',');\n    params['BBOXSR'] = srid;\n    params['IMAGESR'] = srid;\n    params['DPI'] = Math.round(\n      params['DPI'] ? params['DPI'] * pixelRatio : 90 * pixelRatio\n    );\n\n    let url;\n    if (urls.length == 1) {\n      url = urls[0];\n    } else {\n      const index = modulo(tileCoordHash(tileCoord), urls.length);\n      url = urls[index];\n    }\n\n    const modifiedUrl = url\n      .replace(/MapServer\\/?$/, 'MapServer/export')\n      .replace(/ImageServer\\/?$/, 'ImageServer/exportImage');\n    return appendParams(modifiedUrl, params);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getTilePixelRatio(pixelRatio) {\n    return /** @type {number} */ (pixelRatio);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  fixedTileUrlFunction(tileCoord, pixelRatio, projection) {\n\n    let tileGrid = this.getTileGrid();\n    if (!tileGrid) {\n      tileGrid = this.getTileGridForProjection(projection);\n    }\n\n    if (tileGrid.getResolutions().length <= tileCoord[0]) {\n      return undefined;\n    }\n\n    const tileExtent = tileGrid.getTileCoordExtent(\n      tileCoord, this.tmpExtent_);\n    let tileSize = toSize(\n      tileGrid.getTileSize(tileCoord[0]), this.tmpSize);\n\n    if (pixelRatio != 1) {\n      tileSize = scaleSize(tileSize, pixelRatio, this.tmpSize);\n    }\n\n    // Apply default params and override with user specified values.\n    const baseParams = {\n      'F': 'image',\n      'FORMAT': 'PNG32',\n      'TRANSPARENT': true\n    };\n    assign(baseParams, this.params_);\n\n    return this.getRequestUrl_(tileCoord, tileSize, tileExtent,\n      pixelRatio, projection, baseParams);\n  }\n\n  /**\n   * Update the user-provided params.\n   * @param {Object} params Params.\n   * @api\n   */\n  updateParams(params) {\n    assign(this.params_, params);\n    this.setKey(this.getKeyForParams_());\n  }\n}\n\n\nexport default TileArcGISRest;\n","/**\n * @module ol/source/TileDebug\n */\n\nimport Tile from '../Tile.js';\nimport TileState from '../TileState.js';\nimport {createCanvasContext2D} from '../dom.js';\nimport {toSize} from '../size.js';\nimport TileSource from '../source/Tile.js';\nimport {getKeyZXY} from '../tilecoord.js';\n\n\nclass LabeledTile extends Tile {\n  /**\n   * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n   * @param {module:ol/size~Size} tileSize Tile size.\n   * @param {string} text Text.\n   */\n  constructor(tileCoord, tileSize, text) {\n\n    super(tileCoord, TileState.LOADED);\n\n    /**\n    * @private\n    * @type {module:ol/size~Size}\n    */\n    this.tileSize_ = tileSize;\n\n    /**\n    * @private\n    * @type {string}\n    */\n    this.text_ = text;\n\n    /**\n    * @private\n    * @type {HTMLCanvasElement}\n    */\n    this.canvas_ = null;\n\n  }\n\n  /**\n  * Get the image element for this tile.\n  * @return {HTMLCanvasElement} Image.\n  */\n  getImage() {\n    if (this.canvas_) {\n      return this.canvas_;\n    } else {\n      const tileSize = this.tileSize_;\n      const context = createCanvasContext2D(tileSize[0], tileSize[1]);\n\n      context.strokeStyle = 'black';\n      context.strokeRect(0.5, 0.5, tileSize[0] + 0.5, tileSize[1] + 0.5);\n\n      context.fillStyle = 'black';\n      context.textAlign = 'center';\n      context.textBaseline = 'middle';\n      context.font = '24px sans-serif';\n      context.fillText(this.text_, tileSize[0] / 2, tileSize[1] / 2);\n\n      this.canvas_ = context.canvas;\n      return context.canvas;\n    }\n  }\n\n  /**\n  * @override\n  */\n  load() {}\n}\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/proj~ProjectionLike} projection Projection.\n * @property {module:ol/tilegrid/TileGrid} [tileGrid] Tile grid.\n * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.\n */\n\n\n/**\n * @classdesc\n * A pseudo tile source, which does not fetch tiles from a server, but renders\n * a grid outline for the tile grid/projection along with the coordinates for\n * each tile. See examples/canvas-tiles for an example.\n *\n * Uses Canvas context2d, so requires Canvas support.\n * @api\n */\nclass TileDebug extends TileSource {\n  /**\n   * @param {module:ol/source/TileDebug~Options=} options Debug tile options.\n   */\n  constructor(options) {\n\n    super({\n      opaque: false,\n      projection: options.projection,\n      tileGrid: options.tileGrid,\n      wrapX: options.wrapX !== undefined ? options.wrapX : true\n    });\n\n  }\n\n  /**\n  * @inheritDoc\n  */\n  getTile(z, x, y) {\n    const tileCoordKey = getKeyZXY(z, x, y);\n    if (this.tileCache.containsKey(tileCoordKey)) {\n      return /** @type {!module:ol/source/TileDebug~LabeledTile} */ (this.tileCache.get(tileCoordKey));\n    } else {\n      const tileSize = toSize(this.tileGrid.getTileSize(z));\n      const tileCoord = [z, x, y];\n      const textTileCoord = this.getTileCoordForTileUrlFunction(tileCoord);\n      const text = !textTileCoord ? '' :\n        this.getTileCoordForTileUrlFunction(textTileCoord).toString();\n      const tile = new LabeledTile(tileCoord, tileSize, text);\n      this.tileCache.set(tileCoordKey, tile);\n      return tile;\n    }\n  }\n}\n\n\nexport default TileDebug;\n","/**\n * @module ol/source/TileJSON\n */\n// FIXME check order of async callbacks\n\n/**\n * See http://mapbox.com/developers/api/.\n */\n\n\nimport {createFromTemplates} from '../tileurlfunction.js';\nimport {assert} from '../asserts.js';\nimport {applyTransform, intersects} from '../extent.js';\nimport {jsonp as requestJSONP} from '../net.js';\nimport {get as getProjection, getTransformFromProjections} from '../proj.js';\nimport SourceState from '../source/State.js';\nimport TileImage from '../source/TileImage.js';\nimport {createXYZ, extentFromProjection} from '../tilegrid.js';\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/source/Source~AttributionLike} [attributions] Attributions.\n * @property {number} [cacheSize=2048] Cache size.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images.  Note that\n * you must provide a `crossOrigin` value if you are using the WebGL renderer or if you want to\n * access pixel data with the Canvas renderer.  See\n * https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {boolean} [jsonp=false] Use JSONP with callback to load the TileJSON.\n * Useful when the server does not support CORS..\n * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).\n * Higher values can increase reprojection performance, but decrease precision.\n * @property {tileJSON} [tileJSON] TileJSON configuration for this source.\n * If not provided, `url` must be configured.\n * @property {module:ol/Tile~LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is\n * ```js\n * function(imageTile, src) {\n *   imageTile.getImage().src = src;\n * };\n * ```\n * @property {string} [url] URL to the TileJSON file. If not provided, `tileJSON` must be configured.\n * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.\n * @property {number} [transition] Duration of the opacity transition for rendering.\n * To disable the opacity transition, pass `transition: 0`.\n */\n\n\n/**\n * @classdesc\n * Layer source for tile data in TileJSON format.\n * @api\n */\nclass TileJSON extends TileImage {\n  /**\n   * @param {module:ol/source/TileJSON~Options=} options TileJSON options.\n   */\n  constructor(options) {\n    super({\n      attributions: options.attributions,\n      cacheSize: options.cacheSize,\n      crossOrigin: options.crossOrigin,\n      projection: getProjection('EPSG:3857'),\n      reprojectionErrorThreshold: options.reprojectionErrorThreshold,\n      state: SourceState.LOADING,\n      tileLoadFunction: options.tileLoadFunction,\n      wrapX: options.wrapX !== undefined ? options.wrapX : true,\n      transition: options.transition\n    });\n\n    /**\n     * @type {TileJSON}\n     * @private\n     */\n    this.tileJSON_ = null;\n\n\n    if (options.url) {\n      if (options.jsonp) {\n        requestJSONP(options.url, this.handleTileJSONResponse.bind(this),\n          this.handleTileJSONError.bind(this));\n      } else {\n        const client = new XMLHttpRequest();\n        client.addEventListener('load', this.onXHRLoad_.bind(this));\n        client.addEventListener('error', this.onXHRError_.bind(this));\n        client.open('GET', options.url);\n        client.send();\n      }\n    } else if (options.tileJSON) {\n      this.handleTileJSONResponse(options.tileJSON);\n    } else {\n      assert(false, 51); // Either `url` or `tileJSON` options must be provided\n    }\n\n  }\n\n  /**\n   * @private\n   * @param {Event} event The load event.\n   */\n  onXHRLoad_(event) {\n    const client = /** @type {XMLHttpRequest} */ (event.target);\n    // status will be 0 for file:// urls\n    if (!client.status || client.status >= 200 && client.status < 300) {\n      let response;\n      try {\n        response = /** @type {TileJSON} */(JSON.parse(client.responseText));\n      } catch (err) {\n        this.handleTileJSONError();\n        return;\n      }\n      this.handleTileJSONResponse(response);\n    } else {\n      this.handleTileJSONError();\n    }\n  }\n\n  /**\n   * @private\n   * @param {Event} event The error event.\n   */\n  onXHRError_(event) {\n    this.handleTileJSONError();\n  }\n\n  /**\n   * @return {TileJSON} The tilejson object.\n   * @api\n   */\n  getTileJSON() {\n    return this.tileJSON_;\n  }\n\n  /**\n   * @protected\n   * @param {TileJSON} tileJSON Tile JSON.\n   */\n  handleTileJSONResponse(tileJSON) {\n\n    const epsg4326Projection = getProjection('EPSG:4326');\n\n    const sourceProjection = this.getProjection();\n    let extent;\n    if (tileJSON.bounds !== undefined) {\n      const transform = getTransformFromProjections(\n        epsg4326Projection, sourceProjection);\n      extent = applyTransform(tileJSON.bounds, transform);\n    }\n\n    const minZoom = tileJSON.minzoom || 0;\n    const maxZoom = tileJSON.maxzoom || 22;\n    const tileGrid = createXYZ({\n      extent: extentFromProjection(sourceProjection),\n      maxZoom: maxZoom,\n      minZoom: minZoom\n    });\n    this.tileGrid = tileGrid;\n\n    this.tileUrlFunction = createFromTemplates(tileJSON.tiles, tileGrid);\n\n    if (tileJSON.attribution !== undefined && !this.getAttributions()) {\n      const attributionExtent = extent !== undefined ?\n        extent : epsg4326Projection.getExtent();\n\n      this.setAttributions(function(frameState) {\n        if (intersects(attributionExtent, frameState.extent)) {\n          return [tileJSON.attribution];\n        }\n        return null;\n      });\n\n    }\n    this.tileJSON_ = tileJSON;\n    this.setState(SourceState.READY);\n\n  }\n\n  /**\n   * @protected\n   */\n  handleTileJSONError() {\n    this.setState(SourceState.ERROR);\n  }\n}\n\n\nexport default TileJSON;\n","/**\n * @module ol/source/TileWMS\n */\n\nimport {DEFAULT_WMS_VERSION} from './common.js';\n\nimport {assert} from '../asserts.js';\nimport {buffer, createEmpty} from '../extent.js';\nimport {assign} from '../obj.js';\nimport {modulo} from '../math.js';\nimport {get as getProjection, transform, transformExtent} from '../proj.js';\nimport {calculateSourceResolution} from '../reproj.js';\nimport {toSize, buffer as bufferSize, scale as scaleSize} from '../size.js';\nimport TileImage from '../source/TileImage.js';\nimport WMSServerType from '../source/WMSServerType.js';\nimport {hash as tileCoordHash} from '../tilecoord.js';\nimport {compareVersions} from '../string.js';\nimport {appendParams} from '../uri.js';\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/source/Source~AttributionLike} [attributions] Attributions.\n * @property {number} [cacheSize=2048] Cache size.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images.  Note that\n * you must provide a `crossOrigin` value if you are using the WebGL renderer or if you want to\n * access pixel data with the Canvas renderer.  See\n * https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {Object.<string,*>} params WMS request parameters.\n * At least a `LAYERS` param is required. `STYLES` is\n * `''` by default. `VERSION` is `1.3.0` by default. `WIDTH`, `HEIGHT`, `BBOX`\n * and `CRS` (`SRS` for WMS version < 1.3.0) will be set dynamically.\n * @property {number} [gutter=0]\n * The size in pixels of the gutter around image tiles to ignore. By setting\n * this property to a non-zero value, images will be requested that are wider\n * and taller than the tile size by a value of `2 x gutter`.\n * Using a non-zero value allows artifacts of rendering at tile edges to be\n * ignored. If you control the WMS service it is recommended to address\n * \"artifacts at tile edges\" issues by properly configuring the WMS service. For\n * example, MapServer has a `tile_map_edge_buffer` configuration parameter for\n * this. See http://mapserver.org/output/tile_mode.html.\n * @property {boolean} [hidpi=true] Use the `ol/Map#pixelRatio` value when requesting\n * the image from the remote server.\n * @property {module:ol/proj~ProjectionLike} projection Projection.\n * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).\n * Higher values can increase reprojection performance, but decrease precision.\n * @property {module:ol/ImageTile~TileClass} [tileClass] Class used to instantiate image tiles.\n * Default is {@link module:ol/ImageTile~TileClass}.\n * @property {module:ol/tilegrid/TileGrid} [tileGrid] Tile grid. Base this on the resolutions,\n * tilesize and extent supported by the server.\n * If this is not defined, a default grid will be used: if there is a projection\n * extent, the grid will be based on that; if not, a grid based on a global\n * extent with origin at 0,0 will be used..\n * @property {module:ol/source/WMSServerType|string} [serverType]\n * The type of the remote WMS server. Currently only used when `hidpi` is\n * `true`.\n * @property {module:ol/Tile~LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is\n * ```js\n * function(imageTile, src) {\n *   imageTile.getImage().src = src;\n * };\n * ```\n * @property {string} [url] WMS service URL.\n * @property {Array.<string>} [urls] WMS service urls.\n * Use this instead of `url` when the WMS supports multiple urls for GetMap requests.\n * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.\n * When set to `false`, only one world\n * will be rendered. When `true`, tiles will be requested for one world only,\n * but they will be wrapped horizontally to render multiple worlds.\n * @property {number} [transition] Duration of the opacity transition for rendering.\n * To disable the opacity transition, pass `transition: 0`.\n */\n\n\n/**\n * @classdesc\n * Layer source for tile data from WMS servers.\n * @api\n */\nclass TileWMS extends TileImage {\n  /**\n   * @param {module:ol/source/TileWMS~Options=} [opt_options] Tile WMS options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options || {};\n\n    const params = options.params || {};\n\n    const transparent = 'TRANSPARENT' in params ? params['TRANSPARENT'] : true;\n\n    super({\n      attributions: options.attributions,\n      cacheSize: options.cacheSize,\n      crossOrigin: options.crossOrigin,\n      opaque: !transparent,\n      projection: options.projection,\n      reprojectionErrorThreshold: options.reprojectionErrorThreshold,\n      tileClass: options.tileClass,\n      tileGrid: options.tileGrid,\n      tileLoadFunction: options.tileLoadFunction,\n      url: options.url,\n      urls: options.urls,\n      wrapX: options.wrapX !== undefined ? options.wrapX : true,\n      transition: options.transition\n    });\n\n    /**\n     * @private\n     * @type {number}\n     */\n    this.gutter_ = options.gutter !== undefined ? options.gutter : 0;\n\n    /**\n     * @private\n     * @type {!Object}\n     */\n    this.params_ = params;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.v13_ = true;\n\n    /**\n     * @private\n     * @type {module:ol/source/WMSServerType|undefined}\n     */\n    this.serverType_ = /** @type {module:ol/source/WMSServerType|undefined} */ (options.serverType);\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.hidpi_ = options.hidpi !== undefined ? options.hidpi : true;\n\n    /**\n     * @private\n     * @type {module:ol/extent~Extent}\n     */\n    this.tmpExtent_ = createEmpty();\n\n    this.updateV13_();\n    this.setKey(this.getKeyForParams_());\n\n  }\n\n  /**\n   * Return the GetFeatureInfo URL for the passed coordinate, resolution, and\n   * projection. Return `undefined` if the GetFeatureInfo URL cannot be\n   * constructed.\n   * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n   * @param {number} resolution Resolution.\n   * @param {module:ol/proj~ProjectionLike} projection Projection.\n   * @param {!Object} params GetFeatureInfo params. `INFO_FORMAT` at least should\n   *     be provided. If `QUERY_LAYERS` is not provided then the layers specified\n   *     in the `LAYERS` parameter will be used. `VERSION` should not be\n   *     specified here.\n   * @return {string|undefined} GetFeatureInfo URL.\n   * @api\n   */\n  getGetFeatureInfoUrl(coordinate, resolution, projection, params) {\n    const projectionObj = getProjection(projection);\n    const sourceProjectionObj = this.getProjection();\n\n    let tileGrid = this.getTileGrid();\n    if (!tileGrid) {\n      tileGrid = this.getTileGridForProjection(projectionObj);\n    }\n\n    const tileCoord = tileGrid.getTileCoordForCoordAndResolution(coordinate, resolution);\n\n    if (tileGrid.getResolutions().length <= tileCoord[0]) {\n      return undefined;\n    }\n\n    let tileResolution = tileGrid.getResolution(tileCoord[0]);\n    let tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent_);\n    let tileSize = toSize(tileGrid.getTileSize(tileCoord[0]), this.tmpSize);\n\n\n    const gutter = this.gutter_;\n    if (gutter !== 0) {\n      tileSize = bufferSize(tileSize, gutter, this.tmpSize);\n      tileExtent = buffer(tileExtent, tileResolution * gutter, tileExtent);\n    }\n\n    if (sourceProjectionObj && sourceProjectionObj !== projectionObj) {\n      tileResolution = calculateSourceResolution(sourceProjectionObj, projectionObj, coordinate, tileResolution);\n      tileExtent = transformExtent(tileExtent, projectionObj, sourceProjectionObj);\n      coordinate = transform(coordinate, projectionObj, sourceProjectionObj);\n    }\n\n    const baseParams = {\n      'SERVICE': 'WMS',\n      'VERSION': DEFAULT_WMS_VERSION,\n      'REQUEST': 'GetFeatureInfo',\n      'FORMAT': 'image/png',\n      'TRANSPARENT': true,\n      'QUERY_LAYERS': this.params_['LAYERS']\n    };\n    assign(baseParams, this.params_, params);\n\n    const x = Math.floor((coordinate[0] - tileExtent[0]) / tileResolution);\n    const y = Math.floor((tileExtent[3] - coordinate[1]) / tileResolution);\n\n    baseParams[this.v13_ ? 'I' : 'X'] = x;\n    baseParams[this.v13_ ? 'J' : 'Y'] = y;\n\n    return this.getRequestUrl_(tileCoord, tileSize, tileExtent,\n      1, sourceProjectionObj || projectionObj, baseParams);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getGutterInternal() {\n    return this.gutter_;\n  }\n\n  /**\n   * Get the user-provided params, i.e. those passed to the constructor through\n   * the \"params\" option, and possibly updated using the updateParams method.\n   * @return {Object} Params.\n   * @api\n   */\n  getParams() {\n    return this.params_;\n  }\n\n  /**\n   * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n   * @param {module:ol/size~Size} tileSize Tile size.\n   * @param {module:ol/extent~Extent} tileExtent Tile extent.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @param {Object} params Params.\n   * @return {string|undefined} Request URL.\n   * @private\n   */\n  getRequestUrl_(tileCoord, tileSize, tileExtent, pixelRatio, projection, params) {\n\n    const urls = this.urls;\n    if (!urls) {\n      return undefined;\n    }\n\n    params['WIDTH'] = tileSize[0];\n    params['HEIGHT'] = tileSize[1];\n\n    params[this.v13_ ? 'CRS' : 'SRS'] = projection.getCode();\n\n    if (!('STYLES' in this.params_)) {\n      params['STYLES'] = '';\n    }\n\n    if (pixelRatio != 1) {\n      switch (this.serverType_) {\n        case WMSServerType.GEOSERVER:\n          const dpi = (90 * pixelRatio + 0.5) | 0;\n          if ('FORMAT_OPTIONS' in params) {\n            params['FORMAT_OPTIONS'] += ';dpi:' + dpi;\n          } else {\n            params['FORMAT_OPTIONS'] = 'dpi:' + dpi;\n          }\n          break;\n        case WMSServerType.MAPSERVER:\n          params['MAP_RESOLUTION'] = 90 * pixelRatio;\n          break;\n        case WMSServerType.CARMENTA_SERVER:\n        case WMSServerType.QGIS:\n          params['DPI'] = 90 * pixelRatio;\n          break;\n        default:\n          assert(false, 52); // Unknown `serverType` configured\n          break;\n      }\n    }\n\n    const axisOrientation = projection.getAxisOrientation();\n    const bbox = tileExtent;\n    if (this.v13_ && axisOrientation.substr(0, 2) == 'ne') {\n      let tmp;\n      tmp = tileExtent[0];\n      bbox[0] = tileExtent[1];\n      bbox[1] = tmp;\n      tmp = tileExtent[2];\n      bbox[2] = tileExtent[3];\n      bbox[3] = tmp;\n    }\n    params['BBOX'] = bbox.join(',');\n\n    let url;\n    if (urls.length == 1) {\n      url = urls[0];\n    } else {\n      const index = modulo(tileCoordHash(tileCoord), urls.length);\n      url = urls[index];\n    }\n    return appendParams(url, params);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getTilePixelRatio(pixelRatio) {\n    return (!this.hidpi_ || this.serverType_ === undefined) ? 1 :\n    /** @type {number} */ (pixelRatio);\n  }\n\n  /**\n   * @private\n   * @return {string} The key for the current params.\n   */\n  getKeyForParams_() {\n    let i = 0;\n    const res = [];\n    for (const key in this.params_) {\n      res[i++] = key + '-' + this.params_[key];\n    }\n    return res.join('/');\n  }\n\n  /**\n   * @inheritDoc\n   */\n  fixedTileUrlFunction(tileCoord, pixelRatio, projection) {\n\n    let tileGrid = this.getTileGrid();\n    if (!tileGrid) {\n      tileGrid = this.getTileGridForProjection(projection);\n    }\n\n    if (tileGrid.getResolutions().length <= tileCoord[0]) {\n      return undefined;\n    }\n\n    if (pixelRatio != 1 && (!this.hidpi_ || this.serverType_ === undefined)) {\n      pixelRatio = 1;\n    }\n\n    const tileResolution = tileGrid.getResolution(tileCoord[0]);\n    let tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent_);\n    let tileSize = toSize(\n      tileGrid.getTileSize(tileCoord[0]), this.tmpSize);\n\n    const gutter = this.gutter_;\n    if (gutter !== 0) {\n      tileSize = bufferSize(tileSize, gutter, this.tmpSize);\n      tileExtent = buffer(tileExtent, tileResolution * gutter, tileExtent);\n    }\n\n    if (pixelRatio != 1) {\n      tileSize = scaleSize(tileSize, pixelRatio, this.tmpSize);\n    }\n\n    const baseParams = {\n      'SERVICE': 'WMS',\n      'VERSION': DEFAULT_WMS_VERSION,\n      'REQUEST': 'GetMap',\n      'FORMAT': 'image/png',\n      'TRANSPARENT': true\n    };\n    assign(baseParams, this.params_);\n\n    return this.getRequestUrl_(tileCoord, tileSize, tileExtent,\n      pixelRatio, projection, baseParams);\n  }\n\n  /**\n   * Update the user-provided params.\n   * @param {Object} params Params.\n   * @api\n   */\n  updateParams(params) {\n    assign(this.params_, params);\n    this.updateV13_();\n    this.setKey(this.getKeyForParams_());\n  }\n\n  /**\n   * @private\n   */\n  updateV13_() {\n    const version = this.params_['VERSION'] || DEFAULT_WMS_VERSION;\n    this.v13_ = compareVersions(version, '1.3') >= 0;\n  }\n}\n\n\nexport default TileWMS;\n","/**\n * @module ol/source/UTFGrid\n */\n\nimport Tile from '../Tile.js';\nimport TileState from '../TileState.js';\nimport {createFromTemplates, nullTileUrlFunction} from '../tileurlfunction.js';\nimport {assert} from '../asserts.js';\nimport {listenOnce} from '../events.js';\nimport EventType from '../events/EventType.js';\nimport {applyTransform, intersects} from '../extent.js';\nimport {jsonp as requestJSONP} from '../net.js';\nimport {get as getProjection, getTransformFromProjections} from '../proj.js';\nimport SourceState from '../source/State.js';\nimport TileSource from '../source/Tile.js';\nimport {getKeyZXY} from '../tilecoord.js';\nimport {createXYZ, extentFromProjection} from '../tilegrid.js';\n\n\nexport class CustomTile extends Tile {\n\n  /**\n   * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n   * @param {module:ol/TileState} state State.\n   * @param {string} src Image source URI.\n   * @param {module:ol/extent~Extent} extent Extent of the tile.\n   * @param {boolean} preemptive Load the tile when visible (before it's needed).\n   * @param {boolean} jsonp Load the tile as a script.\n   */\n  constructor(tileCoord, state, src, extent, preemptive, jsonp) {\n\n    super(tileCoord, state);\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.src_ = src;\n\n    /**\n     * @private\n     * @type {module:ol/extent~Extent}\n     */\n    this.extent_ = extent;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.preemptive_ = preemptive;\n\n    /**\n     * @private\n     * @type {Array.<string>}\n     */\n    this.grid_ = null;\n\n    /**\n     * @private\n     * @type {Array.<string>}\n     */\n    this.keys_ = null;\n\n    /**\n     * @private\n     * @type {Object.<string, Object>|undefined}\n     */\n    this.data_ = null;\n\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.jsonp_ = jsonp;\n\n  }\n\n}\n\n\n/**\n * Get the image element for this tile.\n * @return {HTMLImageElement} Image.\n */\nCustomTile.prototype.getImage = function() {\n  return null;\n};\n\n\n/**\n * Synchronously returns data at given coordinate (if available).\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n * @return {*} The data.\n */\nCustomTile.prototype.getData = function(coordinate) {\n  if (!this.grid_ || !this.keys_) {\n    return null;\n  }\n  const xRelative = (coordinate[0] - this.extent_[0]) /\n      (this.extent_[2] - this.extent_[0]);\n  const yRelative = (coordinate[1] - this.extent_[1]) /\n      (this.extent_[3] - this.extent_[1]);\n\n  const row = this.grid_[Math.floor((1 - yRelative) * this.grid_.length)];\n\n  if (typeof row !== 'string') {\n    return null;\n  }\n\n  let code = row.charCodeAt(Math.floor(xRelative * row.length));\n  if (code >= 93) {\n    code--;\n  }\n  if (code >= 35) {\n    code--;\n  }\n  code -= 32;\n\n  let data = null;\n  if (code in this.keys_) {\n    const id = this.keys_[code];\n    if (this.data_ && id in this.data_) {\n      data = this.data_[id];\n    } else {\n      data = id;\n    }\n  }\n  return data;\n};\n\n\n/**\n * Calls the callback (synchronously by default) with the available data\n * for given coordinate (or `null` if not yet loaded).\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n * @param {function(this: T, *)} callback Callback.\n * @param {T=} opt_this The object to use as `this` in the callback.\n * @param {boolean=} opt_request If `true` the callback is always async.\n *                               The tile data is requested if not yet loaded.\n * @template T\n */\nCustomTile.prototype.forDataAtCoordinate = function(coordinate, callback, opt_this, opt_request) {\n  if (this.state == TileState.IDLE && opt_request === true) {\n    listenOnce(this, EventType.CHANGE, function(e) {\n      callback.call(opt_this, this.getData(coordinate));\n    }, this);\n    this.loadInternal_();\n  } else {\n    if (opt_request === true) {\n      setTimeout(function() {\n        callback.call(opt_this, this.getData(coordinate));\n      }.bind(this), 0);\n    } else {\n      callback.call(opt_this, this.getData(coordinate));\n    }\n  }\n};\n\n\n/**\n * @inheritDoc\n */\nCustomTile.prototype.getKey = function() {\n  return this.src_;\n};\n\n\n/**\n * @private\n */\nCustomTile.prototype.handleError_ = function() {\n  this.state = TileState.ERROR;\n  this.changed();\n};\n\n\n/**\n * @param {!UTFGridJSON} json UTFGrid data.\n * @private\n */\nCustomTile.prototype.handleLoad_ = function(json) {\n  this.grid_ = json.grid;\n  this.keys_ = json.keys;\n  this.data_ = json.data;\n\n  this.state = TileState.EMPTY;\n  this.changed();\n};\n\n\n/**\n * @private\n */\nCustomTile.prototype.loadInternal_ = function() {\n  if (this.state == TileState.IDLE) {\n    this.state = TileState.LOADING;\n    if (this.jsonp_) {\n      requestJSONP(this.src_, this.handleLoad_.bind(this),\n        this.handleError_.bind(this));\n    } else {\n      const client = new XMLHttpRequest();\n      client.addEventListener('load', this.onXHRLoad_.bind(this));\n      client.addEventListener('error', this.onXHRError_.bind(this));\n      client.open('GET', this.src_);\n      client.send();\n    }\n  }\n};\n\n\n/**\n * @private\n * @param {Event} event The load event.\n */\nCustomTile.prototype.onXHRLoad_ = function(event) {\n  const client = /** @type {XMLHttpRequest} */ (event.target);\n  // status will be 0 for file:// urls\n  if (!client.status || client.status >= 200 && client.status < 300) {\n    let response;\n    try {\n      response = /** @type {!UTFGridJSON} */(JSON.parse(client.responseText));\n    } catch (err) {\n      this.handleError_();\n      return;\n    }\n    this.handleLoad_(response);\n  } else {\n    this.handleError_();\n  }\n};\n\n\n/**\n * @private\n * @param {Event} event The error event.\n */\nCustomTile.prototype.onXHRError_ = function(event) {\n  this.handleError_();\n};\n\n\n/**\n * @override\n */\nCustomTile.prototype.load = function() {\n  if (this.preemptive_) {\n    this.loadInternal_();\n  }\n};\n\n\n/**\n * @typedef {Object} Options\n * @property {boolean} [preemptive=true]\n * If `true` the UTFGrid source loads the tiles based on their \"visibility\".\n * This improves the speed of response, but increases traffic.\n * Note that if set to `false`, you need to pass `true` as `opt_request`\n * to the `forDataAtCoordinateAndResolution` method otherwise no data\n * will ever be loaded.\n * @property {boolean} [jsonp=false] Use JSONP with callback to load the TileJSON.\n * Useful when the server does not support CORS..\n * @property {tileJSON} [tileJSON] TileJSON configuration for this source.\n * If not provided, `url` must be configured.\n * @property {string} [url] TileJSON endpoint that provides the configuration for this source.\n * Request will be made through JSONP. If not provided, `tileJSON` must be configured.\n */\n\n\n/**\n * @classdesc\n * Layer source for UTFGrid interaction data loaded from TileJSON format.\n * @api\n */\nclass UTFGrid extends TileSource {\n  /**\n   * @param {module:ol/source/UTFGrid~Options=} options Source options.\n   */\n  constructor(options) {\n    super({\n      projection: getProjection('EPSG:3857'),\n      state: SourceState.LOADING\n    });\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.preemptive_ = options.preemptive !== undefined ?\n      options.preemptive : true;\n\n    /**\n     * @private\n     * @type {!module:ol/Tile~UrlFunction}\n     */\n    this.tileUrlFunction_ = nullTileUrlFunction;\n\n    /**\n     * @private\n     * @type {string|undefined}\n     */\n    this.template_ = undefined;\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.jsonp_ = options.jsonp || false;\n\n    if (options.url) {\n      if (this.jsonp_) {\n        requestJSONP(options.url, this.handleTileJSONResponse.bind(this),\n          this.handleTileJSONError.bind(this));\n      } else {\n        const client = new XMLHttpRequest();\n        client.addEventListener('load', this.onXHRLoad_.bind(this));\n        client.addEventListener('error', this.onXHRError_.bind(this));\n        client.open('GET', options.url);\n        client.send();\n      }\n    } else if (options.tileJSON) {\n      this.handleTileJSONResponse(options.tileJSON);\n    } else {\n      assert(false, 51); // Either `url` or `tileJSON` options must be provided\n    }\n\n  }\n\n}\n\n\n/**\n * @private\n * @param {Event} event The load event.\n */\nUTFGrid.prototype.onXHRLoad_ = function(event) {\n  const client = /** @type {XMLHttpRequest} */ (event.target);\n  // status will be 0 for file:// urls\n  if (!client.status || client.status >= 200 && client.status < 300) {\n    let response;\n    try {\n      response = /** @type {TileJSON} */(JSON.parse(client.responseText));\n    } catch (err) {\n      this.handleTileJSONError();\n      return;\n    }\n    this.handleTileJSONResponse(response);\n  } else {\n    this.handleTileJSONError();\n  }\n};\n\n\n/**\n * @private\n * @param {Event} event The error event.\n */\nUTFGrid.prototype.onXHRError_ = function(event) {\n  this.handleTileJSONError();\n};\n\n\n/**\n * Return the template from TileJSON.\n * @return {string|undefined} The template from TileJSON.\n * @api\n */\nUTFGrid.prototype.getTemplate = function() {\n  return this.template_;\n};\n\n\n/**\n * Calls the callback (synchronously by default) with the available data\n * for given coordinate and resolution (or `null` if not yet loaded or\n * in case of an error).\n * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.\n * @param {number} resolution Resolution.\n * @param {function(*)} callback Callback.\n * @param {boolean=} opt_request If `true` the callback is always async.\n *                               The tile data is requested if not yet loaded.\n * @api\n */\nUTFGrid.prototype.forDataAtCoordinateAndResolution = function(\n  coordinate, resolution, callback, opt_request) {\n  if (this.tileGrid) {\n    const tileCoord = this.tileGrid.getTileCoordForCoordAndResolution(\n      coordinate, resolution);\n    const tile = /** @type {!module:ol/source/UTFGrid~CustomTile} */(this.getTile(\n      tileCoord[0], tileCoord[1], tileCoord[2], 1, this.getProjection()));\n    tile.forDataAtCoordinate(coordinate, callback, null, opt_request);\n  } else {\n    if (opt_request === true) {\n      setTimeout(function() {\n        callback(null);\n      }, 0);\n    } else {\n      callback(null);\n    }\n  }\n};\n\n\n/**\n * @protected\n */\nUTFGrid.prototype.handleTileJSONError = function() {\n  this.setState(SourceState.ERROR);\n};\n\n\n/**\n * TODO: very similar to ol/source/TileJSON#handleTileJSONResponse\n * @protected\n * @param {TileJSON} tileJSON Tile JSON.\n */\nUTFGrid.prototype.handleTileJSONResponse = function(tileJSON) {\n\n  const epsg4326Projection = getProjection('EPSG:4326');\n\n  const sourceProjection = this.getProjection();\n  let extent;\n  if (tileJSON.bounds !== undefined) {\n    const transform = getTransformFromProjections(\n      epsg4326Projection, sourceProjection);\n    extent = applyTransform(tileJSON.bounds, transform);\n  }\n\n  const minZoom = tileJSON.minzoom || 0;\n  const maxZoom = tileJSON.maxzoom || 22;\n  const tileGrid = createXYZ({\n    extent: extentFromProjection(sourceProjection),\n    maxZoom: maxZoom,\n    minZoom: minZoom\n  });\n  this.tileGrid = tileGrid;\n\n  this.template_ = tileJSON.template;\n\n  const grids = tileJSON.grids;\n  if (!grids) {\n    this.setState(SourceState.ERROR);\n    return;\n  }\n\n  this.tileUrlFunction_ = createFromTemplates(grids, tileGrid);\n\n  if (tileJSON.attribution !== undefined) {\n    const attributionExtent = extent !== undefined ?\n      extent : epsg4326Projection.getExtent();\n\n    this.setAttributions(function(frameState) {\n      if (intersects(attributionExtent, frameState.extent)) {\n        return [tileJSON.attribution];\n      }\n      return null;\n    });\n  }\n\n  this.setState(SourceState.READY);\n\n};\n\n\n/**\n * @inheritDoc\n */\nUTFGrid.prototype.getTile = function(z, x, y, pixelRatio, projection) {\n  const tileCoordKey = getKeyZXY(z, x, y);\n  if (this.tileCache.containsKey(tileCoordKey)) {\n    return (\n      /** @type {!module:ol/Tile} */ (this.tileCache.get(tileCoordKey))\n    );\n  } else {\n    const tileCoord = [z, x, y];\n    const urlTileCoord =\n        this.getTileCoordForTileUrlFunction(tileCoord, projection);\n    const tileUrl = this.tileUrlFunction_(urlTileCoord, pixelRatio, projection);\n    const tile = new CustomTile(\n      tileCoord,\n      tileUrl !== undefined ? TileState.IDLE : TileState.EMPTY,\n      tileUrl !== undefined ? tileUrl : '',\n      this.tileGrid.getTileCoordExtent(tileCoord),\n      this.preemptive_,\n      this.jsonp_);\n    this.tileCache.set(tileCoordKey, tile);\n    return tile;\n  }\n};\n\n\n/**\n * @inheritDoc\n */\nUTFGrid.prototype.useTile = function(z, x, y) {\n  const tileCoordKey = getKeyZXY(z, x, y);\n  if (this.tileCache.containsKey(tileCoordKey)) {\n    this.tileCache.get(tileCoordKey);\n  }\n};\n\n\nexport default UTFGrid;\n","/**\n * @module ol/VectorImageTile\n */\nimport {getUid} from './util.js';\nimport Tile from './Tile.js';\nimport TileState from './TileState.js';\nimport {createCanvasContext2D} from './dom.js';\nimport {listen, unlistenByKey} from './events.js';\nimport {getHeight, getIntersection, getWidth} from './extent.js';\nimport EventType from './events/EventType.js';\nimport {loadFeaturesXhr} from './featureloader.js';\nimport {UNDEFINED} from './functions.js';\n\n\n/**\n * @typedef {Object} ReplayState\n * @property {boolean} dirty\n * @property {null|module:ol/render~OrderFunction} renderedRenderOrder\n * @property {number} renderedTileRevision\n * @property {number} renderedRevision\n */\n\n\nclass VectorImageTile extends Tile {\n\n  /**\n   * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n   * @param {module:ol/TileState} state State.\n   * @param {number} sourceRevision Source revision.\n   * @param {module:ol/format/Feature} format Feature format.\n   * @param {module:ol/Tile~LoadFunction} tileLoadFunction Tile load function.\n   * @param {module:ol/tilecoord~TileCoord} urlTileCoord Wrapped tile coordinate for source urls.\n   * @param {module:ol/Tile~UrlFunction} tileUrlFunction Tile url function.\n   * @param {module:ol/tilegrid/TileGrid} sourceTileGrid Tile grid of the source.\n   * @param {module:ol/tilegrid/TileGrid} tileGrid Tile grid of the renderer.\n   * @param {Object.<string, module:ol/VectorTile>} sourceTiles Source tiles.\n   * @param {number} pixelRatio Pixel ratio.\n   * @param {module:ol/proj/Projection} projection Projection.\n   * @param {function(new: module:ol/VectorTile, module:ol/tilecoord~TileCoord, module:ol/TileState, string,\n   *     module:ol/format/Feature, module:ol/Tile~LoadFunction)} tileClass Class to\n   *     instantiate for source tiles.\n   * @param {function(this: module:ol/source/VectorTile, module:ol/events/Event)} handleTileChange\n   *     Function to call when a source tile's state changes.\n   * @param {number} zoom Integer zoom to render the tile for.\n   */\n  constructor(tileCoord, state, sourceRevision, format, tileLoadFunction,\n    urlTileCoord, tileUrlFunction, sourceTileGrid, tileGrid, sourceTiles,\n    pixelRatio, projection, tileClass, handleTileChange, zoom) {\n\n    super(tileCoord, state, {transition: 0});\n\n    /**\n     * @private\n     * @type {!Object.<string, CanvasRenderingContext2D>}\n     */\n    this.context_ = {};\n\n    /**\n     * @private\n     * @type {module:ol/featureloader~FeatureLoader}\n     */\n    this.loader_;\n\n    /**\n     * @private\n     * @type {!Object.<string, module:ol/VectorImageTile~ReplayState>}\n     */\n    this.replayState_ = {};\n\n    /**\n     * @private\n     * @type {Object.<string, module:ol/VectorTile>}\n     */\n    this.sourceTiles_ = sourceTiles;\n\n    /**\n     * Keys of source tiles used by this tile. Use with {@link #getTile}.\n     * @type {Array.<string>}\n     */\n    this.tileKeys = [];\n\n    /**\n     * @type {module:ol/extent~Extent}\n     */\n    this.extent = null;\n\n    /**\n     * @type {number}\n     */\n    this.sourceRevision_ = sourceRevision;\n\n    /**\n     * @type {module:ol/tilecoord~TileCoord}\n     */\n    this.wrappedTileCoord = urlTileCoord;\n\n    /**\n     * @type {Array.<module:ol/events~EventsKey>}\n     */\n    this.loadListenerKeys_ = [];\n\n    /**\n     * @type {Array.<module:ol/events~EventsKey>}\n     */\n    this.sourceTileListenerKeys_ = [];\n\n    if (urlTileCoord) {\n      const extent = this.extent = tileGrid.getTileCoordExtent(urlTileCoord);\n      const resolution = tileGrid.getResolution(zoom);\n      const sourceZ = sourceTileGrid.getZForResolution(resolution);\n      const useLoadedOnly = zoom != tileCoord[0];\n      let loadCount = 0;\n      sourceTileGrid.forEachTileCoord(extent, sourceZ, function(sourceTileCoord) {\n        let sharedExtent = getIntersection(extent,\n          sourceTileGrid.getTileCoordExtent(sourceTileCoord));\n        const sourceExtent = sourceTileGrid.getExtent();\n        if (sourceExtent) {\n          sharedExtent = getIntersection(sharedExtent, sourceExtent, sharedExtent);\n        }\n        if (getWidth(sharedExtent) / resolution >= 0.5 &&\n            getHeight(sharedExtent) / resolution >= 0.5) {\n          // only include source tile if overlap is at least 1 pixel\n          ++loadCount;\n          const sourceTileKey = sourceTileCoord.toString();\n          let sourceTile = sourceTiles[sourceTileKey];\n          if (!sourceTile && !useLoadedOnly) {\n            const tileUrl = tileUrlFunction(sourceTileCoord, pixelRatio, projection);\n            sourceTile = sourceTiles[sourceTileKey] = new tileClass(sourceTileCoord,\n              tileUrl == undefined ? TileState.EMPTY : TileState.IDLE,\n              tileUrl == undefined ? '' : tileUrl,\n              format, tileLoadFunction);\n            this.sourceTileListenerKeys_.push(\n              listen(sourceTile, EventType.CHANGE, handleTileChange));\n          }\n          if (sourceTile && (!useLoadedOnly || sourceTile.getState() == TileState.LOADED)) {\n            sourceTile.consumers++;\n            this.tileKeys.push(sourceTileKey);\n          }\n        }\n      }.bind(this));\n\n      if (useLoadedOnly && loadCount == this.tileKeys.length) {\n        this.finishLoading_();\n      }\n\n      if (zoom <= tileCoord[0] && this.state != TileState.LOADED) {\n        while (zoom > tileGrid.getMinZoom()) {\n          const tile = new VectorImageTile(tileCoord, state, sourceRevision,\n            format, tileLoadFunction, urlTileCoord, tileUrlFunction,\n            sourceTileGrid, tileGrid, sourceTiles, pixelRatio, projection,\n            tileClass, UNDEFINED, --zoom);\n          if (tile.state == TileState.LOADED) {\n            this.interimTile = tile;\n            break;\n          }\n        }\n      }\n    }\n\n  }\n\n  /**\n   * @inheritDoc\n   */\n  disposeInternal() {\n    this.state = TileState.ABORT;\n    this.changed();\n    if (this.interimTile) {\n      this.interimTile.dispose();\n    }\n\n    for (let i = 0, ii = this.tileKeys.length; i < ii; ++i) {\n      const sourceTileKey = this.tileKeys[i];\n      const sourceTile = this.getTile(sourceTileKey);\n      sourceTile.consumers--;\n      if (sourceTile.consumers == 0) {\n        delete this.sourceTiles_[sourceTileKey];\n        sourceTile.dispose();\n      }\n    }\n    this.tileKeys.length = 0;\n    this.sourceTiles_ = null;\n    this.loadListenerKeys_.forEach(unlistenByKey);\n    this.loadListenerKeys_.length = 0;\n    this.sourceTileListenerKeys_.forEach(unlistenByKey);\n    this.sourceTileListenerKeys_.length = 0;\n    super.disposeInternal();\n  }\n\n  /**\n   * @param {module:ol/layer/Layer} layer Layer.\n   * @return {CanvasRenderingContext2D} The rendering context.\n   */\n  getContext(layer) {\n    const key = getUid(layer).toString();\n    if (!(key in this.context_)) {\n      this.context_[key] = createCanvasContext2D();\n    }\n    return this.context_[key];\n  }\n\n  /**\n   * Get the Canvas for this tile.\n   * @param {module:ol/layer/Layer} layer Layer.\n   * @return {HTMLCanvasElement} Canvas.\n   */\n  getImage(layer) {\n    return this.getReplayState(layer).renderedTileRevision == -1 ?\n      null : this.getContext(layer).canvas;\n  }\n\n  /**\n   * @param {module:ol/layer/Layer} layer Layer.\n   * @return {module:ol/VectorImageTile~ReplayState} The replay state.\n   */\n  getReplayState(layer) {\n    const key = getUid(layer).toString();\n    if (!(key in this.replayState_)) {\n      this.replayState_[key] = {\n        dirty: false,\n        renderedRenderOrder: null,\n        renderedRevision: -1,\n        renderedTileRevision: -1\n      };\n    }\n    return this.replayState_[key];\n  }\n\n  /**\n   * @inheritDoc\n   */\n  getKey() {\n    return this.tileKeys.join('/') + '-' + this.sourceRevision_;\n  }\n\n  /**\n   * @param {string} tileKey Key (tileCoord) of the source tile.\n   * @return {module:ol/VectorTile} Source tile.\n   */\n  getTile(tileKey) {\n    return this.sourceTiles_[tileKey];\n  }\n\n  /**\n   * @inheritDoc\n   */\n  load() {\n    // Source tiles with LOADED state - we just count them because once they are\n    // loaded, we're no longer listening to state changes.\n    let leftToLoad = 0;\n    // Source tiles with ERROR state - we track them because they can still have\n    // an ERROR state after another load attempt.\n    const errorSourceTiles = {};\n\n    if (this.state == TileState.IDLE) {\n      this.setState(TileState.LOADING);\n    }\n    if (this.state == TileState.LOADING) {\n      this.tileKeys.forEach(function(sourceTileKey) {\n        const sourceTile = this.getTile(sourceTileKey);\n        if (sourceTile.state == TileState.IDLE) {\n          sourceTile.setLoader(this.loader_);\n          sourceTile.load();\n        }\n        if (sourceTile.state == TileState.LOADING) {\n          const key = listen(sourceTile, EventType.CHANGE, function(e) {\n            const state = sourceTile.getState();\n            if (state == TileState.LOADED ||\n                state == TileState.ERROR) {\n              const uid = getUid(sourceTile);\n              if (state == TileState.ERROR) {\n                errorSourceTiles[uid] = true;\n              } else {\n                --leftToLoad;\n                delete errorSourceTiles[uid];\n              }\n              if (leftToLoad - Object.keys(errorSourceTiles).length == 0) {\n                this.finishLoading_();\n              }\n            }\n          }.bind(this));\n          this.loadListenerKeys_.push(key);\n          ++leftToLoad;\n        }\n      }.bind(this));\n    }\n    if (leftToLoad - Object.keys(errorSourceTiles).length == 0) {\n      setTimeout(this.finishLoading_.bind(this), 0);\n    }\n  }\n\n  /**\n   * @private\n   */\n  finishLoading_() {\n    let loaded = this.tileKeys.length;\n    let empty = 0;\n    for (let i = loaded - 1; i >= 0; --i) {\n      const state = this.getTile(this.tileKeys[i]).getState();\n      if (state != TileState.LOADED) {\n        --loaded;\n      }\n      if (state == TileState.EMPTY) {\n        ++empty;\n      }\n    }\n    if (loaded == this.tileKeys.length) {\n      this.loadListenerKeys_.forEach(unlistenByKey);\n      this.loadListenerKeys_.length = 0;\n      this.setState(TileState.LOADED);\n    } else {\n      this.setState(empty == this.tileKeys.length ? TileState.EMPTY : TileState.ERROR);\n    }\n  }\n}\n\n\nexport default VectorImageTile;\n\n/**\n * Sets the loader for a tile.\n * @param {module:ol/VectorTile} tile Vector tile.\n * @param {string} url URL.\n */\nexport function defaultLoadFunction(tile, url) {\n  const loader = loadFeaturesXhr(url, tile.getFormat(), tile.onLoad.bind(tile), tile.onError.bind(tile));\n  tile.setLoader(loader);\n}\n","/**\n * @module ol/source/VectorTile\n */\n\nimport TileState from '../TileState.js';\nimport VectorImageTile, {defaultLoadFunction} from '../VectorImageTile.js';\nimport Tile from '../VectorTile.js';\nimport {toSize} from '../size.js';\nimport UrlTile from '../source/UrlTile.js';\nimport {getKeyZXY} from '../tilecoord.js';\nimport {createXYZ, extentFromProjection, createForProjection} from '../tilegrid.js';\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/source/Source~AttributionLike} [attributions] Attributions.\n * @property {number} [cacheSize=128] Cache size.\n * @property {module:ol/format/Feature} [format] Feature format for tiles. Used and required by the default.\n * @property {boolean} [overlaps=true] This source may have overlapping geometries. Setting this\n * to `false` (e.g. for sources with polygons that represent administrative\n * boundaries or TopoJSON sources) allows the renderer to optimise fill and\n * stroke operations.\n * @property {module:ol/proj~ProjectionLike} projection Projection.\n * @property {module:ol/source/State} [state] Source state.\n * @property {module:ol/VectorTile~TileClass} [tileClass] Class used to instantiate image tiles.\n * Default is {@link module:ol/VectorTile}.\n * @property {number} [maxZoom=22] Optional max zoom level.\n * @property {number} [minZoom] Optional min zoom level.\n * @property {number|module:ol/size~Size} [tileSize=512] Optional tile size.\n * @property {module:ol/tilegrid/TileGrid} [tileGrid] Tile grid.\n * @property {module:ol/Tile~LoadFunction} [tileLoadFunction]\n * Optional function to load a tile given a URL. Could look like this:\n * ```js\n * function(tile, url) {\n *   tile.setLoader(function() {\n *     var data = // ... fetch data\n *     var format = tile.getFormat();\n *     tile.setProjection(format.readProjection(data));\n *     tile.setFeatures(format.readFeatures(data, {\n *       // featureProjection is not required for ol/format/MVT\n *       featureProjection: map.getView().getProjection()\n *     }));\n *     // the line below is only required for ol/format/MVT\n *     tile.setExtent(format.getLastExtent());\n *   };\n * });\n * ```\n * @property {module:ol/Tile~UrlFunction} [tileUrlFunction] Optional function to get tile URL given a tile coordinate and the projection.\n * @property {string} [url] URL template. Must include `{x}`, `{y}` or `{-y}`, and `{z}` placeholders.\n * A `{?-?}` template pattern, for example `subdomain{a-f}.domain.com`, may be\n * used instead of defining each one separately in the `urls` option.\n * @property {number} [transition] A duration for tile opacity\n * transitions in milliseconds. A duration of 0 disables the opacity transition.\n * @property {Array.<string>} [urls] An array of URL templates.\n * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.\n * When set to `false`, only one world\n * will be rendered. When set to `true`, tiles will be wrapped horizontally to\n * render multiple worlds.\n */\n\n\n/**\n * @classdesc\n * Class for layer sources providing vector data divided into a tile grid, to be\n * used with {@link module:ol/layer/VectorTile~VectorTile}. Although this source receives tiles\n * with vector features from the server, it is not meant for feature editing.\n * Features are optimized for rendering, their geometries are clipped at or near\n * tile boundaries and simplified for a view resolution. See\n * {@link module:ol/source/Vector} for vector sources that are suitable for feature\n * editing.\n *\n * @fires module:ol/source/Tile~TileSourceEvent\n * @api\n */\nclass VectorTile extends UrlTile {\n  /**\n   * @param {module:ol/source/VectorTile~Options=} options Vector tile options.\n   */\n  constructor(options) {\n    const projection = options.projection || 'EPSG:3857';\n\n    const extent = options.extent || extentFromProjection(projection);\n\n    const tileGrid = options.tileGrid || createXYZ({\n      extent: extent,\n      maxZoom: options.maxZoom || 22,\n      minZoom: options.minZoom,\n      tileSize: options.tileSize || 512\n    });\n\n    super({\n      attributions: options.attributions,\n      cacheSize: options.cacheSize !== undefined ? options.cacheSize : 128,\n      extent: extent,\n      opaque: false,\n      projection: projection,\n      state: options.state,\n      tileGrid: tileGrid,\n      tileLoadFunction: options.tileLoadFunction ? options.tileLoadFunction : defaultLoadFunction,\n      tileUrlFunction: options.tileUrlFunction,\n      url: options.url,\n      urls: options.urls,\n      wrapX: options.wrapX === undefined ? true : options.wrapX,\n      transition: options.transition\n    });\n\n    /**\n     * @private\n     * @type {module:ol/format/Feature}\n     */\n    this.format_ = options.format ? options.format : null;\n\n    /**\n       * @private\n       * @type {Object.<string, module:ol/VectorTile>}\n       */\n    this.sourceTiles_ = {};\n\n    /**\n     * @private\n     * @type {boolean}\n     */\n    this.overlaps_ = options.overlaps == undefined ? true : options.overlaps;\n\n    /**\n       * @protected\n       * @type {function(new: module:ol/VectorTile, module:ol/tilecoord~TileCoord, module:ol/TileState, string,\n       *        module:ol/format/Feature, module:ol/Tile~LoadFunction)}\n       */\n    this.tileClass = options.tileClass ? options.tileClass : Tile;\n\n    /**\n     * @private\n     * @type {Object.<string, module:ol/tilegrid/TileGrid>}\n     */\n    this.tileGrids_ = {};\n\n  }\n\n}\n\n\n/**\n * @return {boolean} The source can have overlapping geometries.\n */\nVectorTile.prototype.getOverlaps = function() {\n  return this.overlaps_;\n};\n\n/**\n * clear {@link module:ol/TileCache~TileCache} and delete all source tiles\n * @api\n */\nVectorTile.prototype.clear = function() {\n  this.tileCache.clear();\n  this.sourceTiles_ = {};\n};\n\n/**\n * @inheritDoc\n */\nVectorTile.prototype.getTile = function(z, x, y, pixelRatio, projection) {\n  const tileCoordKey = getKeyZXY(z, x, y);\n  if (this.tileCache.containsKey(tileCoordKey)) {\n    return (\n      /** @type {!module:ol/Tile} */ (this.tileCache.get(tileCoordKey))\n    );\n  } else {\n    const tileCoord = [z, x, y];\n    const urlTileCoord = this.getTileCoordForTileUrlFunction(\n      tileCoord, projection);\n    const tile = new VectorImageTile(\n      tileCoord,\n      urlTileCoord !== null ? TileState.IDLE : TileState.EMPTY,\n      this.getRevision(),\n      this.format_, this.tileLoadFunction, urlTileCoord, this.tileUrlFunction,\n      this.tileGrid, this.getTileGridForProjection(projection),\n      this.sourceTiles_, pixelRatio, projection, this.tileClass,\n      this.handleTileChange.bind(this), tileCoord[0]);\n\n    this.tileCache.set(tileCoordKey, tile);\n    return tile;\n  }\n};\n\n\n/**\n * @inheritDoc\n */\nVectorTile.prototype.getTileGridForProjection = function(projection) {\n  const code = projection.getCode();\n  let tileGrid = this.tileGrids_[code];\n  if (!tileGrid) {\n    // A tile grid that matches the tile size of the source tile grid is more\n    // likely to have 1:1 relationships between source tiles and rendered tiles.\n    const sourceTileGrid = this.tileGrid;\n    tileGrid = this.tileGrids_[code] = createForProjection(projection, undefined,\n      sourceTileGrid ? sourceTileGrid.getTileSize(sourceTileGrid.getMinZoom()) : undefined);\n  }\n  return tileGrid;\n};\n\n\n/**\n * @inheritDoc\n */\nVectorTile.prototype.getTilePixelRatio = function(pixelRatio) {\n  return pixelRatio;\n};\n\n\n/**\n * @inheritDoc\n */\nVectorTile.prototype.getTilePixelSize = function(z, pixelRatio, projection) {\n  const tileGrid = this.getTileGridForProjection(projection);\n  const tileSize = toSize(tileGrid.getTileSize(z), this.tmpSize);\n  return [Math.round(tileSize[0] * pixelRatio), Math.round(tileSize[1] * pixelRatio)];\n};\nexport default VectorTile;\n","/**\n * @module ol/source/WMTSRequestEncoding\n */\n\n/**\n * Request encoding. One of 'KVP', 'REST'.\n * @enum {string}\n */\nexport default {\n  KVP: 'KVP', // see spec §8\n  REST: 'REST' // see spec §10\n};\n","/**\n * @module ol/tilegrid/WMTS\n */\n\nimport {find} from '../array.js';\nimport {get as getProjection} from '../proj.js';\nimport TileGrid from '../tilegrid/TileGrid.js';\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/extent~Extent} [extent] Extent for the tile grid. No tiles\n * outside this extent will be requested by {@link module:ol/source/Tile} sources.\n * When no `origin` or `origins` are configured, the `origin` will be set to the\n * top-left corner of the extent.\n * @property {module:ol/coordinate~Coordinate} [origin] The tile grid origin, i.e.\n * where the `x` and `y` axes meet (`[z, 0, 0]`). Tile coordinates increase left\n * to right and upwards. If not specified, `extent` or `origins` must be provided.\n * @property {Array.<module:ol/coordinate~Coordinate>} [origins] Tile grid origins,\n * i.e. where the `x` and `y` axes meet (`[z, 0, 0]`), for each zoom level. If\n * given, the array length should match the length of the `resolutions` array, i.e.\n * each resolution can have a different origin. Tile coordinates increase left to\n * right and upwards. If not specified, `extent` or `origin` must be provided.\n * @property {!Array.<number>} resolutions Resolutions. The array index of each\n * resolution needs to match the zoom level. This means that even if a `minZoom`\n * is configured, the resolutions array will have a length of `maxZoom + 1`\n * @property {!Array.<string>} matrixIds matrix IDs. The length of this array needs\n * to match the length of the `resolutions` array.\n * @property {Array.<module:ol/size~Size>} [sizes] Number of tile rows and columns\n * of the grid for each zoom level. The values here are the `TileMatrixWidth` and\n * `TileMatrixHeight` advertised in the GetCapabilities response of the WMTS, and\n * define the grid's extent together with the `origin`.\n * An `extent` can be configured in addition, and will further limit the extent for\n * which tile requests are made by sources. Note that when the top-left corner of\n * the `extent` is used as `origin` or `origins`, then the `y` value must be\n * negative because OpenLayers tile coordinates increase upwards.\n * @property {number|module:ol/size~Size} [tileSize] Tile size.\n * @property {Array.<module:ol/size~Size>} [tileSizes] Tile sizes. The length of\n * this array needs to match the length of the `resolutions` array.\n * @property {Array.<number>} [widths] Number of tile columns that cover the grid's\n * extent for each zoom level. Only required when used with a source that has `wrapX`\n * set to `true`, and only when the grid's origin differs from the one of the\n * projection's extent. The array length has to match the length of the `resolutions`\n * array, i.e. each resolution will have a matching entry here.\n */\n\n\n/**\n * @classdesc\n * Set the grid pattern for sources accessing WMTS tiled-image servers.\n * @api\n */\nclass WMTSTileGrid extends TileGrid {\n  /**\n   * @param {module:ol/tilegrid/WMTS~Options} options WMTS options.\n   */\n  constructor(options) {\n    super({\n      extent: options.extent,\n      origin: options.origin,\n      origins: options.origins,\n      resolutions: options.resolutions,\n      tileSize: options.tileSize,\n      tileSizes: options.tileSizes,\n      sizes: options.sizes\n    });\n\n    /**\n     * @private\n     * @type {!Array.<string>}\n     */\n    this.matrixIds_ = options.matrixIds;\n  }\n\n  /**\n   * @param {number} z Z.\n   * @return {string} MatrixId..\n   */\n  getMatrixId(z) {\n    return this.matrixIds_[z];\n  }\n\n  /**\n   * Get the list of matrix identifiers.\n   * @return {Array.<string>} MatrixIds.\n   * @api\n   */\n  getMatrixIds() {\n    return this.matrixIds_;\n  }\n}\n\n\nexport default WMTSTileGrid;\n\n/**\n * Create a tile grid from a WMTS capabilities matrix set and an\n * optional TileMatrixSetLimits.\n * @param {Object} matrixSet An object representing a matrixSet in the\n *     capabilities document.\n * @param {module:ol/extent~Extent=} opt_extent An optional extent to restrict the tile\n *     ranges the server provides.\n * @param {Array.<Object>=} opt_matrixLimits An optional object representing\n *     the available matrices for tileGrid.\n * @return {module:ol/tilegrid/WMTS} WMTS tileGrid instance.\n * @api\n */\nexport function createFromCapabilitiesMatrixSet(matrixSet, opt_extent, opt_matrixLimits) {\n\n  /** @type {!Array.<number>} */\n  const resolutions = [];\n  /** @type {!Array.<string>} */\n  const matrixIds = [];\n  /** @type {!Array.<module:ol/coordinate~Coordinate>} */\n  const origins = [];\n  /** @type {!Array.<module:ol/size~Size>} */\n  const tileSizes = [];\n  /** @type {!Array.<module:ol/size~Size>} */\n  const sizes = [];\n\n  const matrixLimits = opt_matrixLimits !== undefined ? opt_matrixLimits : [];\n\n  const supportedCRSPropName = 'SupportedCRS';\n  const matrixIdsPropName = 'TileMatrix';\n  const identifierPropName = 'Identifier';\n  const scaleDenominatorPropName = 'ScaleDenominator';\n  const topLeftCornerPropName = 'TopLeftCorner';\n  const tileWidthPropName = 'TileWidth';\n  const tileHeightPropName = 'TileHeight';\n\n  const code = matrixSet[supportedCRSPropName];\n  const projection = getProjection(code.replace(/urn:ogc:def:crs:(\\w+):(.*:)?(\\w+)$/, '$1:$3')) ||\n      getProjection(code);\n  const metersPerUnit = projection.getMetersPerUnit();\n  // swap origin x and y coordinates if axis orientation is lat/long\n  const switchOriginXY = projection.getAxisOrientation().substr(0, 2) == 'ne';\n\n  matrixSet[matrixIdsPropName].sort(function(a, b) {\n    return b[scaleDenominatorPropName] - a[scaleDenominatorPropName];\n  });\n\n  matrixSet[matrixIdsPropName].forEach(function(elt) {\n\n    let matrixAvailable;\n    // use of matrixLimits to filter TileMatrices from GetCapabilities\n    // TileMatrixSet from unavailable matrix levels.\n    if (matrixLimits.length > 0) {\n      matrixAvailable = find(matrixLimits, function(elt_ml) {\n        if (elt[identifierPropName] == elt_ml[matrixIdsPropName]) {\n          return true;\n        }\n        // Fallback for tileMatrix identifiers that don't get prefixed\n        // by their tileMatrixSet identifiers.\n        if (elt[identifierPropName].indexOf(':') === -1) {\n          return matrixSet[identifierPropName] + ':' + elt[identifierPropName] === elt_ml[matrixIdsPropName];\n        }\n        return false;\n      });\n    } else {\n      matrixAvailable = true;\n    }\n\n    if (matrixAvailable) {\n      matrixIds.push(elt[identifierPropName]);\n      const resolution = elt[scaleDenominatorPropName] * 0.28E-3 / metersPerUnit;\n      const tileWidth = elt[tileWidthPropName];\n      const tileHeight = elt[tileHeightPropName];\n      if (switchOriginXY) {\n        origins.push([elt[topLeftCornerPropName][1],\n          elt[topLeftCornerPropName][0]]);\n      } else {\n        origins.push(elt[topLeftCornerPropName]);\n      }\n      resolutions.push(resolution);\n      tileSizes.push(tileWidth == tileHeight ?\n        tileWidth : [tileWidth, tileHeight]);\n      // top-left origin, so height is negative\n      sizes.push([elt['MatrixWidth'], -elt['MatrixHeight']]);\n    }\n  });\n\n  return new WMTSTileGrid({\n    extent: opt_extent,\n    origins: origins,\n    resolutions: resolutions,\n    matrixIds: matrixIds,\n    tileSizes: tileSizes,\n    sizes: sizes\n  });\n}\n","/**\n * @module ol/source/WMTS\n */\n\nimport {expandUrl, createFromTileUrlFunctions, nullTileUrlFunction} from '../tileurlfunction.js';\nimport {find, findIndex, includes} from '../array.js';\nimport {containsExtent} from '../extent.js';\nimport {assign} from '../obj.js';\nimport {get as getProjection, equivalent, transformExtent} from '../proj.js';\nimport TileImage from '../source/TileImage.js';\nimport WMTSRequestEncoding from '../source/WMTSRequestEncoding.js';\nimport {createFromCapabilitiesMatrixSet} from '../tilegrid/WMTS.js';\nimport {appendParams} from '../uri.js';\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/source/Source~AttributionLike} [attributions] Attributions.\n * @property {number} [cacheSize=2048] Cache size.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images.  Note that\n * you must provide a `crossOrigin` value if you are using the WebGL renderer or if you want to\n * access pixel data with the Canvas renderer.  See\n * https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {module:ol/tilegrid/WMTS} tileGrid Tile grid.\n * @property {module:ol/proj~ProjectionLike} projection Projection.\n * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).\n * Higher values can increase reprojection performance, but decrease precision.\n * @property {module:ol/source/WMTSRequestEncoding|string} [requestEncoding='KVP'] Request encoding.\n * @property {string} layer Layer name as advertised in the WMTS capabilities.\n * @property {string} style Style name as advertised in the WMTS capabilities.\n * @property {module:ol/ImageTile~TileClass} [tileClass]  Class used to instantiate image tiles. Default is {@link module:ol/ImageTile~ImageTile}.\n * @property {number} [tilePixelRatio=1] The pixel ratio used by the tile service.\n * For example, if the tile service advertizes 256px by 256px tiles but actually sends 512px\n * by 512px images (for retina/hidpi devices) then `tilePixelRatio`\n * should be set to `2`.\n * @property {string} [version='image/jpeg'] Image format.\n * @property {string} [format='1.0.0'] WMTS version.\n * @property {string} matrixSet Matrix set.\n * @property {!Object} [dimensions] Additional \"dimensions\" for tile requests.\n * This is an object with properties named like the advertised WMTS dimensions.\n * @property {string} [url]  A URL for the service.\n * For the RESTful request encoding, this is a URL\n * template.  For KVP encoding, it is normal URL. A `{?-?}` template pattern,\n * for example `subdomain{a-f}.domain.com`, may be used instead of defining\n * each one separately in the `urls` option.\n * @property {module:ol/Tile~LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is\n * ```js\n * function(imageTile, src) {\n *   imageTile.getImage().src = src;\n * };\n * ```\n * @property {Array.<string>} [urls] An array of URLs.\n * Requests will be distributed among the URLs in this array.\n * @property {boolean} [wrapX=false] Whether to wrap the world horizontally.\n * @property {number} [transition] Duration of the opacity transition for rendering.\n * To disable the opacity transition, pass `transition: 0`.\n */\n\n\n/**\n * @classdesc\n * Layer source for tile data from WMTS servers.\n * @api\n */\nclass WMTS extends TileImage {\n  /**\n   * @param {module:ol/source/WMTS~Options=} options WMTS options.\n   */\n  constructor(options) {\n\n    // TODO: add support for TileMatrixLimits\n\n    const requestEncoding = options.requestEncoding !== undefined ?\n      /** @type {module:ol/source/WMTSRequestEncoding} */ (options.requestEncoding) :\n      WMTSRequestEncoding.KVP;\n\n    // FIXME: should we create a default tileGrid?\n    // we could issue a getCapabilities xhr to retrieve missing configuration\n    const tileGrid = options.tileGrid;\n\n    let urls = options.urls;\n    if (urls === undefined && options.url !== undefined) {\n      urls = expandUrl(options.url);\n    }\n\n    super({\n      attributions: options.attributions,\n      cacheSize: options.cacheSize,\n      crossOrigin: options.crossOrigin,\n      projection: options.projection,\n      reprojectionErrorThreshold: options.reprojectionErrorThreshold,\n      tileClass: options.tileClass,\n      tileGrid: tileGrid,\n      tileLoadFunction: options.tileLoadFunction,\n      tilePixelRatio: options.tilePixelRatio,\n      tileUrlFunction: nullTileUrlFunction,\n      urls: urls,\n      wrapX: options.wrapX !== undefined ? options.wrapX : false,\n      transition: options.transition\n    });\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.version_ = options.version !== undefined ? options.version : '1.0.0';\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.format_ = options.format !== undefined ? options.format : 'image/jpeg';\n\n    /**\n     * @private\n     * @type {!Object}\n     */\n    this.dimensions_ = options.dimensions !== undefined ? options.dimensions : {};\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.layer_ = options.layer;\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.matrixSet_ = options.matrixSet;\n\n    /**\n     * @private\n     * @type {string}\n     */\n    this.style_ = options.style;\n\n    // FIXME: should we guess this requestEncoding from options.url(s)\n    //        structure? that would mean KVP only if a template is not provided.\n\n    /**\n     * @private\n     * @type {module:ol/source/WMTSRequestEncoding}\n     */\n    this.requestEncoding_ = requestEncoding;\n\n    this.setKey(this.getKeyForDimensions_());\n\n    if (urls && urls.length > 0) {\n      this.tileUrlFunction = createFromTileUrlFunctions(urls.map(createFromWMTSTemplate.bind(this)));\n    }\n\n  }\n\n}\n\n/**\n * Set the URLs to use for requests.\n * URLs may contain OCG conform URL Template Variables: {TileMatrix}, {TileRow}, {TileCol}.\n * @override\n */\nWMTS.prototype.setUrls = function(urls) {\n  this.urls = urls;\n  const key = urls.join('\\n');\n  this.setTileUrlFunction(this.fixedTileUrlFunction ?\n    this.fixedTileUrlFunction.bind(this) :\n    createFromTileUrlFunctions(urls.map(createFromWMTSTemplate.bind(this))), key);\n};\n\n/**\n * Get the dimensions, i.e. those passed to the constructor through the\n * \"dimensions\" option, and possibly updated using the updateDimensions\n * method.\n * @return {!Object} Dimensions.\n * @api\n */\nWMTS.prototype.getDimensions = function() {\n  return this.dimensions_;\n};\n\n\n/**\n * Return the image format of the WMTS source.\n * @return {string} Format.\n * @api\n */\nWMTS.prototype.getFormat = function() {\n  return this.format_;\n};\n\n\n/**\n * Return the layer of the WMTS source.\n * @return {string} Layer.\n * @api\n */\nWMTS.prototype.getLayer = function() {\n  return this.layer_;\n};\n\n\n/**\n * Return the matrix set of the WMTS source.\n * @return {string} MatrixSet.\n * @api\n */\nWMTS.prototype.getMatrixSet = function() {\n  return this.matrixSet_;\n};\n\n\n/**\n * Return the request encoding, either \"KVP\" or \"REST\".\n * @return {module:ol/source/WMTSRequestEncoding} Request encoding.\n * @api\n */\nWMTS.prototype.getRequestEncoding = function() {\n  return this.requestEncoding_;\n};\n\n\n/**\n * Return the style of the WMTS source.\n * @return {string} Style.\n * @api\n */\nWMTS.prototype.getStyle = function() {\n  return this.style_;\n};\n\n\n/**\n * Return the version of the WMTS source.\n * @return {string} Version.\n * @api\n */\nWMTS.prototype.getVersion = function() {\n  return this.version_;\n};\n\n\n/**\n * @private\n * @return {string} The key for the current dimensions.\n */\nWMTS.prototype.getKeyForDimensions_ = function() {\n  let i = 0;\n  const res = [];\n  for (const key in this.dimensions_) {\n    res[i++] = key + '-' + this.dimensions_[key];\n  }\n  return res.join('/');\n};\n\n\n/**\n * Update the dimensions.\n * @param {Object} dimensions Dimensions.\n * @api\n */\nWMTS.prototype.updateDimensions = function(dimensions) {\n  assign(this.dimensions_, dimensions);\n  this.setKey(this.getKeyForDimensions_());\n};\n\n\n/**\n * Generate source options from a capabilities object.\n * @param {Object} wmtsCap An object representing the capabilities document.\n * @param {!Object} config Configuration properties for the layer.  Defaults for\n *                  the layer will apply if not provided.\n *\n * Required config properties:\n *  - layer - {string} The layer identifier.\n *\n * Optional config properties:\n *  - matrixSet - {string} The matrix set identifier, required if there is\n *       more than one matrix set in the layer capabilities.\n *  - projection - {string} The desired CRS when no matrixSet is specified.\n *       eg: \"EPSG:3857\". If the desired projection is not available,\n *       an error is thrown.\n *  - requestEncoding - {string} url encoding format for the layer. Default is\n *       the first tile url format found in the GetCapabilities response.\n *  - style - {string} The name of the style\n *  - format - {string} Image format for the layer. Default is the first\n *       format returned in the GetCapabilities response.\n *  - crossOrigin - {string|null|undefined} Cross origin. Default is `undefined`.\n * @return {?module:ol/source/WMTS~Options} WMTS source options object or `null` if the layer was not found.\n * @api\n */\nexport function optionsFromCapabilities(wmtsCap, config) {\n  const layers = wmtsCap['Contents']['Layer'];\n  const l = find(layers, function(elt, index, array) {\n    return elt['Identifier'] == config['layer'];\n  });\n  if (l === null) {\n    return null;\n  }\n  const tileMatrixSets = wmtsCap['Contents']['TileMatrixSet'];\n  let idx;\n  if (l['TileMatrixSetLink'].length > 1) {\n    if ('projection' in config) {\n      idx = findIndex(l['TileMatrixSetLink'],\n        function(elt, index, array) {\n          const tileMatrixSet = find(tileMatrixSets, function(el) {\n            return el['Identifier'] == elt['TileMatrixSet'];\n          });\n          const supportedCRS = tileMatrixSet['SupportedCRS'];\n          const proj1 = getProjection(supportedCRS.replace(/urn:ogc:def:crs:(\\w+):(.*:)?(\\w+)$/, '$1:$3')) ||\n                getProjection(supportedCRS);\n          const proj2 = getProjection(config['projection']);\n          if (proj1 && proj2) {\n            return equivalent(proj1, proj2);\n          } else {\n            return supportedCRS == config['projection'];\n          }\n        });\n    } else {\n      idx = findIndex(l['TileMatrixSetLink'],\n        function(elt, index, array) {\n          return elt['TileMatrixSet'] == config['matrixSet'];\n        });\n    }\n  } else {\n    idx = 0;\n  }\n  if (idx < 0) {\n    idx = 0;\n  }\n  const matrixSet = /** @type {string} */\n    (l['TileMatrixSetLink'][idx]['TileMatrixSet']);\n  const matrixLimits = /** @type {Array.<Object>} */\n    (l['TileMatrixSetLink'][idx]['TileMatrixSetLimits']);\n\n  let format = /** @type {string} */ (l['Format'][0]);\n  if ('format' in config) {\n    format = config['format'];\n  }\n  idx = findIndex(l['Style'], function(elt, index, array) {\n    if ('style' in config) {\n      return elt['Title'] == config['style'];\n    } else {\n      return elt['isDefault'];\n    }\n  });\n  if (idx < 0) {\n    idx = 0;\n  }\n  const style = /** @type {string} */ (l['Style'][idx]['Identifier']);\n\n  const dimensions = {};\n  if ('Dimension' in l) {\n    l['Dimension'].forEach(function(elt, index, array) {\n      const key = elt['Identifier'];\n      let value = elt['Default'];\n      if (value === undefined) {\n        value = elt['Value'][0];\n      }\n      dimensions[key] = value;\n    });\n  }\n\n  const matrixSets = wmtsCap['Contents']['TileMatrixSet'];\n  const matrixSetObj = find(matrixSets, function(elt, index, array) {\n    return elt['Identifier'] == matrixSet;\n  });\n\n  let projection;\n  const code = matrixSetObj['SupportedCRS'];\n  if (code) {\n    projection = getProjection(code.replace(/urn:ogc:def:crs:(\\w+):(.*:)?(\\w+)$/, '$1:$3')) ||\n        getProjection(code);\n  }\n  if ('projection' in config) {\n    const projConfig = getProjection(config['projection']);\n    if (projConfig) {\n      if (!projection || equivalent(projConfig, projection)) {\n        projection = projConfig;\n      }\n    }\n  }\n\n  const wgs84BoundingBox = l['WGS84BoundingBox'];\n  let extent, wrapX;\n  if (wgs84BoundingBox !== undefined) {\n    const wgs84ProjectionExtent = getProjection('EPSG:4326').getExtent();\n    wrapX = (wgs84BoundingBox[0] == wgs84ProjectionExtent[0] &&\n        wgs84BoundingBox[2] == wgs84ProjectionExtent[2]);\n    extent = transformExtent(\n      wgs84BoundingBox, 'EPSG:4326', projection);\n    const projectionExtent = projection.getExtent();\n    if (projectionExtent) {\n      // If possible, do a sanity check on the extent - it should never be\n      // bigger than the validity extent of the projection of a matrix set.\n      if (!containsExtent(projectionExtent, extent)) {\n        extent = undefined;\n      }\n    }\n  }\n\n  const tileGrid = createFromCapabilitiesMatrixSet(matrixSetObj, extent, matrixLimits);\n\n  /** @type {!Array.<string>} */\n  const urls = [];\n  let requestEncoding = config['requestEncoding'];\n  requestEncoding = requestEncoding !== undefined ? requestEncoding : '';\n\n  if ('OperationsMetadata' in wmtsCap && 'GetTile' in wmtsCap['OperationsMetadata']) {\n    const gets = wmtsCap['OperationsMetadata']['GetTile']['DCP']['HTTP']['Get'];\n\n    for (let i = 0, ii = gets.length; i < ii; ++i) {\n      if (gets[i]['Constraint']) {\n        const constraint = find(gets[i]['Constraint'], function(element) {\n          return element['name'] == 'GetEncoding';\n        });\n        const encodings = constraint['AllowedValues']['Value'];\n\n        if (requestEncoding === '') {\n          // requestEncoding not provided, use the first encoding from the list\n          requestEncoding = encodings[0];\n        }\n        if (requestEncoding === WMTSRequestEncoding.KVP) {\n          if (includes(encodings, WMTSRequestEncoding.KVP)) {\n            urls.push(/** @type {string} */ (gets[i]['href']));\n          }\n        } else {\n          break;\n        }\n      } else if (gets[i]['href']) {\n        requestEncoding = WMTSRequestEncoding.KVP;\n        urls.push(/** @type {string} */ (gets[i]['href']));\n      }\n    }\n  }\n  if (urls.length === 0) {\n    requestEncoding = WMTSRequestEncoding.REST;\n    l['ResourceURL'].forEach(function(element) {\n      if (element['resourceType'] === 'tile') {\n        format = element['format'];\n        urls.push(/** @type {string} */ (element['template']));\n      }\n    });\n  }\n\n  return {\n    urls: urls,\n    layer: config['layer'],\n    matrixSet: matrixSet,\n    format: format,\n    projection: projection,\n    requestEncoding: requestEncoding,\n    tileGrid: tileGrid,\n    style: style,\n    dimensions: dimensions,\n    wrapX: wrapX,\n    crossOrigin: config['crossOrigin']\n  };\n}\n\n/**\n * @param {string} template Template.\n * @return {module:ol/Tile~UrlFunction} Tile URL function.\n * @this {module:ol/source/WMTS}\n */\nfunction createFromWMTSTemplate(template) {\n  const requestEncoding = this.requestEncoding_;\n\n  // context property names are lower case to allow for a case insensitive\n  // replacement as some services use different naming conventions\n  const context = {\n    'layer': this.layer_,\n    'style': this.style_,\n    'tilematrixset': this.matrixSet_\n  };\n\n  if (requestEncoding == WMTSRequestEncoding.KVP) {\n    assign(context, {\n      'Service': 'WMTS',\n      'Request': 'GetTile',\n      'Version': this.version_,\n      'Format': this.format_\n    });\n  }\n\n  // TODO: we may want to create our own appendParams function so that params\n  // order conforms to wmts spec guidance, and so that we can avoid to escape\n  // special template params\n\n  template = (requestEncoding == WMTSRequestEncoding.KVP) ?\n    appendParams(template, context) :\n    template.replace(/\\{(\\w+?)\\}/g, function(m, p) {\n      return (p.toLowerCase() in context) ? context[p.toLowerCase()] : m;\n    });\n\n  const tileGrid = this.tileGrid;\n\n  return (\n    /**\n     * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n     * @param {number} pixelRatio Pixel ratio.\n     * @param {module:ol/proj/Projection} projection Projection.\n     * @return {string|undefined} Tile URL.\n     */\n    function(tileCoord, pixelRatio, projection) {\n      if (!tileCoord) {\n        return undefined;\n      } else {\n        const localContext = {\n          'TileMatrix': tileGrid.getMatrixId(tileCoord[0]),\n          'TileCol': tileCoord[1],\n          'TileRow': -tileCoord[2] - 1\n        };\n        assign(localContext, this.dimensions_);\n        let url = template;\n        if (requestEncoding == WMTSRequestEncoding.KVP) {\n          url = appendParams(url, localContext);\n        } else {\n          url = url.replace(/\\{(\\w+?)\\}/g, function(m, p) {\n            return localContext[p];\n          });\n        }\n        return url;\n      }\n    }\n  );\n}\n\n\nexport default WMTS;\n","/**\n * @module ol/source/Zoomify\n */\nimport {DEFAULT_TILE_SIZE} from '../tilegrid/common.js';\n\nimport ImageTile from '../ImageTile.js';\nimport TileState from '../TileState.js';\nimport {expandUrl, createFromTileUrlFunctions} from '../tileurlfunction.js';\nimport {assert} from '../asserts.js';\nimport {createCanvasContext2D} from '../dom.js';\nimport {getTopLeft} from '../extent.js';\nimport {toSize} from '../size.js';\nimport TileImage from '../source/TileImage.js';\nimport TileGrid from '../tilegrid/TileGrid.js';\n\n\n/**\n * @enum {string}\n */\nconst TierSizeCalculation = {\n  DEFAULT: 'default',\n  TRUNCATED: 'truncated'\n};\n\n\nexport class CustomTile extends ImageTile {\n\n  /**\n   * @param {module:ol/tilegrid/TileGrid} tileGrid TileGrid that the tile belongs to.\n   * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.\n   * @param {module:ol/TileState} state State.\n   * @param {string} src Image source URI.\n   * @param {?string} crossOrigin Cross origin.\n   * @param {module:ol/Tile~LoadFunction} tileLoadFunction Tile load function.\n   * @param {module:ol/Tile~Options=} opt_options Tile options.\n   */\n  constructor(tileGrid, tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options) {\n\n    super(tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options);\n\n    /**\n     * @private\n     * @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement}\n     */\n    this.zoomifyImage_ = null;\n\n    /**\n     * @private\n     * @type {module:ol/size~Size}\n     */\n    this.tileSize_ = toSize(tileGrid.getTileSize(tileCoord[0]));\n\n  }\n\n}\n\n\n/**\n * @inheritDoc\n */\nCustomTile.prototype.getImage = function() {\n  if (this.zoomifyImage_) {\n    return this.zoomifyImage_;\n  }\n  const image = ImageTile.prototype.getImage.call(this);\n  if (this.state == TileState.LOADED) {\n    const tileSize = this.tileSize_;\n    if (image.width == tileSize[0] && image.height == tileSize[1]) {\n      this.zoomifyImage_ = image;\n      return image;\n    } else {\n      const context = createCanvasContext2D(tileSize[0], tileSize[1]);\n      context.drawImage(image, 0, 0);\n      this.zoomifyImage_ = context.canvas;\n      return context.canvas;\n    }\n  } else {\n    return image;\n  }\n};\n\n\n/**\n * @typedef {Object} Options\n * @property {module:ol/source/Source~AttributionLike} [attributions] Attributions.\n * @property {number} [cacheSize=2048] Cache size.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images.  Note that\n * you must provide a `crossOrigin` value if you are using the WebGL renderer or if you want to\n * access pixel data with the Canvas renderer.  See\n * https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {module:ol/proj~ProjectionLike} [projection] Projection.\n * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).\n * Higher values can increase reprojection performance, but decrease precision.\n * @property {string} [url] URL template or base URL of the Zoomify service.\n * A base URL is the fixed part\n * of the URL, excluding the tile group, z, x, and y folder structure, e.g.\n * `http://my.zoomify.info/IMAGE.TIF/`. A URL template must include\n * `{TileGroup}`, `{x}`, `{y}`, and `{z}` placeholders, e.g.\n * `http://my.zoomify.info/IMAGE.TIF/{TileGroup}/{z}-{x}-{y}.jpg`.\n * Internet Imaging Protocol (IIP) with JTL extension can be also used with\n * `{tileIndex}` and `{z}` placeholders, e.g.\n * `http://my.zoomify.info?FIF=IMAGE.TIF&JTL={z},{tileIndex}`.\n * A `{?-?}` template pattern, for example `subdomain{a-f}.domain.com`, may be\n * used instead of defining each one separately in the `urls` option.\n * @property {string} [tierSizeCalculation] Tier size calculation method: `default` or `truncated`.\n * @property {module:ol/size~Size} [size] Size of the image.\n * @property {module:ol/extent~Extent} [extent] Extent for the TileGrid that is created.\n * Default sets the TileGrid in the\n * fourth quadrant, meaning extent is `[0, -height, width, 0]`. To change the\n * extent to the first quadrant (the default for OpenLayers 2) set the extent\n * as `[0, 0, width, height]`.\n * @property {number} [transition] Duration of the opacity transition for rendering.\n * To disable the opacity transition, pass `transition: 0`.\n * @property {number} [tileSize=256] Tile size. Same tile size is used for all zoom levels.\n */\n\n\n/**\n * @classdesc\n * Layer source for tile data in Zoomify format (both Zoomify and Internet\n * Imaging Protocol are supported).\n * @api\n */\nclass Zoomify extends TileImage {\n\n  /**\n   * @param {module:ol/source/Zoomify~Options=} opt_options Options.\n   */\n  constructor(opt_options) {\n\n    const options = opt_options || {};\n\n    const size = options.size;\n    const tierSizeCalculation = options.tierSizeCalculation !== undefined ?\n      options.tierSizeCalculation :\n      TierSizeCalculation.DEFAULT;\n\n    const imageWidth = size[0];\n    const imageHeight = size[1];\n    const extent = options.extent || [0, -size[1], size[0], 0];\n    const tierSizeInTiles = [];\n    const tileSize = options.tileSize || DEFAULT_TILE_SIZE;\n    let tileSizeForTierSizeCalculation = tileSize;\n\n    switch (tierSizeCalculation) {\n      case TierSizeCalculation.DEFAULT:\n        while (imageWidth > tileSizeForTierSizeCalculation || imageHeight > tileSizeForTierSizeCalculation) {\n          tierSizeInTiles.push([\n            Math.ceil(imageWidth / tileSizeForTierSizeCalculation),\n            Math.ceil(imageHeight / tileSizeForTierSizeCalculation)\n          ]);\n          tileSizeForTierSizeCalculation += tileSizeForTierSizeCalculation;\n        }\n        break;\n      case TierSizeCalculation.TRUNCATED:\n        let width = imageWidth;\n        let height = imageHeight;\n        while (width > tileSizeForTierSizeCalculation || height > tileSizeForTierSizeCalculation) {\n          tierSizeInTiles.push([\n            Math.ceil(width / tileSizeForTierSizeCalculation),\n            Math.ceil(height / tileSizeForTierSizeCalculation)\n          ]);\n          width >>= 1;\n          height >>= 1;\n        }\n        break;\n      default:\n        assert(false, 53); // Unknown `tierSizeCalculation` configured\n        break;\n    }\n\n    tierSizeInTiles.push([1, 1]);\n    tierSizeInTiles.reverse();\n\n    const resolutions = [1];\n    const tileCountUpToTier = [0];\n    for (let i = 1, ii = tierSizeInTiles.length; i < ii; i++) {\n      resolutions.push(1 << i);\n      tileCountUpToTier.push(\n        tierSizeInTiles[i - 1][0] * tierSizeInTiles[i - 1][1] +\n          tileCountUpToTier[i - 1]\n      );\n    }\n    resolutions.reverse();\n\n    const tileGrid = new TileGrid({\n      tileSize: tileSize,\n      extent: extent,\n      origin: getTopLeft(extent),\n      resolutions: resolutions\n    });\n\n    let url = options.url;\n    if (url && url.indexOf('{TileGroup}') == -1 && url.indexOf('{tileIndex}') == -1) {\n      url += '{TileGroup}/{z}-{x}-{y}.jpg';\n    }\n    const urls = expandUrl(url);\n\n    /**\n     * @param {string} template Template.\n     * @return {module:ol/Tile~UrlFunction} Tile URL function.\n     */\n    function createFromTemplate(template) {\n\n      return (\n        /**\n         * @param {module:ol/tilecoord~TileCoord} tileCoord Tile Coordinate.\n         * @param {number} pixelRatio Pixel ratio.\n         * @param {module:ol/proj/Projection} projection Projection.\n         * @return {string|undefined} Tile URL.\n         */\n        function(tileCoord, pixelRatio, projection) {\n          if (!tileCoord) {\n            return undefined;\n          } else {\n            const tileCoordZ = tileCoord[0];\n            const tileCoordX = tileCoord[1];\n            const tileCoordY = -tileCoord[2] - 1;\n            const tileIndex =\n                tileCoordX +\n                tileCoordY * tierSizeInTiles[tileCoordZ][0];\n            const tileSize = tileGrid.getTileSize(tileCoordZ);\n            const tileGroup = ((tileIndex + tileCountUpToTier[tileCoordZ]) / tileSize) | 0;\n            const localContext = {\n              'z': tileCoordZ,\n              'x': tileCoordX,\n              'y': tileCoordY,\n              'tileIndex': tileIndex,\n              'TileGroup': 'TileGroup' + tileGroup\n            };\n            return template.replace(/\\{(\\w+?)\\}/g, function(m, p) {\n              return localContext[p];\n            });\n          }\n        }\n      );\n    }\n\n    const tileUrlFunction = createFromTileUrlFunctions(urls.map(createFromTemplate));\n\n    const ZoomifyTileClass = CustomTile.bind(null, tileGrid);\n\n    super({\n      attributions: options.attributions,\n      cacheSize: options.cacheSize,\n      crossOrigin: options.crossOrigin,\n      projection: options.projection,\n      reprojectionErrorThreshold: options.reprojectionErrorThreshold,\n      tileClass: ZoomifyTileClass,\n      tileGrid: tileGrid,\n      tileUrlFunction: tileUrlFunction,\n      transition: options.transition\n    });\n\n  }\n\n}\n\nexport default Zoomify;\n","import $ol$Collection from './ol/Collection';\nimport $ol$Feature from './ol/Feature';\nimport $ol$Geolocation from './ol/Geolocation';\nimport $ol$Graticule from './ol/Graticule';\nimport $ol$Image from './ol/Image';\nimport $ol$ImageTile from './ol/ImageTile';\nimport $ol$Kinetic from './ol/Kinetic';\nimport $ol$Map from './ol/Map';\nimport $ol$MapBrowserEvent from './ol/MapBrowserEvent';\nimport $ol$Object from './ol/Object';\nimport $ol$Observable from './ol/Observable';\nimport $ol$Overlay from './ol/Overlay';\nimport $ol$PluggableMap from './ol/PluggableMap';\nimport $ol$Tile from './ol/Tile';\nimport $ol$VectorTile from './ol/VectorTile';\nimport $ol$View from './ol/View';\nimport $ol$WebGLMap from './ol/WebGLMap';\nimport $ol$control$Attribution from './ol/control/Attribution';\nimport $ol$control$Control from './ol/control/Control';\nimport $ol$control$FullScreen from './ol/control/FullScreen';\nimport $ol$control$MousePosition from './ol/control/MousePosition';\nimport $ol$control$OverviewMap from './ol/control/OverviewMap';\nimport $ol$control$Rotate from './ol/control/Rotate';\nimport $ol$control$ScaleLine from './ol/control/ScaleLine';\nimport $ol$control$Zoom from './ol/control/Zoom';\nimport $ol$control$ZoomSlider from './ol/control/ZoomSlider';\nimport $ol$control$ZoomToExtent from './ol/control/ZoomToExtent';\nimport $ol$events$Event from './ol/events/Event';\nimport $ol$events$EventTarget from './ol/events/EventTarget';\nimport $ol$format$EsriJSON from './ol/format/EsriJSON';\nimport $ol$format$Feature from './ol/format/Feature';\nimport $ol$format$GML from './ol/format/GML';\nimport $ol$format$GML2 from './ol/format/GML2';\nimport $ol$format$GML3 from './ol/format/GML3';\nimport $ol$format$GPX from './ol/format/GPX';\nimport $ol$format$GeoJSON from './ol/format/GeoJSON';\nimport $ol$format$IGC from './ol/format/IGC';\nimport $ol$format$JSONFeature from './ol/format/JSONFeature';\nimport $ol$format$KML from './ol/format/KML';\nimport $ol$format$MVT from './ol/format/MVT';\nimport $ol$format$OSMXML from './ol/format/OSMXML';\nimport $ol$format$Polyline from './ol/format/Polyline';\nimport $ol$format$TextFeature from './ol/format/TextFeature';\nimport $ol$format$TopoJSON from './ol/format/TopoJSON';\nimport $ol$format$WFS from './ol/format/WFS';\nimport $ol$format$WKT from './ol/format/WKT';\nimport $ol$format$WMSCapabilities from './ol/format/WMSCapabilities';\nimport $ol$format$WMSGetFeatureInfo from './ol/format/WMSGetFeatureInfo';\nimport $ol$format$WMTSCapabilities from './ol/format/WMTSCapabilities';\nimport $ol$format$XML from './ol/format/XML';\nimport $ol$format$XMLFeature from './ol/format/XMLFeature';\nimport $ol$format$filter$Bbox from './ol/format/filter/Bbox';\nimport $ol$format$filter$Contains from './ol/format/filter/Contains';\nimport $ol$format$filter$During from './ol/format/filter/During';\nimport $ol$format$filter$EqualTo from './ol/format/filter/EqualTo';\nimport $ol$format$filter$GreaterThan from './ol/format/filter/GreaterThan';\nimport $ol$format$filter$GreaterThanOrEqualTo from './ol/format/filter/GreaterThanOrEqualTo';\nimport $ol$format$filter$Intersects from './ol/format/filter/Intersects';\nimport $ol$format$filter$IsBetween from './ol/format/filter/IsBetween';\nimport $ol$format$filter$IsLike from './ol/format/filter/IsLike';\nimport $ol$format$filter$IsNull from './ol/format/filter/IsNull';\nimport $ol$format$filter$LessThan from './ol/format/filter/LessThan';\nimport $ol$format$filter$LessThanOrEqualTo from './ol/format/filter/LessThanOrEqualTo';\nimport $ol$format$filter$Not from './ol/format/filter/Not';\nimport $ol$format$filter$NotEqualTo from './ol/format/filter/NotEqualTo';\nimport $ol$format$filter$Or from './ol/format/filter/Or';\nimport $ol$format$filter$Within from './ol/format/filter/Within';\nimport $ol$geom$Circle from './ol/geom/Circle';\nimport $ol$geom$Geometry from './ol/geom/Geometry';\nimport $ol$geom$GeometryCollection from './ol/geom/GeometryCollection';\nimport $ol$geom$LineString from './ol/geom/LineString';\nimport $ol$geom$LinearRing from './ol/geom/LinearRing';\nimport $ol$geom$MultiLineString from './ol/geom/MultiLineString';\nimport $ol$geom$MultiPoint from './ol/geom/MultiPoint';\nimport $ol$geom$MultiPolygon from './ol/geom/MultiPolygon';\nimport $ol$geom$Point from './ol/geom/Point';\nimport $ol$geom$Polygon from './ol/geom/Polygon';\nimport $ol$geom$SimpleGeometry from './ol/geom/SimpleGeometry';\nimport $ol$interaction$DoubleClickZoom from './ol/interaction/DoubleClickZoom';\nimport $ol$interaction$DragAndDrop from './ol/interaction/DragAndDrop';\nimport $ol$interaction$DragBox from './ol/interaction/DragBox';\nimport $ol$interaction$DragPan from './ol/interaction/DragPan';\nimport $ol$interaction$DragRotate from './ol/interaction/DragRotate';\nimport $ol$interaction$DragRotateAndZoom from './ol/interaction/DragRotateAndZoom';\nimport $ol$interaction$DragZoom from './ol/interaction/DragZoom';\nimport $ol$interaction$Draw from './ol/interaction/Draw';\nimport $ol$interaction$Extent from './ol/interaction/Extent';\nimport $ol$interaction$Interaction from './ol/interaction/Interaction';\nimport $ol$interaction$KeyboardPan from './ol/interaction/KeyboardPan';\nimport $ol$interaction$KeyboardZoom from './ol/interaction/KeyboardZoom';\nimport $ol$interaction$Modify from './ol/interaction/Modify';\nimport $ol$interaction$MouseWheelZoom from './ol/interaction/MouseWheelZoom';\nimport $ol$interaction$PinchRotate from './ol/interaction/PinchRotate';\nimport $ol$interaction$PinchZoom from './ol/interaction/PinchZoom';\nimport $ol$interaction$Pointer from './ol/interaction/Pointer';\nimport $ol$interaction$Select from './ol/interaction/Select';\nimport $ol$interaction$Snap from './ol/interaction/Snap';\nimport $ol$interaction$Translate from './ol/interaction/Translate';\nimport $ol$layer$Base from './ol/layer/Base';\nimport $ol$layer$Group from './ol/layer/Group';\nimport $ol$layer$Heatmap from './ol/layer/Heatmap';\nimport $ol$layer$Image from './ol/layer/Image';\nimport $ol$layer$Layer from './ol/layer/Layer';\nimport $ol$layer$Tile from './ol/layer/Tile';\nimport $ol$layer$Vector from './ol/layer/Vector';\nimport $ol$layer$VectorTile from './ol/layer/VectorTile';\nimport $ol$proj$Projection from './ol/proj/Projection';\nimport $ol$render$Feature from './ol/render/Feature';\nimport $ol$render$VectorContext from './ol/render/VectorContext';\nimport $ol$render$canvas$Immediate from './ol/render/canvas/Immediate';\nimport $ol$render$webgl$Immediate from './ol/render/webgl/Immediate';\nimport $ol$renderer$canvas$ImageLayer from './ol/renderer/canvas/ImageLayer';\nimport $ol$renderer$canvas$Map from './ol/renderer/canvas/Map';\nimport $ol$renderer$canvas$TileLayer from './ol/renderer/canvas/TileLayer';\nimport $ol$renderer$canvas$VectorLayer from './ol/renderer/canvas/VectorLayer';\nimport $ol$renderer$canvas$VectorTileLayer from './ol/renderer/canvas/VectorTileLayer';\nimport $ol$renderer$webgl$ImageLayer from './ol/renderer/webgl/ImageLayer';\nimport $ol$renderer$webgl$Map from './ol/renderer/webgl/Map';\nimport $ol$renderer$webgl$TileLayer from './ol/renderer/webgl/TileLayer';\nimport $ol$renderer$webgl$VectorLayer from './ol/renderer/webgl/VectorLayer';\nimport $ol$source$BingMaps from './ol/source/BingMaps';\nimport $ol$source$CartoDB from './ol/source/CartoDB';\nimport $ol$source$Cluster from './ol/source/Cluster';\nimport $ol$source$Image from './ol/source/Image';\nimport $ol$source$ImageArcGISRest from './ol/source/ImageArcGISRest';\nimport $ol$source$ImageCanvas from './ol/source/ImageCanvas';\nimport $ol$source$ImageMapGuide from './ol/source/ImageMapGuide';\nimport $ol$source$ImageStatic from './ol/source/ImageStatic';\nimport $ol$source$ImageWMS from './ol/source/ImageWMS';\nimport $ol$source$OSM from './ol/source/OSM';\nimport $ol$source$Raster from './ol/source/Raster';\nimport $ol$source$Source from './ol/source/Source';\nimport $ol$source$Stamen from './ol/source/Stamen';\nimport $ol$source$Tile from './ol/source/Tile';\nimport $ol$source$TileArcGISRest from './ol/source/TileArcGISRest';\nimport $ol$source$TileDebug from './ol/source/TileDebug';\nimport $ol$source$TileImage from './ol/source/TileImage';\nimport $ol$source$TileJSON from './ol/source/TileJSON';\nimport $ol$source$TileWMS from './ol/source/TileWMS';\nimport $ol$source$UTFGrid from './ol/source/UTFGrid';\nimport $ol$source$UrlTile from './ol/source/UrlTile';\nimport $ol$source$Vector from './ol/source/Vector';\nimport $ol$source$VectorTile from './ol/source/VectorTile';\nimport $ol$source$WMTS from './ol/source/WMTS';\nimport $ol$source$XYZ from './ol/source/XYZ';\nimport $ol$source$Zoomify from './ol/source/Zoomify';\nimport $ol$structs$LRUCache from './ol/structs/LRUCache';\nimport $ol$style$AtlasManager from './ol/style/AtlasManager';\nimport $ol$style$Circle from './ol/style/Circle';\nimport $ol$style$Fill from './ol/style/Fill';\nimport $ol$style$Icon from './ol/style/Icon';\nimport $ol$style$IconImageCache from './ol/style/IconImageCache';\nimport $ol$style$Image from './ol/style/Image';\nimport $ol$style$RegularShape from './ol/style/RegularShape';\nimport $ol$style$Stroke from './ol/style/Stroke';\nimport $ol$style$Style from './ol/style/Style';\nimport $ol$style$Text from './ol/style/Text';\nimport $ol$tilegrid$TileGrid from './ol/tilegrid/TileGrid';\nimport $ol$tilegrid$WMTS from './ol/tilegrid/WMTS';\nimport $ol$webgl$Context from './ol/webgl/Context';\nimport * as _ol from './ol';\nimport * as _ol_Observable from './ol/Observable';\nimport * as _ol_color from './ol/color';\nimport * as _ol_colorlike from './ol/colorlike';\nimport * as _ol_control from './ol/control';\nimport * as _ol_control_Attribution from './ol/control/Attribution';\nimport * as _ol_control_MousePosition from './ol/control/MousePosition';\nimport * as _ol_control_OverviewMap from './ol/control/OverviewMap';\nimport * as _ol_control_Rotate from './ol/control/Rotate';\nimport * as _ol_control_ScaleLine from './ol/control/ScaleLine';\nimport * as _ol_control_ZoomSlider from './ol/control/ZoomSlider';\nimport * as _ol_coordinate from './ol/coordinate';\nimport * as _ol_easing from './ol/easing';\nimport * as _ol_events_condition from './ol/events/condition';\nimport * as _ol_extent from './ol/extent';\nimport * as _ol_featureloader from './ol/featureloader';\nimport * as _ol_format_Polyline from './ol/format/Polyline';\nimport * as _ol_format_WFS from './ol/format/WFS';\nimport * as _ol_format_filter from './ol/format/filter';\nimport * as _ol_geom_Polygon from './ol/geom/Polygon';\nimport * as _ol_has from './ol/has';\nimport * as _ol_interaction from './ol/interaction';\nimport * as _ol_interaction_Draw from './ol/interaction/Draw';\nimport * as _ol_interaction_Pointer from './ol/interaction/Pointer';\nimport * as _ol_interaction_Translate from './ol/interaction/Translate';\nimport * as _ol_loadingstrategy from './ol/loadingstrategy';\nimport * as _ol_proj from './ol/proj';\nimport * as _ol_proj_Units from './ol/proj/Units';\nimport * as _ol_proj_proj4 from './ol/proj/proj4';\nimport * as _ol_render from './ol/render';\nimport * as _ol_render_canvas from './ol/render/canvas';\nimport * as _ol_size from './ol/size';\nimport * as _ol_source_OSM from './ol/source/OSM';\nimport * as _ol_source_WMTS from './ol/source/WMTS';\nimport * as _ol_sphere from './ol/sphere';\nimport * as _ol_style_IconImageCache from './ol/style/IconImageCache';\nimport * as _ol_tilegrid from './ol/tilegrid';\nimport * as _ol_tilegrid_WMTS from './ol/tilegrid/WMTS';\nimport * as _ol_xml from './ol/xml';\n\nvar ol = window['ol'] = {};\n\nol.color = {};\nol.colorlike = {};\nol.control = {};\nol.coordinate = {};\nol.easing = {};\nol.events = {};\nol.events.condition = {};\nol.extent = {};\nol.featureloader = {};\nol.format = {};\nol.format.filter = {};\nol.geom = {};\nol.has = {};\nol.interaction = {};\nol.layer = {};\nol.loadingstrategy = {};\nol.proj = {};\nol.proj.Units = {};\nol.proj.proj4 = {};\nol.render = {};\nol.render.canvas = {};\nol.renderer = {};\nol.renderer.canvas = {};\nol.renderer.webgl = {};\nol.size = {};\nol.source = {};\nol.sphere = {};\nol.style = {};\nol.style.IconImageCache = {};\nol.tilegrid = {};\nol.xml = {};\nol.Collection = $ol$Collection;\nol.Feature = $ol$Feature;\nol.Geolocation = $ol$Geolocation;\nol.Graticule = $ol$Graticule;\nol.Kinetic = $ol$Kinetic;\nol.Map = $ol$Map;\nol.Object = $ol$Object;\nol.Observable = $ol$Observable;\nol.Observable.unByKey = _ol_Observable.unByKey;\nol.Overlay = $ol$Overlay;\nol.PluggableMap = $ol$PluggableMap;\nol.View = $ol$View;\nol.WebGLMap = $ol$WebGLMap;\nol.color.asArray = _ol_color.asArray;\nol.color.asString = _ol_color.asString;\nol.colorlike.asColorLike = _ol_colorlike.asColorLike;\nol.control.Attribution = $ol$control$Attribution;\nol.control.Attribution.render = _ol_control_Attribution.render;\nol.control.Control = $ol$control$Control;\nol.control.FullScreen = $ol$control$FullScreen;\nol.control.MousePosition = $ol$control$MousePosition;\nol.control.MousePosition.render = _ol_control_MousePosition.render;\nol.control.OverviewMap = $ol$control$OverviewMap;\nol.control.OverviewMap.render = _ol_control_OverviewMap.render;\nol.control.Rotate = $ol$control$Rotate;\nol.control.Rotate.render = _ol_control_Rotate.render;\nol.control.ScaleLine = $ol$control$ScaleLine;\nol.control.ScaleLine.render = _ol_control_ScaleLine.render;\nol.control.Zoom = $ol$control$Zoom;\nol.control.ZoomSlider = $ol$control$ZoomSlider;\nol.control.ZoomSlider.render = _ol_control_ZoomSlider.render;\nol.control.ZoomToExtent = $ol$control$ZoomToExtent;\nol.control.defaults = _ol_control.defaults;\nol.coordinate.add = _ol_coordinate.add;\nol.coordinate.createStringXY = _ol_coordinate.createStringXY;\nol.coordinate.format = _ol_coordinate.format;\nol.coordinate.rotate = _ol_coordinate.rotate;\nol.coordinate.toStringHDMS = _ol_coordinate.toStringHDMS;\nol.coordinate.toStringXY = _ol_coordinate.toStringXY;\nol.easing.easeIn = _ol_easing.easeIn;\nol.easing.easeOut = _ol_easing.easeOut;\nol.easing.inAndOut = _ol_easing.inAndOut;\nol.easing.linear = _ol_easing.linear;\nol.easing.upAndDown = _ol_easing.upAndDown;\nol.events.condition.altKeyOnly = _ol_events_condition.altKeyOnly;\nol.events.condition.altShiftKeysOnly = _ol_events_condition.altShiftKeysOnly;\nol.events.condition.always = _ol_events_condition.always;\nol.events.condition.click = _ol_events_condition.click;\nol.events.condition.doubleClick = _ol_events_condition.doubleClick;\nol.events.condition.focus = _ol_events_condition.focus;\nol.events.condition.mouseOnly = _ol_events_condition.mouseOnly;\nol.events.condition.never = _ol_events_condition.never;\nol.events.condition.noModifierKeys = _ol_events_condition.noModifierKeys;\nol.events.condition.platformModifierKeyOnly = _ol_events_condition.platformModifierKeyOnly;\nol.events.condition.pointerMove = _ol_events_condition.pointerMove;\nol.events.condition.primaryAction = _ol_events_condition.primaryAction;\nol.events.condition.shiftKeyOnly = _ol_events_condition.shiftKeyOnly;\nol.events.condition.singleClick = _ol_events_condition.singleClick;\nol.events.condition.targetNotEditable = _ol_events_condition.targetNotEditable;\nol.extent.applyTransform = _ol_extent.applyTransform;\nol.extent.boundingExtent = _ol_extent.boundingExtent;\nol.extent.buffer = _ol_extent.buffer;\nol.extent.containsCoordinate = _ol_extent.containsCoordinate;\nol.extent.containsExtent = _ol_extent.containsExtent;\nol.extent.containsXY = _ol_extent.containsXY;\nol.extent.createEmpty = _ol_extent.createEmpty;\nol.extent.equals = _ol_extent.equals;\nol.extent.extend = _ol_extent.extend;\nol.extent.getArea = _ol_extent.getArea;\nol.extent.getBottomLeft = _ol_extent.getBottomLeft;\nol.extent.getBottomRight = _ol_extent.getBottomRight;\nol.extent.getCenter = _ol_extent.getCenter;\nol.extent.getHeight = _ol_extent.getHeight;\nol.extent.getIntersection = _ol_extent.getIntersection;\nol.extent.getSize = _ol_extent.getSize;\nol.extent.getTopLeft = _ol_extent.getTopLeft;\nol.extent.getTopRight = _ol_extent.getTopRight;\nol.extent.getWidth = _ol_extent.getWidth;\nol.extent.intersects = _ol_extent.intersects;\nol.extent.isEmpty = _ol_extent.isEmpty;\nol.featureloader.xhr = _ol_featureloader.xhr;\nol.format.EsriJSON = $ol$format$EsriJSON;\nol.format.Feature = $ol$format$Feature;\nol.format.GML = $ol$format$GML;\nol.format.GML2 = $ol$format$GML2;\nol.format.GML3 = $ol$format$GML3;\nol.format.GPX = $ol$format$GPX;\nol.format.GeoJSON = $ol$format$GeoJSON;\nol.format.IGC = $ol$format$IGC;\nol.format.KML = $ol$format$KML;\nol.format.MVT = $ol$format$MVT;\nol.format.OSMXML = $ol$format$OSMXML;\nol.format.Polyline = $ol$format$Polyline;\nol.format.Polyline.decodeDeltas = _ol_format_Polyline.decodeDeltas;\nol.format.Polyline.decodeFloats = _ol_format_Polyline.decodeFloats;\nol.format.Polyline.encodeDeltas = _ol_format_Polyline.encodeDeltas;\nol.format.Polyline.encodeFloats = _ol_format_Polyline.encodeFloats;\nol.format.TopoJSON = $ol$format$TopoJSON;\nol.format.WFS = $ol$format$WFS;\nol.format.WFS.writeFilter = _ol_format_WFS.writeFilter;\nol.format.WKT = $ol$format$WKT;\nol.format.WMSCapabilities = $ol$format$WMSCapabilities;\nol.format.WMSGetFeatureInfo = $ol$format$WMSGetFeatureInfo;\nol.format.WMTSCapabilities = $ol$format$WMTSCapabilities;\nol.format.filter.Bbox = $ol$format$filter$Bbox;\nol.format.filter.Contains = $ol$format$filter$Contains;\nol.format.filter.During = $ol$format$filter$During;\nol.format.filter.EqualTo = $ol$format$filter$EqualTo;\nol.format.filter.GreaterThan = $ol$format$filter$GreaterThan;\nol.format.filter.GreaterThanOrEqualTo = $ol$format$filter$GreaterThanOrEqualTo;\nol.format.filter.Intersects = $ol$format$filter$Intersects;\nol.format.filter.IsBetween = $ol$format$filter$IsBetween;\nol.format.filter.IsLike = $ol$format$filter$IsLike;\nol.format.filter.IsNull = $ol$format$filter$IsNull;\nol.format.filter.LessThan = $ol$format$filter$LessThan;\nol.format.filter.LessThanOrEqualTo = $ol$format$filter$LessThanOrEqualTo;\nol.format.filter.Not = $ol$format$filter$Not;\nol.format.filter.NotEqualTo = $ol$format$filter$NotEqualTo;\nol.format.filter.Or = $ol$format$filter$Or;\nol.format.filter.Within = $ol$format$filter$Within;\nol.format.filter.and = _ol_format_filter.and;\nol.format.filter.bbox = _ol_format_filter.bbox;\nol.format.filter.between = _ol_format_filter.between;\nol.format.filter.contains = _ol_format_filter.contains;\nol.format.filter.during = _ol_format_filter.during;\nol.format.filter.equalTo = _ol_format_filter.equalTo;\nol.format.filter.greaterThan = _ol_format_filter.greaterThan;\nol.format.filter.greaterThanOrEqualTo = _ol_format_filter.greaterThanOrEqualTo;\nol.format.filter.intersects = _ol_format_filter.intersects;\nol.format.filter.isNull = _ol_format_filter.isNull;\nol.format.filter.lessThan = _ol_format_filter.lessThan;\nol.format.filter.lessThanOrEqualTo = _ol_format_filter.lessThanOrEqualTo;\nol.format.filter.like = _ol_format_filter.like;\nol.format.filter.not = _ol_format_filter.not;\nol.format.filter.notEqualTo = _ol_format_filter.notEqualTo;\nol.format.filter.or = _ol_format_filter.or;\nol.format.filter.within = _ol_format_filter.within;\nol.geom.Circle = $ol$geom$Circle;\nol.geom.Geometry = $ol$geom$Geometry;\nol.geom.GeometryCollection = $ol$geom$GeometryCollection;\nol.geom.LineString = $ol$geom$LineString;\nol.geom.LinearRing = $ol$geom$LinearRing;\nol.geom.MultiLineString = $ol$geom$MultiLineString;\nol.geom.MultiPoint = $ol$geom$MultiPoint;\nol.geom.MultiPolygon = $ol$geom$MultiPolygon;\nol.geom.Point = $ol$geom$Point;\nol.geom.Polygon = $ol$geom$Polygon;\nol.geom.Polygon.circular = _ol_geom_Polygon.circular;\nol.geom.Polygon.fromCircle = _ol_geom_Polygon.fromCircle;\nol.geom.Polygon.fromExtent = _ol_geom_Polygon.fromExtent;\nol.geom.SimpleGeometry = $ol$geom$SimpleGeometry;\nol.has.DEVICE_PIXEL_RATIO = _ol_has.DEVICE_PIXEL_RATIO;\nol.has.GEOLOCATION = _ol_has.GEOLOCATION;\nol.has.TOUCH = _ol_has.TOUCH;\nol.inherits = _ol.inherits;\nol.interaction.DoubleClickZoom = $ol$interaction$DoubleClickZoom;\nol.interaction.DragAndDrop = $ol$interaction$DragAndDrop;\nol.interaction.DragBox = $ol$interaction$DragBox;\nol.interaction.DragPan = $ol$interaction$DragPan;\nol.interaction.DragRotate = $ol$interaction$DragRotate;\nol.interaction.DragRotateAndZoom = $ol$interaction$DragRotateAndZoom;\nol.interaction.DragZoom = $ol$interaction$DragZoom;\nol.interaction.Draw = $ol$interaction$Draw;\nol.interaction.Draw.createBox = _ol_interaction_Draw.createBox;\nol.interaction.Draw.createRegularPolygon = _ol_interaction_Draw.createRegularPolygon;\nol.interaction.Draw.handleEvent = _ol_interaction_Draw.handleEvent;\nol.interaction.Extent = $ol$interaction$Extent;\nol.interaction.Interaction = $ol$interaction$Interaction;\nol.interaction.KeyboardPan = $ol$interaction$KeyboardPan;\nol.interaction.KeyboardZoom = $ol$interaction$KeyboardZoom;\nol.interaction.Modify = $ol$interaction$Modify;\nol.interaction.MouseWheelZoom = $ol$interaction$MouseWheelZoom;\nol.interaction.PinchRotate = $ol$interaction$PinchRotate;\nol.interaction.PinchZoom = $ol$interaction$PinchZoom;\nol.interaction.Pointer = $ol$interaction$Pointer;\nol.interaction.Pointer.handleEvent = _ol_interaction_Pointer.handleEvent;\nol.interaction.Select = $ol$interaction$Select;\nol.interaction.Snap = $ol$interaction$Snap;\nol.interaction.Translate = $ol$interaction$Translate;\nol.interaction.defaults = _ol_interaction.defaults;\nol.layer.Base = $ol$layer$Base;\nol.layer.Group = $ol$layer$Group;\nol.layer.Heatmap = $ol$layer$Heatmap;\nol.layer.Image = $ol$layer$Image;\nol.layer.Tile = $ol$layer$Tile;\nol.layer.Vector = $ol$layer$Vector;\nol.layer.VectorTile = $ol$layer$VectorTile;\nol.loadingstrategy.all = _ol_loadingstrategy.all;\nol.loadingstrategy.bbox = _ol_loadingstrategy.bbox;\nol.loadingstrategy.tile = _ol_loadingstrategy.tile;\nol.proj.Projection = $ol$proj$Projection;\nol.proj.Units.METERS_PER_UNIT = _ol_proj_Units.METERS_PER_UNIT;\nol.proj.addCoordinateTransforms = _ol_proj.addCoordinateTransforms;\nol.proj.addEquivalentProjections = _ol_proj.addEquivalentProjections;\nol.proj.addProjection = _ol_proj.addProjection;\nol.proj.equivalent = _ol_proj.equivalent;\nol.proj.fromLonLat = _ol_proj.fromLonLat;\nol.proj.get = _ol_proj.get;\nol.proj.getPointResolution = _ol_proj.getPointResolution;\nol.proj.getTransform = _ol_proj.getTransform;\nol.proj.proj4.register = _ol_proj_proj4.register;\nol.proj.toLonLat = _ol_proj.toLonLat;\nol.proj.transform = _ol_proj.transform;\nol.proj.transformExtent = _ol_proj.transformExtent;\nol.render.VectorContext = $ol$render$VectorContext;\nol.render.canvas.labelCache = _ol_render_canvas.labelCache;\nol.render.toContext = _ol_render.toContext;\nol.renderer.canvas.ImageLayer = $ol$renderer$canvas$ImageLayer;\nol.renderer.canvas.Map = $ol$renderer$canvas$Map;\nol.renderer.canvas.TileLayer = $ol$renderer$canvas$TileLayer;\nol.renderer.canvas.VectorLayer = $ol$renderer$canvas$VectorLayer;\nol.renderer.canvas.VectorTileLayer = $ol$renderer$canvas$VectorTileLayer;\nol.renderer.webgl.ImageLayer = $ol$renderer$webgl$ImageLayer;\nol.renderer.webgl.Map = $ol$renderer$webgl$Map;\nol.renderer.webgl.TileLayer = $ol$renderer$webgl$TileLayer;\nol.renderer.webgl.VectorLayer = $ol$renderer$webgl$VectorLayer;\nol.size.toSize = _ol_size.toSize;\nol.source.BingMaps = $ol$source$BingMaps;\nol.source.CartoDB = $ol$source$CartoDB;\nol.source.Cluster = $ol$source$Cluster;\nol.source.Image = $ol$source$Image;\nol.source.ImageArcGISRest = $ol$source$ImageArcGISRest;\nol.source.ImageCanvas = $ol$source$ImageCanvas;\nol.source.ImageMapGuide = $ol$source$ImageMapGuide;\nol.source.ImageStatic = $ol$source$ImageStatic;\nol.source.ImageWMS = $ol$source$ImageWMS;\nol.source.OSM = $ol$source$OSM;\nol.source.OSM.ATTRIBUTION = _ol_source_OSM.ATTRIBUTION;\nol.source.Raster = $ol$source$Raster;\nol.source.Source = $ol$source$Source;\nol.source.Stamen = $ol$source$Stamen;\nol.source.Tile = $ol$source$Tile;\nol.source.TileArcGISRest = $ol$source$TileArcGISRest;\nol.source.TileDebug = $ol$source$TileDebug;\nol.source.TileImage = $ol$source$TileImage;\nol.source.TileJSON = $ol$source$TileJSON;\nol.source.TileWMS = $ol$source$TileWMS;\nol.source.UTFGrid = $ol$source$UTFGrid;\nol.source.Vector = $ol$source$Vector;\nol.source.VectorTile = $ol$source$VectorTile;\nol.source.WMTS = $ol$source$WMTS;\nol.source.WMTS.optionsFromCapabilities = _ol_source_WMTS.optionsFromCapabilities;\nol.source.XYZ = $ol$source$XYZ;\nol.source.Zoomify = $ol$source$Zoomify;\nol.sphere.getArea = _ol_sphere.getArea;\nol.sphere.getDistance = _ol_sphere.getDistance;\nol.sphere.getLength = _ol_sphere.getLength;\nol.style.AtlasManager = $ol$style$AtlasManager;\nol.style.Circle = $ol$style$Circle;\nol.style.Fill = $ol$style$Fill;\nol.style.Icon = $ol$style$Icon;\nol.style.IconImageCache.shared = _ol_style_IconImageCache.shared;\nol.style.Image = $ol$style$Image;\nol.style.RegularShape = $ol$style$RegularShape;\nol.style.Stroke = $ol$style$Stroke;\nol.style.Style = $ol$style$Style;\nol.style.Text = $ol$style$Text;\nol.tilegrid.TileGrid = $ol$tilegrid$TileGrid;\nol.tilegrid.WMTS = $ol$tilegrid$WMTS;\nol.tilegrid.WMTS.createFromCapabilitiesMatrixSet = _ol_tilegrid_WMTS.createFromCapabilitiesMatrixSet;\nol.tilegrid.createXYZ = _ol_tilegrid.createXYZ;\nol.xml.getAllTextContent = _ol_xml.getAllTextContent;\nol.xml.parse = _ol_xml.parse;\n","/**\n * @module ol/proj/proj4\n */\nimport {addCoordinateTransforms, addProjection, addEquivalentProjections, get} from '../proj.js';\nimport {get as getTransform} from './transforms.js';\nimport Projection from './Projection.js';\n\n/**\n * Make projections defined in proj4 (with `proj4.defs()`) available in\n * OpenLayers.\n *\n * This function should be called whenever changes are made to the proj4\n * registry, e.g. after calling `proj4.defs()`. Existing transforms will not be\n * modified by this function.\n *\n * @param {?} proj4 Proj4.\n * @api\n */\nexport function register(proj4) {\n  const projCodes = Object.keys(proj4.defs);\n  const len = projCodes.length;\n  let i, j;\n  for (i = 0; i < len; ++i) {\n    const code = projCodes[i];\n    if (!get(code)) {\n      const def = proj4.defs(code);\n      addProjection(new Projection({\n        code: code,\n        axisOrientation: def.axis,\n        metersPerUnit: def.to_meter,\n        units: def.units\n      }));\n    }\n  }\n  for (i = 0; i < len; ++i) {\n    const code1 = projCodes[i];\n    const proj1 = get(code1);\n    for (j = 0; j < len; ++j) {\n      const code2 = projCodes[j];\n      const proj2 = get(code2);\n      if (!getTransform(code1, code2)) {\n        if (proj4.defs[code1] === proj4.defs[code2]) {\n          addEquivalentProjections([proj1, proj2]);\n        } else {\n          const transform = proj4(code1, code2);\n          addCoordinateTransforms(proj1, proj2, transform.forward, transform.inverse);\n        }\n      }\n    }\n  }\n}\n","/**\n * @module ol/render\n */\nimport {DEVICE_PIXEL_RATIO} from './has.js';\nimport {create as createTransform, scale as scaleTransform} from './transform.js';\nimport CanvasImmediateRenderer from './render/canvas/Immediate.js';\n\n\n/**\n * @typedef {Object} State\n * @property {CanvasRenderingContext2D} context Canvas context that the layer is being rendered to.\n * @property {module:ol/Feature|module:ol/render/Feature} feature\n * @property {module:ol/geom/SimpleGeometry} geometry\n * @property {number} pixelRatio Pixel ratio used by the layer renderer.\n * @property {number} resolution Resolution that the render batch was created and optimized for.\n * This is not the view's resolution that is being rendered.\n * @property {number} rotation Rotation of the rendered layer in radians.\n */\n\n\n/**\n * A function to be used when sorting features before rendering.\n * It takes two instances of {@link module:ol/Feature} or\n * {@link module:ol/render/Feature} and returns a `{number}`.\n *\n * @typedef {function((module:ol/Feature|module:ol/render/Feature),\n *           (module:ol/Feature|module:ol/render/Feature)):number} OrderFunction\n */\n\n\n/**\n * @typedef {Object} ToContextOptions\n * @property {module:ol/size~Size} [size] Desired size of the canvas in css\n * pixels. When provided, both canvas and css size will be set according to the\n * `pixelRatio`. If not provided, the current canvas and css sizes will not be\n * altered.\n * @property {number} [pixelRatio=window.devicePixelRatio] Pixel ratio (canvas\n * pixel to css pixel ratio) for the canvas.\n */\n\n\n/**\n * Binds a Canvas Immediate API to a canvas context, to allow drawing geometries\n * to the context's canvas.\n *\n * The units for geometry coordinates are css pixels relative to the top left\n * corner of the canvas element.\n * ```js\n * import {toContext} from 'ol/render';\n * import Fill from 'ol/style/Fill';\n * import Polygon from 'ol/geom/Polygon';\n *\n * var canvas = document.createElement('canvas');\n * var render = toContext(canvas.getContext('2d'),\n *     { size: [100, 100] });\n * render.setFillStrokeStyle(new Fill({ color: blue }));\n * render.drawPolygon(\n *     new Polygon([[[0, 0], [100, 100], [100, 0], [0, 0]]]));\n * ```\n *\n * @param {CanvasRenderingContext2D} context Canvas context.\n * @param {module:ol/render~ToContextOptions=} opt_options Options.\n * @return {module:ol/render/canvas/Immediate} Canvas Immediate.\n * @api\n */\nexport function toContext(context, opt_options) {\n  const canvas = context.canvas;\n  const options = opt_options ? opt_options : {};\n  const pixelRatio = options.pixelRatio || DEVICE_PIXEL_RATIO;\n  const size = options.size;\n  if (size) {\n    canvas.width = size[0] * pixelRatio;\n    canvas.height = size[1] * pixelRatio;\n    canvas.style.width = size[0] + 'px';\n    canvas.style.height = size[1] + 'px';\n  }\n  const extent = [0, 0, canvas.width, canvas.height];\n  const transform = scaleTransform(createTransform(), pixelRatio, pixelRatio);\n  return new CanvasImmediateRenderer(context, pixelRatio, extent, transform, 0);\n}\n"],"names":["let","uidCounter_","getUid","obj","ol_uid","const","AssertionError","code","message","split","super","this","name","Error","assign","Object","target","var_sources","TypeError","output","i","ii","arguments","length","source","key","hasOwnProperty","clear","object","property","getValues","values","push","isEmpty","findListener","listeners","listener","opt_this","opt_setDeleteIndex","listenerObj","bindTo","deleteIndex","getListeners","type","listenerMap","ol_lm","undefined","getListenerMap","removeListeners","removeEventListener","boundListener","keys","listen","opt_once","callOnce","addEventListener","evt","unlistenByKey","call","listenOnce","unlisten","indexOf","splice","unlistenAll","TRUE","FALSE","UNDEFINED","Disposable","dispose","disposed_","disposeInternal","prototype","Event","propagationStopped","stopPropagation","preventDefault","EventTarget","pendingRemovals_","dispatching_","listeners_","dispatchEvent","event","propagate","pendingRemovals","hasListener","opt_type","index","CHANGE","CLEAR","CONTEXTMENU","CLICK","DBLCLICK","DRAGENTER","DRAGOVER","DROP","ERROR","KEYDOWN","KEYPRESS","LOAD","MOUSEDOWN","MOUSEMOVE","MOUSEOUT","MOUSEUP","MOUSEWHEEL","MSPOINTERDOWN","RESIZE","TOUCHSTART","TOUCHMOVE","TOUCHEND","WHEEL","Observable","revision_","changed","EventType","getRevision","on","Array","isArray","len","once","un","ObjectEvent","oldValue","BaseObject","opt_values","values_","setProperties","get","value","getKeys","getProperties","notify","eventType","getChangeEventType","ObjectEventType","set","opt_silent","unset","changeEventTypeCache","Property","CollectionEvent","opt_element","element","Collection","opt_array","opt_options","options","unique_","unique","array_","assertUnique_","updateLength_","getLength","pop","extend","arr","forEach","f","array","getArray","item","insertAt","elem","CollectionEventType","removeAt","n","remove","prev","setAt","j","opt_except","assert","assertion","errorCode","BOTTOM_LEFT","BOTTOM_RIGHT","TOP_LEFT","TOP_RIGHT","UNKNOWN","INTERSECTING","ABOVE","RIGHT","BELOW","LEFT","boundingExtent","coordinates","extent","createEmpty","extendCoordinate","buffer","opt_extent","clone","slice","closestSquaredDistanceXY","x","y","dx","dy","containsCoordinate","coordinate","containsXY","containsExtent","extent1","extent2","coordinateRelationship","minX","minY","maxX","maxY","relationship","Relationship","Infinity","createOrUpdate","createOrUpdateEmpty","createOrUpdateFromCoordinate","createOrUpdateFromCoordinates","extendCoordinates","createOrUpdateFromFlatCoordinates","flatCoordinates","offset","end","stride","extendFlatCoordinates","equals","extendXY","Math","min","max","forEachCorner","callback","val","getBottomLeft","getBottomRight","getTopRight","getTopLeft","getArea","area","getWidth","getHeight","getCenter","getForViewAndSize","center","resolution","rotation","size","cosRotation","cos","sinRotation","sin","xCos","xSin","yCos","ySin","x0","x1","x2","x3","y0","y1","y2","y3","getIntersection","intersection","intersects","scaleFromCenter","deltaX","deltaY","applyTransform","transformFn","xs","ys","apply","transform2D","transform","opt_dest","dest","translate","k","clamp","cosh","exp","squaredSegmentDistance","t","squaredDistance","toDegrees","angleInRadians","PI","toRadians","angleInDegrees","modulo","a","b","r","lerp","POINT","LINE_STRING","LINEAR_RING","POLYGON","MULTI_POINT","MULTI_LINE_STRING","MULTI_POLYGON","GEOMETRY_COLLECTION","CIRCLE","DEFAULT_RADIUS","getDistance","c1","c2","opt_radius","radius","lat1","lat2","deltaLatBy2","deltaLonBy2","atan2","sqrt","getLengthInternal","getAreaInternal","Units","DEGREES","FEET","METERS","PIXELS","TILE_PIXELS","USFEET","METERS_PER_UNIT","Projection","code_","units_","extent_","worldExtent_","worldExtent","axisOrientation_","axisOrientation","global_","global","canWrapX_","getPointResolutionFunc_","getPointResolution","defaultTileGrid_","metersPerUnit_","metersPerUnit","canWrapX","getCode","getExtent","getUnits","getMetersPerUnit","getWorldExtent","getAxisOrientation","isGlobal","setGlobal","getDefaultTileGrid","setDefaultTileGrid","tileGrid","setExtent","setWorldExtent","setGetPointResolution","func","getPointResolutionFunc","RADIUS","HALF_SIZE","EXTENT","WORLD_EXTENT","EPSG3857Projection","units","point","PROJECTIONS","fromEPSG4326","input","opt_output","opt_dimension","dimension","halfSize","log","tan","toEPSG4326","atan","EPSG4326Projection","opt_axisOrientation","cache","projections2","forwardTransform","inverseTransform","transforms","add","destination","sourceCode","destinationCode","cloneTransform","identityTransform","addProjection","projection","addTransformFunc","projectionLike","opt_units","pointResolution","getter","getTransformFromProjections","vertices","addEquivalentProjections","projections","createProjection","defaultCode","createTransformFromCoordinateTransform","coordTransform","addCoordinateTransforms","forward","inverse","sourceProj","destProj","equivalent","projection1","projection2","equalUnits","sourceProjection","destinationProjection","transformFunc","getTransformFunc","getTransform","transformExtent","EPSG3857_PROJECTIONS","EPSG4326_PROJECTIONS","tmp_","reset","multiply","transform1","transform2","a1","b1","d1","e1","f1","a2","b2","d2","e2","f2","c","d","e","setFromArray","rotate","angle","scale","compose","dx1","dy1","sx","sy","dx2","dy2","invert","mat","det","tmpTransform","Geometry","extentRevision_","simplifiedGeometryCache","simplifiedGeometryMaxMinSquaredTolerance","simplifiedGeometryRevision","closestPointXY","closestPoint","minSquaredDistance","getClosestPoint","opt_closestPoint","NaN","intersectsCoordinate","computeExtent","anchor","opt_sy","opt_anchor","simplify","tolerance","getSimplifiedGeometry","squaredTolerance","getType","intersectsExtent","getProjection","inCoordinates","outCoordinates","pixelExtent","projectedExtent","composeTransform","HEX_COLOR_RE_","NAMED_COLOR_RE_","asString","color","toString","cacheSize","fromString","s","g","exec","el","document","createElement","style","body","appendChild","rgb","getComputedStyle","removeChild","fromNamed","hasAlpha","parseInt","substr","normalize","map","Number","fromStringInternal_","asArray","asColorLike","CanvasPattern","CanvasGradient","createCanvasContext2D","opt_width","opt_height","canvas","width","height","getContext","replaceNode","newNode","oldNode","parent","parentNode","replaceChild","removeNode","node","removeChildren","lastChild","MAX_TEXTURE_SIZE","EXTENSIONS","ARRAY_BUFFER","FLOAT","TEXTURE_WRAP_S","TEXTURE_WRAP_T","TEXTURE_2D","CLAMP_TO_EDGE","FRAMEBUFFER","CONTEXT_IDS","opt_attributes","context","window","gl","failIfMajorPerformanceCaveat","getParameter","getSupportedExtensions","ua","navigator","userAgent","toLowerCase","FIREFOX","SAFARI","WEBKIT","MAC","DEVICE_PIXEL_RATIO","devicePixelRatio","CANVAS_LINE_DASH","has","setLineDash","GEOLOCATION","TOUCH","POINTER","MSPOINTER","IDLE","LOADING","LOADED","CLASS_HIDDEN","CLASS_UNSELECTABLE","CLASS_CONTROL","CLASS_COLLAPSED","getFontFamilies","font","family","fontFamily","LRUCache","opt_highWaterMark","highWaterMark","count_","entries_","oldest_","newest_","canExpireCache","getCount","containsKey","entry","value_","key_","newer","older","peekLast","peekLastKey","peekFirstKey","replace","setSize","prune","defaultFont","defaultFillStyle","defaultLineCap","defaultLineDash","defaultLineJoin","defaultStrokeStyle","defaultTextAlign","defaultPadding","labelCache","checkedFonts","measureContext","textHeights","checkFont","interval","referenceWidth","retries","checked","referenceFonts","text","isAvailable","getMeasureContext","available","referenceFont","measureText","check","done","clearInterval","fontSpec","fontFamilies","setInterval","span","heights","measureTextHeight","textContent","margin","padding","position","left","offsetHeight","measureTextWidth","rotateAtOffset","offsetX","offsetY","resetTransform","drawImage","opacity","image","originX","originY","w","h","alpha","globalAlpha","setTransform","ImageStyle","opacity_","rotateWithView_","rotateWithView","rotation_","scale_","snapToPixel_","snapToPixel","getOpacity","getRotateWithView","getRotation","getScale","getSnapToPixel","getAnchor","getImage","pixelRatio","getHitDetectionImage","getImageState","getImageSize","getHitDetectionImageSize","getOrigin","getSize","setOpacity","setRotateWithView","setRotation","setScale","setSnapToPixel","listenImageChange","thisArg","load","unlistenImageChange","RegularShape","checksums_","canvas_","hitDetectionCanvas_","fill_","fill","origin_","points_","points","radius_","radius1","radius2_","radius2","angle_","stroke_","stroke","anchor_","size_","imageSize_","hitDetectionImageSize_","atlasManager_","atlasManager","render_","getFill","getPoints","getRadius","getRadius2","getAngle","getStroke","ImageState","imageSize","strokeStyle","lineCap","lineJoin","miterLimit","lineDash","lineDashOffset","strokeWidth","getColor","getLineDash","getLineDashOffset","getLineJoin","getLineCap","getMiterLimit","renderOptions","draw_","createHitDetectionCanvas_","round","renderHitDetectionCallback","hasCustomHitDetectionImage","drawHitDetectionCanvas_","bind","id","getChecksum","info","hitImage","angle0","radiusC","beginPath","arc","lineTo","fillStyle","lineWidth","closePath","strokeChecksum","fillChecksum","checksum","CircleStyle","setRadius","Fill","color_","checksum_","setColor","Stroke","lineCap_","lineDash_","lineDashOffset_","lineJoin_","miterLimit_","width_","setLineCap","setLineDashOffset","setLineJoin","setMiterLimit","setWidth","Style","geometry_","geometryFunction_","defaultGeometryFunction","geometry","setGeometry","image_","renderer_","renderer","text_","zIndex_","zIndex","getGeometry","getText","getZIndex","getRenderer","setRenderer","getGeometryFunction","setFill","setImage","setStroke","setText","feature","setZIndex","defaultStyles","createDefaultStyle","createEditingStyle","styles","white","blue","GeometryType","concat","Feature","opt_geometryOrProperties","id_","geometryName_","style_","styleFunction_","geometryChangeKey_","handleGeometryChanged_","properties","setGeometryName","getGeometryName","getStyle","setStyle","getId","getStyleFunction","handleGeometryChange_","createStyleFunction","setId","numberSafeCompareFunction","includes","linearFindNearest","direction","reverseSubArray","begin","tmp","data","extension","find","arr1","arr2","len1","stableSort","compareFnc","sort","findIndex","every","idx","XY","XYZ","XYM","XYZM","SimpleGeometry","layout","GeometryLayout","getCoordinates","getFirstCoordinate","getFlatCoordinates","getLastCoordinate","getLayout","simplifiedGeometry","getSimplifiedGeometryInternal","getStride","setFlatCoordinates","getStrideForLayout","setCoordinates","opt_layout","setLayout","nesting","getLayoutForStride","anchorX","anchorY","linearRing","twiceArea","linearRings","ends","assignClosest","offset1","offset2","maxSquaredDelta","squaredDelta","squaredDx","arrayMaxSquaredDelta","assignClosestPoint","maxDelta","isRing","opt_tmpPoint","tmpPoint","assignClosestArrayPoint","deflateCoordinate","deflateCoordinates","deflateCoordinatesArray","coordinatess","opt_ends","jj","inflateCoordinates","opt_coordinates","inflateCoordinatesArray","opt_coordinatess","inflateMultiCoordinatesArray","endss","opt_coordinatesss","coordinatesss","douglasPeucker","simplifiedFlatCoordinates","simplifiedOffset","markers","stack","last","first","maxSquaredDistance","snap","quantize","quantizeArray","simplifiedEnds","LinearRing","maxDelta_","maxDeltaRevision_","linearRingArea","Point","linearRingContainsExtent","linearRingContainsXY","wn","linearRingsContainsXY","getInteriorPointOfArray","flatCenters","flatCentersOffset","intersections","rr","pointX","maxSegmentLength","segmentLength","abs","isNaN","getInteriorPointsOfMultiArray","interiorPoints","ret","point1","point2","intersectsLineString","coordinatesExtent","forEachSegment","start","startRel","endRel","startX","startY","endX","endY","slope","intersectsSegment","intersectsLinearRingArray","linearRingIsClockwise","edge","linearRingIsOriented","opt_right","right","isClockwise","orientLinearRings","reverseCoordinates","orientLinearRingsArray","Polygon","ends_","flatInteriorPointRevision_","flatInteriorPoint_","orientedRevision_","orientedFlatCoordinates_","appendLinearRing","getOrientedFlatCoordinates","linearRingsArea","getEnds","getFlatInteriorPoint","flatCenter","getInteriorPoint","getLinearRingCount","getLinearRing","getLinearRings","circular","opt_n","opt_sphereRadius","distance","bearing","lon1","dByR","lat","asin","fromExtent","fromCircle","circle","opt_sides","opt_angle","sides","arrayLength","polygon","makeRegular","startAngle","Geolocation","position_","transform_","watchId_","GeolocationProperty","handleProjectionChanged_","handleTrackingChanged_","setProjection","trackingOptions","setTrackingOptions","setTracking","tracking","getTracking","geolocation","watchPosition","positionChange_","positionError_","getTrackingOptions","clearWatch","coords","accuracy","altitude","altitudeAccuracy","heading","longitude","latitude","projectedPosition","speed","circularPolygon","error","getAccuracy","getAccuracyGeometry","getAltitude","getAltitudeAccuracy","getHeading","getPosition","getSpeed","padNumber","number","opt_precision","numberString","toFixed","decimal","join","compareVersions","v1","v2","s1","s2","n1","n2","delta","closestOnSegment","segment","along","degreesToStringHDMS","hemispheres","degrees","opt_fractionDigits","normalizedDegrees","dflPrecision","precision","pow","deg","floor","sec","ceil","charAt","format","template","coordinate1","coordinate2","cosAngle","sinAngle","coord1","coord2","squaredDistanceToSegment","toStringXY","interpolatePoint","fraction","pointY","cumulativeLengths","haystack","needle","opt_comparator","mid","cmp","comparator","low","high","found","binarySearch","o","lineStringCoordinateAtM","m","extrapolate","lo","hi","m0","lineStringLength","LineString","flatMidpoint_","flatMidpointRevision_","appendCoordinate","getCoordinateAtM","opt_extrapolate","getCoordinateAt","getFlatMidpoint","line","interpolate","geoM","fracA","fracB","fracM","geoA","geoB","geoStack","fractionStack","fractions","maxIterations","Text","font_","textAlign_","textAlign","textBaseline_","textBaseline","maxAngle_","maxAngle","placement_","placement","TextPlacement","overflow_","overflow","offsetX_","offsetY_","backgroundFill_","backgroundFill","backgroundStroke_","backgroundStroke","padding_","getFont","getPlacement","getMaxAngle","getOverflow","getTextAlign","getTextBaseline","getOffsetX","getOffsetY","getBackgroundFill","getBackgroundStroke","getPadding","setOverflow","setFont","setMaxAngle","setOffsetX","setOffsetY","setPlacement","setTextAlign","setTextBaseline","setBackgroundFill","setBackgroundStroke","setPadding","DEFAULT_STROKE_STYLE","INTERVALS","Graticule","map_","postcomposeListenerKey_","projection_","maxLat_","maxLon_","minLat_","minLon_","maxLatP_","maxLonP_","minLatP_","minLonP_","targetSize_","targetSize","maxLines_","maxLines","meridians_","parallels_","strokeStyle_","fromLonLatTransform_","toLonLatTransform_","projectionCenterLonLat_","meridiansLabels_","parallelsLabels_","showLabels","lonLabelFormatter_","lonLabelFormatter","latLabelFormatter_","latLabelFormatter","lonLabelPosition_","lonLabelPosition","latLabelPosition_","latLabelPosition","lonLabelStyle_","lonLabelStyle","latLabelStyle_","latLabelStyle","setMap","addMeridian_","lon","minLat","maxLat","lineString","getMeridian_","textPoint","getMeridianPoint_","geom","clampedBottom","clampedTop","addParallel_","minLon","maxLon","getParallel_","getParallelPoint_","clampedLeft","clampedRight","createGraticule_","getInterval_","cnt","centerLonLat","centerLon","centerLat","validExtent","p1","p2","getMap","frac","getMeridians","lon2","getParallels","handlePostCompose_","l","labelData","vectorContext","frameState","viewState","equivalentProjection","updateProjectionInfo_","setFillStrokeStyle","drawGeometry","setTextStyle","epsg4326Projection","worldExtentP","render","RenderEventType","ImageBase","state","pixelRatio_","getPixelRatio","getResolution","getState","ImageWrapper","src","crossOrigin","imageLoadFunction","src_","Image","imageListenerKeys_","imageLoadFunction_","handleImageError_","unlistenImage_","handleImageLoad_","easeIn","easeOut","inAndOut","linear","Tile","tileCoord","interimTile","transition_","transition","transitionStarts_","getKey","getInterimTile","tile","TileState","refreshInterimChain","getTileCoord","setState","getAlpha","time","inTransition","endTransition","ImageTile","tileLoadFunction","crossOrigin_","tileLoadFunction_","getBlankImage","naturalWidth","naturalHeight","ctx","fillRect","Kinetic","decay","minVelocity","delay","decay_","minVelocity_","delay_","initialVelocity_","update","Date","now","lastIndex","firstIndex","duration","MapEvent","opt_frameState","MapBrowserEvent","browserEvent","opt_dragging","originalEvent","pixel","getEventPixel","getCoordinateFromPixel","dragging","SINGLECLICK","POINTERDRAG","POINTERMOVE","POINTERDOWN","POINTERUP","POINTEROVER","POINTEROUT","POINTERENTER","POINTERLEAVE","POINTERCANCEL","MapBrowserPointerEvent","pointerEvent","EventSource","dispatcher","mapping","mapping_","getEvents","getHandlerForEvent","POINTER_ID","POINTER_TYPE","mousedown","inEvent","isEventSimulatedFromTouch_","pointerMap","cancel","prepareEvent","down","mousemove","move","mouseup","p","button","up","cleanupMouse","mouseover","enterOver","mouseout","leaveOut","MouseSource","lastTouches","lts","clientX","clientY","cloneEvent","pd","pointerId","isPrimary","pointerType","POINTER_TYPES","msPointerDown","prepareEvent_","msPointerMove","msPointerUp","cleanup","msPointerOut","msPointerOver","msPointerCancel","msLostPointerCapture","makeEvent","msGotPointerCapture","MsSource","MSPointerDown","MSPointerMove","MSPointerUp","MSPointerOut","MSPointerOver","MSPointerCancel","MSGotPointerCapture","MSLostPointerCapture","pointerDown","fireNativeEvent","pointerMove","pointerUp","pointerOut","pointerOver","pointerCancel","lostPointerCapture","gotPointerCapture","NativeSource","pointerdown","pointermove","pointerup","pointerout","pointerover","pointercancel","gotpointercapture","lostpointercapture","HAS_BUTTONS","PointerEvent","opt_eventDict","eventDict","buttons","getButtons_","pressure","getPressure_","bubbles","cancelable","view","detail","screenX","screenY","ctrlKey","altKey","shiftKey","metaKey","relatedTarget","tiltX","tiltY","hwTimestamp","which","ev","MouseEvent","touchstart","vacuumTouches_","setPrimaryTouch_","changedTouches","dedupSynthMouse_","clickCount_","processTouches_","overDown_","touchmove","moveOverOut_","touchend","upOut_","touchcancel","cancelOut_","TouchSource","mouseSource","firstTouchId_","resetId_","dedupTimeout_","isPrimaryTouch_","inTouch","identifier","count","cancelResetClickCount_","removePrimaryPointer_","inPointer","resetClickCount_","setTimeout","resetClickCountHandler_","clearTimeout","touchToPointer_","webkitRadiusX","radiusX","webkitRadiusY","radiusY","webkitForce","force","inFunction","touches","pointer","findTouch_","touchList","searchId","out","outTarget","over","enter","outEvent","leave","cleanUpPointer_","lt","CLONE_PROPS","PointerEventHandler","element_","eventMap_","eventSourceList_","registerSources","registerSource","register_","newEvents","handler","eventSource","addEvents_","unregister_","removeEvents_","eventHandler_","events","eventName","eventCopy","fireEvent","PointerEventType","contains_","container","contained","contains","inType","wrapMouseEvent","MapBrowserEventHandler","moveTolerance","clickTimeoutId_","dragging_","dragListenerKeys_","moveTolerance_","down_","getViewport","activePointers_","trackedTouches_","pointerEventHandler_","documentPointerEventHandler_","pointerdownListenerKey_","handlePointerDown_","relayedListenerKey_","relayEvent_","emulateClick_","newEvent","MapBrowserEventType","updateActivePointers_","handlePointerUp_","isMouseActionButton_","handlePointerMove_","isMoving_","LAYERGROUP","SIZE","TARGET","VIEW","PriorityQueue","priorityFunction","keyFunction","priorityFunction_","keyFunction_","elements_","priorities_","queuedElements_","dequeue","elements","priorities","siftUp_","elementKey","enqueue","priority","siftDown_","getLeftChildIndex_","getRightChildIndex_","getParentIndex_","heapify_","isKeyQueued","isQueued","startIndex","lIndex","rIndex","smallerChildIndex","parentIndex","reprioritize","TileQueue","tilePriorityFunction","tileChangeCallback","tileChangeCallback_","tilesLoading_","tilesLoadingKeys_","added","handleTileChange","getTilesLoading","tileKey","loadMoreTiles","maxTotalLoading","maxNewLoads","newLoads","abortedTiles","DEFAULT_MAX_ZOOM","DEFAULT_TILE_SIZE","none","disable","ANIMATING","INTERACTING","View","hints_","animations_","updateAnimationKey_","updateAnimations_","applyOptions_","ViewProperty","resolutionConstraintInfo","resolutionConstraint","maxResolution","minResolution","minZoom","maxZoom","zoomFactor","resolutions","z","power","defaultMaxResolution","defaultMinResolution","defaultMaxZoom","opt_maxLevel","oldLevel","newLevel","constraint","createResolutionConstraint","maxResolution_","minResolution_","zoomFactor_","resolutions_","minZoom_","centerConstraint","centerNone","rotationConstraint","enableRotation","constrainRotation","opt_tolerance","rotationNone","theta","createRotationConstraint","constraints_","zoom","constrainResolution","options_","getUpdatedOptions_","newOptions","getZoom","animate","var_args","animationCount","isDef","setCenter","setZoom","series","animation","complete","easing","sourceCenter","targetCenter","sourceResolution","targetResolution","sourceRotation","targetRotation","isNoopAnimation","setHint","ViewHint","getAnimating","getInteracting","cancelAnimations","cancelAnimationFrame","more","seriesComplete","elapsed","progress","calculateCenterZoom","calculateCenterRotate","filter","Boolean","requestAnimationFrame","currentCenter","rotateCoordinate","addCoordinate","currentResolution","getSizeFromViewport_","selector","querySelector","metrics","constrainCenter","opt_delta","opt_direction","getConstraints","getHints","opt_hints","calculateExtent","opt_size","getMaxResolution","getMinResolution","getMaxZoom","getZoomForResolution","setMaxZoom","getMinZoom","setMinZoom","getResolutions","getResolutionForExtent","xResolution","yResolution","getResolutionForValueFunction","opt_power","getValueForResolutionFunction","nearest","getResolutionForZoom","fit","geometryOrExtent","polygonFromExtent","minRotX","minRotY","maxRotX","maxRotY","rotX","rotY","constrainedResolution","centerRotX","centerRotY","setResolution","centerOn","centerX","centerY","hint","coordinatesEqual","BaseLayer","LayerProperty","visible","state_","layer","managed","getLayerState","sourceState","getSourceState","getVisible","getLayersArray","getLayerStatesArray","opt_states","setMaxResolution","setMinResolution","setVisible","zindex","LayerGroup","baseOptions","layers","layersListenerKeys_","listenerKeys_","handleLayersChanged_","setLayers","handleLayerChange_","getLayers","handleLayersAdd_","handleLayersRemove_","layersArray","collectionEvent","states","pos","ownLayerState","layerState","SourceState","num","ratio","toSize","PluggableMap","optionsInternal","keyboardEventTarget","getElementById","controls","interactions","overlays","layerGroup","MapProperty","createOptionsInternal","maxTilesLoading_","maxTilesLoading","loadTilesWhileAnimating_","loadTilesWhileAnimating","loadTilesWhileInteracting_","loadTilesWhileInteracting","animationDelayKey_","animationDelay_","renderFrame_","coordinateToPixelTransform_","pixelToCoordinateTransform_","frameIndex_","frameState_","previousExtent_","viewPropertyListenerKey_","viewChangeListenerKey_","layerGroupPropertyListenerKeys_","viewport_","className","msTouchAction","touchAction","overlayContainer_","overlayContainerStopEvent_","overlayEvents","mapBrowserEventHandler_","handleMapBrowserEvent","keyboardEventTarget_","keyHandlerKeys_","handleBrowserEvent","overlays_","overlayIdIndex_","createRenderer","handleResize_","focus_","postRenderFunctions_","tileQueue_","getTilePriority","handleTileChange_","skippedFeatureUids_","handleLayerGroupChanged_","handleViewChanged_","handleSizeChanged_","handleTargetChanged_","control","interaction","addOverlayInternal_","addControl","getControls","addInteraction","getInteractions","addLayer","getLayerGroup","addOverlay","overlay","getOverlays","setTarget","forEachFeatureAtPixel","hitTolerance","layerFilter","forEachFeatureAtCoordinate","getFeaturesAtPixel","features","forEachLayerAtPixel","hasFeatureAtPixel","hasFeatureAtCoordinate","getEventCoordinate","viewportPosition","getBoundingClientRect","eventPosition","top","getTarget","getTargetElement","pixelToCoordinateTransform","getOverlayById","getPixelFromCoordinate","coordinateToPixelTransform","getView","getOverlayContainer","getOverlayContainerStopEvent","tileSourceKey","tileCenter","tileResolution","wantedTiles","focus","mapBrowserEvent","interactionsArray","getActive","handleEvent","handlePostRender","tileQueue","hints","viewHints","postRenderFunctions","targetElement","updateSize","removeLayerRenderers","handleViewPropertyChanged_","setAttribute","isRendered","renderSync","removeControl","removeInteraction","removeLayer","removeOverlay","previousFrameState","layerStatesArray","layerStates","pixelResolution","skippedFeatureUids","usedTiles","renderFrame","MapEventType","setLayerGroup","setView","skipFeature","featureUid","computedStyle","offsetWidth","parseFloat","unskipFeature","Control","target_","listenerKeys","Layer","mapPrecomposeKey_","mapRenderKey_","sourceChangeKey_","handleSourcePropertyChange_","setSource","getSource","handleSourceChange_","visibleAtResolution","Attribution","ulElement_","collapsed_","collapsed","collapsible_","collapsible","tipLabel","collapseLabel","collapseLabel_","label","label_","activeLabel","title","handleClick_","cssClasses","renderedAttributions_","renderedVisible_","getSourceAttributions_","lookup","visibleAttributions","attributionGetter","getAttributions","attributions","updateElement_","display","innerHTML","handleToggle_","classList","toggle","getCollapsible","setCollapsible","setCollapsed","getCollapsed","mapEvent","Rotate","callResetNorth_","resetNorth","duration_","autoHide_","autoHide","resetNorth_","msTransform","webkitTransform","Zoom","zoomInLabel","zoomOutLabel","zoomInTipLabel","zoomOutTipLabel","inElement","createTextNode","outElement","zoomByDelta_","newResolution","defaults","zoomOptions","rotateOptions","attribution","attributionOptions","Interaction","setActive","InteractionProperty","active","opt_duration","rotateWithoutConstraints","currentRotation","zoomWithoutConstraints","zoomByDelta","DoubleClickZoom","delta_","stopEvent","altKeyOnly","altShiftKeysOnly","always","mouseActionButton","never","singleClick","noModifierKeys","shiftKeyOnly","targetNotEditable","tagName","mouseOnly","primaryAction","handleDragEvent","handleUpEvent","handleDownEvent","handleMoveEvent","PointerInteraction","handleDownEvent_","handleDragEvent_","handleMoveEvent_","handleUpEvent_","handlingDownUpSequence","stopDown","trackedPointers_","targetPointers","updateTrackedPointers_","centroid","pointerEvents","handledUp","handled","DragPan","kinetic_","kinetic","lastCentroid","lastPointersCount_","condition_","condition","noKinetic_","centroidFromPointers","scaleCoordinate","centerpx","DragRotate","lastAngle_","RenderBox","startPixel_","endPixel_","startPixel","endPixel","setPixels","createOrUpdateGeometry","DragBoxEventType","BOXSTART","BOXDRAG","BOXEND","DragBoxEvent","DragBox","box_","minArea_","minArea","onBoxEnd_","onBoxEnd","boxEndCondition_","boxEndCondition","defaultBoxEndCondition","DragZoom","out_","mapExtent","boxPixelExtent","UP","DOWN","KeyboardPan","defaultCondition_","pixelDelta_","pixelDelta","keyCode","KeyCode","mapUnitsDelta","pan","KeyboardZoom","charCode","charCodeAt","Mode","TRACKPAD","MouseWheelZoom","timeout_","timeout","useAnchor_","useAnchor","constrainResolution_","lastAnchor_","startTime_","timeoutId_","mode_","trackpadEventGap_","trackpadTimeoutId_","trackpadDeltaPerZoom_","trackpadZoomBuffer_","decrementInteractingHint_","handleWheelZoom_","setMouseAnchor","wheelEvent","deltaMode","WheelEvent","DOM_DELTA_PIXEL","DOM_DELTA_LINE","wheelDeltaY","rebound","timeLeft","PinchRotate","rotating_","rotationDelta_","threshold_","threshold","rotationDelta","touch0","touch1","PinchZoom","lastDistance_","lastScaleDelta_","scaleDelta","DragAndDropEventType","DragAndDropEvent","file","opt_features","opt_projection","DragAndDrop","formatConstructors_","formatConstructors","dropListenKeys_","source_","handleResult_","result","tryReadFeatures_","featureProjection","addFeatures","registerListeners_","dropArea","handleDrop","handleStop","unregisterListeners_","readFeatures","files","dataTransfer","reader","FileReader","readAsText","dropEffect","DragRotateAndZoom","lastMagnitude_","magnitude","angleDelta","Circle","setCenterAndRadius","getRadiusSquared_","MultiLineString","appendLineString","opt_interpolate","lineStringsCoordinateAtM","getLineString","getLineStrings","lineStrings","getFlatMidpoints","midpoints","douglasPeuckerArray","intersectsLineStringArray","MultiPoint","appendPoint","getPoint","linearRingss","MultiPolygon","opt_endss","endss_","flatInteriorPointsRevision_","flatInteriorPoints_","appendPolygon","newEndss","multiArrayMaxSquaredDelta","assignClosestMultiArrayPoint","linearRingssContainsXY","linearRingssArea","getEndss","getFlatInteriorPoints","linearRingssCenter","getInteriorPoints","linearRingsAreOriented","simplifiedEndss","quantizeMultiArray","getPolygon","prevEnds","getPolygons","polygons","intersectsLinearRingMultiArray","deflateMultiCoordinatesArray","lastEnds","IMAGE","TILE","VECTOR_TILE","VECTOR","VectorLayer","renderBuffer","updateWhileAnimating","updateWhileInteracting","declutter_","declutter","renderBuffer_","updateWhileAnimating_","updateWhileInteracting_","renderMode_","renderMode","VectorRenderType","LayerType","getDeclutter","setDeclutter","getRenderBuffer","getRenderOrder","getUpdateWhileAnimating","getUpdateWhileInteracting","setRenderOrder","renderOrder","styleFunction","getRenderMode","JSON","TEXT","XML","loadFeaturesXhr","url","success","failure","xhr","XMLHttpRequest","open","FormatType","responseType","onload","status","responseText","responseXML","DOMParser","parseFromString","readProjection","getLastExtent","onerror","send","dataProjection","all","Source","attributions_","adaptAttributions_","wrapX_","wrapX","attributionLike","getWrapX","refresh","setAttributions","module","swap","defaultCompare","compare","quickselectStep","sd","newLeft","newRight","factory","rbush","maxEntries","_maxEntries","_minEntries","_initFormat","findItem","items","equalsFn","calcBBox","toBBox","distBBox","children","destNode","createNode","child","leaf","compareNodeMinX","compareNodeMinY","bboxArea","bboxMargin","multiSelect","quickselect","_all","search","bbox","childBBox","nodesToSearch","collides","insert","_build","_splitRoot","tmpNode","_insert","goingUp","path","indexes","_condense","compareMinX","compareMinY","toJSON","fromJSON","N","M","right2","right3","N2","N1","_chooseSubtree","level","targetNode","enlargement","minEnlargement","isNode","insertPath","_split","_adjustParentBBoxes","_chooseSplitAxis","splitIndex","_chooseSplitIndex","bbox1","bbox2","overlap","minOverlap","_allDistMargin","leftBBox","rightBBox","siblings","compareArr","Function","RBush","opt_maxEntries","rbush_","items_","extents","uid","getAll","getInExtent","forEach_","forEachInExtent","VectorSourceEvent","opt_feature","VectorSource","loader_","format_","overlaps_","overlaps","url_","loader","strategy_","strategy","allStrategy","collection","useSpatialIndex","featuresRtree_","loadedExtentsRtree_","nullGeometryFeatures_","idIndex_","undefIdIndex_","featureChangeKeys_","featuresCollection_","addFeaturesInternal","bindFeaturesCollection_","addFeature","addFeatureInternal","featureKey","addToIndex_","setupChangeEvents_","VectorEventType","handleFeatureChange_","valid","newFeatures","geometryFeatures","modifyingCollection","removeFeature","opt_fast","featureId","removeFeatureInternal","clearEvent","forEachFeature","forEachFeatureAtCoordinateDirect","forEachFeatureInExtent","forEachFeatureIntersectingExtent","getFeaturesCollection","getFeatures","getFeaturesAtCoordinate","getFeaturesInExtent","getClosestFeatureToCoordinate","opt_filter","closestFeature","previousMinSquaredDistance","minDistance","getFeatureById","getFormat","getOverlaps","getUrl","sid","removeFromIdIndex_","hasFeature","loadFeatures","loadedExtentsRtree","extentsToLoad","extentToLoad","removeLoadedExtent","removed","setLoader","DrawEventType","DrawEvent","Draw","shouldHandle_","downPx_","downTimeout_","lastDragTime_","freehand_","features_","snapTolerance_","snapTolerance","type_","mode","getMode","stopClick_","stopClick","minPoints_","minPoints","maxPoints_","maxPoints","finishCondition_","finishCondition","geometryFunction","opt_geometry","squaredLength","squaredCoordinateDistance","Constructor","dragVertexDelay_","dragVertexDelay","finishCoordinate_","sketchFeature_","sketchPoint_","sketchCoords_","sketchLine_","sketchLineCoords_","squaredClickTolerance_","clickTolerance","overlay_","geometryName","freehandCondition_","freehand","freehandCondition","updateState_","downPx","clickPx","modifyDrawing_","createOrUpdateSketchPoint_","atFinish_","at","potentiallyDone","potentiallyFinishCoordinates","finishCoordinate","finishPixel","updateSketchFeatures_","startDrawing_","sketchLineGeom","ring","addToDrawing_","finishDrawing","removeLastPoint","sketchFeature","abortDrawing_","sketchFeatures","overlaySource","pass","handlePointerEvent","circleMode","ExtentEventType","ExtentInteractionEvent","ExtentInteraction","pointerHandler_","pixelTolerance_","pixelTolerance","snappedToVertex_","extentFeature_","vertexFeature_","extentOverlay_","boxStyle","vertexOverlay_","pointerStyle","snapToVertex_","pixelCoordinate","segments","closestSegment","vertex","vertexPixel","coordinateDistance","pixel1","pixel2","squaredDist1","squaredDist2","dist","createOrUpdatePointerFeature_","createOrUpdateExtentFeature_","extentFeature","vertexFeature","getOpposingPoint","x_","y_","getPointHandler","getEdgeHandler","fixedPoint","fixedP1","fixedP2","CIRCLE_CENTER_INDEX","CIRCLE_CIRCUMFERENCE_INDEX","ModifyEventType","MODIFYSTART","MODIFYEND","ModifyEvent","mapBrowserPointerEvent","Modify","defaultDeleteCondition_","deleteCondition_","deleteCondition","insertVertexCondition_","insertVertexCondition","vertexSegments_","lastPixel_","ignoreNextSingleClick_","modified_","rBush_","changingFeature_","dragSegments_","SEGMENT_WRITERS_","writePointGeometry_","writeLineStringGeometry_","writePolygonGeometry_","writeMultiPointGeometry_","writeMultiLineStringGeometry_","writeMultiPolygonGeometry_","writeCircleGeometry_","GeometryCollection","writeGeometryCollectionGeometry_","handleSourceAdd_","handleSourceRemove_","addFeature_","handleFeatureAdd_","handleFeatureRemove_","lastPointerEvent_","handlePointerAtPixel_","willModifyFeatures_","removeFeature_","removeFeatureSegmentData_","rBush","nodesToRemove","segmentData","depth","lines","rings","kk","centerSegmentData","circumferenceSegmentData","featureSegments","geometries","getGeometriesArray","createOrUpdateVertexFeature_","box","nodes","pointDistanceToSegmentDataSquared","closestOnSegmentData","vertexSegments","insertVertex_","setGeometryCoordinates_","rTree","updateSegmentIndices_","newSegmentData","newSegmentData2","removePoint","removeVertex_","component","dragSegment","newIndex","dragSegments","segmentsByFeature","deleted","segmentDataMatch","compareIndexes","insertVertices","vertexExtent","segmentDataMatches","componentSegments","pointCoordinates","circleGeometry","distanceToCenterSquared","distanceToCircumference","SelectEventType","SELECT","SelectEvent","selected","deselected","Select","addCondition_","addCondition","removeCondition_","removeCondition","toggleCondition_","toggleCondition","multi_","multi","filter_","hitTolerance_","featureOverlay","featureOverlay_","layerFilter_","featureLayerAssociation_","addFeatureLayerAssociation_","getHitTolerance","getLayer","setHitTolerance","currentMap","selectedFeatures","removeFeatureLayerAssociation_","Snap","vertex_","edge_","featuresListenerKeys_","featureChangeListenerKeys_","indexedFeaturesExtents_","pendingFeatures_","pixelCoordinate_","sortByDistance_","deltaA","deltaB","opt_listen","register","feature_uid","segmentWriter","forEachFeatureAdd_","forEachFeatureRemove_","getFeatures_","updateFeature_","opt_unlisten","unregister","snapTo","snapped","isCircle","closestOnCircle","featuresToUpdate","TranslateEventType","TRANSLATESTART","TRANSLATING","TRANSLATEEND","TranslateEvent","Translate","lastCoordinate_","lastFeature_","handleActiveChanged_","featuresAtPixel_","oldMap","newCoordinate","altShiftDragRotate","doubleClickZoom","zoomDelta","zoomDuration","dragPan","pinchRotate","pinchZoom","keyboard","mouseWheelZoom","shiftDragZoom","ImageCanvas","opt_loader","error_","getError","handleLoad_","err","RenderEvent","opt_vectorContext","opt_context","opt_glContext","glContext","VectorContext","drawCustom","drawCircle","drawFeature","drawGeometryCollection","geometryCollectionGeometry","drawLineString","lineStringGeometry","drawMultiLineString","multiLineStringGeometry","drawMultiPoint","multiPointGeometry","drawMultiPolygon","multiPolygonGeometry","drawPoint","pointGeometry","drawPolygon","polygonGeometry","drawText","setImageStyle","imageStyle","opt_declutterGroup","textStyle","CanvasImmediateRenderer","viewRotation","context_","viewRotation_","contextFillState_","contextStrokeState_","contextTextState_","fillState_","strokeState_","imageAnchorX_","imageAnchorY_","imageHeight_","imageOpacity_","imageOriginX_","imageOriginY_","imageRotateWithView_","imageRotation_","imageScale_","imageSnapToPixel_","imageWidth_","textOffsetX_","textOffsetY_","textRotateWithView_","textRotation_","textScale_","textFillState_","textStrokeState_","textState_","pixelCoordinates_","tmpLocalTransform_","drawImages_","pixelCoordinates","localTransform","drawText_","setContextFillState_","setContextStrokeState_","setContextTextState_","strokeText","fillText","moveToLineTo_","close","moveTo","drawRings_","simpleGeometry","transformGeom2D","flatMidpoint","geometryExtent","flatMidpoints","flatInteriorPoint","flatInteriorPoints","fillState","contextFillState","strokeState","contextStrokeState","textState","contextTextState","fillStyleColor","strokeStyleColor","strokeStyleLineCap","strokeStyleLineDash","strokeStyleLineDashOffset","strokeStyleLineJoin","strokeStyleWidth","strokeStyleMiterLimit","imageAnchor","imageImage","imageOrigin","textFillStyle","textFillStyleColor","textStrokeStyle","textStrokeStyleColor","textStrokeStyleLineCap","textStrokeStyleLineDash","textStrokeStyleLineDashOffset","textStrokeStyleLineJoin","textStrokeStyleWidth","textStrokeStyleMiterLimit","textFont","textOffsetX","textOffsetY","textRotateWithView","textRotation","textScale","textText","textTextAlign","textTextBaseline","IconImageCache","cache_","cacheSize_","maxCacheSize_","expire","iconImage","maxCacheSize","shared","MapRenderer","layerRenderers_","layerRendererListeners_","layerRendererConstructors_","registerLayerRenderers","constructors","getLayerRendererConstructors","calculateMatrices2D","invertTransform","transformSetFromArray","removeLayerRendererByKey_","thisArg2","viewResolution","translatedCoordinate","projectionExtent","worldWidth","layerRenderer","getLayerRenderer","layerKey","candidate","handleLayerRendererChange_","getLayerRendererByKey","getLayerRenderers","removeUnusedLayerRenderers_","scheduleExpireIconCache","scheduleRemoveUnusedLayerRenderers","expireIconCache","iconImageCache","sortByZIndex","state1","state2","layerRendererConstructors","CanvasMapRenderer","insertBefore","childNodes","dispatchComposeEvent_","composeEvent","clearRect","save","prepareFrame","composeFrame","restore","numLayers","forEachLayerAtCoordinate","ctor","LayerRenderer","layer_","createLoadedTileFinder","tiles","tileRange","forEachLoadedTile","handleImageChange_","renderIfReadyAndVisible","loadImage","imageState","scheduleExpireCache","tileSource","postRenderFunction","expireCache","updateUsedTiles","zKey","manageTilePyramid","currentZ","preload","opt_tileCallback","getTileRangeForExtentAndZ","getTile","getTileCoordCenter","useTile","CanvasLayerRenderer","renderedResolution","clip","topLeft","topRight","bottomRight","bottomLeft","opt_transform","postCompose","preCompose","dispatchRenderEvent","IntermediateCanvasRenderer","coordinateToCanvasPixelTransform","hitCanvasContext_","clipped","imageTransform","getImageTransform","dw","dh","imageData","getImageData","CanvasImageLayerRenderer","imageLayer","imageTransform_","skippedFeatures_","vectorRenderer_","viewCenter","imageSource","vectorRenderer","renderedExtent","skippedFeatures","imageFrameState","newSkippedFeatures","replayGroupChanged","imageExtent","imageResolution","imagePixelRatio","mapRenderer","TileRange","containsTileRange","CanvasTileLayerRenderer","tileLayer","opt_noContext","oversampling_","renderedExtent_","renderedRevision","renderedTiles","newTiles_","tmpExtent","tmpTileRange_","zDirection","isDrawableTile_","tileState","useInterimTilesOnError","getUseInterimTilesOnError","getPreload","sourceRevision","getTileGridForProjection","getZForResolution","oversampling","getTileRangeExtent","tilePixelRatio","getTilePixelRatio","tilesToDrawByZ","findLoadedTiles","animatingOrInteracting","tmpTileRange","childTileRange","getTileCoordChildTileRange","covered","forEachTileCoordParentTileRange","tilePixelSize","getTilePixelSize","currentScale","currentTilePixelSize","tileExtent","tileGutter","tilesToDraw","zs","tileCoordKey","getGutter","getTileCoordExtent","drawTileImage","gutter","getOpaque","alphaChanged","ReplayGroup","getReplay","replayType","DEFAULT","drawTextOnPath","measure","startM","previousAngle","reverse","numChars","segmentM","chunk","chunkLength","char","charLength","charM","segmentPos","unshift","Instruction","fillInstruction","strokeInstruction","beginPathInstruction","closePathInstruction","ORDER","ReplayType","TEXT_ALIGN","middle","hanging","alphabetic","ideographic","bottom","CanvasReplay","maxExtent","declutterTree","maxLineWidth","alignFill_","beginGeometryInstruction1_","beginGeometryInstruction2_","bufferedMaxExtent_","instructions","coordinateCache_","renderedTransform_","hitDetectionInstructions","replayTextBackground_","p3","p4","setStrokeStyle_","replayImage_","declutterGroup","fillStroke","boxW","boxH","boxX","boxY","strokePadding","declutterArgs","applyPixelRatio","dashArray","dash","appendFlatCoordinates","closed","skipFirst","myEnd","getBufferedMaxExtent","lastRel","nextRel","lastCoord","nextCoord","skipped","drawCustomCoordinates_","replayEnds","replayEnd","beginGeometry","replayEndss","replayBegin","myEnds","CanvasInstruction","endGeometry","origin","repeatSize","instruction","renderDeclutter_","groupCount","declutterData","replay_","skippedFeaturesHash","featureCallback","opt_hitExtent","dd","prevX","prevY","roundX","roundY","skipFeatures","pendingFill","pendingStroke","lastFillInstruction","lastStrokeInstruction","coordinateCache","batchSize","fn","baseline","fillKey","strokeKey","textKey","pathLength","textLength","textStates","parts","cc","chars","part","replay","replayHitDetection","opt_featureCallback","reverseHitDetectionInstructions","createFill","applyStroke","createStroke","updateFillStyle","currentFillStyle","updateStrokeStyle","currentStrokeStyle","currentLineCap","currentLineDash","currentLineDashOffset","currentLineJoin","currentLineWidth","currentMiterLimit","endGeometryInstruction","finish","CanvasImageReplay","declutterGroup_","hitDetectionImage_","anchorX_","anchorY_","height_","originX_","originY_","drawCoordinates_","myBegin","hitDetectionImage","CanvasLineStringReplay","drawFlatCoordinates_","moveToLineToInstruction","lastStroke","CanvasPolygonReplay","drawFlatCoordinatess_","numEnds","setFillStrokeStyles_","circleInstruction","matchingChunk","m12","m23","x12","y12","x23","y23","chunkStart","chunkEnd","chunkM","acos","BATCH_CONSTRUCTORS","Default","labels_","fillStates","strokeStates","textKey_","fillKey_","strokeKey_","widths_","geometryType","flatEnd","flatOffset","oo","range","drawChars_","drawTextImage_","align","numLines","widths","currentWidth","measureTextWidths","lineHeight","renderWidth","leftRight","CanvasReplayGroup","opt_renderBuffer","declutterTree_","tolerance_","maxExtent_","resolution_","replaysByZIndex_","hitDetectionContext_","hitDetectionTransform_","addDeclutter","group","flatClipCoords","getClipCoords","hasReplays","replays","candidates","replayKey","declutterReplays","hitExtent","contextSize","declutteredFeatures","mask","circleArrayCache","arraySize","fillCircleArrayRowToMiddle","getCircleArray","zIndexKey","getReplays","opt_replayTypes","opt_declutterReplays","replayTypes","0","SIMPLIFY_TOLERANCE","GEOMETRY_RENDERERS","replayGroup","imageReplay","textReplay","lineStringReplay","polygonReplay","geometryRenderer","circleReplay","defaultOrder","feature1","feature2","getSquaredTolerance","getTolerance","renderFeature","loading","renderGeometry","getGeometries","renderFeatureInternal","CanvasVectorLayerRenderer","vectorLayer","dirty_","renderedRevision_","renderedResolution_","renderedRenderOrder_","replayGroup_","handleFontsChanged_","vectorSource","clipExtent","replayContext","drawOffsetX","drawOffsetY","transparentLayer","hasRenderListeners","drawWidth","drawHeight","drawSize","world","mainContextAlpha","handleStyleImageChange_","animating","interacting","frameStateExtent","vectorLayerRevision","vectorLayerRenderBuffer","vectorLayerRenderOrder","defaultRenderOrder","getRenderTolerance","dirty","getSquaredRenderTolerance","IMAGE_REPLAYS","hybrid","VECTOR_REPLAYS","vector","CanvasVectorTileLayerRenderer","renderedLayerRevision_","tmpTransform_","VectorTileRenderType","createReplayGroup_","renderTileImage_","layerRevision","revision","replayState","getReplayState","renderedRenderOrder","sourceTileGrid","getTileGrid","sourceTile","tileKeys","sourceTileCoord","sourceTileExtent","sharedExtent","bufferedExtent","tileProjection","reproject","setReplayGroup","tt","getReplayGroup","getReplayTransform_","renderResolution","clips","worldOffset","currentClip","zz","replayData","replayDeclutter","renderedTileRevision","wrappedTileCoord","pixelScale","scaleTransform","translateTransform","changeType","Map","defaultControls","defaultInteractions","Overlay","insertFirst","autoPan","autoPanAnimation","autoPanMargin","rendered","bottom_","left_","right_","top_","mapPostrenderListenerKey","handleElementChanged","handleMapChanged","handleOffsetChanged","handlePositionChanged","handlePositioningChanged","setElement","setOffset","setPositioning","positioning","OverlayPositioning","setPosition","getElement","getOffset","getPositioning","updatePixelPosition","panIntoView","mapRect","getRect","overlayRect","marginLeft","marginRight","marginTop","marginBottom","offsetLeft","offsetRight","offsetTop","offsetBottom","centerPx","newCenterPx","pageXOffset","pageYOffset","mapSize","updateRenderedPosition","getOptions","DEFAULT_EXTENT","VectorTile","consumers","replayGroups_","onLoad","setFeatures","onError","getChangeType","webkitRequestFullscreen","mozRequestFullScreen","msRequestFullscreen","requestFullscreen","FullScreen","cssClassName_","labelNode_","labelActive","labelActiveNode_","isFullScreen","isFullScreenSupported","keys_","handleFullScreen_","exitFullscreen","msExitFullscreen","mozCancelFullScreen","webkitExitFullscreen","mozRequestFullScreenWithKeys","Element","ALLOW_KEYBOARD_INPUT","requestFullScreen","handleFullScreenChange_","firstElementChild","mozFullScreenEnabled","msFullscreenEnabled","fullscreenEnabled","webkitIsFullScreen","mozFullScreen","msFullscreenElement","fullscreenElement","OverviewMap","ovmapDiv_","ovmap_","ovmap","boxSizing","boxOverlay_","scope","overlayBox","mousePosition","endMoving","oldView","unbindView_","handleMapPropertyChange_","bindView_","resetExtent_","newView","handleRotationChanged_","validateExtent_","ovmapSize","ovextent","topLeftPixel","bottomRightPixel","boxWidth","boxHeight","ovmapWidth","ovmapHeight","recenter_","ovview","steps","MAX_RATIO","LN2","updateBox_","ovresolution","rotateBottomLeft","calculateCoordinateRotate_","coordinateRotate","getOverviewMap","UNITS_PROP","LEADING_DIGITS","ScaleLine","innerElement_","viewState_","minWidth_","minWidth","renderedWidth_","renderedHTML_","handleUnitsChanged_","setUnits","pointResolutionUnits","ProjUnits","nominalCount","suffix","metersPerDegree","html","Direction","ZoomSlider","currentResolution_","direction_","heightLimit_","widthLimit_","previousX_","previousY_","thumbSize_","sliderInitialized_","thumbElement","containerElement","dragger_","handleDraggerStart_","handleDraggerDrag_","handleDraggerEnd_","handleContainerClick_","initSlider_","containerSize","thumb","thumbWidth","thumbHeight","relativePosition","getRelativePosition_","getResolutionForPosition_","setThumbPosition_","res","getPositionForResolution_","ZoomToExtent","handleZoomToExtent","WebGLShader","isAnimated","WebGLFragment","WebGLVertex","fragment","Locations","program","u_projectionMatrix","getUniformLocation","u_offsetScaleMatrix","u_offsetRotateMatrix","u_lineWidth","u_pixelRatio","u_opacity","u_fillColor","u_strokeColor","u_size","a_position","getAttribLocation","a_instruction","a_radius","fromTransform","mat4","WebGLReplay","projectionMatrix_","offsetRotateMatrix_","offsetScaleMatrix_","tmpMat4_","indices","indicesBuffer","startIndices","startIndicesFeature","verticesBuffer","getDeleteResourcesFunction","setUpProgram","shutDownProgram","locations","drawReplay","hitDetection","drawHitDetectionReplayOneByOne","drawHitDetectionReplay","oneByOne","drawHitDetectionReplayAll","COLOR_BUFFER_BIT","DEPTH_BUFFER_BIT","tmpStencil","tmpStencilFunc","tmpStencilMaskVal","tmpStencilRef","tmpStencilMask","tmpStencilOpFail","tmpStencilOpPass","tmpStencilOpZFail","getGL","isEnabled","STENCIL_TEST","STENCIL_FUNC","STENCIL_VALUE_MASK","STENCIL_REF","STENCIL_WRITEMASK","STENCIL_FAIL","STENCIL_PASS_DEPTH_PASS","STENCIL_PASS_DEPTH_FAIL","enable","STENCIL_BUFFER_BIT","stencilMask","stencilFunc","ALWAYS","stencilOp","KEEP","REPLACE","NOTEQUAL","bindBuffer","projectionMatrix","rotateTransform","offsetScaleMatrix","offsetRotateMatrix","uniformMatrix4fv","uniform1f","drawElements","elementType","hasOESElementIndexUint","numItems","offsetInBytes","DEFAULT_FILLSTYLE","DEFAULT_LINEDASH","DEFAULT_STROKESTYLE","EPSILON","triangleIsCounterClockwise","BufferUsage","WebGLBuffer","opt_arr","opt_usage","arr_","usage_","getUsage","WebGLCircleReplay","defaultLocations_","styles_","styleIndices_","fillColor","strokeColor","numVertices","numIndices","lastState","deleteBuffer","getProgram","useProgram","enableVertexAttribArray","vertexAttribPointer","uniform2fv","disableVertexAttribArray","nextStyle","setFillStyle_","drawReplaySkipping_","groupStart","featureIndex","featureStart","uniform4fv","u_image","a_texCoord","a_offsets","a_opacity","a_rotateWithView","WebGLContext","gl_","bufferCache_","shaderCache_","programCache_","currentProgram_","hitDetectionFramebuffer_","hitDetectionTexture_","hitDetectionRenderbuffer_","WEBGL_EXTENSIONS","getExtension","ContextEventType","handleWebGLContextLost","handleWebGLContextRestored","buf","bufferKey","String","bufferCacheEntry","arrayBuffer","createBuffer","Float32Array","Uint32Array","Uint16Array","bufferData","isContextLost","deleteProgram","deleteShader","deleteFramebuffer","deleteRenderbuffer","deleteTexture","getCanvas","getHitDetectionFramebuffer","initHitDetectionFramebuffer_","getShader","shaderObject","shaderKey","shader","createShader","shaderSource","compileShader","fragmentShaderObject","vertexShaderObject","programKey","createProgram","attachShader","linkProgram","framebuffer","createFramebuffer","bindFramebuffer","texture","createEmptyTexture","renderbuffer","createRenderbuffer","bindRenderbuffer","RENDERBUFFER","renderbufferStorage","DEPTH_COMPONENT16","framebufferTexture2D","COLOR_ATTACHMENT0","framebufferRenderbuffer","DEPTH_ATTACHMENT","bindTexture","createTextureInternal","opt_wrapS","opt_wrapT","createTexture","texParameteri","TEXTURE_MAG_FILTER","LINEAR","TEXTURE_MIN_FILTER","texImage2D","RGBA","UNSIGNED_BYTE","WebGLTextureReplay","groupIndices","hitDetectionGroupIndices","imageHeight","imageWidth","defaultLocations","textures","getTextures","drawCoordinates","createTextures","images","texturePerImage","getHitDetectionTextures","drawReplaySkipping","groupEnd","hitDetectionTextures","opt_all","WebGLImageReplay","images_","hitDetectionImages_","textures_","hitDetectionTextures_","lineStringIsClosed","u_miterLimit","u_color","a_lastPos","a_nextPos","a_direction","WebGLLineStringReplay","startCoords","sign","p0","lastSign","addVertices_","product","isValid_","indexCount","drawPolygonCoordinates","holeFlatCoordinates","setPolygonStyle","opt_index","getCurrentIndex","tmpDepthFunc","DEPTH_FUNC","tmpDepthMask","DEPTH_WRITEMASK","DEPTH_TEST","depthMask","depthFunc","LinkedList","opt_circular","first_","last_","head_","circular_","length_","insertItem","next","head","removeItem","firstItem","lastItem","nextItem","getNextItem","prevItem","getPrevItem","getCurrItem","setFirstItem","list","WebGLPolygonReplay","outerRing","rtree","processFlatCoordinates_","maxCoords","getMaxCoords_","holeLists","holeList","classifyPoints_","currList","currItem","getIntersections_","bridgeHole_","triangulate_","clockwise","createPoint_","insertItem_","seg","ccw","s0","pointsReclassified","reflex","removeItem_","hole","holeMaxX","listMaxX","bestPoint","p5","minDist","intersectingSegments","currSeg","calculateIntersection_","pointsInTriangle","getPointsInTriangle_","currPoint","currTheta","p0Bridge","p1Bridge","simple","isSimple_","clipEars_","resolveSelfIntersections_","splitPolygon_","isClockwise_","s3","processedEars","variableCriterion","diagonalIsInside_","opt_touch","resolvedIntersections","breakCond","newPolygon","newRtree","opt_rtree","opt_reflex","segmentsInExtent","denom","ub","p1IsLeftOf","p1IsRightOf","p3IsLeftOf","p3IsRightOf","p1InCone","p3InCone","currIndex","currLineIndex","holes","holeFlatCoords","lineDeleter","nullStrokeStyle","Atlas","space","space_","emptyBlocks_","renderCallback","block","this$1","split_","newBlock1","newBlock2","deltaWidth","updateBlocks_","args","AtlasManager","currentSize_","initialSize","maxSize_","maxSize","WEBGL_MAX_TEXTURE_SIZE","atlases_","currentHitSize_","hitAtlases_","getInfo","getInfo_","hitInfo","mergeInfos_","atlases","opt_renderHitCallback","add_","renderHitCallback","isHitAtlas","atlas","WebGLTextReplay","measureCanvas_","currAtlas_","currX","currY","charArr","charInfo","glyphAtlas","textSize","getTextSize_","self","textHeight","str","sum","curr","addCharToAtlas_","reduce","mCtx","getAtlas_","params","hash","calculateHash_","HIT_DETECTION_SIZE","WebGLReplayGroup","functions","replayHitDetection_","Uint8Array","readPixels","WebGLImmediateRenderer","center_","imageStyle_","fillStyle_","textStyle_","u_texCoordMatrix","u_texture","WebGLLayerRenderer","arrayBuffer_","framebufferDimension","texCoordMatrix","uniform1i","getTexCoordMatrix","getProjectionMatrix","getTexture","drawArrays","WebGLImageLayerRenderer","hitTransformationMatrix_","createTexture_","imageElement","updateProjectionMatrix_","canvasWidth","canvasHeight","canvasExtentWidth","canvasExtentHeight","getHitTransformationMatrix_","pixelOnFrameBuffer","mapCoordTransform","projectionMatrixInv","multiplyTransform","WebGLMapRenderer","clipTileCanvasWidth_","clipTileCanvasHeight_","clipTileContext_","antialias","preserveDrawingBuffer","stencil","textureCache_","tileTextureQueue_","loadNextTileTexture_","tileSize","bindTileTexture","textureCacheFrameMarkerCount_","initializeGL_","magFilter","minFilter","textureCacheEntry","clipTileCanvas","clipTileContext","expireCache_","getTileTextureQueue","renderers","activeTexture","blendFuncSeparate","isTileTextureLoaded","layerStatesToDraw","clearColor","viewport","u_tileOffset","WebGLTileLayerRenderer","fragmentShader_","vertexShader_","locations_","renderArrayBuffer_","renderedTileRange_","renderedFramebufferExtent_","tmpSize_","loaded","framebufferExtent","getTileSize","tilePixelResolution","tileRangeSize","maxDimension","framebufferExtentDimension","allTilesLoaded","tileTextureQueue","pixelOnMapScaled","pixelOnFrameBufferScaled","WebGLVectorLayerRenderer","layerState_","SCISSOR_TEST","scissor","WebGLMap","PROJECTION","COORDINATE_FORMAT","MousePosition","coordinateFormat","setCoordinateFormat","undefinedHTML_","undefinedHTML","renderOnMouseOut_","mapProjection_","lastMouseMovePixel_","getCoordinateFormat","handleMouseMove","updateHTML_","handleMouseOut","FeatureFormat","defaultFeatureProjection","transformWithOptions","write","transformed","decimals","getReadOptions","adaptOptions","readFeature","readGeometry","writeFeature","writeFeatures","writeGeometry","JSONFeature","readFeatureFromObject","getObject","readFeaturesFromObject","readGeometryFromObject","readProjectionFromObject","stringify","writeFeatureObject","writeFeaturesObject","writeGeometryObject","parse","GEOMETRY_READERS","getGeometryLayout","paths","GEOMETRY_WRITERS","esriJSON","hasZM","getHasZM","hasZ","hasM","EsriJSON","esriJSONFeature","idField","attributes","esriJSONFeatures","objectIdFieldName","esriJSONObject","spatialReference","wkid","objects","flatRing","outerRings","shift","matched","containsHole","convertRings","geometryReader","geometryWriter","DOCUMENT","implementation","createDocument","XML_SCHEMA_INSTANCE_URI","createElementNS","namespaceURI","qualifiedName","getAllTextContent","normalizeWhitespace","getAllTextContent_","accumulator","nodeType","Node","CDATA_SECTION_NODE","TEXT_NODE","nodeValue","firstChild","nextSibling","isDocument","Document","xml","makeArrayExtender","valueReader","objectStack","makeArrayPusher","makeReplacer","makeObjectPropertyPusher","opt_property","localName","makeObjectPropertySetter","makeChildAppender","nodeWriter","makeArraySerializer","serializersNS","nodeFactory","serializers","makeSimpleNodeFactory","serialize","opt_nodeName","opt_namespaceURI","fixedNodeName","nodeName","OBJECT_PROPERTY_NODE_FACTORY","makeSequence","orderedKeys","sequence","makeStructureNS","namespaceURIs","structure","opt_structureNS","structureNS","parseNode","parsersNS","nextElementSibling","parsers","parser","pushParseAndPop","opt_keys","pushSerializeAndPop","XMLFeature","xmlSerializer_","XMLSerializer","readFeatureFromDocument","readFeatureFromNode","doc","readFeaturesFromDocument","readFeaturesFromNode","ELEMENT_NODE","readGeometryFromDocument","readGeometryFromNode","readProjectionFromDocument","readProjectionFromNode","writeFeatureNode","serializeToString","writeFeaturesNode","writeGeometryNode","GMLNS","ONLY_WHITESPACE_RE","GMLBase","featureType","featureNS","srsName","schemaLocation","FEATURE_COLLECTION_PARSERS","featureMember","readFeaturesInternal","featureMembers","ft","uri","ns","featureTypes","readFeatureElement","readGeometryElement","getAttribute","GEOMETRY_PARSERS_","fid","getAttributeNS","test","readPoint","readFlatCoordinatesFromNode_","readMultiPoint","MULTIPOINT_PARSERS_","readMultiLineString","MULTILINESTRING_PARSERS_","readMultiPolygon","MULTIPOLYGON_PARSERS_","pointMemberParser_","POINTMEMBER_PARSERS_","lineStringMemberParser_","LINESTRINGMEMBER_PARSERS_","polygonMemberParser_","POLYGONMEMBER_PARSERS_","readLineString","readFlatLinearRing_","GEOMETRY_FLAT_COORDINATES_PARSERS_","readLinearRing","readPolygon","flatLinearRings","FLAT_LINEAR_RINGS_PARSERS_","readBoolean","readBooleanString","string","readDateTime","dateTime","readDecimal","readDecimalString","readNonNegativeInteger","readNonNegativeIntegerString","readString","trim","writeBooleanTextNode","bool","writeStringTextNode","writeDecimalTextNode","toPrecision","writeNonNegativeIntegerTextNode","nonNegativeInteger","http://www.opengis.net/gml","pointMember","pointMembers","lineStringMember","lineStringMembers","polygonMember","polygonMembers","RING_PARSERS","MULTIGEOMETRY_TO_MEMBER_NODENAME","MultiCurve","MultiSurface","GML3","surface_","surface","curve_","curve","multiCurve_","multiCurve","multiSurface_","multiSurface","readMultiCurve_","MULTICURVE_PARSERS_","readMultiSurface_","MULTISURFACE_PARSERS_","curveMemberParser_","CURVEMEMBER_PARSERS_","surfaceMemberParser_","SURFACEMEMBER_PARSERS_","readPatch_","PATCHES_PARSERS_","readSegment_","SEGMENTS_PARSERS_","readPolygonPatch_","readLineStringSegment_","interiorParser_","flatLinearRing","exteriorParser_","readSurface_","SURFACE_PARSERS_","readCurve_","CURVE_PARSERS_","readEnvelope_","ENVELOPE_PARSERS_","readFlatPos_","re","containerSrs","readFlatPosList_","contextDimension","dim","writePos_","srsDimension","getCoords_","opt_srsName","opt_hasZ","writePosList_","writePoint_","writeEnvelope","ENVELOPE_SERIALIZERS_","writeLinearRing_","posList","RING_NODE_FACTORY_","exteriorWritten","writeSurfaceOrPolygon_","RING_SERIALIZERS_","patches","writeSurfacePatches_","writeCurveOrLineString_","writeCurveSegments_","writeMultiSurfaceOrPolygon_","SURFACEORPOLYGONMEMBER_SERIALIZERS_","MULTIGEOMETRY_MEMBER_NODE_FACTORY_","writeMultiPoint_","POINTMEMBER_SERIALIZERS_","writeMultiCurveOrLineString_","LINESTRINGORCURVEMEMBER_SERIALIZERS_","writeRing_","writeSurfaceOrPolygonMember_","GEOMETRY_NODE_FACTORY_","writePointMember_","writeLineStringOrCurveMember_","writeGeometryElement","GEOMETRY_SERIALIZERS_","writeFeatureElement","writeFeatureMembers_","setAttributeNS","interior","exterior","Surface","Curve","Envelope","curveMember","curveMembers","surfaceMember","surfaceMembers","lowerCorner","upperCorner","PolygonPatch","LineStringSegment","GML","GML2","readFlatCoordinates_","proj","coordsGroups","readBox_","BOX_PARSERS_","innerBoundaryIsParser_","outerBoundaryIsParser_","createCoordinatesNode_","writeCoordinates_","innerBoundaryIs","outerBoundaryIs","Box","NAMESPACE_URIS","FEATURE_READER","rte","readRte","trk","readTrk","wpt","readWpt","GPX_PARSERS","LINK_PARSERS","GPX_SERIALIZERS","RTE_SEQUENCE","RTE_SERIALIZERS","TRK_SEQUENCE","TRK_SERIALIZERS","writeWptType","GPX","readExtensions_","readExtensions","handleReadExtensions_","extensionsNode","featureReader","gpx","GPX_NODE_FACTORY","RTE_PARSERS","cmt","desc","link","parseLink","extensions","parseExtensions","rtept","RTEPT_PARSERS","rteValues","layoutOptions","ele","TRK_PARSERS","trkseg","TRKSEG_PARSERS","trkpt","TRKPT_PARSERS","trkValues","WPT_PARSERS","magvar","geoidheight","sym","fix","sat","hdop","vdop","pdop","ageofdgpsdata","dgpsid","LINK_SEQUENCE","LINK_SERIALIZERS","writeLink","RTEPT_TYPE_SEQUENCE","geometryLayout","TRKSEG_SERIALIZERS","TRKSEG_NODE_FACTORY","WPT_TYPE_SEQUENCE","WPT_TYPE_SERIALIZERS","date","getUTCFullYear","getUTCMonth","getUTCDate","getUTCHours","getUTCMinutes","getUTCSeconds","GEOMETRY_TYPE_TO_NODENAME","applyLayoutOptions","href","opt_geometries","geometries_","listenGeometriesChange_","unlistenGeometriesChange_","geometryCollection","setGeometries","cloneGeometries","simplifiedGeometries","simplified","simplifiedGeometryCollection","setGeometriesArray","clonedGeometries","GeoJSON","extractGeometryName_","extractGeometryName","geoJSONFeature","geometry_name","geoJSONFeatures","crs","rightHanded","TextFeature","readFeatureFromText","readFeaturesFromText","readGeometryFromText","readProjectionFromText","writeFeatureText","writeFeaturesText","writeGeometryText","IGCZ","B_RECORD_RE","H_RECORD_RE","HFDTE_RECORD_RE","NEWLINE_RE","IGC","altitudeMode_","altitudeMode","year","month","day","lastDateTime","hour","minute","second","UTC","FRACTION","IconImage","imageState_","tainting_","determineTainting_","dispatchChangeEvent_","replaceColor_","getSrc","imgData","putImageData","DEFAULT_COLOR","DEFAULT_IMAGE_STYLE_ANCHOR","DEFAULT_IMAGE_STYLE_ANCHOR_X_UNITS","DEFAULT_IMAGE_STYLE_ANCHOR_Y_UNITS","DEFAULT_IMAGE_STYLE_SIZE","DEFAULT_IMAGE_STYLE_SRC","DEFAULT_IMAGE_SCALE_MULTIPLIER","DEFAULT_NO_IMAGE_STYLE","DEFAULT_TEXT_STROKE_STYLE","Icon","normalizedAnchor_","anchorOrigin_","anchorOrigin","IconOrigin","anchorXUnits_","anchorXUnits","IconAnchorUnits","anchorYUnits_","anchorYUnits","img","imgSize","iconImage_","offset_","offsetOrigin_","offsetOrigin","setAnchor","iconImageSize","GX_NAMESPACE_URIS","ICON_ANCHOR_UNITS_MAP","pixels","insetPixels","PLACEMARK_PARSERS","ExtendedData","extendedDataParser","Region","regionParser","MultiGeometry","readMultiGeometry","readStyle","StyleMap","styleMapValue","readStyleMapValue","placemarkObject","address","description","phoneNumber","styleUrl","readURI","visibility","MultiTrack","GX_MULTITRACK_GEOMETRY_PARSERS","Track","readGxTrack","NETWORK_LINK_PARSERS","Link","REGION_PARSERS","LatLonAltBox","LAT_LON_ALT_BOX_PARSERS","regionObject","Lod","LOD_PARSERS","lodObject","KML_SEQUENCE","KML_SERIALIZERS","DOCUMENT_SERIALIZERS","DOCUMENT_NODE_FACTORY","Placemark","writePlacemark","DEFAULT_FILL_STYLE","DEFAULT_IMAGE_STYLE","DEFAULT_TEXT_STYLE","DEFAULT_STYLE","DEFAULT_STYLE_ARRAY","KML","defaultStyle_","defaultStyle","extractStyles_","extractStyles","writeStyles_","writeStyles","sharedStyles_","showPointNames_","showPointNames","readDocumentOrFolder_","Folder","readPlacemark_","readSharedStyle_","readSharedStyleMap_","sharedStyles","nameStyle","drawName","createNameStyleFunction","foundStyle","findStyle","styleValue","styleUri","baseURI","location","URL","fs","readName","readNameFromDocument","readNameFromNode","readNetworkLinks","networkLinks","readNetworkLinksFromDocument","readNetworkLinksFromNode","readRegion","regions","readRegionFromDocument","readRegionFromNode","kml","xmlnsUri","textOffset","imageScale","foundText","readColor","hexColor","readFlatCoordinates","readScale","STYLE_MAP_PARSERS","Pair","pairObject","PAIR_PARSERS","ICON_STYLE_PARSERS","iconObject","ICON_PARSERS","hotSpot","xunits","yunits","LABEL_STYLE_PARSERS","LINE_STYLE_PARSERS","POLY_STYLE_PARSERS","outline","FLAT_LINEAR_RING_PARSERS","readFlatLinearRing","GX_TRACK_PARSERS","when","whens","coord","gxTrackObject","GEOMETRY_FLAT_COORDINATES_PARSERS","readFlatCoordinatesFromNode","EXTRUDE_AND_ALTITUDE_MODE_PARSERS","extrude","tessellate","MULTI_GEOMETRY_PARSERS","multiGeometry","homogeneous","setCommonGeometryProperties","FLAT_LINEAR_RINGS_PARSERS","INNER_BOUNDARY_IS_PARSERS","OUTER_BOUNDARY_IS_PARSERS","STYLE_PARSERS","IconStyle","styleObject","IconObject","drawIcon","LabelStyle","LineStyle","PolyStyle","hasExtrude","hasTessellate","hasAltitudeMode","extrudes","tessellates","altitudeModes","DATA_PARSERS","displayName","EXTENDED_DATA_PARSERS","Data","featureObject","SchemaData","SCHEMA_DATA_PARSERS","SimpleData","minAltitude","maxAltitude","north","south","east","west","minLodPixels","maxLodPixels","minFadeExtent","maxFadeExtent","writeColorTextNode","rgba","abgr","hex","EXTENDEDDATA_NODE_SERIALIZERS","pair","createCDATASection","DATA_NODE_FACTORY","ICON_SEQUENCE","ICON_SERIALIZERS","GX_NODE_FACTORY","ICON_STYLE_SEQUENCE","ICON_STYLE_SERIALIZERS","icon","vec2","writeScaleTextNode","LABEL_STYLE_SEQUENCE","LABEL_STYLE_SERIALIZERS","LINE_STYLE_SEQUENCE","LINE_STYLE_SERIALIZERS","GEOMETRY_NODE_FACTORY","POINT_NODE_FACTORY","LINE_STRING_NODE_FACTORY","LINEAR_RING_NODE_FACTORY","POLYGON_NODE_FACTORY","MULTI_GEOMETRY_SERIALIZERS","writePrimitiveGeometry","writePolygon","writeMultiGeometry","BOUNDARY_IS_SERIALIZERS","writeBoundaryIs","PLACEMARK_SERIALIZERS","namesAndValues","names","STYLE_SEQUENCE","STYLE_SERIALIZERS","PLACEMARK_SEQUENCE","EXTENDEDDATA_NODE_FACTORY","v","PRIMITIVE_GEOMETRY_SEQUENCE","PRIMITIVE_GEOMETRY_SERIALIZERS","POLYGON_SERIALIZERS","INNER_BOUNDARY_NODE_FACTORY","OUTER_BOUNDARY_NODE_FACTORY","POLY_STYLE_SERIALIZERS","COLOR_NODE_FACTORY","iconProperties","isLE","mLen","nBytes","eLen","eMax","eBias","nBits","rt","Pbf","ArrayBuffer","isView","Varint","Fixed64","Bytes","Fixed32","SHIFT_LEFT_32","SHIFT_RIGHT_32","readPackedEnd","pbf","readVarint","toNum","isSigned","makeRoomForExtraLength","startPos","extraLen","realloc","writePackedVarint","writeVarint","writePackedSVarint","writeSVarint","writePackedFloat","writeFloat","writePackedDouble","writeDouble","writePackedBoolean","writeBoolean","writePackedFixed32","writeFixed32","writePackedSFixed32","writeSFixed32","writePackedFixed64","writeFixed64","writePackedSFixed64","writeSFixed64","readUInt32","writeInt32","readInt32","destroy","readFields","readField","tag","skip","readMessage","readFixed32","readSFixed32","readFixed64","readSFixed64","readFloat","ieee754","readDouble","readVarintRemainder","readVarint64","readSVarint","b3","b0","bytesPerSequence","fromCharCode","readUtf8","readBytes","subarray","readPackedVarint","readPackedSVarint","readPackedBoolean","readPackedFloat","readPackedDouble","readPackedFixed32","readPackedSFixed32","readPackedFixed64","readPackedSFixed64","writeTag","lsb","writeBigVarintHigh","writeBigVarint","writeString","lead","writeUtf8","writeBytes","writeRawMessage","writeMessage","writeBytesField","writeFixed32Field","writeSFixed32Field","writeFixed64Field","writeSFixed64Field","writeVarintField","writeSVarintField","writeStringField","writeFloatField","writeDoubleField","writeBooleanField","RenderFeature","flatCoordinates_","flatMidpoints_","properties_","midpoint","MVT","featureClass_","featureClass","layerName_","layerName","layers_","readRawGeometry_","cmd","coordsLen","currentEnd","cmdLen","createFeature_","rawFeature","getGeometryType","prevEndIndex","PBF","pbfLayers","layersPBFReader","pbfLayer","readRawFeature","layerPBFReader","version","featurePBFReader","WAY_PARSERS","nd","ndrefs","readTag","PARSERS","tags","NODE_PARSERS","way","ways","OSMXML","flipXY","opt_destOffset","destOffset","Polyline","factor_","factor","geometryLayout_","decodeDeltas","encodeDeltas","numbers","opt_factor","lastNumbers","encodeFloats","encoded","decodeFloats","encodeUnsignedInteger","encodeUnsignedIntegers","encodeSignedIntegers","current","decodeUnsignedIntegers","decodeSignedIntegers","TopoJSON","topoJSONTopology","arcs","transformArc","transformArcs","topoJSONFeatures","objectName","readFeaturesFromGeometryCollection","readFeatureFromGeometry","transformVertex","concatenateArcs","polyArray","ringCoords","Filter","tagName_","getTagName","LogicalNary","conditions","And","Bbox","Spatial","Contains","Comparison","propertyName","During","ComparisonBinary","expression","opt_matchCase","matchCase","EqualTo","GreaterThan","GreaterThanOrEqualTo","Intersects","IsBetween","lowerBoundary","upperBoundary","IsLike","pattern","opt_wildCard","opt_singleChar","opt_escapeChar","wildCard","singleChar","escapeChar","IsNull","LessThan","LessThanOrEqualTo","Not","NotEqualTo","Or","Within","and","boundedBy","TRANSACTION_SUMMARY_PARSERS","http://www.opengis.net/wfs","totalInserted","totalUpdated","totalDeleted","TRANSACTION_RESPONSE_PARSERS","TransactionSummary","InsertResults","INSERT_RESULTS_PARSERS","QUERY_SERIALIZERS","PropertyName","TRANSACTION_SERIALIZERS","Insert","gmlVersion","Update","featurePrefix","typeName","getTypeName","XMLNS","writeOgcFidFilter","Delete","WFSNS","Native","nativeElement","vendorId","safeToIgnore","FEATURE_PREFIX","OGCNS","SCHEMA_LOCATIONS","1.1.0","1.0.0","WFS","featureType_","featureNS_","gmlFormat_","gmlFormat","schemaLocation_","getFeatureType","setFeatureType","readTransactionResponse","readTransactionResponseFromDocument","readTransactionResponseFromNode","readFeatureCollectionMetadata","readFeatureCollectionMetadataFromDocument","readFeatureCollectionMetadataFromNode","writeGetFeature","handle","outputFormat","maxFeatures","resultType","bboxFilter","andFilter","propertyNames","GETFEATURE_SERIALIZERS","writeTransaction","inserts","updates","deletes","baseObj","gmlOptions","nativeElements","OGC_FID_PARSERS","http://www.opengis.net/ogc","FeatureId","prefix","Query","writeFilterCondition","valueReference","timePeriod","writeTimeInstant","writeLogicalFilter","BBOX","writeOgcPropertyName","PropertyIsEqualTo","writeComparisonFilter","PropertyIsNotEqualTo","PropertyIsLessThan","PropertyIsLessThanOrEqualTo","PropertyIsGreaterThan","PropertyIsGreaterThanOrEqualTo","PropertyIsNull","PropertyIsBetween","writeOgcLiteral","PropertyIsLike","writeOgcExpression","timeInstant","timePosition","GeometryConstructor","LINESTRING","MULTIPOINT","MULTILINESTRING","MULTIPOLYGON","EMPTY","Z","TokenType","WKTGeometryType","toUpperCase","Lexer","wkt","index_","isAlpha_","isNumeric_","opt_decimal","isWhiteSpace_","nextChar_","nextToken","token","readNumber_","readText_","scientificNotation","substring","Parser","lexer","lexer_","token_","layout_","consume_","isTokenType","match","isMatch","parseGeometry_","parseGeometryLayout_","dimToken","dimInfo","parseGeometryCollectionText_","isEmptyGeometry_","formatErrorMessage_","parsePointText_","parsePoint_","parseLineStringText_","parsePointList_","parsePolygonText_","parseLineStringTextList_","parseMultiPointText_","parsePointTextList_","parseMultiLineStringText_","parseMultiPolygonText_","parsePolygonTextList_","dimensions","geomType","WKT","splitCollection_","splitCollection","parse_","encode","encodePointGeometry","encodeLineStringGeometry","encodePolygonGeometry","GeometryEncoder","components","geoms","enc","geometryEncoder","NAMESPACE_URI","readHref","read","readFromDocument","readFromNode","Service","SERVICE_PARSERS","Capability","CAPABILITY_PARSERS","Request","REQUEST_PARSERS","Exception","EXCEPTION_PARSERS","LAYER_PARSERS","WMSCapabilities","wmsCapabilityObject","Name","Title","Abstract","KeywordList","readKeywordList","OnlineResource","ContactInformation","CONTACT_INFORMATION_PARSERS","Fees","AccessConstraints","LayerLimit","MaxWidth","MaxHeight","ContactPersonPrimary","CONTACT_PERSON_PARSERS","ContactPosition","ContactAddress","CONTACT_ADDRESS_PARSERS","ContactVoiceTelephone","ContactFacsimileTelephone","ContactElectronicMailAddress","ContactPerson","ContactOrganization","AddressType","Address","City","StateOrProvince","PostCode","Country","Format","CRS","EX_GeographicBoundingBox","geographicBoundingBox","EX_GEOGRAPHIC_BOUNDING_BOX_PARSERS","westBoundLongitude","southBoundLatitude","eastBoundLongitude","northBoundLatitude","BoundingBox","Dimension","unitSymbol","default","multipleValues","nearestValue","ATTRIBUTION_PARSERS","AuthorityURL","authorityObject","readFormatOnlineresource","Identifier","MetadataURL","metadataObject","DataURL","FeatureListURL","MinScaleDenominator","MaxScaleDenominator","parentLayerObject","layerObject","queryable","cascaded","opaque","noSubsets","fixedWidth","fixedHeight","childValue","parentValue","LogoURL","readSizedFormatOnlineresource","GetCapabilities","readOperationType","GetMap","GetFeatureInfo","OPERATIONTYPE_PARSERS","DCPType","DCPTYPE_PARSERS","HTTP","HTTP_PARSERS","Get","Post","LegendURL","StyleSheetURL","StyleURL","FORMAT_ONLINERESOURCE_PARSERS","KEYWORDLIST_PARSERS","Keyword","formatOnlineresource","WMSGetFeatureInfo","readFeatures_","layerFeatures","gmlFeatures","ServiceIdentification","SERVICE_IDENTIFICATION_PARSERS","ServiceProvider","SERVICE_PROVIDER_PARSERS","OperationsMetadata","OPERATIONS_METADATA_PARSERS","OWS","owsObject","ADDRESS_PARSERS","DeliveryPoint","AdministrativeArea","PostalCode","ElectronicMailAddress","ALLOWED_VALUES_PARSERS","Value","CONSTRAINT_PARSERS","AllowedValues","CONTACT_INFO_PARSERS","Phone","PHONE_PARSERS","DCP_PARSERS","REQUEST_METHOD_PARSERS","OPERATION_PARSERS","DCP","Operation","Voice","Facsimile","Constraint","SERVICE_CONTACT_PARSERS","IndividualName","PositionName","ContactInfo","ServiceTypeVersion","ServiceType","ProviderName","ProviderSite","ServiceContact","OWS_NAMESPACE_URIS","Contents","CONTENTS_PARSERS","WMTSCapabilities","owsParser_","WMTSCapabilityObject","TileMatrixSet","TMS_PARSERS","isDefault","TileMatrixSetLink","TMS_LINKS_PARSERS","DIMENSION_PARSERS","ResourceURL","resourceType","resource","WGS84BoundingBox","WGS84_BBOX_READERS","legend","TileMatrixSetLimits","TMS_LIMITS_LIST_PARSERS","TileMatrixLimits","TMS_LIMITS_PARSERS","TileMatrix","MinTileRow","MaxTileRow","MinTileCol","MaxTileCol","LowerCorner","readCoordinates","UpperCorner","WellKnownScaleSet","TM_PARSERS","SupportedCRS","TopLeftCorner","ScaleDenominator","TileWidth","TileHeight","MatrixWidth","MatrixHeight","DEFAULT_GRADIENT","Heatmap","gradient","blur","shadow","weight","gradient_","shadow_","circleImage_","styleCache_","handleGradientChanged_","setGradient","setBlur","handleStyleChanged_","weightFunction","handleRender_","createCircle_","getBlur","shadowOffsetX","shadowOffsetY","shadowBlur","shadowColor","toDataURL","getGradient","colors","createLinearGradient","step","addColorStop","createGradient","view8","ImageLayer","TileLayer","setPreload","setUseInterimTilesOnError","TileProperty","VectorTileLayer","opt_tileCoord","getKeyZXY","createFromTemplate","zRegEx","xRegEx","yRegEx","dashYRegEx","getFullTileRange","createFromTemplates","templates","tileUrlFunctions","createFromTileUrlFunctions","tileCoordHash","nullTileUrlFunction","expandUrl","urls","startCharCode","stopCharCode","stop","jsonp","opt_errback","opt_callbackParam","script","async","timer","getElementsByTagName","TileCache","pruneExceptNewestZ","calculateSourceResolution","targetProj","targetMetersPerUnit","sourceMetersPerUnit","sourceExtent","compensationFactor","isFinite","enlargeClipPoint","centroidX","centroidY","dX","dY","targetExtent","triangulation","sources","opt_renderEdges","sourceDataExtent","canvasWidthInUnits","canvasHeightInUnits","stitchContext","stitchScale","xPos","yPos","srcWidth","srcHeight","targetTopLeft","getTriangles","triangle","u0","v0","u1","u2","sourceNumericalShiftX","sourceNumericalShiftY","affineCoefs","maxRow","maxEl","absValue","coef","solveLinearSystem","Triangulation","maxSourceExtent","errorThreshold","sourceProj_","targetProj_","transformInvCache","transformInv","transformInv_","maxSourceExtent_","errorThresholdSquared_","triangles_","wrapsXInSource_","canWrapXInSource_","sourceWorldWidth_","targetWorldWidth_","destinationTopLeft","destinationTopRight","destinationBottomRight","destinationBottomLeft","sourceTopLeft","sourceTopRight","sourceBottomRight","sourceBottomLeft","addQuad_","leftBound","newTriangle","addTriangle_","aSrc","bSrc","cSrc","dSrc","maxSubdivision","sourceQuadExtent","sourceCoverageX","sourceWorldWidth","wrapsX","needsSubdivision","centerSrc","bc","bcSrc","da","daSrc","ab","abSrc","cd","cdSrc","calculateSourceExtent","ReprojTile","targetTileGrid","getTileFunction","opt_errorThreshold","renderEdges_","gutter_","sourceTileGrid_","targetTileGrid_","wrappedTileCoord_","sourceTiles_","sourcesListenerKeys_","sourceZ_","maxTargetExtent","limitedTargetExtent","sourceProjExtent","errorThresholdInPixels","triangulation_","sourceRange","srcX","srcY","unlistenSources_","reproject_","renderReprojected","leftToLoad","sourceListenKey","tmpTileCoord","TileGrid","opt_strict","currentVal","origins","origins_","tileSizes_","tileSizes","tileSize_","fullTileRanges_","sizes","calculateTileRanges_","getForProjection","createForProjection","createForExtent","opt_maxZoom","opt_tileSize","opt_corner","corner","Corner","resolutionsFromExtent","createXYZ","extentFromProjection","half","forEachTileCoord","opt_tileRange","tileCoordExtent","createOrUpdateTileRange","getTileCoordForXYAndZ_","getTileCoordForCoordAndResolution","getTileCoordForXYAndResolution_","reverseIntersectionPolicy","adjustX","adjustY","xFromOrigin","yFromOrigin","tileCoordX","tileCoordY","createOrUpdateTileCoord","getTileCoordForCoordAndZ","getTileCoordResolution","fullTileRanges","TileSource","opaque_","tilePixelRatio_","tileCache","tmpSize","tileOptions","getTileCacheForProjection","setKey","thisProj","scaleSize","getTileCoordForTileUrlFunction","worldsAway","withinExtentAndZ","TileSourceEvent","UrlTile","tileUrlFunction","fixedTileUrlFunction","setUrls","setUrl","setTileUrlFunction","tileLoadingKeys_","getTileLoadFunction","getTileUrlFunction","getUrls","TileEventType","setTileLoadFunction","opt_key","TileImage","defaultTileLoadFunction","tileClass","tileCacheForProjection","tileGridForProjection","reprojectionErrorThreshold_","reprojectionErrorThreshold","renderReprojectionEdges_","usedTileCache","getGutterInternal","projKey","createTile_","urlTileCoord","tileUrl","newTile","getTileInternal","setRenderReprojectionEdges","setTileGridForProjection","tilegrid","imageTile","BingMaps","hidpi","hidpi_","culture_","culture","maxZoom_","apiKey_","imagerySet_","imagerySet","requestJSONP","handleImageryMetadataResponse","getApiKey","getImagerySet","response","statusCode","statusDescription","authenticationResultCode","resourceSets","resources","zoomMax","zoomMin","imageUrlSubdomains","subdomain","quadKeyTileCoord","imageUrl","digits","quadKey","imageryProviders","imageryProvider","intersecting","coverageAreas","coverageArea","CartoDB","account_","account","mapId_","config_","config","templateCache_","initializeMap_","getConfig","updateConfig","setConfig","paramHash","applyTemplate_","mapUrl","client","handleInitResponse_","handleInitError_","setRequestHeader","tilesUrl","cdn_url","https","layergroupid","Cluster","cluster","setDistance","mapDistance","clustered","neighbors","neighbor","createCluster","ReprojImage","getImageFunction","sourceImage","sourcePixelRatio","targetResolution_","targetExtent_","sourceImage_","sourcePixelRatio_","sourceListenerKey_","unlistenSource_","ImageSourceEventType","ImageSourceEvent","ImageSource","reprojectedImage_","reprojectedRevision_","findNearestResolution","getImageInternal","handleImageChange","defaultImageLoadFunction","appendParams","keyParams","encodeURIComponent","qs","ImageArcGISRest","params_","ratio_","getParams","F","FORMAT","TRANSPARENT","halfWidth","halfHeight","getRequestUrl_","getImageLoadFunction","srid","modifiedUrl","setImageLoadFunction","updateParams","ImageCanvasSource","canvasFunction_","canvasFunction","canvasElement","ImageMapGuide","displayDpi_","displayDpi","useOverlay_","useOverlay","baseUrl","dpi","mcsW","mcsH","devW","devH","mpp","baseParams","OPERATION","VERSION","LOCALE","CLIENTAGENT","CLIP","SETDISPLAYDPI","SETDISPLAYWIDTH","SETDISPLAYHEIGHT","SETVIEWSCALE","SETVIEWCENTERX","SETVIEWCENTERY","Static","targetWidth","DEFAULT_WMS_VERSION","GETFEATUREINFO_IMAGE_SIZE","ImageWMS","v13_","updateV13_","serverType_","getGetFeatureInfoUrl","projectionObj","sourceProjectionObj","SERVICE","REQUEST","QUERY_LAYERS","viewExtent","requestExtent","WMSServerType","ATTRIBUTION","OSM","hasImageData","ImageData","_","newImageData","createImageData","createMinion","operation","workerHasImageData","buffers","meta","imageOps","numBuffers","numBytes","byteLength","Uint8ClampedArray","arrays","createWorker","onMessage","lib","blob","Blob","createObjectURL","worker","Worker","Processor","threads","_imageOps","minion","workers","_onWorkerMessage","postMessage","_workers","_queue","_maxQueueLength","queue","_running","_dataLookup","_job","process","inputs","_enqueue","_dispatch","_destroyed","job","slices","_resolveJob","RasterEventType","RasterOperationType","RasterSourceEvent","RasterSource","worker_","operationType_","operationType","threads_","renderers_","createRenderers","requestedFrameState_","renderedImageCanvas_","setOperation","opt_lib","updateFrameState_","allSourcesReady_","ready","processSources_","imageDatas","onWorkerComplete_","sharedContext","ATTRIBUTIONS","OSM_ATTRIBUTION","LayerConfig","terrain","terrain-background","terrain-labels","terrain-lines","toner-background","toner","toner-hybrid","toner-labels","toner-lines","toner-lite","watercolor","ProviderConfig","Stamen","provider","providerConfig","layerConfig","TileArcGISRest","tmpExtent_","getKeyForParams_","LabeledTile","strokeRect","TileDebug","textTileCoord","TileJSON","tileJSON_","handleTileJSONResponse","handleTileJSONError","onXHRLoad_","onXHRError_","tileJSON","getTileJSON","bounds","minzoom","maxzoom","attributionExtent","TileWMS","transparent","bufferSize","CustomTile","preemptive","preemptive_","grid_","data_","jsonp_","getData","xRelative","yRelative","row","forDataAtCoordinate","opt_request","loadInternal_","handleError_","json","grid","UTFGrid","tileUrlFunction_","template_","getTemplate","forDataAtCoordinateAndResolution","grids","VectorImageTile","sourceTiles","replayState_","sourceRevision_","loadListenerKeys_","sourceTileListenerKeys_","sourceZ","useLoadedOnly","loadCount","sourceTileKey","finishLoading_","errorSourceTiles","empty","defaultLoadFunction","tileGrids_","KVP","REST","WMTSTileGrid","matrixIds_","matrixIds","getMatrixId","getMatrixIds","createFromCapabilitiesMatrixSet","matrixSet","opt_matrixLimits","matrixLimits","matrixIdsPropName","identifierPropName","scaleDenominatorPropName","topLeftCornerPropName","switchOriginXY","elt","elt_ml","tileWidth","tileHeight","WMTS","requestEncoding","WMTSRequestEncoding","version_","dimensions_","matrixSet_","requestEncoding_","getKeyForDimensions_","createFromWMTSTemplate","tilematrixset","Version","localContext","TileCol","TileRow","getDimensions","getMatrixSet","getRequestEncoding","getVersion","updateDimensions","TierSizeCalculation","zoomifyImage_","Zoomify","tierSizeCalculation","tierSizeInTiles","tileSizeForTierSizeCalculation","tileCountUpToTier","tileCoordZ","tileIndex","TileGroup","ZoomifyTileClass","ol","colorlike","featureloader","loadingstrategy","proj4","webgl","sphere","$ol$Collection","$ol$Feature","$ol$Geolocation","$ol$Graticule","$ol$Kinetic","$ol$Map","$ol$Object","$ol$Observable","unByKey","$ol$Overlay","$ol$PluggableMap","$ol$View","$ol$WebGLMap","_ol_color.asArray","_ol_color.asString","_ol_colorlike.asColorLike","$ol$control$Attribution","_ol_control_Attribution.render","$ol$control$Control","$ol$control$FullScreen","$ol$control$MousePosition","_ol_control_MousePosition.render","$ol$control$OverviewMap","_ol_control_OverviewMap.render","$ol$control$Rotate","_ol_control_Rotate.render","$ol$control$ScaleLine","_ol_control_ScaleLine.render","$ol$control$Zoom","$ol$control$ZoomSlider","_ol_control_ZoomSlider.render","$ol$control$ZoomToExtent","_ol_control.defaults","_ol_coordinate.add","createStringXY","_ol_coordinate.format","_ol_coordinate.rotate","toStringHDMS","_ol_coordinate.toStringXY","_ol_easing.easeIn","_ol_easing.easeOut","_ol_easing.inAndOut","_ol_easing.linear","upAndDown","_ol_events_condition.altKeyOnly","_ol_events_condition.altShiftKeysOnly","_ol_events_condition.always","click","doubleClick","activeElement","_ol_events_condition.mouseOnly","_ol_events_condition.never","_ol_events_condition.noModifierKeys","platformModifierKeyOnly","_ol_events_condition.pointerMove","_ol_events_condition.primaryAction","_ol_events_condition.shiftKeyOnly","_ol_events_condition.singleClick","_ol_events_condition.targetNotEditable","_ol_extent.applyTransform","_ol_extent.boundingExtent","_ol_extent.buffer","_ol_extent.containsCoordinate","_ol_extent.containsExtent","_ol_extent.containsXY","_ol_extent.createEmpty","_ol_extent.equals","_ol_extent.extend","_ol_extent.getArea","_ol_extent.getBottomLeft","_ol_extent.getBottomRight","_ol_extent.getCenter","_ol_extent.getHeight","_ol_extent.getIntersection","_ol_extent.getTopLeft","_ol_extent.getTopRight","_ol_extent.getWidth","_ol_extent.intersects","_ol_extent.isEmpty","_ol_featureloader.xhr","$ol$format$EsriJSON","$ol$format$Feature","$ol$format$GML","$ol$format$GML2","$ol$format$GML3","$ol$format$GPX","$ol$format$GeoJSON","$ol$format$IGC","$ol$format$KML","$ol$format$MVT","$ol$format$OSMXML","$ol$format$Polyline","_ol_format_Polyline.decodeDeltas","_ol_format_Polyline.decodeFloats","_ol_format_Polyline.encodeDeltas","_ol_format_Polyline.encodeFloats","$ol$format$TopoJSON","$ol$format$WFS","writeFilter","$ol$format$WKT","$ol$format$WMSCapabilities","$ol$format$WMSGetFeatureInfo","$ol$format$WMTSCapabilities","$ol$format$filter$Bbox","$ol$format$filter$Contains","$ol$format$filter$During","$ol$format$filter$EqualTo","$ol$format$filter$GreaterThan","$ol$format$filter$GreaterThanOrEqualTo","$ol$format$filter$Intersects","$ol$format$filter$IsBetween","$ol$format$filter$IsLike","$ol$format$filter$IsNull","$ol$format$filter$LessThan","$ol$format$filter$LessThanOrEqualTo","$ol$format$filter$Not","$ol$format$filter$NotEqualTo","$ol$format$filter$Or","$ol$format$filter$Within","_ol_format_filter.and","_ol_format_filter.bbox","between","during","equalTo","greaterThan","greaterThanOrEqualTo","isNull","lessThan","lessThanOrEqualTo","like","not","notEqualTo","or","within","$ol$geom$Circle","$ol$geom$Geometry","$ol$geom$GeometryCollection","$ol$geom$LineString","$ol$geom$LinearRing","$ol$geom$MultiLineString","$ol$geom$MultiPoint","$ol$geom$MultiPolygon","$ol$geom$Point","$ol$geom$Polygon","_ol_geom_Polygon.circular","_ol_geom_Polygon.fromCircle","_ol_geom_Polygon.fromExtent","$ol$geom$SimpleGeometry","_ol_has.DEVICE_PIXEL_RATIO","_ol_has.GEOLOCATION","_ol_has.TOUCH","inherits","childCtor","parentCtor","create","constructor","$ol$interaction$DoubleClickZoom","$ol$interaction$DragAndDrop","$ol$interaction$DragBox","$ol$interaction$DragPan","$ol$interaction$DragRotate","$ol$interaction$DragRotateAndZoom","$ol$interaction$DragZoom","$ol$interaction$Draw","createBox","boxCoordinates","createRegularPolygon","_ol_interaction_Draw.handleEvent","Extent","$ol$interaction$Extent","$ol$interaction$Interaction","$ol$interaction$KeyboardPan","$ol$interaction$KeyboardZoom","$ol$interaction$Modify","$ol$interaction$MouseWheelZoom","$ol$interaction$PinchRotate","$ol$interaction$PinchZoom","Pointer","$ol$interaction$Pointer","_ol_interaction_Pointer.handleEvent","$ol$interaction$Select","$ol$interaction$Snap","$ol$interaction$Translate","_ol_interaction.defaults","Base","$ol$layer$Base","Group","$ol$layer$Group","$ol$layer$Heatmap","$ol$layer$Image","$ol$layer$Tile","Vector","$ol$layer$Vector","$ol$layer$VectorTile","_ol_loadingstrategy.all","$ol$proj$Projection","_ol_proj_Units.METERS_PER_UNIT","_ol_proj.addCoordinateTransforms","_ol_proj.addEquivalentProjections","_ol_proj.addProjection","_ol_proj.equivalent","fromLonLat","_ol_proj.get","_ol_proj.getPointResolution","_ol_proj.getTransform","projCodes","defs","def","axis","to_meter","code1","proj1","code2","proj2","toLonLat","lonLat","_ol_proj.transform","_ol_proj.transformExtent","$ol$render$VectorContext","_ol_render_canvas.labelCache","toContext","$ol$renderer$canvas$ImageLayer","$ol$renderer$canvas$Map","$ol$renderer$canvas$TileLayer","$ol$renderer$canvas$VectorLayer","$ol$renderer$canvas$VectorTileLayer","$ol$renderer$webgl$ImageLayer","$ol$renderer$webgl$Map","$ol$renderer$webgl$TileLayer","$ol$renderer$webgl$VectorLayer","_ol_size.toSize","$ol$source$BingMaps","$ol$source$CartoDB","$ol$source$Cluster","$ol$source$Image","$ol$source$ImageArcGISRest","$ol$source$ImageCanvas","$ol$source$ImageMapGuide","ImageStatic","$ol$source$ImageStatic","$ol$source$ImageWMS","$ol$source$OSM","_ol_source_OSM.ATTRIBUTION","Raster","$ol$source$Raster","$ol$source$Source","$ol$source$Stamen","$ol$source$Tile","$ol$source$TileArcGISRest","$ol$source$TileDebug","$ol$source$TileImage","$ol$source$TileJSON","$ol$source$TileWMS","$ol$source$UTFGrid","$ol$source$Vector","$ol$source$VectorTile","$ol$source$WMTS","optionsFromCapabilities","wmtsCap","tileMatrixSets","supportedCRS","matrixSetObj","projConfig","wgs84BoundingBox","wgs84ProjectionExtent","gets","encodings","$ol$source$XYZ","$ol$source$Zoomify","_ol_sphere.getDistance","$ol$style$AtlasManager","$ol$style$Circle","$ol$style$Fill","$ol$style$Icon","_ol_style_IconImageCache.shared","$ol$style$Image","$ol$style$RegularShape","$ol$style$Stroke","$ol$style$Style","$ol$style$Text","$ol$tilegrid$TileGrid","$ol$tilegrid$WMTS","_ol_tilegrid_WMTS.createFromCapabilitiesMatrixSet","_ol_tilegrid.createXYZ","_ol_xml.getAllTextContent","_ol_xml.parse"],"mappings":"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"}