diff options
| -rw-r--r-- | chimere/static/ol3/ol-debug.js | 57917 | ||||
| -rw-r--r-- | chimere/static/ol3/ol.js | 1989 |
2 files changed, 23116 insertions, 36790 deletions
diff --git a/chimere/static/ol3/ol-debug.js b/chimere/static/ol3/ol-debug.js index 5bf1864..91f7ae3 100644 --- a/chimere/static/ol3/ol-debug.js +++ b/chimere/static/ol3/ol-debug.js @@ -1,6 +1,6 @@ // OpenLayers 3. See http://openlayers.org/ // License: https://raw.githubusercontent.com/openlayers/ol3/master/LICENSE.md -// Version: v3.12.1 +// Version: v3.16.0 (function (root, factory) { if (typeof exports === "object") { @@ -177,7 +177,8 @@ goog.define = function(name, defaultValue) { Object.prototype.hasOwnProperty.call( goog.global.CLOSURE_UNCOMPILED_DEFINES, name)) { value = goog.global.CLOSURE_UNCOMPILED_DEFINES[name]; - } else if (goog.global.CLOSURE_DEFINES && + } else if ( + goog.global.CLOSURE_DEFINES && Object.prototype.hasOwnProperty.call( goog.global.CLOSURE_DEFINES, name)) { value = goog.global.CLOSURE_DEFINES[name]; @@ -239,7 +240,7 @@ goog.define('goog.TRUSTED_SITE', true); * * This define can be used to trigger alternate implementations compatible with * running in EcmaScript Strict mode or warn about unavailable functionality. - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode + * @see https://goo.gl/g5EoHI * */ goog.define('goog.STRICT_MODE_COMPATIBLE', false); @@ -282,6 +283,9 @@ goog.define('goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING', false); * "goog.package.part". */ goog.provide = function(name) { + if (goog.isInModuleLoader_()) { + throw Error('goog.provide can not be used within a goog.module.'); + } if (!COMPILED) { // Ensure that the same namespace isn't provided twice. // A goog.module/goog.provide maps a goog.require to a specific file @@ -359,8 +363,7 @@ goog.VALID_MODULE_RE_ = /^[a-zA-Z_$][a-zA-Z0-9._$]*$/; * "goog.package.part", is expected but not required. */ goog.module = function(name) { - if (!goog.isString(name) || - !name || + if (!goog.isString(name) || !name || name.search(goog.VALID_MODULE_RE_) == -1) { throw Error('Invalid module identifier'); } @@ -408,9 +411,8 @@ goog.module.getInternal_ = function(name) { if (!COMPILED) { if (goog.isProvided_(name)) { // goog.require only return a value with-in goog.module files. - return name in goog.loadedModules_ ? - goog.loadedModules_[name] : - goog.getObjectByName(name); + return name in goog.loadedModules_ ? goog.loadedModules_[name] : + goog.getObjectByName(name); } else { return null; } @@ -419,7 +421,7 @@ goog.module.getInternal_ = function(name) { /** - * @private {?{moduleName: (string|undefined)}} + * @private {?{moduleName: (string|undefined), declareLegacyNamespace:boolean}} */ goog.moduleLoaderState_ = null; @@ -441,11 +443,13 @@ goog.isInModuleLoader_ = function() { */ goog.module.declareLegacyNamespace = function() { if (!COMPILED && !goog.isInModuleLoader_()) { - throw new Error('goog.module.declareLegacyNamespace must be called from ' + + throw new Error( + 'goog.module.declareLegacyNamespace must be called from ' + 'within a goog.module'); } if (!COMPILED && !goog.moduleLoaderState_.moduleName) { - throw Error('goog.module must be called prior to ' + + throw Error( + 'goog.module must be called prior to ' + 'goog.module.declareLegacyNamespace.'); } goog.moduleLoaderState_.declareLegacyNamespace = true; @@ -466,8 +470,9 @@ goog.module.declareLegacyNamespace = function() { goog.setTestOnly = function(opt_message) { if (goog.DISALLOW_TEST_ONLY_CODE) { opt_message = opt_message || ''; - throw Error('Importing test-only code into non-debug environment' + - (opt_message ? ': ' + opt_message : '.')); + throw Error( + 'Importing test-only code into non-debug environment' + + (opt_message ? ': ' + opt_message : '.')); } }; @@ -497,11 +502,11 @@ goog.forwardDeclare = function(name) {}; * and thus block property disambiguation. */ goog.forwardDeclare('Document'); +goog.forwardDeclare('HTMLScriptElement'); goog.forwardDeclare('XMLHttpRequest'); if (!COMPILED) { - /** * Check if the given name has been goog.provided. This will return false for * names that are available only as implicit namespaces. @@ -512,7 +517,7 @@ if (!COMPILED) { goog.isProvided_ = function(name) { return (name in goog.loadedModules_) || (!goog.implicitNamespaces_[name] && - goog.isDefAndNotNull(goog.getObjectByName(name))); + goog.isDefAndNotNull(goog.getObjectByName(name))); }; /** @@ -546,7 +551,7 @@ if (!COMPILED) { goog.getObjectByName = function(name, opt_obj) { var parts = name.split('.'); var cur = opt_obj || goog.global; - for (var part; part = parts.shift(); ) { + for (var part; part = parts.shift();) { if (goog.isDefAndNotNull(cur[part])) { cur = cur[part]; } else { @@ -580,17 +585,22 @@ goog.globalize = function(obj, opt_global) { * the names of the objects this file provides. * @param {!Array<string>} requires An array of strings with * the names of the objects this file requires. - * @param {boolean=} opt_isModule Whether this dependency must be loaded as - * a module as declared by goog.module. + * @param {boolean|!Object<string>=} opt_loadFlags Parameters indicating + * how the file must be loaded. The boolean 'true' is equivalent + * to {'module': 'goog'} for backwards-compatibility. Valid properties + * and values include {'module': 'goog'} and {'lang': 'es6'}. */ -goog.addDependency = function(relPath, provides, requires, opt_isModule) { +goog.addDependency = function(relPath, provides, requires, opt_loadFlags) { if (goog.DEPENDENCIES_ENABLED) { var provide, require; var path = relPath.replace(/\\/g, '/'); var deps = goog.dependencies_; + if (!opt_loadFlags || typeof opt_loadFlags === 'boolean') { + opt_loadFlags = opt_loadFlags ? {'module': 'goog'} : {}; + } for (var i = 0; provide = provides[i]; i++) { deps.nameToPath[provide] = path; - deps.pathIsModule[path] = !!opt_isModule; + deps.pathIsModule[path] = opt_loadFlags['module'] == 'goog'; } for (var j = 0; require = requires[j]; j++) { if (!(path in deps.requires)) { @@ -612,9 +622,10 @@ goog.addDependency = function(relPath, provides, requires, opt_isModule) { // will not load until some point after the current script. If a namespace is // needed at runtime, it needs to be defined in a previous script, or loaded via // require() with its registered dependencies. -// User-defined namespaces may need their own deps file. See http://go/js_deps, -// http://go/genjsdeps, or, externally, DepsWriter. -// https://developers.google.com/closure/library/docs/depswriter +// +// User-defined namespaces may need their own deps file. For a reference on +// creating a deps file, see: +// Externally: https://developers.google.com/closure/library/docs/depswriter // // Because of legacy clients, the DOM loader can't be easily removed from // base.js. Work is being done to make it disableable or replaceable for @@ -810,7 +821,6 @@ goog.DEPENDENCIES_ENABLED = !COMPILED && goog.ENABLE_DEBUG_LOADER; if (goog.DEPENDENCIES_ENABLED) { - /** * This object is used to keep track of dependencies and other data that is * used for loading scripts. @@ -825,18 +835,18 @@ if (goog.DEPENDENCIES_ENABLED) { * }} */ goog.dependencies_ = { - pathIsModule: {}, // 1 to 1 + pathIsModule: {}, // 1 to 1 - nameToPath: {}, // 1 to 1 + nameToPath: {}, // 1 to 1 - requires: {}, // 1 to many + requires: {}, // 1 to many // Used when resolving dependencies to prevent us from visiting file twice. visited: {}, - written: {}, // Used to keep track of script files we have written. + written: {}, // Used to keep track of script files we have written. - deferred: {} // Used to track deferred module evaluations in old IEs + deferred: {} // Used to track deferred module evaluations in old IEs }; @@ -848,8 +858,7 @@ if (goog.DEPENDENCIES_ENABLED) { goog.inHtmlDocument_ = function() { /** @type {Document} */ var doc = goog.global.document; - return typeof doc != 'undefined' && - 'write' in doc; // XULDocument misses write. + return doc != null && 'write' in doc; // XULDocument misses write. }; @@ -890,8 +899,8 @@ if (goog.DEPENDENCIES_ENABLED) { * @private */ goog.importScript_ = function(src, opt_sourceText) { - var importScript = goog.global.CLOSURE_IMPORT_SCRIPT || - goog.writeScriptTag_; + var importScript = + goog.global.CLOSURE_IMPORT_SCRIPT || goog.writeScriptTag_; if (importScript(src, opt_sourceText)) { goog.dependencies_.written[src] = true; } @@ -899,8 +908,8 @@ if (goog.DEPENDENCIES_ENABLED) { /** @const @private {boolean} */ - goog.IS_OLD_IE_ = !!(!goog.global.atob && goog.global.document && - goog.global.document.all); + goog.IS_OLD_IE_ = + !!(!goog.global.atob && goog.global.document && goog.global.document.all); /** @@ -935,9 +944,8 @@ if (goog.DEPENDENCIES_ENABLED) { if (!goog.LOAD_MODULE_USING_EVAL || !goog.isDef(goog.global.JSON)) { return '' + 'goog.loadModule(function(exports) {' + - '"use strict";' + - scriptText + - '\n' + // terminate any trailing single line comment. + '"use strict";' + scriptText + + '\n' + // terminate any trailing single line comment. ';return exports' + '});' + '\n//# sourceURL=' + srcUrl + '\n'; @@ -996,8 +1004,7 @@ if (goog.DEPENDENCIES_ENABLED) { * @private */ goog.maybeProcessDeferredDep_ = function(name) { - if (goog.isDeferredModule_(name) && - goog.allDepsAreAvailable_(name)) { + if (goog.isDeferredModule_(name) && goog.allDepsAreAvailable_(name)) { var path = goog.getPathFromDeps_(name); goog.maybeProcessDeferredPath_(goog.basePath + path); } @@ -1053,6 +1060,33 @@ if (goog.DEPENDENCIES_ENABLED) { /** + * Load a goog.module from the provided URL. This is not a general purpose + * code loader and does not support late loading code, that is it should only + * be used during page load. This method exists to support unit tests and + * "debug" loaders that would otherwise have inserted script tags. Under the + * hood this needs to use a synchronous XHR and is not recommeneded for + * production code. + * + * The module's goog.requires must have already been satisified; an exception + * will be thrown if this is not the case. This assumption is that no + * "deps.js" file exists, so there is no way to discover and locate the + * module-to-be-loaded's dependencies and no attempt is made to do so. + * + * There should only be one attempt to load a module. If + * "goog.loadModuleFromUrl" is called for an already loaded module, an + * exception will be throw. + * + * @param {string} url The URL from which to attempt to load the goog.module. + */ + goog.loadModuleFromUrl = function(url) { + // Because this executes synchronously, we don't need to do any additional + // bookkeeping. When "goog.loadModule" the namespace will be marked as + // having been provided which is sufficient. + goog.retrieveAndExecModule_(url); + }; + + + /** * @param {function(?):?|string} moduleDef The module definition. */ goog.loadModule = function(moduleDef) { @@ -1063,7 +1097,10 @@ if (goog.DEPENDENCIES_ENABLED) { // of the module. var previousState = goog.moduleLoaderState_; try { - goog.moduleLoaderState_ = {moduleName: undefined}; + goog.moduleLoaderState_ = { + moduleName: undefined, + declareLegacyNamespace: false + }; var exports; if (goog.isFunction(moduleDef)) { exports = moduleDef.call(goog.global, {}); @@ -1095,6 +1132,10 @@ if (goog.DEPENDENCIES_ENABLED) { /** * @private @const {function(string):?} + * + * The new type inference warns because this function has no formal + * parameters, but its jsdoc says that it takes one argument. + * (The argument is used via arguments[0], but NTI does not detect this.) * @suppress {newCheckTypes} */ goog.loadModuleFromSource_ = function() { @@ -1118,7 +1159,8 @@ if (goog.DEPENDENCIES_ENABLED) { */ goog.writeScriptSrcNode_ = function(src) { goog.global.document.write( - '<script type="text/javascript" src="' + src + '"></' + 'script>'); + '<script type="text/javascript" src="' + src + '"></' + + 'script>'); }; @@ -1143,7 +1185,8 @@ if (goog.DEPENDENCIES_ENABLED) { goog.appendScriptSrcNode_ = function(src) { /** @type {Document} */ var doc = goog.global.document; - var scriptEl = doc.createElement('script'); + var scriptEl = + /** @type {HTMLScriptElement} */ (doc.createElement('script')); scriptEl.type = 'text/javascript'; scriptEl.src = src; scriptEl.defer = false; @@ -1163,7 +1206,7 @@ if (goog.DEPENDENCIES_ENABLED) { */ goog.writeScriptTag_ = function(src, opt_sourceText) { if (goog.inHtmlDocument_()) { - /** @type {Document} */ + /** @type {!HTMLDocument} */ var doc = goog.global.document; // If the user tries to require a new symbol after document load, @@ -1197,14 +1240,14 @@ if (goog.DEPENDENCIES_ENABLED) { var state = " onreadystatechange='goog.onScriptLoad_(this, " + ++goog.lastNonModuleScriptIndex_ + ")' "; doc.write( - '<script type="text/javascript" src="' + - src + '"' + state + '></' + 'script>'); + '<script type="text/javascript" src="' + src + '"' + state + + '></' + + 'script>'); } } else { doc.write( - '<script type="text/javascript">' + - opt_sourceText + - '</' + 'script>'); + '<script type="text/javascript">' + opt_sourceText + '</' + + 'script>'); } return true; } else { @@ -1351,8 +1394,9 @@ goog.normalizePath_ = function(path) { while (i < components.length) { if (components[i] == '.') { components.splice(i, 1); - } else if (i && components[i] == '..' && - components[i - 1] && components[i - 1] != '..') { + } else if ( + i && components[i] == '..' && components[i - 1] && + components[i - 1] != '..') { components.splice(--i, 2); } else { i++; @@ -1394,8 +1438,8 @@ goog.retrieveAndExecModule_ = function(src) { // console doesn't auto-canonicalize XHR loads as it does <script> srcs. src = goog.normalizePath_(src); - var importScript = goog.global.CLOSURE_IMPORT_SCRIPT || - goog.writeScriptTag_; + var importScript = + goog.global.CLOSURE_IMPORT_SCRIPT || goog.writeScriptTag_; var scriptText = goog.loadFileSync_(src); @@ -1423,7 +1467,7 @@ goog.retrieveAndExecModule_ = function(src) { /** * This is a "fixed" version of the typeof operator. It differs from the typeof * operator in such a way that null returns 'null' and arrays return 'array'. - * @param {*} value The value to get the type of. + * @param {?} value The value to get the type of. * @return {string} The name of the type. */ goog.typeOf = function(value) { @@ -1433,7 +1477,7 @@ goog.typeOf = function(value) { // Check these first, so we can avoid calling Object.prototype.toString if // possible. // - // IE improperly marshals tyepof across execution contexts, but a + // IE improperly marshals typeof across execution contexts, but a // cross-context object will still return false for "instanceof Object". if (value instanceof Array) { return 'array'; @@ -1445,7 +1489,7 @@ goog.typeOf = function(value) { // value, the compiler requires the value be cast to type Object, // even though the ECMA spec explicitly allows it. var className = Object.prototype.toString.call( - /** @type {Object} */ (value)); + /** @type {!Object} */ (value)); // In Firefox 3.6, attempting to access iframe window objects' length // property throws an NS_ERROR_FAILURE, so we need to special-case it // here. @@ -1476,11 +1520,11 @@ goog.typeOf = function(value) { // boundaries (not iframe though) so we have to do object detection // for this edge case. typeof value.length == 'number' && - typeof value.splice != 'undefined' && - typeof value.propertyIsEnumerable != 'undefined' && - !value.propertyIsEnumerable('splice') + typeof value.splice != 'undefined' && + typeof value.propertyIsEnumerable != 'undefined' && + !value.propertyIsEnumerable('splice') - )) { + )) { return 'array'; } // HACK: There is still an array case that fails. @@ -1498,9 +1542,9 @@ goog.typeOf = function(value) { // 'function'. However, if the object has a call property, it is a // function. if ((className == '[object Function]' || - typeof value.call != 'undefined' && - typeof value.propertyIsEnumerable != 'undefined' && - !value.propertyIsEnumerable('call'))) { + typeof value.call != 'undefined' && + typeof value.propertyIsEnumerable != 'undefined' && + !value.propertyIsEnumerable('call'))) { return 'function'; } @@ -1676,7 +1720,7 @@ goog.removeUid = function(obj) { // In IE, DOM nodes are not instances of Object and throw an exception if we // try to delete. Instead we try to use removeAttribute. - if ('removeAttribute' in obj) { + if (obj !== null && 'removeAttribute' in obj) { obj.removeAttribute(goog.UID_PROPERTY_); } /** @preserveTry */ @@ -1799,9 +1843,7 @@ goog.bindJs_ = function(fn, selfObj, var_args) { }; } else { - return function() { - return fn.apply(selfObj, arguments); - }; + return function() { return fn.apply(selfObj, arguments); }; } }; @@ -1898,10 +1940,11 @@ goog.mixin = function(target, source) { * between midnight, January 1, 1970 and the current time. */ goog.now = (goog.TRUSTED_SITE && Date.now) || (function() { - // Unary plus operator converts its operand to a number which in the case of - // a date is done by calling getTime(). - return +new Date(); -}); + // Unary plus operator converts its operand to a number which in + // the case of + // a date is done by calling getTime(). + return +new Date(); + }); /** @@ -1935,7 +1978,8 @@ goog.globalEval = function(script) { } else { /** @type {Document} */ var doc = goog.global.document; - var scriptElt = doc.createElement('SCRIPT'); + var scriptElt = + /** @type {!HTMLScriptElement} */ (doc.createElement('SCRIPT')); scriptElt.type = 'text/javascript'; scriptElt.defer = false; // Note(user): can't use .innerHTML since "t('<test>')" will fail and @@ -1998,7 +2042,7 @@ goog.cssNameMappingStyle_; * var x = goog.getCssName('foo'); * var y = goog.getCssName(this.baseClass, 'active'); * becomes: - * var x= 'foo'; + * var x = 'foo'; * var y = this.baseClass + '-active'; * * If one argument is passed it will be processed, if two are passed only the @@ -2027,12 +2071,10 @@ goog.getCssName = function(className, opt_modifier) { var rename; if (goog.cssNameMapping_) { - rename = goog.cssNameMappingStyle_ == 'BY_WHOLE' ? - getMapping : renameByParts; + rename = + goog.cssNameMappingStyle_ == 'BY_WHOLE' ? getMapping : renameByParts; } else { - rename = function(a) { - return a; - }; + rename = function(a) { return a; }; } if (opt_modifier) { @@ -2106,6 +2148,10 @@ if (!COMPILED && goog.global.CLOSURE_CSS_NAME_MAPPING) { * var MSG_NAME = goog.getMsg('Hello {$placeholder}', {'placeholder': 'world'}); * </code> * + * This function produces a string which should be treated as plain text. Use + * {@link goog.html.SafeHtmlFormatter} in conjunction with goog.getMsg to + * produce SafeHtml. + * * @param {string} str Translatable string, places holders in the form {$foo}. * @param {Object<string, string>=} opt_values Maps place holder name to value. * @return {string} message with placeholders filled. @@ -2113,7 +2159,8 @@ if (!COMPILED && goog.global.CLOSURE_CSS_NAME_MAPPING) { goog.getMsg = function(str, opt_values) { if (opt_values) { str = str.replace(/\{\$([^}]+)}/g, function(match, key) { - return key in opt_values ? opt_values[key] : match; + return (opt_values != null && key in opt_values) ? opt_values[key] : + match; }); } return str; @@ -2201,7 +2248,7 @@ goog.exportProperty = function(object, publicName, symbol) { */ goog.inherits = function(childCtor, parentCtor) { /** @constructor */ - function tempCtor() {}; + function tempCtor() {} tempCtor.prototype = parentCtor.prototype; childCtor.superClass_ = parentCtor.prototype; childCtor.prototype = new tempCtor(); @@ -2266,9 +2313,10 @@ goog.base = function(me, opt_methodName, var_args) { var caller = arguments.callee.caller; if (goog.STRICT_MODE_COMPATIBLE || (goog.DEBUG && !caller)) { - throw Error('arguments.caller not defined. goog.base() cannot be used ' + - 'with strict mode code. See ' + - 'http://www.ecma-international.org/ecma-262/5.1/#sec-C'); + throw Error( + 'arguments.caller not defined. goog.base() cannot be used ' + + 'with strict mode code. See ' + + 'http://www.ecma-international.org/ecma-262/5.1/#sec-C'); } if (caller.superClass_) { @@ -2289,8 +2337,8 @@ goog.base = function(me, opt_methodName, var_args) { args[i - 2] = arguments[i]; } var foundCaller = false; - for (var ctor = me.constructor; - ctor; ctor = ctor.superClass_ && ctor.superClass_.constructor) { + for (var ctor = me.constructor; ctor; + ctor = ctor.superClass_ && ctor.superClass_.constructor) { if (ctor.prototype[opt_methodName] === caller) { foundCaller = true; } else if (foundCaller) { @@ -2324,6 +2372,9 @@ goog.base = function(me, opt_methodName, var_args) { * (e.g. "var Timer = goog.Timer"). */ goog.scope = function(fn) { + if (goog.isInModuleLoader_()) { + throw Error('goog.scope is not supported within a goog.module.'); + } fn.call(goog.global); }; @@ -2343,7 +2394,6 @@ if (!COMPILED) { } - //============================================================================== // goog.defineClass implementation //============================================================================== @@ -2404,10 +2454,10 @@ goog.defineClass = function(superClass, def) { /** - * @typedef { - * !Object| - * {constructor:!Function}| - * {constructor:!Function, statics:(Object|function(Function):void)}} + * @typedef {{ + * constructor: (!Function|undefined), + * statics: (Object|undefined|function(Function):void) + * }} * @suppress {missingProvide} */ goog.defineClass.ClassDescriptor; @@ -2466,13 +2516,8 @@ goog.defineClass.createSealingConstructor_ = function(ctr, superClass) { * @const */ goog.defineClass.OBJECT_PROTOTYPE_FIELDS_ = [ - 'constructor', - 'hasOwnProperty', - 'isPrototypeOf', - 'propertyIsEnumerable', - 'toLocaleString', - 'toString', - 'valueOf' + 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', + 'toLocaleString', 'toString', 'valueOf' ]; @@ -2565,12 +2610,6 @@ ol.DEFAULT_RASTER_REPROJECTION_ERROR_THRESHOLD = 0.5; /** - * @define {number} Default high water mark. - */ -ol.DEFAULT_TILE_CACHE_HIGH_WATER_MARK = 2048; - - -/** * @define {number} Default tile size. */ ol.DEFAULT_TILE_SIZE = 256; @@ -2791,14 +2830,6 @@ ol.WEBGL_EXTENSIONS; // value is set in `ol.has` * var child = new ChildClass('a', 'b', 'see'); * child.foo(); // This works. * - * In addition, a superclass' implementation of a method can be invoked as - * follows: - * - * ChildClass.prototype.foo = function(a) { - * ChildClass.base(this, 'foo', a); - * // Other code here. - * }; - * * @param {!Function} childCtor Child constructor. * @param {!Function} parentCtor Parent constructor. * @function @@ -2816,27 +2847,8 @@ ol.inherits = */ ol.nullFunction = function() {}; -// FIXME factor out common code between usedTiles and wantedTiles - -goog.provide('ol.PostRenderFunction'); -goog.provide('ol.PreRenderFunction'); - -/** - * @typedef {function(ol.Map, ?olx.FrameState): boolean} - */ -ol.PostRenderFunction; - - -/** - * Function to perform manipulations before rendering. This function is called - * with the {@link ol.Map} as first and an optional {@link olx.FrameState} as - * second argument. Return `true` to keep this function for the next frame, - * `false` to remove it. - * @typedef {function(ol.Map, ?olx.FrameState): boolean} - * @api - */ -ol.PreRenderFunction; +ol.global = Function('return this')(); // Copyright 2009 The Closure Library Authors. All Rights Reserved. // @@ -3032,7 +3044,7 @@ goog.string.endsWith = function(str, suffix) { */ goog.string.caseInsensitiveStartsWith = function(str, prefix) { return goog.string.caseInsensitiveCompare( - prefix, str.substr(0, prefix.length)) == 0; + prefix, str.substr(0, prefix.length)) == 0; }; @@ -3045,7 +3057,8 @@ goog.string.caseInsensitiveStartsWith = function(str, prefix) { */ goog.string.caseInsensitiveEndsWith = function(str, suffix) { return goog.string.caseInsensitiveCompare( - suffix, str.substr(str.length - suffix.length, suffix.length)) == 0; + suffix, str.substr(str.length - suffix.length, suffix.length)) == + 0; }; @@ -3081,7 +3094,7 @@ goog.string.subs = function(str, var_args) { returnString += splitParts.shift() + subsArguments.shift(); } - return returnString + splitParts.join('%s'); // Join unused '%s' + return returnString + splitParts.join('%s'); // Join unused '%s' }; @@ -3220,7 +3233,7 @@ goog.string.isSpace = function(ch) { */ goog.string.isUnicodeChar = function(ch) { return ch.length == 1 && ch >= ' ' && ch <= '~' || - ch >= '\u0080' && ch <= '\uFFFD'; + ch >= '\u0080' && ch <= '\uFFFD'; }; @@ -3276,8 +3289,8 @@ goog.string.normalizeSpaces = function(str) { * @return {string} Copy of the string with normalized breaking spaces. */ goog.string.collapseBreakingSpaces = function(str) { - return str.replace(/[\t\r\n ]+/g, ' ').replace( - /^[\t\r\n ]+|[\t\r\n ]+$/g, ''); + return str.replace(/[\t\r\n ]+/g, ' ') + .replace(/^[\t\r\n ]+|[\t\r\n ]+$/g, ''); }; @@ -3286,11 +3299,10 @@ goog.string.collapseBreakingSpaces = function(str) { * @param {string} str The string to trim. * @return {string} A trimmed copy of {@code str}. */ -goog.string.trim = (goog.TRUSTED_SITE && String.prototype.trim) ? - function(str) { +goog.string.trim = + (goog.TRUSTED_SITE && String.prototype.trim) ? function(str) { return str.trim(); - } : - function(str) { + } : function(str) { // Since IE doesn't include non-breaking-space (0xa0) in their \s // character class (as required by section 7.2 of the ECMAScript spec), // we explicitly include it in the regexp to enforce consistent @@ -3350,31 +3362,18 @@ goog.string.caseInsensitiveCompare = function(str1, str2) { /** - * Regular expression used for splitting a string into substrings of fractional - * numbers, integers, and non-numeric characters. - * @type {RegExp} - * @private - */ -goog.string.numerateCompareRegExp_ = /(\.\d+)|(\d+)|(\D+)/g; - - -/** - * String comparison function that handles numbers in a way humans might expect. - * Using this function, the string "File 2.jpg" sorts before "File 10.jpg". The - * comparison is mostly case-insensitive, though strings that are identical - * except for case are sorted with the upper-case strings before lower-case. - * - * This comparison function is significantly slower (about 500x) than either - * the default or the case-insensitive compare. It should not be used in - * time-critical code, but should be fast enough to sort several hundred short - * strings (like filenames) with a reasonable delay. + * Compares two strings interpreting their numeric substrings as numbers. * - * @param {string} str1 The string to compare in a numerically sensitive way. - * @param {string} str2 The string to compare {@code str1} to. - * @return {number} less than 0 if str1 < str2, 0 if str1 == str2, greater than - * 0 if str1 > str2. + * @param {string} str1 First string. + * @param {string} str2 Second string. + * @param {!RegExp} tokenizerRegExp Splits a string into substrings of + * non-negative integers, non-numeric characters and optionally fractional + * numbers starting with a decimal point. + * @return {number} Negative if str1 < str2, 0 is str1 == str2, positive if + * str1 > str2. + * @private */ -goog.string.numerateCompare = function(str1, str2) { +goog.string.numberAwareCompare_ = function(str1, str2, tokenizerRegExp) { if (str1 == str2) { return 0; } @@ -3387,8 +3386,8 @@ goog.string.numerateCompare = function(str1, str2) { // Using match to split the entire string ahead of time turns out to be faster // for most inputs than using RegExp.exec or iterating over each character. - var tokens1 = str1.toLowerCase().match(goog.string.numerateCompareRegExp_); - var tokens2 = str2.toLowerCase().match(goog.string.numerateCompareRegExp_); + var tokens1 = str1.toLowerCase().match(tokenizerRegExp); + var tokens2 = str2.toLowerCase().match(tokenizerRegExp); var count = Math.min(tokens1.length, tokens2.length); @@ -3398,7 +3397,6 @@ goog.string.numerateCompare = function(str1, str2) { // Compare pairs of tokens, returning if one token sorts before the other. if (a != b) { - // Only if both tokens are integers is a special comparison required. // Decimal numbers are sorted as strings (e.g., '.09' < '.1'). var num1 = parseInt(a, 10); @@ -3418,13 +3416,62 @@ goog.string.numerateCompare = function(str1, str2) { } // The two strings must be equivalent except for case (perfect equality is - // tested at the head of the function.) Revert to default ASCII-betical string - // comparison to stablize the sort. + // tested at the head of the function.) Revert to default ASCII string + // comparison to stabilize the sort. return str1 < str2 ? -1 : 1; }; /** + * String comparison function that handles non-negative integer numbers in a + * way humans might expect. Using this function, the string 'File 2.jpg' sorts + * before 'File 10.jpg', and 'Version 1.9' before 'Version 1.10'. The comparison + * is mostly case-insensitive, though strings that are identical except for case + * are sorted with the upper-case strings before lower-case. + * + * This comparison function is up to 50x slower than either the default or the + * case-insensitive compare. It should not be used in time-critical code, but + * should be fast enough to sort several hundred short strings (like filenames) + * with a reasonable delay. + * + * @param {string} str1 The string to compare in a numerically sensitive way. + * @param {string} str2 The string to compare {@code str1} to. + * @return {number} less than 0 if str1 < str2, 0 if str1 == str2, greater than + * 0 if str1 > str2. + */ +goog.string.intAwareCompare = function(str1, str2) { + return goog.string.numberAwareCompare_(str1, str2, /\d+|\D+/g); +}; + + +/** + * String comparison function that handles non-negative integer and fractional + * numbers in a way humans might expect. Using this function, the string + * 'File 2.jpg' sorts before 'File 10.jpg', and '3.14' before '3.2'. Equivalent + * to {@link goog.string.intAwareCompare} apart from the way how it interprets + * dots. + * + * @param {string} str1 The string to compare in a numerically sensitive way. + * @param {string} str2 The string to compare {@code str1} to. + * @return {number} less than 0 if str1 < str2, 0 if str1 == str2, greater than + * 0 if str1 > str2. + */ +goog.string.floatAwareCompare = function(str1, str2) { + return goog.string.numberAwareCompare_(str1, str2, /\d+|\.\d+|\D+/g); +}; + + +/** + * Alias for {@link goog.string.floatAwareCompare}. + * + * @param {string} str1 + * @param {string} str2 + * @return {number} + */ +goog.string.numerateCompare = goog.string.floatAwareCompare; + + +/** * URL-encodes a string * @param {*} str The string to url-encode. * @return {string} An encoded copy of {@code str} that is safe for urls. @@ -3506,11 +3553,11 @@ goog.string.htmlEscape = function(str, opt_isLikelyToContainHtmlChars) { if (opt_isLikelyToContainHtmlChars) { str = str.replace(goog.string.AMP_RE_, '&') - .replace(goog.string.LT_RE_, '<') - .replace(goog.string.GT_RE_, '>') - .replace(goog.string.QUOT_RE_, '"') - .replace(goog.string.SINGLE_QUOTE_RE_, ''') - .replace(goog.string.NULL_RE_, '�'); + .replace(goog.string.LT_RE_, '<') + .replace(goog.string.GT_RE_, '>') + .replace(goog.string.QUOT_RE_, '"') + .replace(goog.string.SINGLE_QUOTE_RE_, ''') + .replace(goog.string.NULL_RE_, '�'); if (goog.string.DETECT_DOUBLE_ESCAPING) { str = str.replace(goog.string.E_RE_, 'e'); } @@ -3609,9 +3656,8 @@ goog.string.E_RE_ = /e/g; * @const {!RegExp} * @private */ -goog.string.ALL_RE_ = (goog.string.DETECT_DOUBLE_ESCAPING ? - /[\x00&<>"'e]/ : - /[\x00&<>"']/); +goog.string.ALL_RE_ = + (goog.string.DETECT_DOUBLE_ESCAPING ? /[\x00&<>"'e]/ : /[\x00&<>"']/); /** @@ -3834,8 +3880,8 @@ goog.string.truncate = function(str, chars, opt_protectEscapedCharacters) { * middle as possible. * @return {string} A truncated copy of {@code str}. */ -goog.string.truncateMiddle = function(str, chars, - opt_protectEscapedCharacters, opt_trailingChars) { +goog.string.truncateMiddle = function( + str, chars, opt_protectEscapedCharacters, opt_trailingChars) { if (opt_protectEscapedCharacters) { str = goog.string.unescapeEntities(str); } @@ -3874,9 +3920,15 @@ goog.string.specialEscapeChars_ = { '\n': '\\n', '\r': '\\r', '\t': '\\t', - '\x0B': '\\x0B', // '\v' is not supported in JScript + '\x0B': '\\x0B', // '\v' is not supported in JScript '"': '\\"', - '\\': '\\\\' + '\\': '\\\\', + // To support the use case of embedding quoted strings inside of script + // tags, we have to make sure HTML comments and opening/closing script tags do + // not appear in the resulting string. The specific strings that must be + // escaped are documented at: + // http://www.w3.org/TR/html51/semantics.html#restrictions-for-contents-of-script-elements + '<': '\x3c' }; @@ -3891,25 +3943,22 @@ goog.string.jsEscapeCache_ = { /** * Encloses a string in double quotes and escapes characters so that the - * string is a valid JS string. + * string is a valid JS string. The resulting string is safe to embed in + * `<script>` tags as "<" is escaped. * @param {string} s The string to quote. * @return {string} A copy of {@code s} surrounded by double quotes. */ goog.string.quote = function(s) { s = String(s); - if (s.quote) { - return s.quote(); - } else { - var sb = ['"']; - for (var i = 0; i < s.length; i++) { - var ch = s.charAt(i); - var cc = ch.charCodeAt(0); - sb[i + 1] = goog.string.specialEscapeChars_[ch] || - ((cc > 31 && cc < 127) ? ch : goog.string.escapeChar(ch)); - } - sb.push('"'); - return sb.join(''); - } + var sb = ['"']; + for (var i = 0; i < s.length; i++) { + var ch = s.charAt(i); + var cc = ch.charCodeAt(0); + sb[i + 1] = goog.string.specialEscapeChars_[ch] || + ((cc > 31 && cc < 127) ? ch : goog.string.escapeChar(ch)); + } + sb.push('"'); + return sb.join(''); }; @@ -3955,7 +4004,7 @@ goog.string.escapeChar = function(c) { } } else { rv = '\\u'; - if (cc < 4096) { // \u1000 + if (cc < 4096) { // \u1000 rv += '0'; } } @@ -4053,8 +4102,9 @@ goog.string.removeAll = function(s, ss) { * @return {string} A RegExp safe, escaped copy of {@code s}. */ goog.string.regExpEscape = function(s) { - return String(s).replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1'). - replace(/\x08/g, '\\x08'); + return String(s) + .replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1') + .replace(/\x08/g, '\\x08'); }; @@ -4065,14 +4115,12 @@ goog.string.regExpEscape = function(s) { * @return {string} A string containing {@code length} repetitions of * {@code string}. */ -goog.string.repeat = (String.prototype.repeat) ? - function(string, length) { - // The native method is over 100 times faster than the alternative. - return string.repeat(length); - } : - function(string, length) { - return new Array(length + 1).join(string); - }; +goog.string.repeat = (String.prototype.repeat) ? function(string, length) { + // The native method is over 100 times faster than the alternative. + return string.repeat(length); +} : function(string, length) { + return new Array(length + 1).join(string); +}; /** @@ -4141,7 +4189,7 @@ goog.string.buildString = function(var_args) { goog.string.getRandomString = function() { var x = 2147483648; return Math.floor(Math.random() * x).toString(36) + - Math.abs(Math.floor(Math.random() * x) ^ goog.now()).toString(36); + Math.abs(Math.floor(Math.random() * x) ^ goog.now()).toString(36); }; @@ -4191,8 +4239,8 @@ goog.string.compareVersions = function(version1, version2) { // qualifier is always higher than a subversion with any qualifier. Next, // the qualifiers are compared as strings. order = goog.string.compareElements_(v1CompNum, v2CompNum) || - goog.string.compareElements_(v1Comp[2].length == 0, - v2Comp[2].length == 0) || + goog.string.compareElements_( + v1Comp[2].length == 0, v2Comp[2].length == 0) || goog.string.compareElements_(v1Comp[2], v2Comp[2]); // Stop as soon as an inequality is discovered. } while (order == 0); @@ -4318,9 +4366,8 @@ goog.string.isUpperCamelCase = function(str) { * @return {string} The string in camelCase form. */ goog.string.toCamelCase = function(str) { - return String(str).replace(/\-([a-z])/g, function(all, match) { - return match.toUpperCase(); - }); + return String(str).replace( + /\-([a-z])/g, function(all, match) { return match.toUpperCase(); }); }; @@ -4369,16 +4416,16 @@ goog.string.toSelectorCase = function(str) { */ goog.string.toTitleCase = function(str, opt_delimiters) { var delimiters = goog.isString(opt_delimiters) ? - goog.string.regExpEscape(opt_delimiters) : '\\s'; + goog.string.regExpEscape(opt_delimiters) : + '\\s'; // For IE8, we need to prevent using an empty character set. Otherwise, // incorrect matching will occur. delimiters = delimiters ? '|[' + delimiters + ']+' : ''; var regexp = new RegExp('(^' + delimiters + ')([a-z])', 'g'); - return str.replace(regexp, function(all, p1, p2) { - return p1 + p2.toUpperCase(); - }); + return str.replace( + regexp, function(all, p1, p2) { return p1 + p2.toUpperCase(); }); }; @@ -4426,8 +4473,7 @@ goog.string.parseInt = function(value) { if (goog.isString(value)) { // If the string starts with '0x' or '-0x', parse as hex. - return /^\s*-?0x/i.test(value) ? - parseInt(value, 16) : parseInt(value, 10); + return /^\s*-?0x/i.test(value) ? parseInt(value, 16) : parseInt(value, 10); } return NaN; @@ -4452,7 +4498,6 @@ goog.string.parseInt = function(value) { * as zero. * @return {!Array<string>} The string, split. */ - goog.string.splitLimit = function(str, separator, limit) { var parts = str.split(separator); var returnVal = []; @@ -4474,6 +4519,43 @@ goog.string.splitLimit = function(str, separator, limit) { /** + * Finds the characters to the right of the last instance of any separator + * + * This function is similar to goog.string.path.baseName, except it can take a + * list of characters to split the string on. It will return the rightmost + * grouping of characters to the right of any separator as a left-to-right + * oriented string. + * + * @see goog.string.path.baseName + * @param {string} str The string + * @param {string|!Array<string>} separators A list of separator characters + * @return {string} The last part of the string with respect to the separators + */ +goog.string.lastComponent = function(str, separators) { + if (!separators) { + return str; + } else if (typeof separators == 'string') { + separators = [separators]; + } + + var lastSeparatorIndex = -1; + for (var i = 0; i < separators.length; i++) { + if (separators[i] == '') { + continue; + } + var currentSeparatorIndex = str.lastIndexOf(separators[i]); + if (currentSeparatorIndex > lastSeparatorIndex) { + lastSeparatorIndex = currentSeparatorIndex; + } + } + if (lastSeparatorIndex == -1) { + return str; + } + return str.slice(lastSeparatorIndex + 1); +}; + + +/** * Computes the Levenshtein edit distance between two strings. * @param {string} a * @param {string} b @@ -4499,7 +4581,7 @@ goog.string.editDistance = function(a, b) { v1[0] = i + 1; for (var j = 0; j < b.length; j++) { - var cost = a[i] != b[j]; + var cost = Number(a[i] != b[j]); // Cost for the substring is the minimum of adding one character, removing // one character, or a swap. v1[j + 1] = Math.min(v1[j] + 1, v0[j + 1] + 1, v0[j] + cost); @@ -4597,7 +4679,9 @@ goog.asserts.AssertionError.prototype.name = 'AssertionError'; * The default error handler. * @param {!goog.asserts.AssertionError} e The exception to be handled. */ -goog.asserts.DEFAULT_ERROR_HANDLER = function(e) { throw e; }; +goog.asserts.DEFAULT_ERROR_HANDLER = function(e) { + throw e; +}; /** @@ -4617,8 +4701,8 @@ goog.asserts.errorHandler_ = goog.asserts.DEFAULT_ERROR_HANDLER; * @throws {goog.asserts.AssertionError} When the value is not a number. * @private */ -goog.asserts.doAssertFailure_ = - function(defaultMessage, defaultArgs, givenMessage, givenArgs) { +goog.asserts.doAssertFailure_ = function( + defaultMessage, defaultArgs, givenMessage, givenArgs) { var message = 'Assertion failed'; if (givenMessage) { message += ': ' + givenMessage; @@ -4661,8 +4745,8 @@ goog.asserts.setErrorHandler = function(errorHandler) { */ goog.asserts.assert = function(condition, opt_message, var_args) { if (goog.asserts.ENABLE_ASSERTS && !condition) { - goog.asserts.doAssertFailure_('', null, opt_message, - Array.prototype.slice.call(arguments, 2)); + goog.asserts.doAssertFailure_( + '', null, opt_message, Array.prototype.slice.call(arguments, 2)); } return condition; }; @@ -4688,9 +4772,10 @@ goog.asserts.assert = function(condition, opt_message, var_args) { */ goog.asserts.fail = function(opt_message, var_args) { if (goog.asserts.ENABLE_ASSERTS) { - goog.asserts.errorHandler_(new goog.asserts.AssertionError( - 'Failure' + (opt_message ? ': ' + opt_message : ''), - Array.prototype.slice.call(arguments, 1))); + goog.asserts.errorHandler_( + new goog.asserts.AssertionError( + 'Failure' + (opt_message ? ': ' + opt_message : ''), + Array.prototype.slice.call(arguments, 1))); } }; @@ -4705,9 +4790,9 @@ goog.asserts.fail = function(opt_message, var_args) { */ goog.asserts.assertNumber = function(value, opt_message, var_args) { if (goog.asserts.ENABLE_ASSERTS && !goog.isNumber(value)) { - goog.asserts.doAssertFailure_('Expected number but got %s: %s.', - [goog.typeOf(value), value], opt_message, - Array.prototype.slice.call(arguments, 2)); + goog.asserts.doAssertFailure_( + 'Expected number but got %s: %s.', [goog.typeOf(value), value], + opt_message, Array.prototype.slice.call(arguments, 2)); } return /** @type {number} */ (value); }; @@ -4723,9 +4808,9 @@ goog.asserts.assertNumber = function(value, opt_message, var_args) { */ goog.asserts.assertString = function(value, opt_message, var_args) { if (goog.asserts.ENABLE_ASSERTS && !goog.isString(value)) { - goog.asserts.doAssertFailure_('Expected string but got %s: %s.', - [goog.typeOf(value), value], opt_message, - Array.prototype.slice.call(arguments, 2)); + goog.asserts.doAssertFailure_( + 'Expected string but got %s: %s.', [goog.typeOf(value), value], + opt_message, Array.prototype.slice.call(arguments, 2)); } return /** @type {string} */ (value); }; @@ -4742,9 +4827,9 @@ goog.asserts.assertString = function(value, opt_message, var_args) { */ goog.asserts.assertFunction = function(value, opt_message, var_args) { if (goog.asserts.ENABLE_ASSERTS && !goog.isFunction(value)) { - goog.asserts.doAssertFailure_('Expected function but got %s: %s.', - [goog.typeOf(value), value], opt_message, - Array.prototype.slice.call(arguments, 2)); + goog.asserts.doAssertFailure_( + 'Expected function but got %s: %s.', [goog.typeOf(value), value], + opt_message, Array.prototype.slice.call(arguments, 2)); } return /** @type {!Function} */ (value); }; @@ -4760,8 +4845,8 @@ goog.asserts.assertFunction = function(value, opt_message, var_args) { */ goog.asserts.assertObject = function(value, opt_message, var_args) { if (goog.asserts.ENABLE_ASSERTS && !goog.isObject(value)) { - goog.asserts.doAssertFailure_('Expected object but got %s: %s.', - [goog.typeOf(value), value], + goog.asserts.doAssertFailure_( + 'Expected object but got %s: %s.', [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2)); } return /** @type {!Object} */ (value); @@ -4778,9 +4863,9 @@ goog.asserts.assertObject = function(value, opt_message, var_args) { */ goog.asserts.assertArray = function(value, opt_message, var_args) { if (goog.asserts.ENABLE_ASSERTS && !goog.isArray(value)) { - goog.asserts.doAssertFailure_('Expected array but got %s: %s.', - [goog.typeOf(value), value], opt_message, - Array.prototype.slice.call(arguments, 2)); + goog.asserts.doAssertFailure_( + 'Expected array but got %s: %s.', [goog.typeOf(value), value], + opt_message, Array.prototype.slice.call(arguments, 2)); } return /** @type {!Array<?>} */ (value); }; @@ -4797,9 +4882,9 @@ goog.asserts.assertArray = function(value, opt_message, var_args) { */ goog.asserts.assertBoolean = function(value, opt_message, var_args) { if (goog.asserts.ENABLE_ASSERTS && !goog.isBoolean(value)) { - goog.asserts.doAssertFailure_('Expected boolean but got %s: %s.', - [goog.typeOf(value), value], opt_message, - Array.prototype.slice.call(arguments, 2)); + goog.asserts.doAssertFailure_( + 'Expected boolean but got %s: %s.', [goog.typeOf(value), value], + opt_message, Array.prototype.slice.call(arguments, 2)); } return /** @type {boolean} */ (value); }; @@ -4815,11 +4900,11 @@ goog.asserts.assertBoolean = function(value, opt_message, var_args) { * @throws {goog.asserts.AssertionError} When the value is not an Element. */ goog.asserts.assertElement = function(value, opt_message, var_args) { - if (goog.asserts.ENABLE_ASSERTS && (!goog.isObject(value) || - value.nodeType != goog.dom.NodeType.ELEMENT)) { - goog.asserts.doAssertFailure_('Expected Element but got %s: %s.', - [goog.typeOf(value), value], opt_message, - Array.prototype.slice.call(arguments, 2)); + if (goog.asserts.ENABLE_ASSERTS && + (!goog.isObject(value) || value.nodeType != goog.dom.NodeType.ELEMENT)) { + goog.asserts.doAssertFailure_( + 'Expected Element but got %s: %s.', [goog.typeOf(value), value], + opt_message, Array.prototype.slice.call(arguments, 2)); } return /** @type {!Element} */ (value); }; @@ -4831,7 +4916,7 @@ goog.asserts.assertElement = function(value, opt_message, var_args) { * * The compiler may tighten the type returned by this function. * - * @param {*} value The value to check. + * @param {?} value The value to check. * @param {function(new: T, ...)} type A user-defined constructor. * @param {string=} opt_message Error message in case of failure. * @param {...*} var_args The items to substitute into the failure message. @@ -4842,7 +4927,8 @@ goog.asserts.assertElement = function(value, opt_message, var_args) { */ goog.asserts.assertInstanceof = function(value, type, opt_message, var_args) { if (goog.asserts.ENABLE_ASSERTS && !(value instanceof type)) { - goog.asserts.doAssertFailure_('Expected instanceof %s but got %s.', + goog.asserts.doAssertFailure_( + 'Expected instanceof %s but got %s.', [goog.asserts.getType_(type), goog.asserts.getType_(value)], opt_message, Array.prototype.slice.call(arguments, 3)); } @@ -5061,21 +5147,38 @@ ol.math.toRadians = function(angleInDegrees) { return angleInDegrees * Math.PI / 180; }; -goog.provide('ol.CenterConstraint'); -goog.provide('ol.CenterConstraintType'); - -goog.require('ol.math'); - +/** + * Returns the modulo of a / b, depending on the sign of b. + * + * @param {number} a Dividend. + * @param {number} b Divisor. + * @return {number} Modulo. + */ +ol.math.modulo = function(a, b) { + var r = a % b; + return r * b < 0 ? r + b : r; +}; /** - * @typedef {function((ol.Coordinate|undefined)): (ol.Coordinate|undefined)} + * Calculates the linearly interpolated value of x between a and b. + * + * @param {number} a Number + * @param {number} b Number + * @param {number} x Value to be interpolated. + * @return {number} Interpolated value. */ -ol.CenterConstraintType; +ol.math.lerp = function(a, b, x) { + return a + x * (b - a); +}; + +goog.provide('ol.CenterConstraint'); + +goog.require('ol.math'); /** * @param {ol.Extent} extent Extent. - * @return {ol.CenterConstraintType} + * @return {ol.CenterConstraintType} The constraint. */ ol.CenterConstraint.createExtent = function(extent) { return ( @@ -5104,2608 +5207,957 @@ ol.CenterConstraint.none = function(center) { return center; }; -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Utilities for manipulating arrays. - * - * @author arv@google.com (Erik Arvidsson) - */ - - -goog.provide('goog.array'); -goog.provide('goog.array.ArrayLike'); - -goog.require('goog.asserts'); - - -/** - * @define {boolean} NATIVE_ARRAY_PROTOTYPES indicates whether the code should - * rely on Array.prototype functions, if available. - * - * The Array.prototype functions can be defined by external libraries like - * Prototype and setting this flag to false forces closure to use its own - * goog.array implementation. - * - * If your javascript can be loaded by a third party site and you are wary about - * relying on the prototype functions, specify - * "--define goog.NATIVE_ARRAY_PROTOTYPES=false" to the JSCompiler. - * - * Setting goog.TRUSTED_SITE to false will automatically set - * NATIVE_ARRAY_PROTOTYPES to false. - */ -goog.define('goog.NATIVE_ARRAY_PROTOTYPES', goog.TRUSTED_SITE); +goog.provide('ol.Constraints'); /** - * @define {boolean} If true, JSCompiler will use the native implementation of - * array functions where appropriate (e.g., {@code Array#filter}) and remove the - * unused pure JS implementation. + * @constructor + * @param {ol.CenterConstraintType} centerConstraint Center constraint. + * @param {ol.ResolutionConstraintType} resolutionConstraint + * Resolution constraint. + * @param {ol.RotationConstraintType} rotationConstraint + * Rotation constraint. */ -goog.define('goog.array.ASSUME_NATIVE_FUNCTIONS', false); +ol.Constraints = function(centerConstraint, resolutionConstraint, rotationConstraint) { + /** + * @type {ol.CenterConstraintType} + */ + this.center = centerConstraint; -/** - * @typedef {Array|NodeList|Arguments|{length: number}} - */ -goog.array.ArrayLike; + /** + * @type {ol.ResolutionConstraintType} + */ + this.resolution = resolutionConstraint; + /** + * @type {ol.RotationConstraintType} + */ + this.rotation = rotationConstraint; -/** - * Returns the last element in an array without removing it. - * Same as goog.array.last. - * @param {Array<T>|goog.array.ArrayLike} array The array. - * @return {T} Last item in array. - * @template T - */ -goog.array.peek = function(array) { - return array[array.length - 1]; }; - -/** - * Returns the last element in an array without removing it. - * Same as goog.array.peek. - * @param {Array<T>|goog.array.ArrayLike} array The array. - * @return {T} Last item in array. - * @template T - */ -goog.array.last = goog.array.peek; - - -/** - * Reference to the original {@code Array.prototype}. - * @private - */ -goog.array.ARRAY_PROTOTYPE_ = Array.prototype; - - -// NOTE(arv): Since most of the array functions are generic it allows you to -// pass an array-like object. Strings have a length and are considered array- -// like. However, the 'in' operator does not work on strings so we cannot just -// use the array path even if the browser supports indexing into strings. We -// therefore end up splitting the string. +goog.provide('ol.object'); /** - * Returns the index of the first element of an array with a specified value, or - * -1 if the element is not present in the array. - * - * See {@link http://tinyurl.com/developer-mozilla-org-array-indexof} + * Polyfill for Object.assign(). Assigns enumerable and own properties from + * one or more source objects to a target object. * - * @param {Array<T>|goog.array.ArrayLike} arr The array to be searched. - * @param {T} obj The object for which we are searching. - * @param {number=} opt_fromIndex The index at which to start the search. If - * omitted the search starts at index 0. - * @return {number} The index of the first matching array element. - * @template T + * @see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign + * @param {!Object} target The target object. + * @param {...Object} var_sources The source object(s). + * @return {!Object} The modified target object. */ -goog.array.indexOf = goog.NATIVE_ARRAY_PROTOTYPES && - (goog.array.ASSUME_NATIVE_FUNCTIONS || - goog.array.ARRAY_PROTOTYPE_.indexOf) ? - function(arr, obj, opt_fromIndex) { - goog.asserts.assert(arr.length != null); - - return goog.array.ARRAY_PROTOTYPE_.indexOf.call(arr, obj, opt_fromIndex); - } : - function(arr, obj, opt_fromIndex) { - var fromIndex = opt_fromIndex == null ? - 0 : (opt_fromIndex < 0 ? - Math.max(0, arr.length + opt_fromIndex) : opt_fromIndex); - - if (goog.isString(arr)) { - // Array.prototype.indexOf uses === so only strings should be found. - if (!goog.isString(obj) || obj.length != 1) { - return -1; - } - return arr.indexOf(obj, fromIndex); - } - - for (var i = fromIndex; i < arr.length; i++) { - if (i in arr && arr[i] === obj) - return i; - } - return -1; - }; - - -/** - * Returns the index of the last element of an array with a specified value, or - * -1 if the element is not present in the array. - * - * See {@link http://tinyurl.com/developer-mozilla-org-array-lastindexof} - * - * @param {!Array<T>|!goog.array.ArrayLike} arr The array to be searched. - * @param {T} obj The object for which we are searching. - * @param {?number=} opt_fromIndex The index at which to start the search. If - * omitted the search starts at the end of the array. - * @return {number} The index of the last matching array element. - * @template T - */ -goog.array.lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES && - (goog.array.ASSUME_NATIVE_FUNCTIONS || - goog.array.ARRAY_PROTOTYPE_.lastIndexOf) ? - function(arr, obj, opt_fromIndex) { - goog.asserts.assert(arr.length != null); - - // Firefox treats undefined and null as 0 in the fromIndex argument which - // leads it to always return -1 - var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex; - return goog.array.ARRAY_PROTOTYPE_.lastIndexOf.call(arr, obj, fromIndex); - } : - function(arr, obj, opt_fromIndex) { - var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex; - - if (fromIndex < 0) { - fromIndex = Math.max(0, arr.length + fromIndex); - } - - if (goog.isString(arr)) { - // Array.prototype.lastIndexOf uses === so only strings should be found. - if (!goog.isString(obj) || obj.length != 1) { - return -1; - } - return arr.lastIndexOf(obj, fromIndex); - } - - for (var i = fromIndex; i >= 0; i--) { - if (i in arr && arr[i] === obj) - return i; - } - return -1; - }; - - -/** - * Calls a function for each element in an array. Skips holes in the array. - * See {@link http://tinyurl.com/developer-mozilla-org-array-foreach} - * - * @param {Array<T>|goog.array.ArrayLike} arr Array or array like object over - * which to iterate. - * @param {?function(this: S, T, number, ?): ?} f The function to call for every - * element. This function takes 3 arguments (the element, the index and the - * array). The return value is ignored. - * @param {S=} opt_obj The object to be used as the value of 'this' within f. - * @template T,S - */ -goog.array.forEach = goog.NATIVE_ARRAY_PROTOTYPES && - (goog.array.ASSUME_NATIVE_FUNCTIONS || - goog.array.ARRAY_PROTOTYPE_.forEach) ? - function(arr, f, opt_obj) { - goog.asserts.assert(arr.length != null); - - goog.array.ARRAY_PROTOTYPE_.forEach.call(arr, f, opt_obj); - } : - function(arr, f, opt_obj) { - var l = arr.length; // must be fixed during loop... see docs - var arr2 = goog.isString(arr) ? arr.split('') : arr; - for (var i = 0; i < l; i++) { - if (i in arr2) { - f.call(opt_obj, arr2[i], i, arr); - } - } - }; - - -/** - * Calls a function for each element in an array, starting from the last - * element rather than the first. - * - * @param {Array<T>|goog.array.ArrayLike} arr Array or array - * like object over which to iterate. - * @param {?function(this: S, T, number, ?): ?} f The function to call for every - * element. This function - * takes 3 arguments (the element, the index and the array). The return - * value is ignored. - * @param {S=} opt_obj The object to be used as the value of 'this' - * within f. - * @template T,S - */ -goog.array.forEachRight = function(arr, f, opt_obj) { - var l = arr.length; // must be fixed during loop... see docs - var arr2 = goog.isString(arr) ? arr.split('') : arr; - for (var i = l - 1; i >= 0; --i) { - if (i in arr2) { - f.call(opt_obj, arr2[i], i, arr); - } +ol.object.assign = (typeof Object.assign === 'function') ? Object.assign : function(target, var_sources) { + if (target === undefined || target === null) { + throw new TypeError('Cannot convert undefined or null to object'); } -}; - - -/** - * Calls a function for each element in an array, and if the function returns - * true adds the element to a new array. - * - * See {@link http://tinyurl.com/developer-mozilla-org-array-filter} - * - * @param {Array<T>|goog.array.ArrayLike} arr Array or array - * like object over which to iterate. - * @param {?function(this:S, T, number, ?):boolean} f The function to call for - * every element. This function - * takes 3 arguments (the element, the index and the array) and must - * return a Boolean. If the return value is true the element is added to the - * result array. If it is false the element is not included. - * @param {S=} opt_obj The object to be used as the value of 'this' - * within f. - * @return {!Array<T>} a new array in which only elements that passed the test - * are present. - * @template T,S - */ -goog.array.filter = goog.NATIVE_ARRAY_PROTOTYPES && - (goog.array.ASSUME_NATIVE_FUNCTIONS || - goog.array.ARRAY_PROTOTYPE_.filter) ? - function(arr, f, opt_obj) { - goog.asserts.assert(arr.length != null); - - return goog.array.ARRAY_PROTOTYPE_.filter.call(arr, f, opt_obj); - } : - function(arr, f, opt_obj) { - var l = arr.length; // must be fixed during loop... see docs - var res = []; - var resLength = 0; - var arr2 = goog.isString(arr) ? arr.split('') : arr; - for (var i = 0; i < l; i++) { - if (i in arr2) { - var val = arr2[i]; // in case f mutates arr2 - if (f.call(opt_obj, val, i, arr)) { - res[resLength++] = val; - } - } - } - return res; - }; - - -/** - * Calls a function for each element in an array and inserts the result into a - * new array. - * - * See {@link http://tinyurl.com/developer-mozilla-org-array-map} - * - * @param {Array<VALUE>|goog.array.ArrayLike} arr Array or array like object - * over which to iterate. - * @param {function(this:THIS, VALUE, number, ?): RESULT} f The function to call - * for every element. This function takes 3 arguments (the element, - * the index and the array) and should return something. The result will be - * inserted into a new array. - * @param {THIS=} opt_obj The object to be used as the value of 'this' within f. - * @return {!Array<RESULT>} a new array with the results from f. - * @template THIS, VALUE, RESULT - */ -goog.array.map = goog.NATIVE_ARRAY_PROTOTYPES && - (goog.array.ASSUME_NATIVE_FUNCTIONS || - goog.array.ARRAY_PROTOTYPE_.map) ? - function(arr, f, opt_obj) { - goog.asserts.assert(arr.length != null); - - return goog.array.ARRAY_PROTOTYPE_.map.call(arr, f, opt_obj); - } : - function(arr, f, opt_obj) { - var l = arr.length; // must be fixed during loop... see docs - var res = new Array(l); - var arr2 = goog.isString(arr) ? arr.split('') : arr; - for (var i = 0; i < l; i++) { - if (i in arr2) { - res[i] = f.call(opt_obj, arr2[i], i, arr); - } - } - return res; - }; - - -/** - * Passes every element of an array into a function and accumulates the result. - * - * See {@link http://tinyurl.com/developer-mozilla-org-array-reduce} - * - * For example: - * var a = [1, 2, 3, 4]; - * goog.array.reduce(a, function(r, v, i, arr) {return r + v;}, 0); - * returns 10 - * - * @param {Array<T>|goog.array.ArrayLike} arr Array or array - * like object over which to iterate. - * @param {function(this:S, R, T, number, ?) : R} f The function to call for - * every element. This function - * takes 4 arguments (the function's previous result or the initial value, - * the value of the current array element, the current array index, and the - * array itself) - * function(previousValue, currentValue, index, array). - * @param {?} val The initial value to pass into the function on the first call. - * @param {S=} opt_obj The object to be used as the value of 'this' - * within f. - * @return {R} Result of evaluating f repeatedly across the values of the array. - * @template T,S,R - */ -goog.array.reduce = goog.NATIVE_ARRAY_PROTOTYPES && - (goog.array.ASSUME_NATIVE_FUNCTIONS || - goog.array.ARRAY_PROTOTYPE_.reduce) ? - function(arr, f, val, opt_obj) { - goog.asserts.assert(arr.length != null); - if (opt_obj) { - f = goog.bind(f, opt_obj); - } - return goog.array.ARRAY_PROTOTYPE_.reduce.call(arr, f, val); - } : - function(arr, f, val, opt_obj) { - var rval = val; - goog.array.forEach(arr, function(val, index) { - rval = f.call(opt_obj, rval, val, index, arr); - }); - return rval; - }; - - -/** - * Passes every element of an array into a function and accumulates the result, - * starting from the last element and working towards the first. - * - * See {@link http://tinyurl.com/developer-mozilla-org-array-reduceright} - * - * For example: - * var a = ['a', 'b', 'c']; - * goog.array.reduceRight(a, function(r, v, i, arr) {return r + v;}, ''); - * returns 'cba' - * - * @param {Array<T>|goog.array.ArrayLike} arr Array or array - * like object over which to iterate. - * @param {?function(this:S, R, T, number, ?) : R} f The function to call for - * every element. This function - * takes 4 arguments (the function's previous result or the initial value, - * the value of the current array element, the current array index, and the - * array itself) - * function(previousValue, currentValue, index, array). - * @param {?} val The initial value to pass into the function on the first call. - * @param {S=} opt_obj The object to be used as the value of 'this' - * within f. - * @return {R} Object returned as a result of evaluating f repeatedly across the - * values of the array. - * @template T,S,R - */ -goog.array.reduceRight = goog.NATIVE_ARRAY_PROTOTYPES && - (goog.array.ASSUME_NATIVE_FUNCTIONS || - goog.array.ARRAY_PROTOTYPE_.reduceRight) ? - function(arr, f, val, opt_obj) { - goog.asserts.assert(arr.length != null); - if (opt_obj) { - f = goog.bind(f, opt_obj); - } - return goog.array.ARRAY_PROTOTYPE_.reduceRight.call(arr, f, val); - } : - function(arr, f, val, opt_obj) { - var rval = val; - goog.array.forEachRight(arr, function(val, index) { - rval = f.call(opt_obj, rval, val, index, arr); - }); - return rval; - }; - - -/** - * Calls f for each element of an array. If any call returns true, some() - * returns true (without checking the remaining elements). If all calls - * return false, some() returns false. - * - * See {@link http://tinyurl.com/developer-mozilla-org-array-some} - * - * @param {Array<T>|goog.array.ArrayLike} arr Array or array - * like object over which to iterate. - * @param {?function(this:S, T, number, ?) : boolean} f The function to call for - * for every element. This function takes 3 arguments (the element, the - * index and the array) and should return a boolean. - * @param {S=} opt_obj The object to be used as the value of 'this' - * within f. - * @return {boolean} true if any element passes the test. - * @template T,S - */ -goog.array.some = goog.NATIVE_ARRAY_PROTOTYPES && - (goog.array.ASSUME_NATIVE_FUNCTIONS || - goog.array.ARRAY_PROTOTYPE_.some) ? - function(arr, f, opt_obj) { - goog.asserts.assert(arr.length != null); - return goog.array.ARRAY_PROTOTYPE_.some.call(arr, f, opt_obj); - } : - function(arr, f, opt_obj) { - var l = arr.length; // must be fixed during loop... see docs - var arr2 = goog.isString(arr) ? arr.split('') : arr; - for (var i = 0; i < l; i++) { - if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) { - return true; + var output = Object(target); + for (var i = 1, ii = arguments.length; i < ii; ++i) { + var source = arguments[i]; + if (source !== undefined && source !== null) { + for (var key in source) { + if (source.hasOwnProperty(key)) { + output[key] = source[key]; } } - return false; - }; - - -/** - * Call f for each element of an array. If all calls return true, every() - * returns true. If any call returns false, every() returns false and - * does not continue to check the remaining elements. - * - * See {@link http://tinyurl.com/developer-mozilla-org-array-every} - * - * @param {Array<T>|goog.array.ArrayLike} arr Array or array - * like object over which to iterate. - * @param {?function(this:S, T, number, ?) : boolean} f The function to call for - * for every element. This function takes 3 arguments (the element, the - * index and the array) and should return a boolean. - * @param {S=} opt_obj The object to be used as the value of 'this' - * within f. - * @return {boolean} false if any element fails the test. - * @template T,S - */ -goog.array.every = goog.NATIVE_ARRAY_PROTOTYPES && - (goog.array.ASSUME_NATIVE_FUNCTIONS || - goog.array.ARRAY_PROTOTYPE_.every) ? - function(arr, f, opt_obj) { - goog.asserts.assert(arr.length != null); - - return goog.array.ARRAY_PROTOTYPE_.every.call(arr, f, opt_obj); - } : - function(arr, f, opt_obj) { - var l = arr.length; // must be fixed during loop... see docs - var arr2 = goog.isString(arr) ? arr.split('') : arr; - for (var i = 0; i < l; i++) { - if (i in arr2 && !f.call(opt_obj, arr2[i], i, arr)) { - return false; - } - } - return true; - }; - - -/** - * Counts the array elements that fulfill the predicate, i.e. for which the - * callback function returns true. Skips holes in the array. - * - * @param {!(Array<T>|goog.array.ArrayLike)} arr Array or array like object - * over which to iterate. - * @param {function(this: S, T, number, ?): boolean} f The function to call for - * every element. Takes 3 arguments (the element, the index and the array). - * @param {S=} opt_obj The object to be used as the value of 'this' within f. - * @return {number} The number of the matching elements. - * @template T,S - */ -goog.array.count = function(arr, f, opt_obj) { - var count = 0; - goog.array.forEach(arr, function(element, index, arr) { - if (f.call(opt_obj, element, index, arr)) { - ++count; - } - }, opt_obj); - return count; -}; - - -/** - * Search an array for the first element that satisfies a given condition and - * return that element. - * @param {Array<T>|goog.array.ArrayLike} arr Array or array - * like object over which to iterate. - * @param {?function(this:S, T, number, ?) : boolean} f The function to call - * for every element. This function takes 3 arguments (the element, the - * index and the array) and should return a boolean. - * @param {S=} opt_obj An optional "this" context for the function. - * @return {T|null} The first array element that passes the test, or null if no - * element is found. - * @template T,S - */ -goog.array.find = function(arr, f, opt_obj) { - var i = goog.array.findIndex(arr, f, opt_obj); - return i < 0 ? null : goog.isString(arr) ? arr.charAt(i) : arr[i]; -}; - - -/** - * Search an array for the first element that satisfies a given condition and - * return its index. - * @param {Array<T>|goog.array.ArrayLike} arr Array or array - * like object over which to iterate. - * @param {?function(this:S, T, number, ?) : boolean} f The function to call for - * every element. This function - * takes 3 arguments (the element, the index and the array) and should - * return a boolean. - * @param {S=} opt_obj An optional "this" context for the function. - * @return {number} The index of the first array element that passes the test, - * or -1 if no element is found. - * @template T,S - */ -goog.array.findIndex = function(arr, f, opt_obj) { - var l = arr.length; // must be fixed during loop... see docs - var arr2 = goog.isString(arr) ? arr.split('') : arr; - for (var i = 0; i < l; i++) { - if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) { - return i; - } - } - return -1; -}; - - -/** - * Search an array (in reverse order) for the last element that satisfies a - * given condition and return that element. - * @param {Array<T>|goog.array.ArrayLike} arr Array or array - * like object over which to iterate. - * @param {?function(this:S, T, number, ?) : boolean} f The function to call - * for every element. This function - * takes 3 arguments (the element, the index and the array) and should - * return a boolean. - * @param {S=} opt_obj An optional "this" context for the function. - * @return {T|null} The last array element that passes the test, or null if no - * element is found. - * @template T,S - */ -goog.array.findRight = function(arr, f, opt_obj) { - var i = goog.array.findIndexRight(arr, f, opt_obj); - return i < 0 ? null : goog.isString(arr) ? arr.charAt(i) : arr[i]; -}; - - -/** - * Search an array (in reverse order) for the last element that satisfies a - * given condition and return its index. - * @param {Array<T>|goog.array.ArrayLike} arr Array or array - * like object over which to iterate. - * @param {?function(this:S, T, number, ?) : boolean} f The function to call - * for every element. This function - * takes 3 arguments (the element, the index and the array) and should - * return a boolean. - * @param {S=} opt_obj An optional "this" context for the function. - * @return {number} The index of the last array element that passes the test, - * or -1 if no element is found. - * @template T,S - */ -goog.array.findIndexRight = function(arr, f, opt_obj) { - var l = arr.length; // must be fixed during loop... see docs - var arr2 = goog.isString(arr) ? arr.split('') : arr; - for (var i = l - 1; i >= 0; i--) { - if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) { - return i; - } - } - return -1; -}; - - -/** - * Whether the array contains the given object. - * @param {goog.array.ArrayLike} arr The array to test for the presence of the - * element. - * @param {*} obj The object for which to test. - * @return {boolean} true if obj is present. - */ -goog.array.contains = function(arr, obj) { - return goog.array.indexOf(arr, obj) >= 0; -}; - - -/** - * Whether the array is empty. - * @param {goog.array.ArrayLike} arr The array to test. - * @return {boolean} true if empty. - */ -goog.array.isEmpty = function(arr) { - return arr.length == 0; -}; - - -/** - * Clears the array. - * @param {goog.array.ArrayLike} arr Array or array like object to clear. - */ -goog.array.clear = function(arr) { - // For non real arrays we don't have the magic length so we delete the - // indices. - if (!goog.isArray(arr)) { - for (var i = arr.length - 1; i >= 0; i--) { - delete arr[i]; } } - arr.length = 0; + return output; }; /** - * Pushes an item into an array, if it's not already in the array. - * @param {Array<T>} arr Array into which to insert the item. - * @param {T} obj Value to add. - * @template T + * Removes all properties from an object. + * @param {Object} object The object to clear. */ -goog.array.insert = function(arr, obj) { - if (!goog.array.contains(arr, obj)) { - arr.push(obj); +ol.object.clear = function(object) { + for (var property in object) { + delete object[property]; } }; /** - * Inserts an object at the given index of the array. - * @param {goog.array.ArrayLike} arr The array to modify. - * @param {*} obj The object to insert. - * @param {number=} opt_i The index at which to insert the object. If omitted, - * treated as 0. A negative index is counted from the end of the array. - */ -goog.array.insertAt = function(arr, obj, opt_i) { - goog.array.splice(arr, opt_i, 0, obj); -}; - - -/** - * Inserts at the given index of the array, all elements of another array. - * @param {goog.array.ArrayLike} arr The array to modify. - * @param {goog.array.ArrayLike} elementsToAdd The array of elements to add. - * @param {number=} opt_i The index at which to insert the object. If omitted, - * treated as 0. A negative index is counted from the end of the array. - */ -goog.array.insertArrayAt = function(arr, elementsToAdd, opt_i) { - goog.partial(goog.array.splice, arr, opt_i, 0).apply(null, elementsToAdd); -}; - - -/** - * Inserts an object into an array before a specified object. - * @param {Array<T>} arr The array to modify. - * @param {T} obj The object to insert. - * @param {T=} opt_obj2 The object before which obj should be inserted. If obj2 - * is omitted or not found, obj is inserted at the end of the array. - * @template T + * Get an array of property values from an object. + * @param {Object<K,V>} object The object from which to get the values. + * @return {!Array<V>} The property values. + * @template K,V */ -goog.array.insertBefore = function(arr, obj, opt_obj2) { - var i; - if (arguments.length == 2 || (i = goog.array.indexOf(arr, opt_obj2)) < 0) { - arr.push(obj); - } else { - goog.array.insertAt(arr, obj, i); +ol.object.getValues = function(object) { + var values = []; + for (var property in object) { + values.push(object[property]); } + return values; }; /** - * Removes the first occurrence of a particular value from an array. - * @param {Array<T>|goog.array.ArrayLike} arr Array from which to remove - * value. - * @param {T} obj Object to remove. - * @return {boolean} True if an element was removed. - * @template T + * Determine if an object has any properties. + * @param {Object} object The object to check. + * @return {boolean} The object is empty. */ -goog.array.remove = function(arr, obj) { - var i = goog.array.indexOf(arr, obj); - var rv; - if ((rv = i >= 0)) { - goog.array.removeAt(arr, i); +ol.object.isEmpty = function(object) { + var property; + for (property in object) { + return false; } - return rv; + return !property; }; - /** - * Removes from an array the element at index i - * @param {goog.array.ArrayLike} arr Array or array like object from which to - * remove value. - * @param {number} i The index to remove. - * @return {boolean} True if an element was removed. + * File for all typedefs used by the compiler, and referenced by JSDoc. + * + * These look like vars (or var properties), but in fact are simply identifiers + * for the Closure compiler. Originally they were included in the appropriate + * namespace file, but with the move away from Closure namespaces and towards + * self-contained standard modules are now all in this file. + * Unlike the other type definitions - enums and constructor functions - they + * are not code and so are not imported or exported. They are only referred to + * in type-defining comments used by the Closure compiler, and so should not + * appear in module code. + * + * When the code is converted to ES6 modules, the namespace structure will + * disappear, and these typedefs will have to be renamed accordingly, but the + * namespace structure is maintained for the present for backwards compatibility. + * + * In principle, typedefs should not have a `goog.provide` nor should files which + * refer to a typedef in comments need a `goog.require`. However, goog.provides + * are needed for 2 cases, both to prevent compiler errors/warnings: + * - the 1st two for specific errors + * - each sub-namespace needs at least one so the namespace is created when not + * used in the code, as when application code is compiled with the library. */ -goog.array.removeAt = function(arr, i) { - goog.asserts.assert(arr.length != null); +goog.provide('ol.Extent'); +goog.provide('ol.events.EventTargetLike'); - // use generic form of splice - // splice returns the removed items and if successful the length of that - // will be 1 - return goog.array.ARRAY_PROTOTYPE_.splice.call(arr, i, 1).length == 1; -}; +goog.provide('ol.interaction.DragBoxEndConditionType'); +goog.provide('ol.proj.ProjectionLike'); +goog.provide('ol.raster.Operation'); +goog.provide('ol.style.AtlasBlock'); /** - * Removes the first value that satisfies the given condition. - * @param {Array<T>|goog.array.ArrayLike} arr Array or array - * like object over which to iterate. - * @param {?function(this:S, T, number, ?) : boolean} f The function to call - * for every element. This function - * takes 3 arguments (the element, the index and the array) and should - * return a boolean. - * @param {S=} opt_obj An optional "this" context for the function. - * @return {boolean} True if an element was removed. - * @template T,S + * @typedef {string|Array.<string>|ol.Attribution|Array.<ol.Attribution>} + * @api */ -goog.array.removeIf = function(arr, f, opt_obj) { - var i = goog.array.findIndex(arr, f, opt_obj); - if (i >= 0) { - goog.array.removeAt(arr, i); - return true; - } - return false; -}; +ol.AttributionLike; /** - * Removes all values that satisfy the given condition. - * @param {Array<T>|goog.array.ArrayLike} arr Array or array - * like object over which to iterate. - * @param {?function(this:S, T, number, ?) : boolean} f The function to call - * for every element. This function - * takes 3 arguments (the element, the index and the array) and should - * return a boolean. - * @param {S=} opt_obj An optional "this" context for the function. - * @return {number} The number of items removed - * @template T,S + * @typedef {{fillStyle: ol.ColorLike}} */ -goog.array.removeAllIf = function(arr, f, opt_obj) { - var removedCount = 0; - goog.array.forEachRight(arr, function(val, index) { - if (f.call(opt_obj, val, index, arr)) { - if (goog.array.removeAt(arr, index)) { - removedCount++; - } - } - }); - return removedCount; -}; +ol.CanvasFillState; /** - * Returns a new array that is the result of joining the arguments. If arrays - * are passed then their items are added, however, if non-arrays are passed they - * will be added to the return array as is. - * - * Note that ArrayLike objects will be added as is, rather than having their - * items added. - * - * goog.array.concat([1, 2], [3, 4]) -> [1, 2, 3, 4] - * goog.array.concat(0, [1, 2]) -> [0, 1, 2] - * goog.array.concat([1, 2], null) -> [1, 2, null] - * - * There is bug in all current versions of IE (6, 7 and 8) where arrays created - * in an iframe become corrupted soon (not immediately) after the iframe is - * destroyed. This is common if loading data via goog.net.IframeIo, for example. - * This corruption only affects the concat method which will start throwing - * Catastrophic Errors (#-2147418113). - * - * See http://endoflow.com/scratch/corrupted-arrays.html for a test case. - * - * Internally goog.array should use this, so that all methods will continue to - * work on these broken array objects. + * A function returning the canvas element (`{HTMLCanvasElement}`) + * used by the source as an image. The arguments passed to the function are: + * {@link ol.Extent} the image extent, `{number}` the image resolution, + * `{number}` the device pixel ratio, {@link ol.Size} the image size, and + * {@link ol.proj.Projection} the image projection. The canvas returned by + * this function is cached by the source. The this keyword inside the function + * references the {@link ol.source.ImageCanvas}. * - * @param {...*} var_args Items to concatenate. Arrays will have each item - * added, while primitives and objects will be added as is. - * @return {!Array<?>} The new resultant array. + * @typedef {function(this:ol.source.ImageCanvas, ol.Extent, number, + * number, ol.Size, ol.proj.Projection): HTMLCanvasElement} + * @api */ -goog.array.concat = function(var_args) { - return goog.array.ARRAY_PROTOTYPE_.concat.apply( - goog.array.ARRAY_PROTOTYPE_, arguments); -}; +ol.CanvasFunctionType; /** - * Returns a new array that contains the contents of all the arrays passed. - * @param {...!Array<T>} var_args - * @return {!Array<T>} - * @template T + * @typedef {{lineCap: string, + * lineDash: Array.<number>, + * lineJoin: string, + * lineWidth: number, + * miterLimit: number, + * strokeStyle: string}} */ -goog.array.join = function(var_args) { - return goog.array.ARRAY_PROTOTYPE_.concat.apply( - goog.array.ARRAY_PROTOTYPE_, arguments); -}; +ol.CanvasStrokeState; /** - * Converts an object to an array. - * @param {Array<T>|goog.array.ArrayLike} object The object to convert to an - * array. - * @return {!Array<T>} The object converted into an array. If object has a - * length property, every property indexed with a non-negative number - * less than length will be included in the result. If object does not - * have a length property, an empty array will be returned. - * @template T + * @typedef {{font: string, + * textAlign: string, + * textBaseline: string}} */ -goog.array.toArray = function(object) { - var length = object.length; - - // If length is not a number the following it false. This case is kept for - // backwards compatibility since there are callers that pass objects that are - // not array like. - if (length > 0) { - var rv = new Array(length); - for (var i = 0; i < length; i++) { - rv[i] = object[i]; - } - return rv; - } - return []; -}; +ol.CanvasTextState; /** - * Does a shallow copy of an array. - * @param {Array<T>|goog.array.ArrayLike} arr Array or array-like object to - * clone. - * @return {!Array<T>} Clone of the input array. - * @template T + * @typedef {function((ol.Coordinate|undefined)): (ol.Coordinate|undefined)} */ -goog.array.clone = goog.array.toArray; +ol.CenterConstraintType; /** - * Extends an array with another array, element, or "array like" object. - * This function operates 'in-place', it does not create a new Array. - * - * Example: - * var a = []; - * goog.array.extend(a, [0, 1]); - * a; // [0, 1] - * goog.array.extend(a, 2); - * a; // [0, 1, 2] - * - * @param {Array<VALUE>} arr1 The array to modify. - * @param {...(Array<VALUE>|VALUE)} var_args The elements or arrays of elements - * to add to arr1. - * @template VALUE + * A color represented as a short array [red, green, blue, alpha]. + * red, green, and blue should be integers in the range 0..255 inclusive. + * alpha should be a float in the range 0..1 inclusive. If no alpha value is + * given then `1` will be used. + * @typedef {Array.<number>} + * @api */ -goog.array.extend = function(arr1, var_args) { - for (var i = 1; i < arguments.length; i++) { - var arr2 = arguments[i]; - if (goog.isArrayLike(arr2)) { - var len1 = arr1.length || 0; - var len2 = arr2.length || 0; - arr1.length = len1 + len2; - for (var j = 0; j < len2; j++) { - arr1[len1 + j] = arr2[j]; - } - } else { - arr1.push(arr2); - } - } -}; +ol.Color; /** - * Adds or removes elements from an array. This is a generic version of Array - * splice. This means that it might work on other objects similar to arrays, - * such as the arguments object. + * A type accepted by CanvasRenderingContext2D.fillStyle. + * Represents a color, pattern, or gradient. * - * @param {Array<T>|goog.array.ArrayLike} arr The array to modify. - * @param {number|undefined} index The index at which to start changing the - * array. If not defined, treated as 0. - * @param {number} howMany How many elements to remove (0 means no removal. A - * value below 0 is treated as zero and so is any other non number. Numbers - * are floored). - * @param {...T} var_args Optional, additional elements to insert into the - * array. - * @return {!Array<T>} the removed elements. - * @template T + * @typedef {string|CanvasPattern|CanvasGradient} + * @api */ -goog.array.splice = function(arr, index, howMany, var_args) { - goog.asserts.assert(arr.length != null); - - return goog.array.ARRAY_PROTOTYPE_.splice.apply( - arr, goog.array.slice(arguments, 1)); -}; +ol.ColorLike; /** - * Returns a new array from a segment of an array. This is a generic version of - * Array slice. This means that it might work on other objects similar to - * arrays, such as the arguments object. - * - * @param {Array<T>|goog.array.ArrayLike} arr The array from - * which to copy a segment. - * @param {number} start The index of the first element to copy. - * @param {number=} opt_end The index after the last element to copy. - * @return {!Array<T>} A new array containing the specified segment of the - * original array. - * @template T + * An array of numbers representing an xy coordinate. Example: `[16, 48]`. + * @typedef {Array.<number>} ol.Coordinate + * @api stable */ -goog.array.slice = function(arr, start, opt_end) { - goog.asserts.assert(arr.length != null); - - // passing 1 arg to slice is not the same as passing 2 where the second is - // null or undefined (in that case the second argument is treated as 0). - // we could use slice on the arguments object and then use apply instead of - // testing the length - if (arguments.length <= 2) { - return goog.array.ARRAY_PROTOTYPE_.slice.call(arr, start); - } else { - return goog.array.ARRAY_PROTOTYPE_.slice.call(arr, start, opt_end); - } -}; +ol.Coordinate; /** - * Removes all duplicates from an array (retaining only the first - * occurrence of each array element). This function modifies the - * array in place and doesn't change the order of the non-duplicate items. - * - * For objects, duplicates are identified as having the same unique ID as - * defined by {@link goog.getUid}. - * - * Alternatively you can specify a custom hash function that returns a unique - * value for each item in the array it should consider unique. - * - * Runtime: N, - * Worstcase space: 2N (no dupes) + * A function that takes a {@link ol.Coordinate} and transforms it into a + * `{string}`. * - * @param {Array<T>|goog.array.ArrayLike} arr The array from which to remove - * duplicates. - * @param {Array=} opt_rv An optional array in which to return the results, - * instead of performing the removal inplace. If specified, the original - * array will remain unchanged. - * @param {function(T):string=} opt_hashFn An optional function to use to - * apply to every item in the array. This function should return a unique - * value for each item in the array it should consider unique. - * @template T + * @typedef {function((ol.Coordinate|undefined)): string} + * @api stable */ -goog.array.removeDuplicates = function(arr, opt_rv, opt_hashFn) { - var returnArray = opt_rv || arr; - var defaultHashFn = function(item) { - // Prefix each type with a single character representing the type to - // prevent conflicting keys (e.g. true and 'true'). - return goog.isObject(item) ? 'o' + goog.getUid(item) : - (typeof item).charAt(0) + item; - }; - var hashFn = opt_hashFn || defaultHashFn; - - var seen = {}, cursorInsert = 0, cursorRead = 0; - while (cursorRead < arr.length) { - var current = arr[cursorRead++]; - var key = hashFn(current); - if (!Object.prototype.hasOwnProperty.call(seen, key)) { - seen[key] = true; - returnArray[cursorInsert++] = current; - } - } - returnArray.length = cursorInsert; -}; +ol.CoordinateFormatType; /** - * Searches the specified array for the specified target using the binary - * search algorithm. If no opt_compareFn is specified, elements are compared - * using <code>goog.array.defaultCompare</code>, which compares the elements - * using the built in < and > operators. This will produce the expected - * behavior for homogeneous arrays of String(s) and Number(s). The array - * specified <b>must</b> be sorted in ascending order (as defined by the - * comparison function). If the array is not sorted, results are undefined. - * If the array contains multiple instances of the specified target value, any - * of these instances may be found. - * - * Runtime: O(log n) - * - * @param {Array<VALUE>|goog.array.ArrayLike} arr The array to be searched. - * @param {TARGET} target The sought value. - * @param {function(TARGET, VALUE): number=} opt_compareFn Optional comparison - * function by which the array is ordered. Should take 2 arguments to - * compare, and return a negative number, zero, or a positive number - * depending on whether the first argument is less than, equal to, or - * greater than the second. - * @return {number} Lowest index of the target value if found, otherwise - * (-(insertion point) - 1). The insertion point is where the value should - * be inserted into arr to preserve the sorted property. Return value >= 0 - * iff target is found. - * @template TARGET, VALUE + * An array of numbers representing an extent: `[minx, miny, maxx, maxy]`. + * @typedef {Array.<number>} + * @api stable */ -goog.array.binarySearch = function(arr, target, opt_compareFn) { - return goog.array.binarySearch_(arr, - opt_compareFn || goog.array.defaultCompare, false /* isEvaluator */, - target); -}; +ol.Extent; /** - * Selects an index in the specified array using the binary search algorithm. - * The evaluator receives an element and determines whether the desired index - * is before, at, or after it. The evaluator must be consistent (formally, - * goog.array.map(goog.array.map(arr, evaluator, opt_obj), goog.math.sign) - * must be monotonically non-increasing). + * {@link ol.source.Vector} sources use a function of this type to load + * features. * - * Runtime: O(log n) + * This function takes an {@link ol.Extent} representing the area to be loaded, + * a `{number}` representing the resolution (map units per pixel) and an + * {@link ol.proj.Projection} for the projection as arguments. `this` within + * the function is bound to the {@link ol.source.Vector} it's called from. * - * @param {Array<VALUE>|goog.array.ArrayLike} arr The array to be searched. - * @param {function(this:THIS, VALUE, number, ?): number} evaluator - * Evaluator function that receives 3 arguments (the element, the index and - * the array). Should return a negative number, zero, or a positive number - * depending on whether the desired index is before, at, or after the - * element passed to it. - * @param {THIS=} opt_obj The object to be used as the value of 'this' - * within evaluator. - * @return {number} Index of the leftmost element matched by the evaluator, if - * such exists; otherwise (-(insertion point) - 1). The insertion point is - * the index of the first element for which the evaluator returns negative, - * or arr.length if no such element exists. The return value is non-negative - * iff a match is found. - * @template THIS, VALUE + * The function is responsible for loading the features and adding them to the + * source. + * @api + * @typedef {function(this:ol.source.Vector, ol.Extent, number, + * ol.proj.Projection)} */ -goog.array.binarySelect = function(arr, evaluator, opt_obj) { - return goog.array.binarySearch_(arr, evaluator, true /* isEvaluator */, - undefined /* opt_target */, opt_obj); -}; +ol.FeatureLoader; /** - * Implementation of a binary search algorithm which knows how to use both - * comparison functions and evaluators. If an evaluator is provided, will call - * the evaluator with the given optional data object, conforming to the - * interface defined in binarySelect. Otherwise, if a comparison function is - * provided, will call the comparison function against the given data object. - * - * This implementation purposefully does not use goog.bind or goog.partial for - * performance reasons. - * - * Runtime: O(log n) + * A function that returns an array of {@link ol.style.Style styles} given a + * resolution. The `this` keyword inside the function references the + * {@link ol.Feature} to be styled. * - * @param {Array<VALUE>|goog.array.ArrayLike} arr The array to be searched. - * @param {function(TARGET, VALUE): number| - * function(this:THIS, VALUE, number, ?): number} compareFn Either an - * evaluator or a comparison function, as defined by binarySearch - * and binarySelect above. - * @param {boolean} isEvaluator Whether the function is an evaluator or a - * comparison function. - * @param {TARGET=} opt_target If the function is a comparison function, then - * this is the target to binary search for. - * @param {THIS=} opt_selfObj If the function is an evaluator, this is an - * optional this object for the evaluator. - * @return {number} Lowest index of the target value if found, otherwise - * (-(insertion point) - 1). The insertion point is where the value should - * be inserted into arr to preserve the sorted property. Return value >= 0 - * iff target is found. - * @template THIS, VALUE, TARGET - * @private + * @typedef {function(this: ol.Feature, number): + * (ol.style.Style|Array.<ol.style.Style>)} + * @api stable */ -goog.array.binarySearch_ = function(arr, compareFn, isEvaluator, opt_target, - opt_selfObj) { - var left = 0; // inclusive - var right = arr.length; // exclusive - var found; - while (left < right) { - var middle = (left + right) >> 1; - var compareResult; - if (isEvaluator) { - compareResult = compareFn.call(opt_selfObj, arr[middle], middle, arr); - } else { - compareResult = compareFn(opt_target, arr[middle]); - } - if (compareResult > 0) { - left = middle + 1; - } else { - right = middle; - // We are looking for the lowest index so we can't return immediately. - found = !compareResult; - } - } - // left is the index if found, or the insertion point otherwise. - // ~left is a shorthand for -left - 1. - return found ? left : ~left; -}; +ol.FeatureStyleFunction; /** - * Sorts the specified array into ascending order. If no opt_compareFn is - * specified, elements are compared using - * <code>goog.array.defaultCompare</code>, which compares the elements using - * the built in < and > operators. This will produce the expected behavior - * for homogeneous arrays of String(s) and Number(s), unlike the native sort, - * but will give unpredictable results for heterogenous lists of strings and - * numbers with different numbers of digits. - * - * This sort is not guaranteed to be stable. - * - * Runtime: Same as <code>Array.prototype.sort</code> + * {@link ol.source.Vector} sources use a function of this type to get the url + * to load features from. * - * @param {Array<T>} arr The array to be sorted. - * @param {?function(T,T):number=} opt_compareFn Optional comparison - * function by which the - * array is to be ordered. Should take 2 arguments to compare, and return a - * negative number, zero, or a positive number depending on whether the - * first argument is less than, equal to, or greater than the second. - * @template T + * This function takes an {@link ol.Extent} representing the area to be loaded, + * a `{number}` representing the resolution (map units per pixel) and an + * {@link ol.proj.Projection} for the projection as arguments and returns a + * `{string}` representing the URL. + * @api + * @typedef {function(ol.Extent, number, ol.proj.Projection) : string} */ -goog.array.sort = function(arr, opt_compareFn) { - // TODO(arv): Update type annotation since null is not accepted. - arr.sort(opt_compareFn || goog.array.defaultCompare); -}; +ol.FeatureUrlFunction; /** - * Sorts the specified array into ascending order in a stable way. If no - * opt_compareFn is specified, elements are compared using - * <code>goog.array.defaultCompare</code>, which compares the elements using - * the built in < and > operators. This will produce the expected behavior - * for homogeneous arrays of String(s) and Number(s). - * - * Runtime: Same as <code>Array.prototype.sort</code>, plus an additional - * O(n) overhead of copying the array twice. + * A function that is called to trigger asynchronous canvas drawing. It is + * called with a "done" callback that should be called when drawing is done. + * If any error occurs during drawing, the "done" callback should be called with + * that error. * - * @param {Array<T>} arr The array to be sorted. - * @param {?function(T, T): number=} opt_compareFn Optional comparison function - * by which the array is to be ordered. Should take 2 arguments to compare, - * and return a negative number, zero, or a positive number depending on - * whether the first argument is less than, equal to, or greater than the - * second. - * @template T + * @typedef {function(function(Error))} */ -goog.array.stableSort = function(arr, opt_compareFn) { - for (var i = 0; i < arr.length; i++) { - arr[i] = {index: i, value: arr[i]}; - } - var valueCompareFn = opt_compareFn || goog.array.defaultCompare; - function stableCompareFn(obj1, obj2) { - return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index; - }; - goog.array.sort(arr, stableCompareFn); - for (var i = 0; i < arr.length; i++) { - arr[i] = arr[i].value; - } -}; +ol.ImageCanvasLoader; /** - * Sort the specified array into ascending order based on item keys - * returned by the specified key function. - * If no opt_compareFn is specified, the keys are compared in ascending order - * using <code>goog.array.defaultCompare</code>. + * A function that takes an {@link ol.Image} for the image and a `{string}` for + * the src as arguments. It is supposed to make it so the underlying image + * {@link ol.Image#getImage} is assigned the content specified by the src. If + * not specified, the default is * - * Runtime: O(S(f(n)), where S is runtime of <code>goog.array.sort</code> - * and f(n) is runtime of the key function. + * function(image, src) { + * image.getImage().src = src; + * } * - * @param {Array<T>} arr The array to be sorted. - * @param {function(T): K} keyFn Function taking array element and returning - * a key used for sorting this element. - * @param {?function(K, K): number=} opt_compareFn Optional comparison function - * by which the keys are to be ordered. Should take 2 arguments to compare, - * and return a negative number, zero, or a positive number depending on - * whether the first argument is less than, equal to, or greater than the - * second. - * @template T,K - */ -goog.array.sortByKey = function(arr, keyFn, opt_compareFn) { - var keyCompareFn = opt_compareFn || goog.array.defaultCompare; - goog.array.sort(arr, function(a, b) { - return keyCompareFn(keyFn(a), keyFn(b)); - }); -}; - - -/** - * Sorts an array of objects by the specified object key and compare - * function. If no compare function is provided, the key values are - * compared in ascending order using <code>goog.array.defaultCompare</code>. - * This won't work for keys that get renamed by the compiler. So use - * {'foo': 1, 'bar': 2} rather than {foo: 1, bar: 2}. - * @param {Array<Object>} arr An array of objects to sort. - * @param {string} key The object key to sort by. - * @param {Function=} opt_compareFn The function to use to compare key - * values. - */ -goog.array.sortObjectsByKey = function(arr, key, opt_compareFn) { - goog.array.sortByKey(arr, - function(obj) { return obj[key]; }, - opt_compareFn); -}; - - -/** - * Tells if the array is sorted. - * @param {!Array<T>} arr The array. - * @param {?function(T,T):number=} opt_compareFn Function to compare the - * array elements. - * Should take 2 arguments to compare, and return a negative number, zero, - * or a positive number depending on whether the first argument is less - * than, equal to, or greater than the second. - * @param {boolean=} opt_strict If true no equal elements are allowed. - * @return {boolean} Whether the array is sorted. - * @template T - */ -goog.array.isSorted = function(arr, opt_compareFn, opt_strict) { - var compare = opt_compareFn || goog.array.defaultCompare; - for (var i = 1; i < arr.length; i++) { - var compareResult = compare(arr[i - 1], arr[i]); - if (compareResult > 0 || compareResult == 0 && opt_strict) { - return false; - } - } - return true; -}; - - -/** - * Compares two arrays for equality. Two arrays are considered equal if they - * have the same length and their corresponding elements are equal according to - * the comparison function. + * Providing a custom `imageLoadFunction` can be useful to load images with + * post requests or - in general - through XHR requests, where the src of the + * image element would be set to a data URI when the content is loaded. * - * @param {goog.array.ArrayLike} arr1 The first array to compare. - * @param {goog.array.ArrayLike} arr2 The second array to compare. - * @param {Function=} opt_equalsFn Optional comparison function. - * Should take 2 arguments to compare, and return true if the arguments - * are equal. Defaults to {@link goog.array.defaultCompareEquality} which - * compares the elements using the built-in '===' operator. - * @return {boolean} Whether the two arrays are equal. - */ -goog.array.equals = function(arr1, arr2, opt_equalsFn) { - if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) || - arr1.length != arr2.length) { - return false; - } - var l = arr1.length; - var equalsFn = opt_equalsFn || goog.array.defaultCompareEquality; - for (var i = 0; i < l; i++) { - if (!equalsFn(arr1[i], arr2[i])) { - return false; - } - } - return true; -}; - - -/** - * 3-way array compare function. - * @param {!Array<VALUE>|!goog.array.ArrayLike} arr1 The first array to - * compare. - * @param {!Array<VALUE>|!goog.array.ArrayLike} arr2 The second array to - * compare. - * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison - * function by which the array is to be ordered. Should take 2 arguments to - * compare, and return a negative number, zero, or a positive number - * depending on whether the first argument is less than, equal to, or - * greater than the second. - * @return {number} Negative number, zero, or a positive number depending on - * whether the first argument is less than, equal to, or greater than the - * second. - * @template VALUE - */ -goog.array.compare3 = function(arr1, arr2, opt_compareFn) { - var compare = opt_compareFn || goog.array.defaultCompare; - var l = Math.min(arr1.length, arr2.length); - for (var i = 0; i < l; i++) { - var result = compare(arr1[i], arr2[i]); - if (result != 0) { - return result; - } - } - return goog.array.defaultCompare(arr1.length, arr2.length); -}; - - -/** - * Compares its two arguments for order, using the built in < and > - * operators. - * @param {VALUE} a The first object to be compared. - * @param {VALUE} b The second object to be compared. - * @return {number} A negative number, zero, or a positive number as the first - * argument is less than, equal to, or greater than the second, - * respectively. - * @template VALUE + * @typedef {function(ol.Image, string)} + * @api */ -goog.array.defaultCompare = function(a, b) { - return a > b ? 1 : a < b ? -1 : 0; -}; +ol.ImageLoadFunctionType; /** - * Compares its two arguments for inverse order, using the built in < and > - * operators. - * @param {VALUE} a The first object to be compared. - * @param {VALUE} b The second object to be compared. - * @return {number} A negative number, zero, or a positive number as the first - * argument is greater than, equal to, or less than the second, - * respectively. - * @template VALUE + * @typedef {{x: number, xunits: (ol.style.IconAnchorUnits|undefined), + * y: number, yunits: (ol.style.IconAnchorUnits|undefined)}} */ -goog.array.inverseDefaultCompare = function(a, b) { - return -goog.array.defaultCompare(a, b); -}; +ol.KMLVec2_; /** - * Compares its two arguments for equality, using the built in === operator. - * @param {*} a The first object to compare. - * @param {*} b The second object to compare. - * @return {boolean} True if the two arguments are equal, false otherwise. + * @typedef {{flatCoordinates: Array.<number>, + * whens: Array.<number>}} */ -goog.array.defaultCompareEquality = function(a, b) { - return a === b; -}; +ol.KMLGxTrackObject_; /** - * Inserts a value into a sorted array. The array is not modified if the - * value is already present. - * @param {Array<VALUE>|goog.array.ArrayLike} array The array to modify. - * @param {VALUE} value The object to insert. - * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison - * function by which the array is ordered. Should take 2 arguments to - * compare, and return a negative number, zero, or a positive number - * depending on whether the first argument is less than, equal to, or - * greater than the second. - * @return {boolean} True if an element was inserted. - * @template VALUE + * @typedef {{layer: ol.layer.Layer, + * opacity: number, + * sourceState: ol.source.State, + * visible: boolean, + * managed: boolean, + * extent: (ol.Extent|undefined), + * zIndex: number, + * maxResolution: number, + * minResolution: number}} */ -goog.array.binaryInsert = function(array, value, opt_compareFn) { - var index = goog.array.binarySearch(array, value, opt_compareFn); - if (index < 0) { - goog.array.insertAt(array, value, -(index + 1)); - return true; - } - return false; -}; +ol.LayerState; /** - * Removes a value from a sorted array. - * @param {!Array<VALUE>|!goog.array.ArrayLike} array The array to modify. - * @param {VALUE} value The object to remove. - * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison - * function by which the array is ordered. Should take 2 arguments to - * compare, and return a negative number, zero, or a positive number - * depending on whether the first argument is less than, equal to, or - * greater than the second. - * @return {boolean} True if an element was removed. - * @template VALUE + * One of `all`, `bbox`, `tile`. + * + * @typedef {function(ol.Extent, number): Array.<ol.Extent>} + * @api */ -goog.array.binaryRemove = function(array, value, opt_compareFn) { - var index = goog.array.binarySearch(array, value, opt_compareFn); - return (index >= 0) ? goog.array.removeAt(array, index) : false; -}; +ol.LoadingStrategy; /** - * Splits an array into disjoint buckets according to a splitting function. - * @param {Array<T>} array The array. - * @param {function(this:S, T,number,Array<T>):?} sorter Function to call for - * every element. This takes 3 arguments (the element, the index and the - * array) and must return a valid object key (a string, number, etc), or - * undefined, if that object should not be placed in a bucket. - * @param {S=} opt_obj The object to be used as the value of 'this' within - * sorter. - * @return {!Object} An object, with keys being all of the unique return values - * of sorter, and values being arrays containing the items for - * which the splitter returned that key. - * @template T,S + * @typedef {{key_: string, + * newer: ol.LRUCacheEntry, + * older: ol.LRUCacheEntry, + * value_: *}} */ -goog.array.bucket = function(array, sorter, opt_obj) { - var buckets = {}; - - for (var i = 0; i < array.length; i++) { - var value = array[i]; - var key = sorter.call(opt_obj, value, i, array); - if (goog.isDef(key)) { - // Push the value to the right bucket, creating it if necessary. - var bucket = buckets[key] || (buckets[key] = []); - bucket.push(value); - } - } - - return buckets; -}; +ol.LRUCacheEntry; /** - * Creates a new object built from the provided array and the key-generation - * function. - * @param {Array<T>|goog.array.ArrayLike} arr Array or array like object over - * which to iterate whose elements will be the values in the new object. - * @param {?function(this:S, T, number, ?) : string} keyFunc The function to - * call for every element. This function takes 3 arguments (the element, the - * index and the array) and should return a string that will be used as the - * key for the element in the new object. If the function returns the same - * key for more than one element, the value for that key is - * implementation-defined. - * @param {S=} opt_obj The object to be used as the value of 'this' - * within keyFunc. - * @return {!Object<T>} The new object. - * @template T,S + * @typedef {{controls: ol.Collection.<ol.control.Control>, + * interactions: ol.Collection.<ol.interaction.Interaction>, + * keyboardEventTarget: (Element|Document), + * logos: (Object.<string, (string|Element)>), + * overlays: ol.Collection.<ol.Overlay>, + * rendererConstructor: + * function(new: ol.renderer.Map, Element, ol.Map), + * values: Object.<string, *>}} */ -goog.array.toObject = function(arr, keyFunc, opt_obj) { - var ret = {}; - goog.array.forEach(arr, function(element, index) { - ret[keyFunc.call(opt_obj, element, index, arr)] = element; - }); - return ret; -}; +ol.MapOptionsInternal; /** - * Creates a range of numbers in an arithmetic progression. - * - * Range takes 1, 2, or 3 arguments: - * <pre> - * range(5) is the same as range(0, 5, 1) and produces [0, 1, 2, 3, 4] - * range(2, 5) is the same as range(2, 5, 1) and produces [2, 3, 4] - * range(-2, -5, -1) produces [-2, -3, -4] - * range(-2, -5, 1) produces [], since stepping by 1 wouldn't ever reach -5. - * </pre> - * - * @param {number} startOrEnd The starting value of the range if an end argument - * is provided. Otherwise, the start value is 0, and this is the end value. - * @param {number=} opt_end The optional end value of the range. - * @param {number=} opt_step The step size between range values. Defaults to 1 - * if opt_step is undefined or 0. - * @return {!Array<number>} An array of numbers for the requested range. May be - * an empty array if adding the step would not converge toward the end - * value. + * An array with two elements, representing a pixel. The first element is the + * x-coordinate, the second the y-coordinate of the pixel. + * @typedef {Array.<number>} + * @api stable */ -goog.array.range = function(startOrEnd, opt_end, opt_step) { - var array = []; - var start = 0; - var end = startOrEnd; - var step = opt_step || 1; - if (opt_end !== undefined) { - start = startOrEnd; - end = opt_end; - } - - if (step * (end - start) < 0) { - // Sign mismatch: start + step will never reach the end value. - return []; - } - - if (step > 0) { - for (var i = start; i < end; i += step) { - array.push(i); - } - } else { - for (var i = start; i > end; i += step) { - array.push(i); - } - } - return array; -}; +ol.Pixel; /** - * Returns an array consisting of the given value repeated N times. - * - * @param {VALUE} value The value to repeat. - * @param {number} n The repeat count. - * @return {!Array<VALUE>} An array with the repeated value. - * @template VALUE + * @typedef {function(ol.Map, ?olx.FrameState): boolean} */ -goog.array.repeat = function(value, n) { - var array = []; - for (var i = 0; i < n; i++) { - array[i] = value; - } - return array; -}; +ol.PostRenderFunction; /** - * Returns an array consisting of every argument with all arrays - * expanded in-place recursively. - * - * @param {...*} var_args The values to flatten. - * @return {!Array<?>} An array containing the flattened values. + * Function to perform manipulations before rendering. This function is called + * with the {@link ol.Map} as first and an optional {@link olx.FrameState} as + * second argument. Return `true` to keep this function for the next frame, + * `false` to remove it. + * @typedef {function(ol.Map, ?olx.FrameState): boolean} + * @api */ -goog.array.flatten = function(var_args) { - var CHUNK_SIZE = 8192; - - var result = []; - for (var i = 0; i < arguments.length; i++) { - var element = arguments[i]; - if (goog.isArray(element)) { - for (var c = 0; c < element.length; c += CHUNK_SIZE) { - var chunk = goog.array.slice(element, c, c + CHUNK_SIZE); - var recurseResult = goog.array.flatten.apply(null, chunk); - for (var r = 0; r < recurseResult.length; r++) { - result.push(recurseResult[r]); - } - } - } else { - result.push(element); - } - } - return result; -}; +ol.PreRenderFunction; /** - * Rotates an array in-place. After calling this method, the element at - * index i will be the element previously at index (i - n) % - * array.length, for all values of i between 0 and array.length - 1, - * inclusive. - * - * For example, suppose list comprises [t, a, n, k, s]. After invoking - * rotate(array, 1) (or rotate(array, -4)), array will comprise [s, t, a, n, k]. - * - * @param {!Array<T>} array The array to rotate. - * @param {number} n The amount to rotate. - * @return {!Array<T>} The array. - * @template T + * @typedef {function(ol.Extent, number, number) : ol.ImageBase} */ -goog.array.rotate = function(array, n) { - goog.asserts.assert(array.length != null); - - if (array.length) { - n %= array.length; - if (n > 0) { - goog.array.ARRAY_PROTOTYPE_.unshift.apply(array, array.splice(-n, n)); - } else if (n < 0) { - goog.array.ARRAY_PROTOTYPE_.push.apply(array, array.splice(0, -n)); - } - } - return array; -}; +ol.ReprojImageFunctionType; /** - * Moves one item of an array to a new position keeping the order of the rest - * of the items. Example use case: keeping a list of JavaScript objects - * synchronized with the corresponding list of DOM elements after one of the - * elements has been dragged to a new position. - * @param {!(Array|Arguments|{length:number})} arr The array to modify. - * @param {number} fromIndex Index of the item to move between 0 and - * {@code arr.length - 1}. - * @param {number} toIndex Target index between 0 and {@code arr.length - 1}. + * @typedef {function(number, number, number, number) : ol.Tile} */ -goog.array.moveItem = function(arr, fromIndex, toIndex) { - goog.asserts.assert(fromIndex >= 0 && fromIndex < arr.length); - goog.asserts.assert(toIndex >= 0 && toIndex < arr.length); - // Remove 1 item at fromIndex. - var removedItems = goog.array.ARRAY_PROTOTYPE_.splice.call(arr, fromIndex, 1); - // Insert the removed item at toIndex. - goog.array.ARRAY_PROTOTYPE_.splice.call(arr, toIndex, 0, removedItems[0]); - // We don't use goog.array.insertAt and goog.array.removeAt, because they're - // significantly slower than splice. -}; +ol.ReprojTileFunctionType; /** - * Creates a new array for which the element at position i is an array of the - * ith element of the provided arrays. The returned array will only be as long - * as the shortest array provided; additional values are ignored. For example, - * the result of zipping [1, 2] and [3, 4, 5] is [[1,3], [2, 4]]. - * - * This is similar to the zip() function in Python. See {@link - * http://docs.python.org/library/functions.html#zip} + * Single triangle; consists of 3 source points and 3 target points. * - * @param {...!goog.array.ArrayLike} var_args Arrays to be combined. - * @return {!Array<!Array<?>>} A new array of arrays created from - * provided arrays. + * @typedef {{source: Array.<ol.Coordinate>, + * target: Array.<ol.Coordinate>}} */ -goog.array.zip = function(var_args) { - if (!arguments.length) { - return []; - } - var result = []; - for (var i = 0; true; i++) { - var value = []; - for (var j = 0; j < arguments.length; j++) { - var arr = arguments[j]; - // If i is larger than the array length, this is the shortest array. - if (i >= arr.length) { - return result; - } - value.push(arr[i]); - } - result.push(value); - } -}; +ol.ReprojTriangle; /** - * Shuffles the values in the specified array using the Fisher-Yates in-place - * shuffle (also known as the Knuth Shuffle). By default, calls Math.random() - * and so resets the state of that random number generator. Similarly, may reset - * the state of the any other specified random number generator. - * - * Runtime: O(n) - * - * @param {!Array<?>} arr The array to be shuffled. - * @param {function():number=} opt_randFn Optional random function to use for - * shuffling. - * Takes no arguments, and returns a random number on the interval [0, 1). - * Defaults to Math.random() using JavaScript's built-in Math library. - */ -goog.array.shuffle = function(arr, opt_randFn) { - var randFn = opt_randFn || Math.random; - - for (var i = arr.length - 1; i > 0; i--) { - // Choose a random array index in [0, i] (inclusive with i). - var j = Math.floor(randFn() * (i + 1)); - - var tmp = arr[i]; - arr[i] = arr[j]; - arr[j] = tmp; - } -}; - - -/** - * Returns a new array of elements from arr, based on the indexes of elements - * provided by index_arr. For example, the result of index copying - * ['a', 'b', 'c'] with index_arr [1,0,0,2] is ['b', 'a', 'a', 'c']. - * - * @param {!Array<T>} arr The array to get a indexed copy from. - * @param {!Array<number>} index_arr An array of indexes to get from arr. - * @return {!Array<T>} A new array of elements from arr in index_arr order. - * @template T + * @typedef {function((number|undefined), number, number): (number|undefined)} */ -goog.array.copyByIndex = function(arr, index_arr) { - var result = []; - goog.array.forEach(index_arr, function(index) { - result.push(arr[index]); - }); - return result; -}; - -goog.provide('ol.array'); - -goog.require('goog.array'); -goog.require('goog.asserts'); +ol.ResolutionConstraintType; /** - * @param {Array.<number>} arr Array. - * @param {number} target Target. - * @return {number} Index. + * @typedef {function((number|undefined), number): (number|undefined)} */ -ol.array.binaryFindNearest = function(arr, target) { - var index = goog.array.binarySearch(arr, target, - /** - * @param {number} a A. - * @param {number} b B. - * @return {number} b minus a. - */ - function(a, b) { - return b - a; - }); - if (index >= 0) { - return index; - } else if (index == -1) { - return 0; - } else if (index == -arr.length - 1) { - return arr.length - 1; - } else { - var left = -index - 2; - var right = -index - 1; - if (arr[left] - target < target - arr[right]) { - return left; - } else { - return right; - } - } -}; +ol.RotationConstraintType; /** - * Compare function for array sort that is safe for numbers. - * @param {*} a The first object to be compared. - * @param {*} b The second object to be compared. - * @return {number} A negative number, zero, or a positive number as the first - * argument is less than, equal to, or greater than the second. + * An array of numbers representing a size: `[width, height]`. + * @typedef {Array.<number>} + * @api stable */ -ol.array.numberSafeCompareFunction = function(a, b) { - return a > b ? 1 : a < b ? -1 : 0; -}; +ol.Size; /** - * Whether the array contains the given object. - * @param {Array.<*>} arr The array to test for the presence of the element. - * @param {*} obj The object for which to test. - * @return {boolean} The object is in the array. + * @typedef {{attributions: (ol.AttributionLike|undefined), + * extent: (null|ol.Extent|undefined), + * logo: (string|olx.LogoOptions|undefined), + * projection: ol.proj.ProjectionLike, + * resolutions: (Array.<number>|undefined), + * state: (ol.source.State|undefined)}} */ -ol.array.includes = function(arr, obj) { - return arr.indexOf(obj) >= 0; -}; +ol.SourceImageOptions; /** - * @param {Array.<number>} arr Array. - * @param {number} target Target. - * @param {number} direction 0 means return the nearest, > 0 - * means return the largest nearest, < 0 means return the - * smallest nearest. - * @return {number} Index. + * @typedef {{revision: number, + * resolution: number, + * extent: ol.Extent}} */ -ol.array.linearFindNearest = function(arr, target, direction) { - var n = arr.length; - if (arr[0] <= target) { - return 0; - } else if (target <= arr[n - 1]) { - return n - 1; - } else { - var i; - if (direction > 0) { - for (i = 1; i < n; ++i) { - if (arr[i] < target) { - return i - 1; - } - } - } else if (direction < 0) { - for (i = 1; i < n; ++i) { - if (arr[i] <= target) { - return i; - } - } - } else { - for (i = 1; i < n; ++i) { - if (arr[i] == target) { - return i; - } else if (arr[i] < target) { - if (arr[i - 1] - target < target - arr[i]) { - return i - 1; - } else { - return i; - } - } - } - } - // We should never get here, but the compiler complains - // if it finds a path for which no number is returned. - goog.asserts.fail(); - return n - 1; - } -}; +ol.SourceRasterRenderedState; /** - * @param {Array.<*>} arr Array. - * @param {number} begin Begin index. - * @param {number} end End index. + * @typedef {{attributions: (ol.AttributionLike|undefined), + * logo: (string|olx.LogoOptions|undefined), + * projection: ol.proj.ProjectionLike, + * state: (ol.source.State|undefined), + * wrapX: (boolean|undefined)}} */ -ol.array.reverseSubArray = function(arr, begin, end) { - goog.asserts.assert(begin >= 0, - 'Array begin index should be equal to or greater than 0'); - goog.asserts.assert(end < arr.length, - 'Array end index should be less than the array length'); - while (begin < end) { - var tmp = arr[begin]; - arr[begin] = arr[end]; - arr[end] = tmp; - ++begin; - --end; - } -}; - -goog.provide('ol.ResolutionConstraint'); -goog.provide('ol.ResolutionConstraintType'); - -goog.require('ol.array'); -goog.require('ol.math'); +ol.SourceSourceOptions; /** - * @typedef {function((number|undefined), number, number): (number|undefined)} + * @typedef {{attributions: (ol.AttributionLike|undefined), + * cacheSize: (number|undefined), + * extent: (ol.Extent|undefined), + * logo: (string|olx.LogoOptions|undefined), + * opaque: (boolean|undefined), + * tilePixelRatio: (number|undefined), + * projection: ol.proj.ProjectionLike, + * state: (ol.source.State|undefined), + * tileGrid: (ol.tilegrid.TileGrid|undefined), + * wrapX: (boolean|undefined)}} */ -ol.ResolutionConstraintType; +ol.SourceTileOptions; /** - * @param {Array.<number>} resolutions Resolutions. - * @return {ol.ResolutionConstraintType} Zoom function. + * @typedef {{attributions: (ol.AttributionLike|undefined), + * cacheSize: (number|undefined), + * extent: (ol.Extent|undefined), + * logo: (string|olx.LogoOptions|undefined), + * opaque: (boolean|undefined), + * projection: ol.proj.ProjectionLike, + * state: (ol.source.State|undefined), + * tileGrid: (ol.tilegrid.TileGrid|undefined), + * tileLoadFunction: ol.TileLoadFunctionType, + * tilePixelRatio: (number|undefined), + * tileUrlFunction: (ol.TileUrlFunctionType|undefined), + * url: (string|undefined), + * urls: (Array.<string>|undefined), + * wrapX: (boolean|undefined)}} */ -ol.ResolutionConstraint.createSnapToResolutions = - function(resolutions) { - return ( - /** - * @param {number|undefined} resolution Resolution. - * @param {number} delta Delta. - * @param {number} direction Direction. - * @return {number|undefined} Resolution. - */ - function(resolution, delta, direction) { - if (resolution !== undefined) { - var z = - ol.array.linearFindNearest(resolutions, resolution, direction); - z = ol.math.clamp(z + delta, 0, resolutions.length - 1); - return resolutions[z]; - } else { - return undefined; - } - }); -}; +ol.SourceUrlTileOptions; /** - * @param {number} power Power. - * @param {number} maxResolution Maximum resolution. - * @param {number=} opt_maxLevel Maximum level. - * @return {ol.ResolutionConstraintType} Zoom function. + * An array of three numbers representing the location of a tile in a tile + * grid. The order is `z`, `x`, and `y`. `z` is the zoom level. + * @typedef {Array.<number>} ol.TileCoord + * @api */ -ol.ResolutionConstraint.createSnapToPower = - function(power, maxResolution, opt_maxLevel) { - return ( - /** - * @param {number|undefined} resolution Resolution. - * @param {number} delta Delta. - * @param {number} direction Direction. - * @return {number|undefined} Resolution. - */ - function(resolution, delta, direction) { - if (resolution !== undefined) { - var offset; - if (direction > 0) { - offset = 0; - } else if (direction < 0) { - offset = 1; - } else { - offset = 0.5; - } - var oldLevel = Math.floor( - Math.log(maxResolution / resolution) / Math.log(power) + offset); - var newLevel = Math.max(oldLevel + delta, 0); - if (opt_maxLevel !== undefined) { - newLevel = Math.min(newLevel, opt_maxLevel); - } - return maxResolution / Math.pow(power, newLevel); - } else { - return undefined; - } - }); -}; - -goog.provide('ol.RotationConstraint'); -goog.provide('ol.RotationConstraintType'); - -goog.require('ol.math'); +ol.TileCoord; /** - * @typedef {function((number|undefined), number): (number|undefined)} + * A function that takes an {@link ol.Tile} for the tile and a `{string}` for + * the url as arguments. + * + * @typedef {function(ol.Tile, string)} + * @api */ -ol.RotationConstraintType; +ol.TileLoadFunctionType; /** - * @param {number|undefined} rotation Rotation. - * @param {number} delta Delta. - * @return {number|undefined} Rotation. + * @typedef {function(ol.Tile, string, ol.Coordinate, number): number} */ -ol.RotationConstraint.disable = function(rotation, delta) { - if (rotation !== undefined) { - return 0; - } else { - return undefined; - } -}; +ol.TilePriorityFunction; /** - * @param {number|undefined} rotation Rotation. - * @param {number} delta Delta. - * @return {number|undefined} Rotation. + * @typedef {{ + * dirty: boolean, + * renderedRenderOrder: (null|function(ol.Feature, ol.Feature):number), + * renderedTileRevision: number, + * renderedRevision: number, + * replayGroup: ol.render.IReplayGroup, + * skippedFeatures: Array.<string>}} */ -ol.RotationConstraint.none = function(rotation, delta) { - if (rotation !== undefined) { - return rotation + delta; - } else { - return undefined; - } -}; +ol.TileReplayState; /** - * @param {number} n N. - * @return {ol.RotationConstraintType} Rotation constraint. + * {@link ol.source.Tile} sources use a function of this type to get the url + * that provides a tile for a given tile coordinate. + * + * This function takes an {@link ol.TileCoord} for the tile coordinate, a + * `{number}` representing the pixel ratio and an {@link ol.proj.Projection} for + * the projection as arguments and returns a `{string}` representing the tile + * URL, or undefined if no tile should be requested for the passed tile + * coordinate. + * + * @typedef {function(ol.TileCoord, number, + * ol.proj.Projection): (string|undefined)} + * @api */ -ol.RotationConstraint.createSnapToN = function(n) { - var theta = 2 * Math.PI / n; - return ( - /** - * @param {number|undefined} rotation Rotation. - * @param {number} delta Delta. - * @return {number|undefined} Rotation. - */ - function(rotation, delta) { - if (rotation !== undefined) { - rotation = Math.floor((rotation + delta) / theta + 0.5) * theta; - return rotation; - } else { - return undefined; - } - }); -}; +ol.TileUrlFunctionType; /** - * @param {number=} opt_tolerance Tolerance. - * @return {ol.RotationConstraintType} Rotation constraint. + * A transform function accepts an array of input coordinate values, an optional + * output array, and an optional dimension (default should be 2). The function + * transforms the input coordinate values, populates the output array, and + * returns the output array. + * + * @typedef {function(Array.<number>, Array.<number>=, number=): Array.<number>} + * @api stable */ -ol.RotationConstraint.createSnapToZero = function(opt_tolerance) { - var tolerance = opt_tolerance || ol.math.toRadians(5); - return ( - /** - * @param {number|undefined} rotation Rotation. - * @param {number} delta Delta. - * @return {number|undefined} Rotation. - */ - function(rotation, delta) { - if (rotation !== undefined) { - if (Math.abs(rotation + delta) <= tolerance) { - return 0; - } else { - return rotation + delta; - } - } else { - return undefined; - } - }); -}; - -goog.provide('ol.Constraints'); - -goog.require('ol.CenterConstraintType'); -goog.require('ol.ResolutionConstraintType'); -goog.require('ol.RotationConstraintType'); - +ol.TransformFunction; /** - * @constructor - * @param {ol.CenterConstraintType} centerConstraint Center constraint. - * @param {ol.ResolutionConstraintType} resolutionConstraint - * Resolution constraint. - * @param {ol.RotationConstraintType} rotationConstraint - * Rotation constraint. + * @typedef {{buf: ol.webgl.Buffer, + * buffer: WebGLBuffer}} */ -ol.Constraints = - function(centerConstraint, resolutionConstraint, rotationConstraint) { - - /** - * @type {ol.CenterConstraintType} - */ - this.center = centerConstraint; - - /** - * @type {ol.ResolutionConstraintType} - */ - this.resolution = resolutionConstraint; - - /** - * @type {ol.RotationConstraintType} - */ - this.rotation = rotationConstraint; +ol.WebglBufferCacheEntry; -}; - -// Copyright 2010 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. /** - * @fileoverview A global registry for entry points into a program, - * so that they can be instrumented. Each module should register their - * entry points with this registry. Designed to be compiled out - * if no instrumentation is requested. - * - * Entry points may be registered before or after a call to - * goog.debug.entryPointRegistry.monitorAll. If an entry point is registered - * later, the existing monitor will instrument the new entry point. - * - * @author nicksantos@google.com (Nick Santos) + * @typedef {{magFilter: number, minFilter: number, texture: WebGLTexture}} */ - -goog.provide('goog.debug.EntryPointMonitor'); -goog.provide('goog.debug.entryPointRegistry'); - -goog.require('goog.asserts'); - +ol.WebglTextureCacheEntry; /** - * @interface + * Number of features; bounds/extent. + * @typedef {{numberOfFeatures: number, + * bounds: ol.Extent}} + * @api stable */ -goog.debug.EntryPointMonitor = function() {}; +ol.WFSFeatureCollectionMetadata; /** - * Instruments a function. - * - * @param {!Function} fn A function to instrument. - * @return {!Function} The instrumented function. + * Total deleted; total inserted; total updated; array of insert ids. + * @typedef {{totalDeleted: number, + * totalInserted: number, + * totalUpdated: number, + * insertIds: Array.<string>}} + * @api stable */ -goog.debug.EntryPointMonitor.prototype.wrap; +ol.WFSTransactionResponse; /** - * Try to remove an instrumentation wrapper created by this monitor. - * If the function passed to unwrap is not a wrapper created by this - * monitor, then we will do nothing. - * - * Notice that some wrappers may not be unwrappable. For example, if other - * monitors have applied their own wrappers, then it will be impossible to - * unwrap them because their wrappers will have captured our wrapper. - * - * So it is important that entry points are unwrapped in the reverse - * order that they were wrapped. - * - * @param {!Function} fn A function to unwrap. - * @return {!Function} The unwrapped function, or {@code fn} if it was not - * a wrapped function created by this monitor. + * @typedef {{type: number, value: (number|string|undefined), position: number}} */ -goog.debug.EntryPointMonitor.prototype.unwrap; +ol.WKTToken; /** - * An array of entry point callbacks. - * @type {!Array<function(!Function)>} - * @private + * When using {@link ol.xml.makeChildAppender} or + * {@link ol.xml.makeSimpleNodeFactory}, the top `objectStack` item needs to + * have this structure. + * @typedef {{node:Node}} */ -goog.debug.entryPointRegistry.refList_ = []; +ol.XmlNodeStackItem; /** - * Monitors that should wrap all the entry points. - * @type {!Array<!goog.debug.EntryPointMonitor>} - * @private + * @typedef {function(Node, Array.<*>)} */ -goog.debug.entryPointRegistry.monitors_ = []; +ol.XmlParser; /** - * Whether goog.debug.entryPointRegistry.monitorAll has ever been called. - * Checking this allows the compiler to optimize out the registrations. - * @type {boolean} - * @private + * @typedef {function(Node, *, Array.<*>)} */ -goog.debug.entryPointRegistry.monitorsMayExist_ = false; +ol.XmlSerializer; /** - * Register an entry point with this module. - * - * The entry point will be instrumented when a monitor is passed to - * goog.debug.entryPointRegistry.monitorAll. If this has already occurred, the - * entry point is instrumented immediately. + * A function that takes an {@link ol.MapBrowserEvent} and returns a + * `{boolean}`. If the condition is met, true should be returned. * - * @param {function(!Function)} callback A callback function which is called - * with a transforming function to instrument the entry point. The callback - * is responsible for wrapping the relevant entry point with the - * transforming function. + * @typedef {function(ol.MapBrowserEvent): boolean} + * @api stable */ -goog.debug.entryPointRegistry.register = function(callback) { - // Don't use push(), so that this can be compiled out. - goog.debug.entryPointRegistry.refList_[ - goog.debug.entryPointRegistry.refList_.length] = callback; - // If no one calls monitorAll, this can be compiled out. - if (goog.debug.entryPointRegistry.monitorsMayExist_) { - var monitors = goog.debug.entryPointRegistry.monitors_; - for (var i = 0; i < monitors.length; i++) { - callback(goog.bind(monitors[i].wrap, monitors[i])); - } - } -}; +ol.events.ConditionType; /** - * Configures a monitor to wrap all entry points. - * - * Entry points that have already been registered are immediately wrapped by - * the monitor. When an entry point is registered in the future, it will also - * be wrapped by the monitor when it is registered. - * - * @param {!goog.debug.EntryPointMonitor} monitor An entry point monitor. + * @typedef {EventTarget|ol.events.EventTarget| + * {addEventListener: function(string, Function, boolean=), + * removeEventListener: function(string, Function, boolean=), + * dispatchEvent: function(string)}} */ -goog.debug.entryPointRegistry.monitorAll = function(monitor) { - goog.debug.entryPointRegistry.monitorsMayExist_ = true; - var transformer = goog.bind(monitor.wrap, monitor); - for (var i = 0; i < goog.debug.entryPointRegistry.refList_.length; i++) { - goog.debug.entryPointRegistry.refList_[i](transformer); - } - goog.debug.entryPointRegistry.monitors_.push(monitor); -}; +ol.events.EventTargetLike; /** - * Try to unmonitor all the entry points that have already been registered. If - * an entry point is registered in the future, it will not be wrapped by the - * monitor when it is registered. Note that this may fail if the entry points - * have additional wrapping. + * Key to use with {@link ol.Observable#unByKey}. * - * @param {!goog.debug.EntryPointMonitor} monitor The last monitor to wrap - * the entry points. - * @throws {Error} If the monitor is not the most recently configured monitor. + * @typedef {{bindTo: (Object|undefined), + * boundListener: (ol.events.ListenerFunctionType|undefined), + * callOnce: boolean, + * deleteIndex: (number|undefined), + * listener: ol.events.ListenerFunctionType, + * target: (EventTarget|ol.events.EventTarget), + * type: string}} + * @api */ -goog.debug.entryPointRegistry.unmonitorAllIfPossible = function(monitor) { - var monitors = goog.debug.entryPointRegistry.monitors_; - goog.asserts.assert(monitor == monitors[monitors.length - 1], - 'Only the most recent monitor can be unwrapped.'); - var transformer = goog.bind(monitor.unwrap, monitor); - for (var i = 0; i < goog.debug.entryPointRegistry.refList_.length; i++) { - goog.debug.entryPointRegistry.refList_[i](transformer); - } - monitors.length--; -}; +ol.events.Key; -// Copyright 2013 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. /** - * @fileoverview Utilities used by goog.labs.userAgent tools. These functions - * should not be used outside of goog.labs.userAgent.*. - * + * Listener function. This function is called with an event object as argument. + * When the function returns `false`, event propagation will stop. * - * @author nnaze@google.com (Nathan Naze) + * @typedef {function(ol.events.Event)|function(ol.events.Event): boolean} + * @api */ - -goog.provide('goog.labs.userAgent.util'); - -goog.require('goog.string'); +ol.events.ListenerFunctionType; /** - * Gets the native userAgent string from navigator if it exists. - * If navigator or navigator.userAgent string is missing, returns an empty - * string. - * @return {string} - * @private + * A function that takes a {@link ol.MapBrowserEvent} and two + * {@link ol.Pixel}s and returns a `{boolean}`. If the condition is met, + * true should be returned. + * @typedef {function(ol.MapBrowserEvent, ol.Pixel, ol.Pixel):boolean} + * @api */ -goog.labs.userAgent.util.getNativeUserAgentString_ = function() { - var navigator = goog.labs.userAgent.util.getNavigator_(); - if (navigator) { - var userAgent = navigator.userAgent; - if (userAgent) { - return userAgent; - } - } - return ''; -}; +ol.interaction.DragBoxEndConditionType; /** - * Getter for the native navigator. - * This is a separate function so it can be stubbed out in testing. - * @return {Navigator} - * @private + * Function that takes coordinates and an optional existing geometry as + * arguments, and returns a geometry. The optional existing geometry is the + * geometry that is returned when the function is called without a second + * argument. + * @typedef {function(!(ol.Coordinate|Array.<ol.Coordinate>| + * Array.<Array.<ol.Coordinate>>), ol.geom.SimpleGeometry=): + * ol.geom.SimpleGeometry} + * @api */ -goog.labs.userAgent.util.getNavigator_ = function() { - return goog.global.navigator; -}; +ol.interaction.DrawGeometryFunctionType; /** - * A possible override for applications which wish to not check - * navigator.userAgent but use a specified value for detection instead. - * @private {string} + * @typedef {{depth: (Array.<number>|undefined), + * feature: ol.Feature, + * geometry: ol.geom.SimpleGeometry, + * index: (number|undefined), + * segment: Array.<ol.Extent>}} */ -goog.labs.userAgent.util.userAgent_ = - goog.labs.userAgent.util.getNativeUserAgentString_(); +ol.interaction.SegmentDataType; /** - * Applications may override browser detection on the built in - * navigator.userAgent object by setting this string. Set to null to use the - * browser object instead. - * @param {?string=} opt_userAgent The User-Agent override. + * A function that takes an {@link ol.Feature} or {@link ol.render.Feature} and + * an {@link ol.layer.Layer} and returns `true` if the feature may be selected + * or `false` otherwise. + * @typedef {function((ol.Feature|ol.render.Feature), ol.layer.Layer): + * boolean} + * @api */ -goog.labs.userAgent.util.setUserAgent = function(opt_userAgent) { - goog.labs.userAgent.util.userAgent_ = opt_userAgent || - goog.labs.userAgent.util.getNativeUserAgentString_(); -}; +ol.interaction.SelectFilterFunction; /** - * @return {string} The user agent string. + * @typedef {{ + * snapped: {boolean}, + * vertex: (ol.Coordinate|null), + * vertexPixel: (ol.Pixel|null) + * }} */ -goog.labs.userAgent.util.getUserAgent = function() { - return goog.labs.userAgent.util.userAgent_; -}; +ol.interaction.SnapResultType; /** - * @param {string} str - * @return {boolean} Whether the user agent contains the given string, ignoring - * case. + * @typedef {{ + * feature: ol.Feature, + * segment: Array.<ol.Coordinate> + * }} */ -goog.labs.userAgent.util.matchUserAgent = function(str) { - var userAgent = goog.labs.userAgent.util.getUserAgent(); - return goog.string.contains(userAgent, str); -}; +ol.interaction.SnapSegmentDataType; /** - * @param {string} str - * @return {boolean} Whether the user agent contains the given string. + * A projection as {@link ol.proj.Projection}, SRS identifier string or + * undefined. + * @typedef {ol.proj.Projection|string|undefined} ol.proj.ProjectionLike + * @api stable */ -goog.labs.userAgent.util.matchUserAgentIgnoreCase = function(str) { - var userAgent = goog.labs.userAgent.util.getUserAgent(); - return goog.string.caseInsensitiveContains(userAgent, str); -}; +ol.proj.ProjectionLike; /** - * Parses the user agent into tuples for each section. - * @param {string} userAgent - * @return {!Array<!Array<string>>} Tuples of key, version, and the contents - * of the parenthetical. + * A function that takes an array of input data, performs some operation, and + * returns an array of ouput data. For `'pixel'` type operations, functions + * will be called with an array of {@link ol.raster.Pixel} data and should + * return an array of the same. For `'image'` type operations, functions will + * be called with an array of {@link ImageData + * https://developer.mozilla.org/en-US/docs/Web/API/ImageData} and should return + * an array of the same. The operations are called with a second "data" + * argument, which can be used for storage. The data object is accessible + * from raster events, where it can be initialized in "beforeoperations" and + * accessed again in "afteroperations". + * + * @typedef {function((Array.<ol.raster.Pixel>|Array.<ImageData>), Object): + * (Array.<ol.raster.Pixel>|Array.<ImageData>)} + * @api */ -goog.labs.userAgent.util.extractVersionTuples = function(userAgent) { - // Matches each section of a user agent string. - // Example UA: - // Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us) - // AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405 - // This has three version tuples: Mozilla, AppleWebKit, and Mobile. - - var versionRegExp = new RegExp( - // Key. Note that a key may have a space. - // (i.e. 'Mobile Safari' in 'Mobile Safari/5.0') - '(\\w[\\w ]+)' + - - '/' + // slash - '([^\\s]+)' + // version (i.e. '5.0b') - '\\s*' + // whitespace - '(?:\\((.*?)\\))?', // parenthetical info. parentheses not matched. - 'g'); - - var data = []; - var match; - - // Iterate and collect the version tuples. Each iteration will be the - // next regex match. - while (match = versionRegExp.exec(userAgent)) { - data.push([ - match[1], // key - match[2], // value - // || undefined as this is not undefined in IE7 and IE8 - match[3] || undefined // info - ]); - } - - return data; -}; - +ol.raster.Operation; -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. /** - * @fileoverview Utilities for manipulating objects/maps/hashes. - * @author arv@google.com (Erik Arvidsson) + * An array of numbers representing pixel values. + * @typedef {Array.<number>} ol.raster.Pixel + * @api */ - -goog.provide('goog.object'); +ol.raster.Pixel; /** - * Calls a function for each element in an object/map/hash. - * - * @param {Object<K,V>} obj The object over which to iterate. - * @param {function(this:T,V,?,Object<K,V>):?} f The function to call - * for every element. This function takes 3 arguments (the value, the - * key and the object) and the return value is ignored. - * @param {T=} opt_obj This is used as the 'this' object within f. - * @template T,K,V + * @typedef {{x: number, y: number, width: number, height: number}} */ -goog.object.forEach = function(obj, f, opt_obj) { - for (var key in obj) { - f.call(opt_obj, obj[key], key, obj); - } -}; +ol.style.AtlasBlock; /** - * Calls a function for each element in an object/map/hash. If that call returns - * true, adds the element to a new object. - * - * @param {Object<K,V>} obj The object over which to iterate. - * @param {function(this:T,V,?,Object<K,V>):boolean} f The function to call - * for every element. This - * function takes 3 arguments (the value, the key and the object) - * and should return a boolean. If the return value is true the - * element is added to the result object. If it is false the - * element is not included. - * @param {T=} opt_obj This is used as the 'this' object within f. - * @return {!Object<K,V>} a new object in which only elements that passed the - * test are present. - * @template T,K,V + * Provides information for an image inside an atlas. + * `offsetX` and `offsetY` are the position of the image inside + * the atlas image `image`. + * @typedef {{offsetX: number, offsetY: number, image: HTMLCanvasElement}} */ -goog.object.filter = function(obj, f, opt_obj) { - var res = {}; - for (var key in obj) { - if (f.call(opt_obj, obj[key], key, obj)) { - res[key] = obj[key]; - } - } - return res; -}; +ol.style.AtlasInfo; /** - * For every element in an object/map/hash calls a function and inserts the - * result into a new object. - * - * @param {Object<K,V>} obj The object over which to iterate. - * @param {function(this:T,V,?,Object<K,V>):R} f The function to call - * for every element. This function - * takes 3 arguments (the value, the key and the object) - * and should return something. The result will be inserted - * into a new object. - * @param {T=} opt_obj This is used as the 'this' object within f. - * @return {!Object<K,R>} a new object with the results from f. - * @template T,K,V,R + * Provides information for an image inside an atlas manager. + * `offsetX` and `offsetY` is the position of the image inside + * the atlas image `image` and the position of the hit-detection image + * inside the hit-detection atlas image `hitImage`. + * @typedef {{offsetX: number, offsetY: number, image: HTMLCanvasElement, + * hitImage: HTMLCanvasElement}} */ -goog.object.map = function(obj, f, opt_obj) { - var res = {}; - for (var key in obj) { - res[key] = f.call(opt_obj, obj[key], key, obj); - } - return res; -}; +ol.style.AtlasManagerInfo; /** - * Calls a function for each element in an object/map/hash. If any - * call returns true, returns true (without checking the rest). If - * all calls return false, returns false. - * - * @param {Object<K,V>} obj The object to check. - * @param {function(this:T,V,?,Object<K,V>):boolean} f The function to - * call for every element. This function - * takes 3 arguments (the value, the key and the object) and should - * return a boolean. - * @param {T=} opt_obj This is used as the 'this' object within f. - * @return {boolean} true if any element passes the test. - * @template T,K,V + * @typedef {{strokeStyle: (string|undefined), strokeWidth: number, + * size: number, lineDash: Array.<number>}} */ -goog.object.some = function(obj, f, opt_obj) { - for (var key in obj) { - if (f.call(opt_obj, obj[key], key, obj)) { - return true; - } - } - return false; -}; +ol.style.CircleRenderOptions; /** - * Calls a function for each element in an object/map/hash. If - * all calls return true, returns true. If any call returns false, returns - * false at this point and does not continue to check the remaining elements. - * - * @param {Object<K,V>} obj The object to check. - * @param {?function(this:T,V,?,Object<K,V>):boolean} f The function to - * call for every element. This function - * takes 3 arguments (the value, the key and the object) and should - * return a boolean. - * @param {T=} opt_obj This is used as the 'this' object within f. - * @return {boolean} false if any element fails the test. - * @template T,K,V + * @typedef {{opacity: number, + * rotateWithView: boolean, + * rotation: number, + * scale: number, + * snapToPixel: boolean}} */ -goog.object.every = function(obj, f, opt_obj) { - for (var key in obj) { - if (!f.call(opt_obj, obj[key], key, obj)) { - return false; - } - } - return true; -}; +ol.style.ImageOptions; /** - * Returns the number of key-value pairs in the object map. + * A function that takes an {@link ol.Feature} as argument and returns an + * {@link ol.geom.Geometry} that will be rendered and styled for the feature. * - * @param {Object} obj The object for which to get the number of key-value - * pairs. - * @return {number} The number of key-value pairs in the object map. + * @typedef {function((ol.Feature|ol.render.Feature)): + * (ol.geom.Geometry|ol.render.Feature|undefined)} + * @api */ -goog.object.getCount = function(obj) { - // JS1.5 has __count__ but it has been deprecated so it raises a warning... - // in other words do not use. Also __count__ only includes the fields on the - // actual object and not in the prototype chain. - var rv = 0; - for (var key in obj) { - rv++; - } - return rv; -}; +ol.style.GeometryFunction; /** - * Returns one key from the object map, if any exists. - * For map literals the returned key will be the first one in most of the - * browsers (a know exception is Konqueror). - * - * @param {Object} obj The object to pick a key from. - * @return {string|undefined} The key or undefined if the object is empty. + * @typedef {{ + * strokeStyle: (string|undefined), + * strokeWidth: number, + * size: number, + * lineCap: string, + * lineDash: Array.<number>, + * lineJoin: string, + * miterLimit: number + * }} */ -goog.object.getAnyKey = function(obj) { - for (var key in obj) { - return key; - } -}; +ol.style.RegularShapeRenderOptions; /** - * Returns one value from the object map, if any exists. - * For map literals the returned value will be the first one in most of the - * browsers (a know exception is Konqueror). + * A function that takes an {@link ol.Feature} and a `{number}` representing + * the view's resolution. The function should return a {@link ol.style.Style} + * or an array of them. This way e.g. a vector layer can be styled. * - * @param {Object<K,V>} obj The object to pick a value from. - * @return {V|undefined} The value or undefined if the object is empty. - * @template K,V + * @typedef {function((ol.Feature|ol.render.Feature), number): + * (ol.style.Style|Array.<ol.style.Style>)} + * @api */ -goog.object.getAnyValue = function(obj) { - for (var key in obj) { - return obj[key]; - } -}; +ol.style.StyleFunction; +goog.provide('ol.events'); +goog.provide('ol.events.EventType'); +goog.provide('ol.events.KeyCode'); -/** - * Whether the object/hash/map contains the given object as a value. - * An alias for goog.object.containsValue(obj, val). - * - * @param {Object<K,V>} obj The object in which to look for val. - * @param {V} val The object for which to check. - * @return {boolean} true if val is present. - * @template K,V - */ -goog.object.contains = function(obj, val) { - return goog.object.containsValue(obj, val); -}; +goog.require('ol.object'); +goog.require('ol.events.EventTargetLike'); /** - * Returns the values of the object/map/hash. - * - * @param {Object<K,V>} obj The object from which to get the values. - * @return {!Array<V>} The values in the object/map/hash. - * @template K,V + * @enum {string} + * @const */ -goog.object.getValues = function(obj) { - var res = []; - var i = 0; - for (var key in obj) { - res[i++] = obj[key]; - } - return res; -}; - +ol.events.EventType = { + /** + * Generic change event. + * @event ol.events.Event#change + * @api + */ + CHANGE: 'change', -/** - * Returns the keys of the object/map/hash. - * - * @param {Object} obj The object from which to get the keys. - * @return {!Array<string>} Array of property keys. - */ -goog.object.getKeys = function(obj) { - var res = []; - var i = 0; - for (var key in obj) { - res[i++] = key; - } - return res; + CLICK: 'click', + DBLCLICK: 'dblclick', + DRAGENTER: 'dragenter', + DRAGOVER: 'dragover', + DROP: 'drop', + ERROR: 'error', + KEYDOWN: 'keydown', + KEYPRESS: 'keypress', + LOAD: 'load', + MOUSEDOWN: 'mousedown', + MOUSEMOVE: 'mousemove', + MOUSEOUT: 'mouseout', + MOUSEUP: 'mouseup', + MOUSEWHEEL: 'mousewheel', + MSPOINTERDOWN: 'mspointerdown', + RESIZE: 'resize', + TOUCHSTART: 'touchstart', + TOUCHMOVE: 'touchmove', + TOUCHEND: 'touchend', + WHEEL: 'wheel' }; /** - * Get a value from an object multiple levels deep. This is useful for - * pulling values from deeply nested objects, such as JSON responses. - * Example usage: getValueByKeys(jsonObj, 'foo', 'entries', 3) - * - * @param {!Object} obj An object to get the value from. Can be array-like. - * @param {...(string|number|!Array<number|string>)} var_args A number of keys - * (as strings, or numbers, for array-like objects). Can also be - * specified as a single array of keys. - * @return {*} The resulting value. If, at any point, the value for a key - * is undefined, returns undefined. + * @enum {number} + * @const */ -goog.object.getValueByKeys = function(obj, var_args) { - var isArrayLike = goog.isArrayLike(var_args); - var keys = isArrayLike ? var_args : arguments; - - // Start with the 2nd parameter for the variable parameters syntax. - for (var i = isArrayLike ? 0 : 1; i < keys.length; i++) { - obj = obj[keys[i]]; - if (!goog.isDef(obj)) { - break; - } - } - - return obj; +ol.events.KeyCode = { + LEFT: 37, + UP: 38, + RIGHT: 39, + DOWN: 40 }; /** - * Whether the object/map/hash contains the given key. - * - * @param {Object} obj The object in which to look for key. - * @param {*} key The key for which to check. - * @return {boolean} true If the map contains the key. + * Property name on an event target for the listener map associated with the + * event target. + * @const {string} + * @private */ -goog.object.containsKey = function(obj, key) { - return key in obj; -}; +ol.events.LISTENER_MAP_PROP_ = 'olm_' + ((Math.random() * 1e4) | 0); /** - * Whether the object/map/hash contains the given value. This is O(n). - * - * @param {Object<K,V>} obj The object in which to look for val. - * @param {V} val The value for which to check. - * @return {boolean} true If the map contains the value. - * @template K,V + * @param {ol.events.Key} listenerObj Listener object. + * @return {ol.events.ListenerFunctionType} Bound listener. */ -goog.object.containsValue = function(obj, val) { - for (var key in obj) { - if (obj[key] == val) { - return true; +ol.events.bindListener_ = function(listenerObj) { + var boundListener = function(evt) { + var listener = listenerObj.listener; + var bindTo = listenerObj.bindTo || listenerObj.target; + if (listenerObj.callOnce) { + ol.events.unlistenByKey(listenerObj); } + return listener.call(bindTo, evt); } - return false; + listenerObj.boundListener = boundListener; + return boundListener; }; /** - * Searches an object for an element that satisfies the given condition and - * returns its key. - * @param {Object<K,V>} obj The object to search in. - * @param {function(this:T,V,string,Object<K,V>):boolean} f The - * function to call for every element. Takes 3 arguments (the value, - * the key and the object) and should return a boolean. - * @param {T=} opt_this An optional "this" context for the function. - * @return {string|undefined} The key of an element for which the function - * returns true or undefined if no such element is found. - * @template T,K,V + * Finds the matching {@link ol.events.Key} in the given listener + * array. + * + * @param {!Array<!ol.events.Key>} listeners Array of listeners. + * @param {!Function} listener The listener function. + * @param {Object=} opt_this The `this` value inside the listener. + * @param {boolean=} opt_setDeleteIndex Set the deleteIndex on the matching + * listener, for {@link ol.events.unlistenByKey}. + * @return {ol.events.Key|undefined} The matching listener object. + * @private */ -goog.object.findKey = function(obj, f, opt_this) { - for (var key in obj) { - if (f.call(opt_this, obj[key], key, obj)) { - return key; +ol.events.findListener_ = function(listeners, listener, opt_this, + opt_setDeleteIndex) { + var listenerObj; + for (var i = 0, ii = listeners.length; i < ii; ++i) { + listenerObj = listeners[i]; + if (listenerObj.listener === listener && + listenerObj.bindTo === opt_this) { + if (opt_setDeleteIndex) { + listenerObj.deleteIndex = i; + } + return listenerObj; } } return undefined; @@ -7713,6402 +6165,3835 @@ goog.object.findKey = function(obj, f, opt_this) { /** - * Searches an object for an element that satisfies the given condition and - * returns its value. - * @param {Object<K,V>} obj The object to search in. - * @param {function(this:T,V,string,Object<K,V>):boolean} f The function - * to call for every element. Takes 3 arguments (the value, the key - * and the object) and should return a boolean. - * @param {T=} opt_this An optional "this" context for the function. - * @return {V} The value of an element for which the function returns true or - * undefined if no such element is found. - * @template T,K,V - */ -goog.object.findValue = function(obj, f, opt_this) { - var key = goog.object.findKey(obj, f, opt_this); - return key && obj[key]; -}; - - -/** - * Whether the object/map/hash is empty. - * - * @param {Object} obj The object to test. - * @return {boolean} true if obj is empty. + * @param {ol.events.EventTargetLike} target Target. + * @param {string} type Type. + * @return {Array.<ol.events.Key>|undefined} Listeners. */ -goog.object.isEmpty = function(obj) { - for (var key in obj) { - return false; - } - return true; +ol.events.getListeners = function(target, type) { + var listenerMap = target[ol.events.LISTENER_MAP_PROP_]; + return listenerMap ? listenerMap[type] : undefined; }; /** - * Removes all key value pairs from the object/map/hash. - * - * @param {Object} obj The object to clear. + * Get the lookup of listeners. If one does not exist on the target, it is + * created. + * @param {ol.events.EventTargetLike} target Target. + * @return {!Object.<string, Array.<ol.events.Key>>} Map of + * listeners by event type. + * @private */ -goog.object.clear = function(obj) { - for (var i in obj) { - delete obj[i]; +ol.events.getListenerMap_ = function(target) { + var listenerMap = target[ol.events.LISTENER_MAP_PROP_]; + if (!listenerMap) { + listenerMap = target[ol.events.LISTENER_MAP_PROP_] = {}; } + return listenerMap; }; /** - * Removes a key-value pair based on the key. - * - * @param {Object} obj The object from which to remove the key. - * @param {*} key The key to remove. - * @return {boolean} Whether an element was removed. + * Clean up all listener objects of the given type. All properties on the + * listener objects will be removed, and if no listeners remain in the listener + * map, it will be removed from the target. + * @param {ol.events.EventTargetLike} target Target. + * @param {string} type Type. + * @private */ -goog.object.remove = function(obj, key) { - var rv; - if ((rv = key in obj)) { - delete obj[key]; +ol.events.removeListeners_ = function(target, type) { + var listeners = ol.events.getListeners(target, type); + if (listeners) { + for (var i = 0, ii = listeners.length; i < ii; ++i) { + target.removeEventListener(type, listeners[i].boundListener); + ol.object.clear(listeners[i]) + } + listeners.length = 0; + var listenerMap = target[ol.events.LISTENER_MAP_PROP_]; + if (listenerMap) { + delete listenerMap[type]; + if (Object.keys(listenerMap).length === 0) { + delete target[ol.events.LISTENER_MAP_PROP_]; + } + } } - return rv; }; /** - * Adds a key-value pair to the object. Throws an exception if the key is - * already in use. Use set if you want to change an existing pair. + * Registers an event listener on an event target. Inspired by + * {@link https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html} * - * @param {Object<K,V>} obj The object to which to add the key-value pair. - * @param {string} key The key to add. - * @param {V} val The value to add. - * @template K,V - */ -goog.object.add = function(obj, key, val) { - if (key in obj) { - throw Error('The object already contains the key "' + key + '"'); - } - goog.object.set(obj, key, val); -}; - - -/** - * Returns the value for the given key. + * This function efficiently binds a `listener` to a `this` object, and returns + * a key for use with {@link ol.events.unlistenByKey}. * - * @param {Object<K,V>} obj The object from which to get the value. - * @param {string} key The key for which to get the value. - * @param {R=} opt_val The value to return if no item is found for the given - * key (default is undefined). - * @return {V|R|undefined} The value for the given key. - * @template K,V,R - */ -goog.object.get = function(obj, key, opt_val) { - if (key in obj) { - return obj[key]; + * @param {ol.events.EventTargetLike} target Event target. + * @param {string} type Event type. + * @param {ol.events.ListenerFunctionType} listener Listener. + * @param {Object=} opt_this Object referenced by the `this` keyword in the + * listener. Default is the `target`. + * @param {boolean=} opt_once If true, add the listener as one-off listener. + * @return {ol.events.Key} Unique key for the listener. + */ +ol.events.listen = function(target, type, listener, opt_this, opt_once) { + var listenerMap = ol.events.getListenerMap_(target); + var listeners = listenerMap[type]; + if (!listeners) { + listeners = listenerMap[type] = []; + } + var listenerObj = ol.events.findListener_(listeners, listener, opt_this, + false); + if (listenerObj) { + if (!opt_once) { + // Turn one-off listener into a permanent one. + listenerObj.callOnce = false; + } + } else { + listenerObj = /** @type {ol.events.Key} */ ({ + bindTo: opt_this, + callOnce: !!opt_once, + listener: listener, + target: target, + type: type + }); + target.addEventListener(type, ol.events.bindListener_(listenerObj)); + listeners.push(listenerObj); } - return opt_val; -}; - -/** - * Adds a key-value pair to the object/map/hash. - * - * @param {Object<K,V>} obj The object to which to add the key-value pair. - * @param {string} key The key to add. - * @param {V} value The value to add. - * @template K,V - */ -goog.object.set = function(obj, key, value) { - obj[key] = value; + return listenerObj; }; /** - * Adds a key-value pair to the object/map/hash if it doesn't exist yet. + * Registers a one-off event listener on an event target. Inspired by + * {@link https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html} * - * @param {Object<K,V>} obj The object to which to add the key-value pair. - * @param {string} key The key to add. - * @param {V} value The value to add if the key wasn't present. - * @return {V} The value of the entry at the end of the function. - * @template K,V - */ -goog.object.setIfUndefined = function(obj, key, value) { - return key in obj ? obj[key] : (obj[key] = value); -}; - - -/** - * Sets a key and value to an object if the key is not set. The value will be - * the return value of the given function. If the key already exists, the - * object will not be changed and the function will not be called (the function - * will be lazily evaluated -- only called if necessary). + * This function efficiently binds a `listener` as self-unregistering listener + * to a `this` object, and returns a key for use with + * {@link ol.events.unlistenByKey} in case the listener needs to be unregistered + * before it is called. * - * This function is particularly useful for use with a map used a as a cache. + * When {@link ol.events.listen} is called with the same arguments after this + * function, the self-unregistering listener will be turned into a permanent + * listener. * - * @param {!Object<K,V>} obj The object to which to add the key-value pair. - * @param {string} key The key to add. - * @param {function():V} f The value to add if the key wasn't present. - * @return {V} The value of the entry at the end of the function. - * @template K,V + * @param {ol.events.EventTargetLike} target Event target. + * @param {string} type Event type. + * @param {ol.events.ListenerFunctionType} listener Listener. + * @param {Object=} opt_this Object referenced by the `this` keyword in the + * listener. Default is the `target`. + * @return {ol.events.Key} Key for unlistenByKey. */ -goog.object.setWithReturnValueIfNotSet = function(obj, key, f) { - if (key in obj) { - return obj[key]; - } - - var val = f(); - obj[key] = val; - return val; +ol.events.listenOnce = function(target, type, listener, opt_this) { + return ol.events.listen(target, type, listener, opt_this, true); }; /** - * Compares two objects for equality using === on the values. + * Unregisters an event listener on an event target. Inspired by + * {@link https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html} * - * @param {!Object<K,V>} a - * @param {!Object<K,V>} b - * @return {boolean} - * @template K,V - */ -goog.object.equals = function(a, b) { - for (var k in a) { - if (!(k in b) || a[k] !== b[k]) { - return false; - } - } - for (var k in b) { - if (!(k in a)) { - return false; - } - } - return true; -}; - - -/** - * Does a flat clone of the object. + * To return a listener, this function needs to be called with the exact same + * arguments that were used for a previous {@link ol.events.listen} call. * - * @param {Object<K,V>} obj Object to clone. - * @return {!Object<K,V>} Clone of the input object. - * @template K,V - */ -goog.object.clone = function(obj) { - // We cannot use the prototype trick because a lot of methods depend on where - // the actual key is set. - - var res = {}; - for (var key in obj) { - res[key] = obj[key]; + * @param {ol.events.EventTargetLike} target Event target. + * @param {string} type Event type. + * @param {ol.events.ListenerFunctionType} listener Listener. + * @param {Object=} opt_this Object referenced by the `this` keyword in the + * listener. Default is the `target`. + */ +ol.events.unlisten = function(target, type, listener, opt_this) { + var listeners = ol.events.getListeners(target, type); + if (listeners) { + var listenerObj = ol.events.findListener_(listeners, listener, opt_this, + true); + if (listenerObj) { + ol.events.unlistenByKey(listenerObj); + } } - return res; - // We could also use goog.mixin but I wanted this to be independent from that. }; /** - * Clones a value. The input may be an Object, Array, or basic type. Objects and - * arrays will be cloned recursively. + * Unregisters event listeners on an event target. Inspired by + * {@link https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html} * - * WARNINGS: - * <code>goog.object.unsafeClone</code> does not detect reference loops. Objects - * that refer to themselves will cause infinite recursion. + * The argument passed to this function is the key returned from + * {@link ol.events.listen} or {@link ol.events.listenOnce}. * - * <code>goog.object.unsafeClone</code> is unaware of unique identifiers, and - * copies UIDs created by <code>getUid</code> into cloned results. - * - * @param {*} obj The value to clone. - * @return {*} A clone of the input value. + * @param {ol.events.Key} key The key. */ -goog.object.unsafeClone = function(obj) { - var type = goog.typeOf(obj); - if (type == 'object' || type == 'array') { - if (goog.isFunction(obj.clone)) { - return obj.clone(); - } - var clone = type == 'array' ? [] : {}; - for (var key in obj) { - clone[key] = goog.object.unsafeClone(obj[key]); +ol.events.unlistenByKey = function(key) { + if (key && key.target) { + key.target.removeEventListener(key.type, key.boundListener); + var listeners = ol.events.getListeners(key.target, key.type); + if (listeners) { + var i = 'deleteIndex' in key ? key.deleteIndex : listeners.indexOf(key); + if (i !== -1) { + listeners.splice(i, 1); + } + if (listeners.length === 0) { + ol.events.removeListeners_(key.target, key.type); + } } - return clone; + ol.object.clear(key); } - - return obj; }; /** - * Returns a new object in which all the keys and values are interchanged - * (keys become values and values become keys). If multiple keys map to the - * same value, the chosen transposed value is implementation-dependent. + * Unregisters all event listeners on an event target. Inspired by + * {@link https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html} * - * @param {Object} obj The object to transpose. - * @return {!Object} The transposed object. + * @param {ol.events.EventTargetLike} target Target. */ -goog.object.transpose = function(obj) { - var transposed = {}; - for (var key in obj) { - transposed[obj[key]] = key; +ol.events.unlistenAll = function(target) { + var listenerMap = ol.events.getListenerMap_(target); + for (var type in listenerMap) { + ol.events.removeListeners_(target, type); } - return transposed; }; +goog.provide('ol.Disposable'); -/** - * The names of the fields that are defined on Object.prototype. - * @type {Array<string>} - * @private - */ -goog.object.PROTOTYPE_FIELDS_ = [ - 'constructor', - 'hasOwnProperty', - 'isPrototypeOf', - 'propertyIsEnumerable', - 'toLocaleString', - 'toString', - 'valueOf' -]; - +goog.require('ol'); /** - * Extends an object with another object. - * This operates 'in-place'; it does not create a new Object. - * - * Example: - * var o = {}; - * goog.object.extend(o, {a: 0, b: 1}); - * o; // {a: 0, b: 1} - * goog.object.extend(o, {b: 2, c: 3}); - * o; // {a: 0, b: 2, c: 3} - * - * @param {Object} target The object to modify. Existing properties will be - * overwritten if they are also present in one of the objects in - * {@code var_args}. - * @param {...Object} var_args The objects from which values will be copied. + * Objects that need to clean up after themselves. + * @constructor */ -goog.object.extend = function(target, var_args) { - var key, source; - for (var i = 1; i < arguments.length; i++) { - source = arguments[i]; - for (key in source) { - target[key] = source[key]; - } - - // For IE the for-in-loop does not contain any properties that are not - // enumerable on the prototype object (for example isPrototypeOf from - // Object.prototype) and it will also not include 'replace' on objects that - // extend String and change 'replace' (not that it is common for anyone to - // extend anything except Object). - - for (var j = 0; j < goog.object.PROTOTYPE_FIELDS_.length; j++) { - key = goog.object.PROTOTYPE_FIELDS_[j]; - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } -}; - +ol.Disposable = function() {}; /** - * Creates a new object built from the key-value pairs provided as arguments. - * @param {...*} var_args If only one argument is provided and it is an array - * then this is used as the arguments, otherwise even arguments are used as - * the property names and odd arguments are used as the property values. - * @return {!Object} The new object. - * @throws {Error} If there are uneven number of arguments or there is only one - * non array argument. + * The object has already been disposed. + * @type {boolean} + * @private */ -goog.object.create = function(var_args) { - var argLength = arguments.length; - if (argLength == 1 && goog.isArray(arguments[0])) { - return goog.object.create.apply(null, arguments[0]); - } - - if (argLength % 2) { - throw Error('Uneven number of arguments'); - } - - var rv = {}; - for (var i = 0; i < argLength; i += 2) { - rv[arguments[i]] = arguments[i + 1]; - } - return rv; -}; - +ol.Disposable.prototype.disposed_ = false; /** - * Creates a new object where the property names come from the arguments but - * the value is always set to true - * @param {...*} var_args If only one argument is provided and it is an array - * then this is used as the arguments, otherwise the arguments are used - * as the property names. - * @return {!Object} The new object. + * Clean up. */ -goog.object.createSet = function(var_args) { - var argLength = arguments.length; - if (argLength == 1 && goog.isArray(arguments[0])) { - return goog.object.createSet.apply(null, arguments[0]); - } - - var rv = {}; - for (var i = 0; i < argLength; i++) { - rv[arguments[i]] = true; +ol.Disposable.prototype.dispose = function() { + if (!this.disposed_) { + this.disposed_ = true; + this.disposeInternal(); } - return rv; }; - /** - * Creates an immutable view of the underlying object, if the browser - * supports immutable objects. - * - * In default mode, writes to this view will fail silently. In strict mode, - * they will throw an error. - * - * @param {!Object<K,V>} obj An object. - * @return {!Object<K,V>} An immutable view of that object, or the - * original object if this browser does not support immutables. - * @template K,V + * Extension point for disposable objects. + * @protected */ -goog.object.createImmutableView = function(obj) { - var result = obj; - if (Object.isFrozen && !Object.isFrozen(obj)) { - result = Object.create(obj); - Object.freeze(result); - } - return result; -}; +ol.Disposable.prototype.disposeInternal = ol.nullFunction; +goog.provide('ol.events.Event'); -/** - * @param {!Object} obj An object. - * @return {boolean} Whether this is an immutable view of the object. - */ -goog.object.isImmutableView = function(obj) { - return !!Object.isFrozen && Object.isFrozen(obj); -}; - -// Copyright 2013 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. /** - * @fileoverview Closure user agent detection (Browser). - * @see <a href="http://www.useragentstring.com/">User agent strings</a> - * For more information on rendering engine, platform, or device see the other - * sub-namespaces in goog.labs.userAgent, goog.labs.userAgent.platform, - * goog.labs.userAgent.device respectively.) + * @classdesc + * Stripped down implementation of the W3C DOM Level 2 Event interface. + * @see {@link https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-interface} * - * @author martone@google.com (Andy Martone) - */ - -goog.provide('goog.labs.userAgent.browser'); - -goog.require('goog.array'); -goog.require('goog.labs.userAgent.util'); -goog.require('goog.object'); -goog.require('goog.string'); - - -// TODO(nnaze): Refactor to remove excessive exclusion logic in matching -// functions. - - -/** - * @return {boolean} Whether the user's browser is Opera. - * @private - */ -goog.labs.userAgent.browser.matchOpera_ = function() { - return goog.labs.userAgent.util.matchUserAgent('Opera') || - goog.labs.userAgent.util.matchUserAgent('OPR'); -}; - - -/** - * @return {boolean} Whether the user's browser is IE. - * @private - */ -goog.labs.userAgent.browser.matchIE_ = function() { - return goog.labs.userAgent.util.matchUserAgent('Trident') || - goog.labs.userAgent.util.matchUserAgent('MSIE'); -}; - - -/** - * @return {boolean} Whether the user's browser is Edge. - * @private + * This implementation only provides `type` and `target` properties, and + * `stopPropagation` and `preventDefault` methods. It is meant as base class + * for higher level events defined in the library, and works with + * {@link ol.events.EventTarget}. + * + * @constructor + * @implements {oli.events.Event} + * @param {string} type Type. + * @param {Object=} opt_target Target. */ -goog.labs.userAgent.browser.matchEdge_ = function() { - return goog.labs.userAgent.util.matchUserAgent('Edge'); -}; +ol.events.Event = function(type, opt_target) { + /** + * @type {boolean} + */ + this.propagationStopped; -/** - * @return {boolean} Whether the user's browser is Firefox. - * @private - */ -goog.labs.userAgent.browser.matchFirefox_ = function() { - return goog.labs.userAgent.util.matchUserAgent('Firefox'); -}; + /** + * The event type. + * @type {string} + * @api stable + */ + this.type = type; + /** + * The event target. + * @type {Object} + * @api stable + */ + this.target = opt_target || null; -/** - * @return {boolean} Whether the user's browser is Safari. - * @private - */ -goog.labs.userAgent.browser.matchSafari_ = function() { - return goog.labs.userAgent.util.matchUserAgent('Safari') && - !(goog.labs.userAgent.browser.matchChrome_() || - goog.labs.userAgent.browser.matchCoast_() || - goog.labs.userAgent.browser.matchOpera_() || - goog.labs.userAgent.browser.matchEdge_() || - goog.labs.userAgent.browser.isSilk() || - goog.labs.userAgent.util.matchUserAgent('Android')); }; /** - * @return {boolean} Whether the user's browser is Coast (Opera's Webkit-based - * iOS browser). - * @private + * Stop event propagation. + * @function + * @api stable */ -goog.labs.userAgent.browser.matchCoast_ = function() { - return goog.labs.userAgent.util.matchUserAgent('Coast'); -}; - +ol.events.Event.prototype.preventDefault = /** - * @return {boolean} Whether the user's browser is iOS Webview. - * @private + * Stop event propagation. + * @function + * @api stable */ -goog.labs.userAgent.browser.matchIosWebview_ = function() { - // iOS Webview does not show up as Chrome or Safari. Also check for Opera's - // WebKit-based iOS browser, Coast. - return (goog.labs.userAgent.util.matchUserAgent('iPad') || - goog.labs.userAgent.util.matchUserAgent('iPhone')) && - !goog.labs.userAgent.browser.matchSafari_() && - !goog.labs.userAgent.browser.matchChrome_() && - !goog.labs.userAgent.browser.matchCoast_() && - goog.labs.userAgent.util.matchUserAgent('AppleWebKit'); +ol.events.Event.prototype.stopPropagation = function() { + this.propagationStopped = true; }; /** - * @return {boolean} Whether the user's browser is Chrome. - * @private + * @param {Event|ol.events.Event} evt Event */ -goog.labs.userAgent.browser.matchChrome_ = function() { - return (goog.labs.userAgent.util.matchUserAgent('Chrome') || - goog.labs.userAgent.util.matchUserAgent('CriOS')) && - !goog.labs.userAgent.browser.matchOpera_() && - !goog.labs.userAgent.browser.matchEdge_(); +ol.events.Event.stopPropagation = function(evt) { + evt.stopPropagation(); }; /** - * @return {boolean} Whether the user's browser is the Android browser. - * @private + * @param {Event|ol.events.Event} evt Event */ -goog.labs.userAgent.browser.matchAndroidBrowser_ = function() { - // Android can appear in the user agent string for Chrome on Android. - // This is not the Android standalone browser if it does. - return goog.labs.userAgent.util.matchUserAgent('Android') && - !(goog.labs.userAgent.browser.isChrome() || - goog.labs.userAgent.browser.isFirefox() || - goog.labs.userAgent.browser.isOpera() || - goog.labs.userAgent.browser.isSilk()); +ol.events.Event.preventDefault = function(evt) { + evt.preventDefault(); }; +goog.provide('ol.events.EventTarget'); -/** - * @return {boolean} Whether the user's browser is Opera. - */ -goog.labs.userAgent.browser.isOpera = goog.labs.userAgent.browser.matchOpera_; - - -/** - * @return {boolean} Whether the user's browser is IE. - */ -goog.labs.userAgent.browser.isIE = goog.labs.userAgent.browser.matchIE_; - - -/** - * @return {boolean} Whether the user's browser is Edge. - */ -goog.labs.userAgent.browser.isEdge = goog.labs.userAgent.browser.matchEdge_; - - -/** - * @return {boolean} Whether the user's browser is Firefox. - */ -goog.labs.userAgent.browser.isFirefox = - goog.labs.userAgent.browser.matchFirefox_; - - -/** - * @return {boolean} Whether the user's browser is Safari. - */ -goog.labs.userAgent.browser.isSafari = - goog.labs.userAgent.browser.matchSafari_; - - -/** - * @return {boolean} Whether the user's browser is Coast (Opera's Webkit-based - * iOS browser). - */ -goog.labs.userAgent.browser.isCoast = - goog.labs.userAgent.browser.matchCoast_; - +goog.require('goog.asserts'); +goog.require('ol.Disposable'); +goog.require('ol.events'); +goog.require('ol.events.Event'); /** - * @return {boolean} Whether the user's browser is iOS Webview. + * @classdesc + * A simplified implementation of the W3C DOM Level 2 EventTarget interface. + * @see {@link https://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-EventTarget} + * + * There are two important simplifications compared to the specification: + * + * 1. The handling of `useCapture` in `addEventListener` and + * `removeEventListener`. There is no real capture model. + * 2. The handling of `stopPropagation` and `preventDefault` on `dispatchEvent`. + * There is no event target hierarchy. When a listener calls + * `stopPropagation` or `preventDefault` on an event object, it means that no + * more listeners after this one will be called. Same as when the listener + * returns false. + * + * @constructor + * @extends {ol.Disposable} */ -goog.labs.userAgent.browser.isIosWebview = - goog.labs.userAgent.browser.matchIosWebview_; +ol.events.EventTarget = function() { + goog.base(this); -/** - * @return {boolean} Whether the user's browser is Chrome. - */ -goog.labs.userAgent.browser.isChrome = - goog.labs.userAgent.browser.matchChrome_; - + /** + * @private + * @type {!Object.<string, number>} + */ + this.pendingRemovals_ = {}; -/** - * @return {boolean} Whether the user's browser is the Android browser. - */ -goog.labs.userAgent.browser.isAndroidBrowser = - goog.labs.userAgent.browser.matchAndroidBrowser_; + /** + * @private + * @type {!Object.<string, number>} + */ + this.dispatching_ = {}; + /** + * @private + * @type {!Object.<string, Array.<ol.events.ListenerFunctionType>>} + */ + this.listeners_ = {}; -/** - * For more information, see: - * http://docs.aws.amazon.com/silk/latest/developerguide/user-agent.html - * @return {boolean} Whether the user's browser is Silk. - */ -goog.labs.userAgent.browser.isSilk = function() { - return goog.labs.userAgent.util.matchUserAgent('Silk'); }; +goog.inherits(ol.events.EventTarget, ol.Disposable); /** - * @return {string} The browser version or empty string if version cannot be - * determined. Note that for Internet Explorer, this returns the version of - * the browser, not the version of the rendering engine. (IE 8 in - * compatibility mode will return 8.0 rather than 7.0. To determine the - * rendering engine version, look at document.documentMode instead. See - * http://msdn.microsoft.com/en-us/library/cc196988(v=vs.85).aspx for more - * details.) + * @param {string} type Type. + * @param {ol.events.ListenerFunctionType} listener Listener. */ -goog.labs.userAgent.browser.getVersion = function() { - var userAgentString = goog.labs.userAgent.util.getUserAgent(); - // Special case IE since IE's version is inside the parenthesis and - // without the '/'. - if (goog.labs.userAgent.browser.isIE()) { - return goog.labs.userAgent.browser.getIEVersion_(userAgentString); - } - - var versionTuples = goog.labs.userAgent.util.extractVersionTuples( - userAgentString); - - // Construct a map for easy lookup. - var versionMap = {}; - goog.array.forEach(versionTuples, function(tuple) { - // Note that the tuple is of length three, but we only care about the - // first two. - var key = tuple[0]; - var value = tuple[1]; - versionMap[key] = value; - }); - - var versionMapHasKey = goog.partial(goog.object.containsKey, versionMap); - - // Gives the value with the first key it finds, otherwise empty string. - function lookUpValueWithKeys(keys) { - var key = goog.array.find(keys, versionMapHasKey); - return versionMap[key] || ''; - } - - // Check Opera before Chrome since Opera 15+ has "Chrome" in the string. - // See - // http://my.opera.com/ODIN/blog/2013/07/15/opera-user-agent-strings-opera-15-and-beyond - if (goog.labs.userAgent.browser.isOpera()) { - // Opera 10 has Version/10.0 but Opera/9.8, so look for "Version" first. - // Opera uses 'OPR' for more recent UAs. - return lookUpValueWithKeys(['Version', 'Opera', 'OPR']); +ol.events.EventTarget.prototype.addEventListener = function(type, listener) { + var listeners = this.listeners_[type]; + if (!listeners) { + listeners = this.listeners_[type] = []; } - - // Check Edge before Chrome since it has Chrome in the string. - if (goog.labs.userAgent.browser.isEdge()) { - return lookUpValueWithKeys(['Edge']); - } - - if (goog.labs.userAgent.browser.isChrome()) { - return lookUpValueWithKeys(['Chrome', 'CriOS']); + if (listeners.indexOf(listener) === -1) { + listeners.push(listener); } - - // Usually products browser versions are in the third tuple after "Mozilla" - // and the engine. - var tuple = versionTuples[2]; - return tuple && tuple[1] || ''; }; /** - * @param {string|number} version The version to check. - * @return {boolean} Whether the browser version is higher or the same as the - * given version. - */ -goog.labs.userAgent.browser.isVersionOrHigher = function(version) { - return goog.string.compareVersions(goog.labs.userAgent.browser.getVersion(), - version) >= 0; -}; - - -/** - * Determines IE version. More information: - * http://msdn.microsoft.com/en-us/library/ie/bg182625(v=vs.85).aspx#uaString - * http://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx - * http://blogs.msdn.com/b/ie/archive/2010/03/23/introducing-ie9-s-user-agent-string.aspx - * http://blogs.msdn.com/b/ie/archive/2009/01/09/the-internet-explorer-8-user-agent-string-updated-edition.aspx - * - * @param {string} userAgent the User-Agent. - * @return {string} - * @private + * @param {{type: string, + * target: (EventTarget|ol.events.EventTarget|undefined)}|ol.events.Event| + * string} event Event or event type. + * @return {boolean|undefined} `false` if anyone called preventDefault on the + * event object or if any of the listeners returned false. */ -goog.labs.userAgent.browser.getIEVersion_ = function(userAgent) { - // IE11 may identify itself as MSIE 9.0 or MSIE 10.0 due to an IE 11 upgrade - // bug. Example UA: - // Mozilla/5.0 (MSIE 9.0; Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) - // like Gecko. - // See http://www.whatismybrowser.com/developers/unknown-user-agent-fragments. - var rv = /rv: *([\d\.]*)/.exec(userAgent); - if (rv && rv[1]) { - return rv[1]; - } - - var version = ''; - var msie = /MSIE +([\d\.]+)/.exec(userAgent); - if (msie && msie[1]) { - // IE in compatibility mode usually identifies itself as MSIE 7.0; in this - // case, use the Trident version to determine the version of IE. For more - // details, see the links above. - var tridentVersion = /Trident\/(\d.\d)/.exec(userAgent); - if (msie[1] == '7.0') { - if (tridentVersion && tridentVersion[1]) { - switch (tridentVersion[1]) { - case '4.0': - version = '8.0'; - break; - case '5.0': - version = '9.0'; - break; - case '6.0': - version = '10.0'; - break; - case '7.0': - version = '11.0'; - break; - } - } else { - version = '7.0'; +ol.events.EventTarget.prototype.dispatchEvent = function(event) { + var evt = typeof event === 'string' ? new ol.events.Event(event) : event; + var type = evt.type; + evt.target = this; + var listeners = this.listeners_[type]; + var propagate; + if (listeners) { + if (!(type in this.dispatching_)) { + this.dispatching_[type] = 0; + this.pendingRemovals_[type] = 0; + } + ++this.dispatching_[type]; + for (var i = 0, ii = listeners.length; i < ii; ++i) { + if (listeners[i].call(this, evt) === false || evt.propagationStopped) { + propagate = false; + break; } - } else { - version = msie[1]; } + --this.dispatching_[type]; + if (this.dispatching_[type] === 0) { + var pendingRemovals = this.pendingRemovals_[type]; + delete this.pendingRemovals_[type]; + while (pendingRemovals--) { + this.removeEventListener(type, ol.nullFunction); + } + delete this.dispatching_[type]; + } + return propagate; } - return version; }; -// Copyright 2013 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. /** - * @fileoverview Closure user agent detection. - * @see http://en.wikipedia.org/wiki/User_agent - * For more information on browser brand, platform, or device see the other - * sub-namespaces in goog.labs.userAgent (browser, platform, and device). - * - */ - -goog.provide('goog.labs.userAgent.engine'); - -goog.require('goog.array'); -goog.require('goog.labs.userAgent.util'); -goog.require('goog.string'); - - -/** - * @return {boolean} Whether the rendering engine is Presto. - */ -goog.labs.userAgent.engine.isPresto = function() { - return goog.labs.userAgent.util.matchUserAgent('Presto'); -}; - - -/** - * @return {boolean} Whether the rendering engine is Trident. - */ -goog.labs.userAgent.engine.isTrident = function() { - // IE only started including the Trident token in IE8. - return goog.labs.userAgent.util.matchUserAgent('Trident') || - goog.labs.userAgent.util.matchUserAgent('MSIE'); -}; - - -/** - * @return {boolean} Whether the rendering engine is Edge. + * @inheritDoc */ -goog.labs.userAgent.engine.isEdge = function() { - return goog.labs.userAgent.util.matchUserAgent('Edge'); +ol.events.EventTarget.prototype.disposeInternal = function() { + ol.events.unlistenAll(this); }; /** - * @return {boolean} Whether the rendering engine is WebKit. + * Get the listeners for a specified event type. Listeners are returned in the + * order that they will be called in. + * + * @param {string} type Type. + * @return {Array.<ol.events.ListenerFunctionType>} Listeners. */ -goog.labs.userAgent.engine.isWebKit = function() { - return goog.labs.userAgent.util.matchUserAgentIgnoreCase('WebKit') && - !goog.labs.userAgent.engine.isEdge(); +ol.events.EventTarget.prototype.getListeners = function(type) { + return this.listeners_[type]; }; /** - * @return {boolean} Whether the rendering engine is Gecko. + * @param {string=} opt_type Type. If not provided, + * `true` will be returned if this EventTarget has any listeners. + * @return {boolean} Has listeners. */ -goog.labs.userAgent.engine.isGecko = function() { - return goog.labs.userAgent.util.matchUserAgent('Gecko') && - !goog.labs.userAgent.engine.isWebKit() && - !goog.labs.userAgent.engine.isTrident() && - !goog.labs.userAgent.engine.isEdge(); +ol.events.EventTarget.prototype.hasListener = function(opt_type) { + return opt_type ? + opt_type in this.listeners_ : + Object.keys(this.listeners_).length > 0; }; /** - * @return {string} The rendering engine's version or empty string if version - * can't be determined. - */ -goog.labs.userAgent.engine.getVersion = function() { - var userAgentString = goog.labs.userAgent.util.getUserAgent(); - if (userAgentString) { - var tuples = goog.labs.userAgent.util.extractVersionTuples( - userAgentString); - - var engineTuple = goog.labs.userAgent.engine.getEngineTuple_(tuples); - if (engineTuple) { - // In Gecko, the version string is either in the browser info or the - // Firefox version. See Gecko user agent string reference: - // http://goo.gl/mULqa - if (engineTuple[0] == 'Gecko') { - return goog.labs.userAgent.engine.getVersionForKey_( - tuples, 'Firefox'); - } - - return engineTuple[1]; - } - - // MSIE has only one version identifier, and the Trident version is - // specified in the parenthetical. IE Edge is covered in the engine tuple - // detection. - var browserTuple = tuples[0]; - var info; - if (browserTuple && (info = browserTuple[2])) { - var match = /Trident\/([^\s;]+)/.exec(info); - if (match) { - return match[1]; + * @param {string} type Type. + * @param {ol.events.ListenerFunctionType} listener Listener. + */ +ol.events.EventTarget.prototype.removeEventListener = function(type, listener) { + var listeners = this.listeners_[type]; + if (listeners) { + var index = listeners.indexOf(listener); + goog.asserts.assert(index != -1, 'listener not found'); + if (type in this.pendingRemovals_) { + // make listener a no-op, and remove later in #dispatchEvent() + listeners[index] = ol.nullFunction; + ++this.pendingRemovals_[type]; + } else { + listeners.splice(index, 1); + if (listeners.length === 0) { + delete this.listeners_[type]; } } } - return ''; -}; - - -/** - * @param {!Array<!Array<string>>} tuples Extracted version tuples. - * @return {!Array<string>|undefined} The engine tuple or undefined if not - * found. - * @private - */ -goog.labs.userAgent.engine.getEngineTuple_ = function(tuples) { - if (!goog.labs.userAgent.engine.isEdge()) { - return tuples[1]; - } - for (var i = 0; i < tuples.length; i++) { - var tuple = tuples[i]; - if (tuple[0] == 'Edge') { - return tuple; - } - } }; +goog.provide('ol.Observable'); -/** - * @param {string|number} version The version to check. - * @return {boolean} Whether the rendering engine version is higher or the same - * as the given version. - */ -goog.labs.userAgent.engine.isVersionOrHigher = function(version) { - return goog.string.compareVersions(goog.labs.userAgent.engine.getVersion(), - version) >= 0; -}; - - -/** - * @param {!Array<!Array<string>>} tuples Version tuples. - * @param {string} key The key to look for. - * @return {string} The version string of the given key, if present. - * Otherwise, the empty string. - * @private - */ -goog.labs.userAgent.engine.getVersionForKey_ = function(tuples, key) { - // TODO(nnaze): Move to util if useful elsewhere. - - var pair = goog.array.find(tuples, function(pair) { - return key == pair[0]; - }); - - return pair && pair[1] || ''; -}; +goog.require('ol.events'); +goog.require('ol.events.EventTarget'); +goog.require('ol.events.EventType'); -// Copyright 2013 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. /** - * @fileoverview Closure user agent platform detection. - * @see <a href="http://www.useragentstring.com/">User agent strings</a> - * For more information on browser brand, rendering engine, or device see the - * other sub-namespaces in goog.labs.userAgent (browser, engine, and device - * respectively). + * @classdesc + * Abstract base class; normally only used for creating subclasses and not + * instantiated in apps. + * An event target providing convenient methods for listener registration + * and unregistration. A generic `change` event is always available through + * {@link ol.Observable#changed}. * + * @constructor + * @extends {ol.events.EventTarget} + * @fires change + * @struct + * @api stable */ +ol.Observable = function() { -goog.provide('goog.labs.userAgent.platform'); - -goog.require('goog.labs.userAgent.util'); -goog.require('goog.string'); - - -/** - * @return {boolean} Whether the platform is Android. - */ -goog.labs.userAgent.platform.isAndroid = function() { - return goog.labs.userAgent.util.matchUserAgent('Android'); -}; - - -/** - * @return {boolean} Whether the platform is iPod. - */ -goog.labs.userAgent.platform.isIpod = function() { - return goog.labs.userAgent.util.matchUserAgent('iPod'); -}; + goog.base(this); + /** + * @private + * @type {number} + */ + this.revision_ = 0; -/** - * @return {boolean} Whether the platform is iPhone. - */ -goog.labs.userAgent.platform.isIphone = function() { - return goog.labs.userAgent.util.matchUserAgent('iPhone') && - !goog.labs.userAgent.util.matchUserAgent('iPod') && - !goog.labs.userAgent.util.matchUserAgent('iPad'); }; +goog.inherits(ol.Observable, ol.events.EventTarget); /** - * @return {boolean} Whether the platform is iPad. + * Removes an event listener using the key returned by `on()` or `once()`. + * @param {ol.events.Key|Array.<ol.events.Key>} key The key returned by `on()` + * or `once()` (or an array of keys). + * @api stable */ -goog.labs.userAgent.platform.isIpad = function() { - return goog.labs.userAgent.util.matchUserAgent('iPad'); +ol.Observable.unByKey = function(key) { + if (Array.isArray(key)) { + for (var i = 0, ii = key.length; i < ii; ++i) { + ol.events.unlistenByKey(key[i]); + } + } else { + ol.events.unlistenByKey(/** @type {ol.events.Key} */ (key)); + } }; /** - * @return {boolean} Whether the platform is iOS. + * Increases the revision counter and dispatches a 'change' event. + * @api */ -goog.labs.userAgent.platform.isIos = function() { - return goog.labs.userAgent.platform.isIphone() || - goog.labs.userAgent.platform.isIpad() || - goog.labs.userAgent.platform.isIpod(); +ol.Observable.prototype.changed = function() { + ++this.revision_; + this.dispatchEvent(ol.events.EventType.CHANGE); }; /** - * @return {boolean} Whether the platform is Mac. + * Triggered when the revision counter is increased. + * @event change + * @api */ -goog.labs.userAgent.platform.isMacintosh = function() { - return goog.labs.userAgent.util.matchUserAgent('Macintosh'); -}; /** - * Note: ChromeOS is not considered to be Linux as it does not report itself - * as Linux in the user agent string. - * @return {boolean} Whether the platform is Linux. + * Dispatches an event and calls all listeners listening for events + * of this type. The event parameter can either be a string or an + * Object with a `type` property. + * + * @param {{type: string, + * target: (EventTarget|ol.events.EventTarget|undefined)}|ol.events.Event| + * string} event Event object. + * @function + * @api */ -goog.labs.userAgent.platform.isLinux = function() { - return goog.labs.userAgent.util.matchUserAgent('Linux'); -}; +ol.Observable.prototype.dispatchEvent; /** - * @return {boolean} Whether the platform is Windows. + * Get the version number for this object. Each time the object is modified, + * its version number will be incremented. + * @return {number} Revision. + * @api */ -goog.labs.userAgent.platform.isWindows = function() { - return goog.labs.userAgent.util.matchUserAgent('Windows'); +ol.Observable.prototype.getRevision = function() { + return this.revision_; }; /** - * @return {boolean} Whether the platform is ChromeOS. + * Listen for a certain type of event. + * @param {string|Array.<string>} type The event type or array of event types. + * @param {function(?): ?} listener The listener function. + * @param {Object=} opt_this The object to use as `this` in `listener`. + * @return {ol.events.Key|Array.<ol.events.Key>} Unique key for the listener. If + * called with an array of event types as the first argument, the return + * will be an array of keys. + * @api stable */ -goog.labs.userAgent.platform.isChromeOS = function() { - return goog.labs.userAgent.util.matchUserAgent('CrOS'); +ol.Observable.prototype.on = function(type, listener, opt_this) { + if (Array.isArray(type)) { + var len = type.length; + var keys = new Array(len); + for (var i = 0; i < len; ++i) { + keys[i] = ol.events.listen(this, type[i], listener, opt_this); + } + return keys; + } else { + return ol.events.listen( + this, /** @type {string} */ (type), listener, opt_this); + } }; /** - * The version of the platform. We only determine the version for Windows, - * Mac, and Chrome OS. It doesn't make much sense on Linux. For Windows, we only - * look at the NT version. Non-NT-based versions (e.g. 95, 98, etc.) are given - * version 0.0. - * - * @return {string} The platform version or empty string if version cannot be - * determined. + * Listen once for a certain type of event. + * @param {string|Array.<string>} type The event type or array of event types. + * @param {function(?): ?} listener The listener function. + * @param {Object=} opt_this The object to use as `this` in `listener`. + * @return {ol.events.Key|Array.<ol.events.Key>} Unique key for the listener. If + * called with an array of event types as the first argument, the return + * will be an array of keys. + * @api stable */ -goog.labs.userAgent.platform.getVersion = function() { - var userAgentString = goog.labs.userAgent.util.getUserAgent(); - var version = '', re; - if (goog.labs.userAgent.platform.isWindows()) { - re = /Windows (?:NT|Phone) ([0-9.]+)/; - var match = re.exec(userAgentString); - if (match) { - version = match[1]; - } else { - version = '0.0'; +ol.Observable.prototype.once = function(type, listener, opt_this) { + if (Array.isArray(type)) { + var len = type.length; + var keys = new Array(len); + for (var i = 0; i < len; ++i) { + keys[i] = ol.events.listenOnce(this, type[i], listener, opt_this); } - } else if (goog.labs.userAgent.platform.isIos()) { - re = /(?:iPhone|iPod|iPad|CPU)\s+OS\s+(\S+)/; - var match = re.exec(userAgentString); - // Report the version as x.y.z and not x_y_z - version = match && match[1].replace(/_/g, '.'); - } else if (goog.labs.userAgent.platform.isMacintosh()) { - re = /Mac OS X ([0-9_.]+)/; - var match = re.exec(userAgentString); - // Note: some old versions of Camino do not report an OSX version. - // Default to 10. - version = match ? match[1].replace(/_/g, '.') : '10'; - } else if (goog.labs.userAgent.platform.isAndroid()) { - re = /Android\s+([^\);]+)(\)|;)/; - var match = re.exec(userAgentString); - version = match && match[1]; - } else if (goog.labs.userAgent.platform.isChromeOS()) { - re = /(?:CrOS\s+(?:i686|x86_64)\s+([0-9.]+))/; - var match = re.exec(userAgentString); - version = match && match[1]; + return keys; + } else { + return ol.events.listenOnce( + this, /** @type {string} */ (type), listener, opt_this); } - return version || ''; }; /** - * @param {string|number} version The version to check. - * @return {boolean} Whether the browser version is higher or the same as the - * given version. + * Unlisten for a certain type of event. + * @param {string|Array.<string>} type The event type or array of event types. + * @param {function(?): ?} listener The listener function. + * @param {Object=} opt_this The object which was used as `this` by the + * `listener`. + * @api stable */ -goog.labs.userAgent.platform.isVersionOrHigher = function(version) { - return goog.string.compareVersions(goog.labs.userAgent.platform.getVersion(), - version) >= 0; +ol.Observable.prototype.un = function(type, listener, opt_this) { + if (Array.isArray(type)) { + for (var i = 0, ii = type.length; i < ii; ++i) { + ol.events.unlisten(this, type[i], listener, opt_this); + } + return; + } else { + ol.events.unlisten(this, /** @type {string} */ (type), listener, opt_this); + } }; -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Rendering engine detection. - * @see <a href="http://www.useragentstring.com/">User agent strings</a> - * For information on the browser brand (such as Safari versus Chrome), see - * goog.userAgent.product. - * @author arv@google.com (Erik Arvidsson) - * @see ../demos/useragent.html - */ - -goog.provide('goog.userAgent'); - -goog.require('goog.labs.userAgent.browser'); -goog.require('goog.labs.userAgent.engine'); -goog.require('goog.labs.userAgent.platform'); -goog.require('goog.labs.userAgent.util'); -goog.require('goog.string'); - - -/** - * @define {boolean} Whether we know at compile-time that the browser is IE. - */ -goog.define('goog.userAgent.ASSUME_IE', false); - - -/** - * @define {boolean} Whether we know at compile-time that the browser is EDGE. - */ -goog.define('goog.userAgent.ASSUME_EDGE', false); - - -/** - * @define {boolean} Whether we know at compile-time that the browser is GECKO. - */ -goog.define('goog.userAgent.ASSUME_GECKO', false); - - -/** - * @define {boolean} Whether we know at compile-time that the browser is WEBKIT. - */ -goog.define('goog.userAgent.ASSUME_WEBKIT', false); - - -/** - * @define {boolean} Whether we know at compile-time that the browser is a - * mobile device running WebKit e.g. iPhone or Android. - */ -goog.define('goog.userAgent.ASSUME_MOBILE_WEBKIT', false); - - -/** - * @define {boolean} Whether we know at compile-time that the browser is OPERA. - */ -goog.define('goog.userAgent.ASSUME_OPERA', false); - /** - * @define {boolean} Whether the - * {@code goog.userAgent.isVersionOrHigher} - * function will return true for any version. - */ -goog.define('goog.userAgent.ASSUME_ANY_VERSION', false); - - -/** - * Whether we know the browser engine at compile-time. - * @type {boolean} - * @private + * Removes an event listener using the key returned by `on()` or `once()`. + * Note that using the {@link ol.Observable.unByKey} static function is to + * be preferred. + * @param {ol.events.Key|Array.<ol.events.Key>} key The key returned by `on()` + * or `once()` (or an array of keys). + * @function + * @api stable */ -goog.userAgent.BROWSER_KNOWN_ = - goog.userAgent.ASSUME_IE || - goog.userAgent.ASSUME_EDGE || - goog.userAgent.ASSUME_GECKO || - goog.userAgent.ASSUME_MOBILE_WEBKIT || - goog.userAgent.ASSUME_WEBKIT || - goog.userAgent.ASSUME_OPERA; +ol.Observable.prototype.unByKey = ol.Observable.unByKey; +goog.provide('ol.Object'); +goog.provide('ol.ObjectEvent'); +goog.provide('ol.ObjectEventType'); -/** - * Returns the userAgent string for the current browser. - * - * @return {string} The userAgent string. - */ -goog.userAgent.getUserAgentString = function() { - return goog.labs.userAgent.util.getUserAgent(); -}; +goog.require('ol.Observable'); +goog.require('ol.events'); +goog.require('ol.events.Event'); +goog.require('ol.object'); /** - * TODO(nnaze): Change type to "Navigator" and update compilation targets. - * @return {Object} The native navigator object. + * @enum {string} */ -goog.userAgent.getNavigator = function() { - // Need a local navigator reference instead of using the global one, - // to avoid the rare case where they reference different objects. - // (in a WorkerPool, for example). - return goog.global['navigator'] || null; +ol.ObjectEventType = { + /** + * Triggered when a property is changed. + * @event ol.ObjectEvent#propertychange + * @api stable + */ + PROPERTYCHANGE: 'propertychange' }; /** - * Whether the user agent is Opera. - * @type {boolean} - */ -goog.userAgent.OPERA = goog.userAgent.BROWSER_KNOWN_ ? - goog.userAgent.ASSUME_OPERA : - goog.labs.userAgent.browser.isOpera(); - - -/** - * Whether the user agent is Internet Explorer. - * @type {boolean} - */ -goog.userAgent.IE = goog.userAgent.BROWSER_KNOWN_ ? - goog.userAgent.ASSUME_IE : - goog.labs.userAgent.browser.isIE(); - - -/** - * Whether the user agent is Microsoft Edge. - * @type {boolean} - */ -goog.userAgent.EDGE = goog.userAgent.BROWSER_KNOWN_ ? - goog.userAgent.ASSUME_EDGE : - goog.labs.userAgent.engine.isEdge(); - - -/** - * Whether the user agent is MS Internet Explorer or MS Edge. - * @type {boolean} + * @classdesc + * Events emitted by {@link ol.Object} instances are instances of this type. + * + * @param {string} type The event type. + * @param {string} key The property name. + * @param {*} oldValue The old value for `key`. + * @extends {ol.events.Event} + * @implements {oli.ObjectEvent} + * @constructor */ -goog.userAgent.EDGE_OR_IE = goog.userAgent.EDGE || goog.userAgent.IE; - +ol.ObjectEvent = function(type, key, oldValue) { + goog.base(this, type); -/** - * Whether the user agent is Gecko. Gecko is the rendering engine used by - * Mozilla, Firefox, and others. - * @type {boolean} - */ -goog.userAgent.GECKO = goog.userAgent.BROWSER_KNOWN_ ? - goog.userAgent.ASSUME_GECKO : - goog.labs.userAgent.engine.isGecko(); + /** + * The name of the property whose value is changing. + * @type {string} + * @api stable + */ + this.key = key; + /** + * The old value. To get the new value use `e.target.get(e.key)` where + * `e` is the event object. + * @type {*} + * @api stable + */ + this.oldValue = oldValue; -/** - * Whether the user agent is WebKit. WebKit is the rendering engine that - * Safari, Android and others use. - * @type {boolean} - */ -goog.userAgent.WEBKIT = goog.userAgent.BROWSER_KNOWN_ ? - goog.userAgent.ASSUME_WEBKIT || goog.userAgent.ASSUME_MOBILE_WEBKIT : - goog.labs.userAgent.engine.isWebKit(); +}; +goog.inherits(ol.ObjectEvent, ol.events.Event); /** - * Whether the user agent is running on a mobile device. + * @classdesc + * Abstract base class; normally only used for creating subclasses and not + * instantiated in apps. + * Most non-trivial classes inherit from this. * - * This is a separate function so that the logic can be tested. + * This extends {@link ol.Observable} with observable properties, where each + * property is observable as well as the object as a whole. * - * TODO(nnaze): Investigate swapping in goog.labs.userAgent.device.isMobile(). + * Classes that inherit from this have pre-defined properties, to which you can + * add your owns. The pre-defined properties are listed in this documentation as + * 'Observable Properties', and have their own accessors; for example, + * {@link ol.Map} has a `target` property, accessed with `getTarget()` and + * changed with `setTarget()`. Not all properties are however settable. There + * are also general-purpose accessors `get()` and `set()`. For example, + * `get('target')` is equivalent to `getTarget()`. * - * @return {boolean} Whether the user agent is running on a mobile device. - * @private - */ -goog.userAgent.isMobile_ = function() { - return goog.userAgent.WEBKIT && - goog.labs.userAgent.util.matchUserAgent('Mobile'); -}; - - -/** - * Whether the user agent is running on a mobile device. + * The `set` accessors trigger a change event, and you can monitor this by + * registering a listener. For example, {@link ol.View} has a `center` + * property, so `view.on('change:center', function(evt) {...});` would call the + * function whenever the value of the center property changes. Within the + * function, `evt.target` would be the view, so `evt.target.getCenter()` would + * return the new center. * - * TODO(nnaze): Consider deprecating MOBILE when labs.userAgent - * is promoted as the gecko/webkit logic is likely inaccurate. + * You can add your own observable properties with + * `object.set('prop', 'value')`, and retrieve that with `object.get('prop')`. + * You can listen for changes on that property value with + * `object.on('change:prop', listener)`. You can get a list of all + * properties with {@link ol.Object#getProperties object.getProperties()}. * - * @type {boolean} + * Note that the observable properties are separate from standard JS properties. + * You can, for example, give your map object a title with + * `map.title='New title'` and with `map.set('title', 'Another title')`. The + * first will be a `hasOwnProperty`; the second will appear in + * `getProperties()`. Only the second is observable. + * + * Properties can be deleted by using the unset method. E.g. + * object.unset('foo'). + * + * @constructor + * @extends {ol.Observable} + * @param {Object.<string, *>=} opt_values An object with key-value pairs. + * @fires ol.ObjectEvent + * @api */ -goog.userAgent.MOBILE = goog.userAgent.ASSUME_MOBILE_WEBKIT || - goog.userAgent.isMobile_(); - +ol.Object = function(opt_values) { + goog.base(this); -/** - * Used while transitioning code to use WEBKIT instead. - * @type {boolean} - * @deprecated Use {@link goog.userAgent.product.SAFARI} instead. - * TODO(nicksantos): Delete this from goog.userAgent. - */ -goog.userAgent.SAFARI = goog.userAgent.WEBKIT; + // Call goog.getUid to ensure that the order of objects' ids is the same as + // the order in which they were created. This also helps to ensure that + // object properties are always added in the same order, which helps many + // JavaScript engines generate faster code. + goog.getUid(this); + /** + * @private + * @type {!Object.<string, *>} + */ + this.values_ = {}; -/** - * @return {string} the platform (operating system) the user agent is running - * on. Default to empty string because navigator.platform may not be defined - * (on Rhino, for example). - * @private - */ -goog.userAgent.determinePlatform_ = function() { - var navigator = goog.userAgent.getNavigator(); - return navigator && navigator.platform || ''; + if (opt_values !== undefined) { + this.setProperties(opt_values); + } }; +goog.inherits(ol.Object, ol.Observable); /** - * The platform (operating system) the user agent is running on. Default to - * empty string because navigator.platform may not be defined (on Rhino, for - * example). - * @type {string} - */ -goog.userAgent.PLATFORM = goog.userAgent.determinePlatform_(); - - -/** - * @define {boolean} Whether the user agent is running on a Macintosh operating - * system. - */ -goog.define('goog.userAgent.ASSUME_MAC', false); - - -/** - * @define {boolean} Whether the user agent is running on a Windows operating - * system. - */ -goog.define('goog.userAgent.ASSUME_WINDOWS', false); - - -/** - * @define {boolean} Whether the user agent is running on a Linux operating - * system. - */ -goog.define('goog.userAgent.ASSUME_LINUX', false); - - -/** - * @define {boolean} Whether the user agent is running on a X11 windowing - * system. - */ -goog.define('goog.userAgent.ASSUME_X11', false); - - -/** - * @define {boolean} Whether the user agent is running on Android. - */ -goog.define('goog.userAgent.ASSUME_ANDROID', false); - - -/** - * @define {boolean} Whether the user agent is running on an iPhone. - */ -goog.define('goog.userAgent.ASSUME_IPHONE', false); - - -/** - * @define {boolean} Whether the user agent is running on an iPad. - */ -goog.define('goog.userAgent.ASSUME_IPAD', false); - - -/** - * @type {boolean} * @private + * @type {Object.<string, string>} */ -goog.userAgent.PLATFORM_KNOWN_ = - goog.userAgent.ASSUME_MAC || - goog.userAgent.ASSUME_WINDOWS || - goog.userAgent.ASSUME_LINUX || - goog.userAgent.ASSUME_X11 || - goog.userAgent.ASSUME_ANDROID || - goog.userAgent.ASSUME_IPHONE || - goog.userAgent.ASSUME_IPAD; - - -/** - * Whether the user agent is running on a Macintosh operating system. - * @type {boolean} - */ -goog.userAgent.MAC = goog.userAgent.PLATFORM_KNOWN_ ? - goog.userAgent.ASSUME_MAC : goog.labs.userAgent.platform.isMacintosh(); - - -/** - * Whether the user agent is running on a Windows operating system. - * @type {boolean} - */ -goog.userAgent.WINDOWS = goog.userAgent.PLATFORM_KNOWN_ ? - goog.userAgent.ASSUME_WINDOWS : - goog.labs.userAgent.platform.isWindows(); +ol.Object.changeEventTypeCache_ = {}; /** - * Whether the user agent is Linux per the legacy behavior of - * goog.userAgent.LINUX, which considered ChromeOS to also be - * Linux. - * @return {boolean} - * @private + * @param {string} key Key name. + * @return {string} Change name. */ -goog.userAgent.isLegacyLinux_ = function() { - return goog.labs.userAgent.platform.isLinux() || - goog.labs.userAgent.platform.isChromeOS(); +ol.Object.getChangeEventType = function(key) { + return ol.Object.changeEventTypeCache_.hasOwnProperty(key) ? + ol.Object.changeEventTypeCache_[key] : + (ol.Object.changeEventTypeCache_[key] = 'change:' + key); }; /** - * Whether the user agent is running on a Linux operating system. - * - * Note that goog.userAgent.LINUX considers ChromeOS to be Linux, - * while goog.labs.userAgent.platform considers ChromeOS and - * Linux to be different OSes. - * - * @type {boolean} - */ -goog.userAgent.LINUX = goog.userAgent.PLATFORM_KNOWN_ ? - goog.userAgent.ASSUME_LINUX : - goog.userAgent.isLegacyLinux_(); - - -/** - * @return {boolean} Whether the user agent is an X11 windowing system. - * @private + * Gets a value. + * @param {string} key Key name. + * @return {*} Value. + * @api stable */ -goog.userAgent.isX11_ = function() { - var navigator = goog.userAgent.getNavigator(); - return !!navigator && - goog.string.contains(navigator['appVersion'] || '', 'X11'); +ol.Object.prototype.get = function(key) { + var value; + if (this.values_.hasOwnProperty(key)) { + value = this.values_[key]; + } + return value; }; /** - * Whether the user agent is running on a X11 windowing system. - * @type {boolean} - */ -goog.userAgent.X11 = goog.userAgent.PLATFORM_KNOWN_ ? - goog.userAgent.ASSUME_X11 : - goog.userAgent.isX11_(); - - -/** - * Whether the user agent is running on Android. - * @type {boolean} - */ -goog.userAgent.ANDROID = goog.userAgent.PLATFORM_KNOWN_ ? - goog.userAgent.ASSUME_ANDROID : - goog.labs.userAgent.platform.isAndroid(); - - -/** - * Whether the user agent is running on an iPhone. - * @type {boolean} + * Get a list of object property names. + * @return {Array.<string>} List of property names. + * @api stable */ -goog.userAgent.IPHONE = goog.userAgent.PLATFORM_KNOWN_ ? - goog.userAgent.ASSUME_IPHONE : - goog.labs.userAgent.platform.isIphone(); +ol.Object.prototype.getKeys = function() { + return Object.keys(this.values_); +}; /** - * Whether the user agent is running on an iPad. - * @type {boolean} + * Get an object of all property names and values. + * @return {Object.<string, *>} Object. + * @api stable */ -goog.userAgent.IPAD = goog.userAgent.PLATFORM_KNOWN_ ? - goog.userAgent.ASSUME_IPAD : - goog.labs.userAgent.platform.isIpad(); +ol.Object.prototype.getProperties = function() { + return ol.object.assign({}, this.values_); +}; /** - * @return {string} The string that describes the version number of the user - * agent. - * Assumes user agent is opera. - * @private + * @param {string} key Key name. + * @param {*} oldValue Old value. */ -goog.userAgent.operaVersion_ = function() { - var version = goog.global.opera.version; - try { - return version(); - } catch (e) { - return version; - } +ol.Object.prototype.notify = function(key, oldValue) { + var eventType; + eventType = ol.Object.getChangeEventType(key); + this.dispatchEvent(new ol.ObjectEvent(eventType, key, oldValue)); + eventType = ol.ObjectEventType.PROPERTYCHANGE; + this.dispatchEvent(new ol.ObjectEvent(eventType, key, oldValue)); }; /** - * @return {string} The string that describes the version number of the user - * agent. - * @private + * Sets a value. + * @param {string} key Key name. + * @param {*} value Value. + * @param {boolean=} opt_silent Update without triggering an event. + * @api stable */ -goog.userAgent.determineVersion_ = function() { - // All browsers have different ways to detect the version and they all have - // different naming schemes. - - if (goog.userAgent.OPERA && goog.global['opera']) { - return goog.userAgent.operaVersion_(); - } - - // version is a string rather than a number because it may contain 'b', 'a', - // and so on. - var version = ''; - var arr = goog.userAgent.getVersionRegexResult_(); - if (arr) { - version = arr ? arr[1] : ''; - } - - if (goog.userAgent.IE) { - // IE9 can be in document mode 9 but be reporting an inconsistent user agent - // version. If it is identifying as a version lower than 9 we take the - // documentMode as the version instead. IE8 has similar behavior. - // It is recommended to set the X-UA-Compatible header to ensure that IE9 - // uses documentMode 9. - var docMode = goog.userAgent.getDocumentMode_(); - if (docMode > parseFloat(version)) { - return String(docMode); +ol.Object.prototype.set = function(key, value, opt_silent) { + if (opt_silent) { + this.values_[key] = value; + } else { + var oldValue = this.values_[key]; + this.values_[key] = value; + if (oldValue !== value) { + this.notify(key, oldValue); } } - - return version; }; /** - * @return {Array|undefined} The version regex matches from parsing the user - * agent string. These regex statements must be executed inline so they can - * be compiled out by the closure compiler with the rest of the useragent - * detection logic when ASSUME_* is specified. - * @private + * Sets a collection of key-value pairs. Note that this changes any existing + * properties and adds new ones (it does not remove any existing properties). + * @param {Object.<string, *>} values Values. + * @param {boolean=} opt_silent Update without triggering an event. + * @api stable */ -goog.userAgent.getVersionRegexResult_ = function() { - var userAgent = goog.userAgent.getUserAgentString(); - if (goog.userAgent.GECKO) { - return /rv\:([^\);]+)(\)|;)/.exec(userAgent); - } - if (goog.userAgent.EDGE) { - return /Edge\/([\d\.]+)/.exec(userAgent); - } - if (goog.userAgent.IE) { - return /\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(userAgent); - } - if (goog.userAgent.WEBKIT) { - // WebKit/125.4 - return /WebKit\/(\S+)/.exec(userAgent); +ol.Object.prototype.setProperties = function(values, opt_silent) { + var key; + for (key in values) { + this.set(key, values[key], opt_silent); } }; /** - * @return {number|undefined} Returns the document mode (for testing). - * @private - */ -goog.userAgent.getDocumentMode_ = function() { - // NOTE(user): goog.userAgent may be used in context where there is no DOM. - var doc = goog.global['document']; - return doc ? doc['documentMode'] : undefined; -}; - - -/** - * The version of the user agent. This is a string because it might contain - * 'b' (as in beta) as well as multiple dots. - * @type {string} - */ -goog.userAgent.VERSION = goog.userAgent.determineVersion_(); - - -/** - * Compares two version numbers. - * - * @param {string} v1 Version of first item. - * @param {string} v2 Version of second item. - * - * @return {number} 1 if first argument is higher - * 0 if arguments are equal - * -1 if second argument is higher. - * @deprecated Use goog.string.compareVersions. - */ -goog.userAgent.compare = function(v1, v2) { - return goog.string.compareVersions(v1, v2); -}; - - -/** - * Cache for {@link goog.userAgent.isVersionOrHigher}. - * Calls to compareVersions are surprisingly expensive and, as a browser's - * version number is unlikely to change during a session, we cache the results. - * @const - * @private - */ -goog.userAgent.isVersionOrHigherCache_ = {}; - - -/** - * Whether the user agent version is higher or the same as the given version. - * NOTE: When checking the version numbers for Firefox and Safari, be sure to - * use the engine's version, not the browser's version number. For example, - * Firefox 3.0 corresponds to Gecko 1.9 and Safari 3.0 to Webkit 522.11. - * Opera and Internet Explorer versions match the product release number.<br> - * @see <a href="http://en.wikipedia.org/wiki/Safari_version_history"> - * Webkit</a> - * @see <a href="http://en.wikipedia.org/wiki/Gecko_engine">Gecko</a> - * - * @param {string|number} version The version to check. - * @return {boolean} Whether the user agent version is higher or the same as - * the given version. + * Unsets a property. + * @param {string} key Key name. + * @param {boolean=} opt_silent Unset without triggering an event. + * @api stable */ -goog.userAgent.isVersionOrHigher = function(version) { - return goog.userAgent.ASSUME_ANY_VERSION || - goog.userAgent.isVersionOrHigherCache_[version] || - (goog.userAgent.isVersionOrHigherCache_[version] = - goog.string.compareVersions(goog.userAgent.VERSION, version) >= 0); +ol.Object.prototype.unset = function(key, opt_silent) { + if (key in this.values_) { + var oldValue = this.values_[key]; + delete this.values_[key]; + if (!opt_silent) { + this.notify(key, oldValue); + } + } }; +goog.provide('ol.array'); -/** - * Deprecated alias to {@code goog.userAgent.isVersionOrHigher}. - * @param {string|number} version The version to check. - * @return {boolean} Whether the user agent version is higher or the same as - * the given version. - * @deprecated Use goog.userAgent.isVersionOrHigher(). - */ -goog.userAgent.isVersion = goog.userAgent.isVersionOrHigher; +goog.require('goog.asserts'); /** - * Whether the IE effective document mode is higher or the same as the given - * document mode version. - * NOTE: Only for IE, return false for another browser. + * 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. + * https://github.com/darkskyapp/binary-search * - * @param {number} documentMode The document mode version to check. - * @return {boolean} Whether the IE effective document mode is higher or the - * same as the given version. + * @param {Array.<*>} haystack Items to search through. + * @param {*} needle The item to look for. + * @param {Function=} opt_comparator Comparator function. + * @return {number} The index of the item if found, -1 if not. */ -goog.userAgent.isDocumentModeOrHigher = function(documentMode) { - return goog.userAgent.DOCUMENT_MODE >= documentMode; -}; - +ol.array.binarySearch = function(haystack, needle, opt_comparator) { + var mid, cmp; + var comparator = opt_comparator || ol.array.numberSafeCompareFunction; + var low = 0; + var high = haystack.length; + var found = false; -/** - * Deprecated alias to {@code goog.userAgent.isDocumentModeOrHigher}. - * @param {number} version The version to check. - * @return {boolean} Whether the IE effective document mode is higher or the - * same as the given version. - * @deprecated Use goog.userAgent.isDocumentModeOrHigher(). - */ -goog.userAgent.isDocumentMode = goog.userAgent.isDocumentModeOrHigher; + while (low < high) { + /* Note that "(low + high) >>> 1" may overflow, and results in a typecast + * to double (which gives the wrong results). */ + mid = low + (high - low >> 1); + cmp = +comparator(haystack[mid], needle); + if (cmp < 0.0) { /* Too low. */ + low = mid + 1; -/** - * For IE version < 7, documentMode is undefined, so attempt to use the - * CSS1Compat property to see if we are in standards mode. If we are in - * standards mode, treat the browser version as the document mode. Otherwise, - * IE is emulating version 5. - * @type {number|undefined} - * @const - */ -goog.userAgent.DOCUMENT_MODE = (function() { - var doc = goog.global['document']; - var mode = goog.userAgent.getDocumentMode_(); - if (!doc || !goog.userAgent.IE) { - return undefined; + } else { /* Key found or too high */ + high = mid; + found = !cmp; + } } - return mode || (doc['compatMode'] == 'CSS1Compat' ? - parseInt(goog.userAgent.VERSION, 10) : 5); -})(); - -// Copyright 2010 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Browser capability checks for the events package. - * - */ - - -goog.provide('goog.events.BrowserFeature'); - -goog.require('goog.userAgent'); - - -/** - * Enum of browser capabilities. - * @enum {boolean} - */ -goog.events.BrowserFeature = { - /** - * Whether the button attribute of the event is W3C compliant. False in - * Internet Explorer prior to version 9; document-version dependent. - */ - HAS_W3C_BUTTON: !goog.userAgent.IE || - goog.userAgent.isDocumentModeOrHigher(9), - - /** - * Whether the browser supports full W3C event model. - */ - HAS_W3C_EVENT_SUPPORT: !goog.userAgent.IE || - goog.userAgent.isDocumentModeOrHigher(9), - - /** - * To prevent default in IE7-8 for certain keydown events we need set the - * keyCode to -1. - */ - SET_KEY_CODE_TO_PREVENT_DEFAULT: goog.userAgent.IE && - !goog.userAgent.isVersionOrHigher('9'), - - /** - * Whether the {@code navigator.onLine} property is supported. - */ - HAS_NAVIGATOR_ONLINE_PROPERTY: !goog.userAgent.WEBKIT || - goog.userAgent.isVersionOrHigher('528'), - - /** - * Whether HTML5 network online/offline events are supported. - */ - HAS_HTML5_NETWORK_EVENT_SUPPORT: - goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.9b') || - goog.userAgent.IE && goog.userAgent.isVersionOrHigher('8') || - goog.userAgent.OPERA && goog.userAgent.isVersionOrHigher('9.5') || - goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher('528'), - - /** - * Whether HTML5 network events fire on document.body, or otherwise the - * window. - */ - HTML5_NETWORK_EVENTS_FIRE_ON_BODY: - goog.userAgent.GECKO && !goog.userAgent.isVersionOrHigher('8') || - goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9'), - - /** - * Whether touch is enabled in the browser. - */ - TOUCH_ENABLED: - ('ontouchstart' in goog.global || - !!(goog.global['document'] && - document.documentElement && - 'ontouchstart' in document.documentElement) || - // IE10 uses non-standard touch events, so it has a different check. - !!(goog.global['navigator'] && - goog.global['navigator']['msMaxTouchPoints'])) -}; - -// Copyright 2011 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Definition of the disposable interface. A disposable object - * has a dispose method to to clean up references and resources. - * @author nnaze@google.com (Nathan Naze) - */ - - -goog.provide('goog.disposable.IDisposable'); - - - -/** - * Interface for a disposable object. If a instance requires cleanup - * (references COM objects, DOM notes, or other disposable objects), it should - * implement this interface (it may subclass goog.Disposable). - * @interface - */ -goog.disposable.IDisposable = function() {}; - - -/** - * Disposes of the object and its resources. - * @return {void} Nothing. - */ -goog.disposable.IDisposable.prototype.dispose = goog.abstractMethod; - - -/** - * @return {boolean} Whether the object has been disposed of. - */ -goog.disposable.IDisposable.prototype.isDisposed = goog.abstractMethod; - -// Copyright 2005 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Implements the disposable interface. The dispose method is used - * to clean up references and resources. - * @author arv@google.com (Erik Arvidsson) - */ - - -goog.provide('goog.Disposable'); -/** @suppress {extraProvide} */ -goog.provide('goog.dispose'); -/** @suppress {extraProvide} */ -goog.provide('goog.disposeAll'); - -goog.require('goog.disposable.IDisposable'); - + /* Key not found. */ + return found ? low : ~low; +} /** - * Class that provides the basic implementation for disposable objects. If your - * class holds one or more references to COM objects, DOM nodes, or other - * disposable objects, it should extend this class or implement the disposable - * interface (defined in goog.disposable.IDisposable). - * @constructor - * @implements {goog.disposable.IDisposable} + * @param {Array.<number>} arr Array. + * @param {number} target Target. + * @return {number} Index. */ -goog.Disposable = function() { - if (goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF) { - if (goog.Disposable.INCLUDE_STACK_ON_CREATION) { - this.creationStack = new Error().stack; +ol.array.binaryFindNearest = function(arr, target) { + var index = ol.array.binarySearch(arr, target, + /** + * @param {number} a A. + * @param {number} b B. + * @return {number} b minus a. + */ + function(a, b) { + return b - a; + }); + if (index >= 0) { + return index; + } else if (index == -1) { + return 0; + } else if (index == -arr.length - 1) { + return arr.length - 1; + } else { + var left = -index - 2; + var right = -index - 1; + if (arr[left] - target < target - arr[right]) { + return left; + } else { + return right; } - goog.Disposable.instances_[goog.getUid(this)] = this; } - // Support sealing - this.disposed_ = this.disposed_; - this.onDisposeCallbacks_ = this.onDisposeCallbacks_; }; /** - * @enum {number} Different monitoring modes for Disposable. + * Compare function for array sort that is safe for numbers. + * @param {*} a The first object to be compared. + * @param {*} b The second object to be compared. + * @return {number} A negative number, zero, or a positive number as the first + * argument is less than, equal to, or greater than the second. */ -goog.Disposable.MonitoringMode = { - /** - * No monitoring. - */ - OFF: 0, - /** - * Creating and disposing the goog.Disposable instances is monitored. All - * disposable objects need to call the {@code goog.Disposable} base - * constructor. The PERMANENT mode must be switched on before creating any - * goog.Disposable instances. - */ - PERMANENT: 1, - /** - * INTERACTIVE mode can be switched on and off on the fly without producing - * errors. It also doesn't warn if the disposable objects don't call the - * {@code goog.Disposable} base constructor. - */ - INTERACTIVE: 2 +ol.array.numberSafeCompareFunction = function(a, b) { + return a > b ? 1 : a < b ? -1 : 0; }; /** - * @define {number} The monitoring mode of the goog.Disposable - * instances. Default is OFF. Switching on the monitoring is only - * recommended for debugging because it has a significant impact on - * performance and memory usage. If switched off, the monitoring code - * compiles down to 0 bytes. - */ -goog.define('goog.Disposable.MONITORING_MODE', 0); - - -/** - * @define {boolean} Whether to attach creation stack to each created disposable - * instance; This is only relevant for when MonitoringMode != OFF. - */ -goog.define('goog.Disposable.INCLUDE_STACK_ON_CREATION', true); - - -/** - * Maps the unique ID of every undisposed {@code goog.Disposable} object to - * the object itself. - * @type {!Object<number, !goog.Disposable>} - * @private + * Whether the array contains the given object. + * @param {Array.<*>} arr The array to test for the presence of the element. + * @param {*} obj The object for which to test. + * @return {boolean} The object is in the array. */ -goog.Disposable.instances_ = {}; +ol.array.includes = function(arr, obj) { + return arr.indexOf(obj) >= 0; +}; /** - * @return {!Array<!goog.Disposable>} All {@code goog.Disposable} objects that - * haven't been disposed of. + * @param {Array.<number>} arr Array. + * @param {number} target Target. + * @param {number} direction 0 means return the nearest, > 0 + * means return the largest nearest, < 0 means return the + * smallest nearest. + * @return {number} Index. */ -goog.Disposable.getUndisposedObjects = function() { - var ret = []; - for (var id in goog.Disposable.instances_) { - if (goog.Disposable.instances_.hasOwnProperty(id)) { - ret.push(goog.Disposable.instances_[Number(id)]); +ol.array.linearFindNearest = function(arr, target, direction) { + var n = arr.length; + if (arr[0] <= target) { + return 0; + } else if (target <= arr[n - 1]) { + return n - 1; + } else { + var i; + if (direction > 0) { + for (i = 1; i < n; ++i) { + if (arr[i] < target) { + return i - 1; + } + } + } else if (direction < 0) { + for (i = 1; i < n; ++i) { + if (arr[i] <= target) { + return i; + } + } + } else { + for (i = 1; i < n; ++i) { + if (arr[i] == target) { + return i; + } else if (arr[i] < target) { + if (arr[i - 1] - target < target - arr[i]) { + return i - 1; + } else { + return i; + } + } + } } + // We should never get here, but the compiler complains + // if it finds a path for which no number is returned. + goog.asserts.fail(); + return n - 1; } - return ret; }; /** - * Clears the registry of undisposed objects but doesn't dispose of them. + * @param {Array.<*>} arr Array. + * @param {number} begin Begin index. + * @param {number} end End index. */ -goog.Disposable.clearUndisposedObjects = function() { - goog.Disposable.instances_ = {}; +ol.array.reverseSubArray = function(arr, begin, end) { + goog.asserts.assert(begin >= 0, + 'Array begin index should be equal to or greater than 0'); + goog.asserts.assert(end < arr.length, + 'Array end index should be less than the array length'); + while (begin < end) { + var tmp = arr[begin]; + arr[begin] = arr[end]; + arr[end] = tmp; + ++begin; + --end; + } }; /** - * Whether the object has been disposed of. - * @type {boolean} - * @private - */ -goog.Disposable.prototype.disposed_ = false; - - -/** - * Callbacks to invoke when this object is disposed. - * @type {Array<!Function>} - * @private - */ -goog.Disposable.prototype.onDisposeCallbacks_; - - -/** - * If monitoring the goog.Disposable instances is enabled, stores the creation - * stack trace of the Disposable instance. - * @const {string} - */ -goog.Disposable.prototype.creationStack; - - -/** - * @return {boolean} Whether the object has been disposed of. - * @override + * @param {Array.<*>} arr Array. + * @return {!Array.<?>} Flattened Array. */ -goog.Disposable.prototype.isDisposed = function() { - return this.disposed_; +ol.array.flatten = function(arr) { + var data = arr.reduce(function(flattened, value) { + if (Array.isArray(value)) { + return flattened.concat(ol.array.flatten(value)); + } else { + return flattened.concat(value); + } + }, []); + return data; }; /** - * @return {boolean} Whether the object has been disposed of. - * @deprecated Use {@link #isDisposed} instead. + * @param {Array.<VALUE>} arr The array to modify. + * @param {Array.<VALUE>|VALUE} data The elements or arrays of elements + * to add to arr. + * @template VALUE */ -goog.Disposable.prototype.getDisposed = goog.Disposable.prototype.isDisposed; +ol.array.extend = function(arr, data) { + var i; + var extension = goog.isArrayLike(data) ? data : [data]; + var length = extension.length + for (i = 0; i < length; i++) { + arr[arr.length] = extension[i]; + } +} /** - * Disposes of the object. If the object hasn't already been disposed of, calls - * {@link #disposeInternal}. Classes that extend {@code goog.Disposable} should - * override {@link #disposeInternal} in order to delete references to COM - * objects, DOM nodes, and other disposable objects. Reentrant. - * - * @return {void} Nothing. - * @override + * @param {Array.<VALUE>} arr The array to modify. + * @param {VALUE} obj The element to remove. + * @template VALUE + * @return {boolean} If the element was removed. */ -goog.Disposable.prototype.dispose = function() { - if (!this.disposed_) { - // Set disposed_ to true first, in case during the chain of disposal this - // gets disposed recursively. - this.disposed_ = true; - this.disposeInternal(); - if (goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF) { - var uid = goog.getUid(this); - if (goog.Disposable.MONITORING_MODE == - goog.Disposable.MonitoringMode.PERMANENT && - !goog.Disposable.instances_.hasOwnProperty(uid)) { - throw Error(this + ' did not call the goog.Disposable base ' + - 'constructor or was disposed of after a clearUndisposedObjects ' + - 'call'); - } - delete goog.Disposable.instances_[uid]; - } +ol.array.remove = function(arr, obj) { + var i = arr.indexOf(obj); + var found = i > -1; + if (found) { + arr.splice(i, 1); } -}; + return found; +} /** - * Associates a disposable object with this object so that they will be disposed - * together. - * @param {goog.disposable.IDisposable} disposable that will be disposed when - * this object is disposed. + * @param {Array.<VALUE>} arr The array to search in. + * @param {function(VALUE, number, ?) : boolean} func The function to compare. + * @template VALUE + * @return {VALUE} The element found. */ -goog.Disposable.prototype.registerDisposable = function(disposable) { - this.addOnDisposeCallback(goog.partial(goog.dispose, disposable)); -}; - +ol.array.find = function(arr, func) { + var length = arr.length >>> 0; + var value; -/** - * Invokes a callback function when this object is disposed. Callbacks are - * invoked in the order in which they were added. If a callback is added to - * an already disposed Disposable, it will be called immediately. - * @param {function(this:T):?} callback The callback function. - * @param {T=} opt_scope An optional scope to call the callback in. - * @template T - */ -goog.Disposable.prototype.addOnDisposeCallback = function(callback, opt_scope) { - if (this.disposed_) { - callback.call(opt_scope); - return; - } - if (!this.onDisposeCallbacks_) { - this.onDisposeCallbacks_ = []; + for (var i = 0; i < length; i++) { + value = arr[i]; + if (func(value, i, arr)) { + return value; + } } - - this.onDisposeCallbacks_.push( - goog.isDef(opt_scope) ? goog.bind(callback, opt_scope) : callback); -}; + return null; +} /** - * Deletes or nulls out any references to COM objects, DOM nodes, or other - * disposable objects. Classes that extend {@code goog.Disposable} should - * override this method. - * Not reentrant. To avoid calling it twice, it must only be called from the - * subclass' {@code disposeInternal} method. Everywhere else the public - * {@code dispose} method must be used. - * For example: - * <pre> - * mypackage.MyClass = function() { - * mypackage.MyClass.base(this, 'constructor'); - * // Constructor logic specific to MyClass. - * ... - * }; - * goog.inherits(mypackage.MyClass, goog.Disposable); - * - * mypackage.MyClass.prototype.disposeInternal = function() { - * // Dispose logic specific to MyClass. - * ... - * // Call superclass's disposeInternal at the end of the subclass's, like - * // in C++, to avoid hard-to-catch issues. - * mypackage.MyClass.base(this, 'disposeInternal'); - * }; - * </pre> - * @protected + * @param {Array|Uint8ClampedArray} arr1 The first array to compare. + * @param {Array|Uint8ClampedArray} arr2 The second array to compare. + * @return {boolean} Whether the two arrays are equal. */ -goog.Disposable.prototype.disposeInternal = function() { - if (this.onDisposeCallbacks_) { - while (this.onDisposeCallbacks_.length) { - this.onDisposeCallbacks_.shift()(); +ol.array.equals = function(arr1, arr2) { + var len1 = arr1.length; + if (len1 !== arr2.length) { + return false; + } + for (var i = 0; i < len1; i++) { + if (arr1[i] !== arr2[i]) { + return false; } } -}; + return true; +} /** - * Returns True if we can verify the object is disposed. - * Calls {@code isDisposed} on the argument if it supports it. If obj - * is not an object with an isDisposed() method, return false. - * @param {*} obj The object to investigate. - * @return {boolean} True if we can verify the object is disposed. + * @param {Array.<*>} arr The array to sort (modifies original). + * @param {Function} compareFnc Comparison function. */ -goog.Disposable.isDisposed = function(obj) { - if (obj && typeof obj.isDisposed == 'function') { - return obj.isDisposed(); +ol.array.stableSort = function(arr, compareFnc) { + var length = arr.length; + var tmp = Array(arr.length); + var i; + for (i = 0; i < length; i++) { + tmp[i] = {index: i, value: arr[i]}; } - return false; -}; + tmp.sort(function(a, b) { + return compareFnc(a.value, b.value) || a.index - b.index; + }); + for (i = 0; i < arr.length; i++) { + arr[i] = tmp[i].value; + } +} /** - * Calls {@code dispose} on the argument if it supports it. If obj is not an - * object with a dispose() method, this is a no-op. - * @param {*} obj The object to dispose of. + * @param {Array.<*>} arr The array to search in. + * @param {Function} func Comparison function. + * @return {number} Return index. */ -goog.dispose = function(obj) { - if (obj && typeof obj.dispose == 'function') { - obj.dispose(); - } -}; +ol.array.findIndex = function(arr, func) { + var index; + var found = !arr.every(function(el, idx) { + index = idx; + return !func(el, idx, arr); + }); + return found ? index : -1; +} /** - * Calls {@code dispose} on each member of the list that supports it. (If the - * member is an ArrayLike, then {@code goog.disposeAll()} will be called - * recursively on each of its members.) If the member is not an object with a - * {@code dispose()} method, then it is ignored. - * @param {...*} var_args The list. + * @param {Array.<*>} arr The array to test. + * @param {Function=} opt_func Comparison function. + * @param {boolean=} opt_strict Strictly sorted (default false). + * @return {boolean} Return index. */ -goog.disposeAll = function(var_args) { - for (var i = 0, len = arguments.length; i < len; ++i) { - var disposable = arguments[i]; - if (goog.isArrayLike(disposable)) { - goog.disposeAll.apply(null, disposable); - } else { - goog.dispose(disposable); +ol.array.isSorted = function(arr, opt_func, opt_strict) { + var compare = opt_func || ol.array.numberSafeCompareFunction; + return arr.every(function(currentVal, index) { + if (index === 0) { + return true; } - } -}; - -// Copyright 2013 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. + var res = compare(arr[index - 1], currentVal); + return !(res > 0 || opt_strict && res === 0); + }); +} -goog.provide('goog.events.EventId'); +goog.provide('ol.ResolutionConstraint'); +goog.require('ol.array'); +goog.require('ol.math'); /** - * A templated class that is used when registering for events. Typical usage: - * <code> - * /** @type {goog.events.EventId<MyEventObj>} - * var myEventId = new goog.events.EventId( - * goog.events.getUniqueId(('someEvent')); - * - * // No need to cast or declare here since the compiler knows the correct - * // type of 'evt' (MyEventObj). - * something.listen(myEventId, function(evt) {}); - * </code> - * - * @param {string} eventId - * @template T - * @constructor - * @struct - * @final + * @param {Array.<number>} resolutions Resolutions. + * @return {ol.ResolutionConstraintType} Zoom function. */ -goog.events.EventId = function(eventId) { - /** @const */ this.id = eventId; +ol.ResolutionConstraint.createSnapToResolutions = function(resolutions) { + return ( + /** + * @param {number|undefined} resolution Resolution. + * @param {number} delta Delta. + * @param {number} direction Direction. + * @return {number|undefined} Resolution. + */ + function(resolution, delta, direction) { + if (resolution !== undefined) { + var z = + ol.array.linearFindNearest(resolutions, resolution, direction); + z = ol.math.clamp(z + delta, 0, resolutions.length - 1); + return resolutions[z]; + } else { + return undefined; + } + }); }; /** - * @override + * @param {number} power Power. + * @param {number} maxResolution Maximum resolution. + * @param {number=} opt_maxLevel Maximum level. + * @return {ol.ResolutionConstraintType} Zoom function. */ -goog.events.EventId.prototype.toString = function() { - return this.id; +ol.ResolutionConstraint.createSnapToPower = function(power, maxResolution, opt_maxLevel) { + return ( + /** + * @param {number|undefined} resolution Resolution. + * @param {number} delta Delta. + * @param {number} direction Direction. + * @return {number|undefined} Resolution. + */ + function(resolution, delta, direction) { + if (resolution !== undefined) { + var offset; + if (direction > 0) { + offset = 0; + } else if (direction < 0) { + offset = 1; + } else { + offset = 0.5; + } + var oldLevel = Math.floor( + Math.log(maxResolution / resolution) / Math.log(power) + offset); + var newLevel = Math.max(oldLevel + delta, 0); + if (opt_maxLevel !== undefined) { + newLevel = Math.min(newLevel, opt_maxLevel); + } + return maxResolution / Math.pow(power, newLevel); + } else { + return undefined; + } + }); }; -// Copyright 2005 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview A base class for event objects. - * - */ - - -goog.provide('goog.events.Event'); -goog.provide('goog.events.EventLike'); - -/** - * goog.events.Event no longer depends on goog.Disposable. Keep requiring - * goog.Disposable here to not break projects which assume this dependency. - * @suppress {extraRequire} - */ -goog.require('goog.Disposable'); -goog.require('goog.events.EventId'); - - -/** - * A typedef for event like objects that are dispatchable via the - * goog.events.dispatchEvent function. strings are treated as the type for a - * goog.events.Event. Objects are treated as an extension of a new - * goog.events.Event with the type property of the object being used as the type - * of the Event. - * @typedef {string|Object|goog.events.Event|goog.events.EventId} - */ -goog.events.EventLike; +goog.provide('ol.RotationConstraint'); +goog.require('ol.math'); /** - * A base class for event objects, so that they can support preventDefault and - * stopPropagation. - * - * @param {string|!goog.events.EventId} type Event Type. - * @param {Object=} opt_target Reference to the object that is the target of - * this event. It has to implement the {@code EventTarget} interface - * declared at {@link http://developer.mozilla.org/en/DOM/EventTarget}. - * @constructor + * @param {number|undefined} rotation Rotation. + * @param {number} delta Delta. + * @return {number|undefined} Rotation. */ -goog.events.Event = function(type, opt_target) { - /** - * Event type. - * @type {string} - */ - this.type = type instanceof goog.events.EventId ? String(type) : type; - - /** - * TODO(tbreisacher): The type should probably be - * EventTarget|goog.events.EventTarget. - * - * Target of the event. - * @type {Object|undefined} - */ - this.target = opt_target; - - /** - * Object that had the listener attached. - * @type {Object|undefined} - */ - this.currentTarget = this.target; - - /** - * Whether to cancel the event in internal capture/bubble processing for IE. - * @type {boolean} - * @public - * @suppress {underscore|visibility} Technically public, but referencing this - * outside this package is strongly discouraged. - */ - this.propagationStopped_ = false; - - /** - * Whether the default action has been prevented. - * This is a property to match the W3C specification at - * {@link http://www.w3.org/TR/DOM-Level-3-Events/ - * #events-event-type-defaultPrevented}. - * Must be treated as read-only outside the class. - * @type {boolean} - */ - this.defaultPrevented = false; - - /** - * Return value for in internal capture/bubble processing for IE. - * @type {boolean} - * @public - * @suppress {underscore|visibility} Technically public, but referencing this - * outside this package is strongly discouraged. - */ - this.returnValue_ = true; +ol.RotationConstraint.disable = function(rotation, delta) { + if (rotation !== undefined) { + return 0; + } else { + return undefined; + } }; /** - * Stops event propagation. + * @param {number|undefined} rotation Rotation. + * @param {number} delta Delta. + * @return {number|undefined} Rotation. */ -goog.events.Event.prototype.stopPropagation = function() { - this.propagationStopped_ = true; +ol.RotationConstraint.none = function(rotation, delta) { + if (rotation !== undefined) { + return rotation + delta; + } else { + return undefined; + } }; /** - * Prevents the default action, for example a link redirecting to a url. + * @param {number} n N. + * @return {ol.RotationConstraintType} Rotation constraint. */ -goog.events.Event.prototype.preventDefault = function() { - this.defaultPrevented = true; - this.returnValue_ = false; +ol.RotationConstraint.createSnapToN = function(n) { + var theta = 2 * Math.PI / n; + return ( + /** + * @param {number|undefined} rotation Rotation. + * @param {number} delta Delta. + * @return {number|undefined} Rotation. + */ + function(rotation, delta) { + if (rotation !== undefined) { + rotation = Math.floor((rotation + delta) / theta + 0.5) * theta; + return rotation; + } else { + return undefined; + } + }); }; /** - * Stops the propagation of the event. It is equivalent to - * {@code e.stopPropagation()}, but can be used as the callback argument of - * {@link goog.events.listen} without declaring another function. - * @param {!goog.events.Event} e An event. + * @param {number=} opt_tolerance Tolerance. + * @return {ol.RotationConstraintType} Rotation constraint. */ -goog.events.Event.stopPropagation = function(e) { - e.stopPropagation(); +ol.RotationConstraint.createSnapToZero = function(opt_tolerance) { + var tolerance = opt_tolerance || ol.math.toRadians(5); + return ( + /** + * @param {number|undefined} rotation Rotation. + * @param {number} delta Delta. + * @return {number|undefined} Rotation. + */ + function(rotation, delta) { + if (rotation !== undefined) { + if (Math.abs(rotation + delta) <= tolerance) { + return 0; + } else { + return rotation + delta; + } + } else { + return undefined; + } + }); }; +goog.provide('ol.string'); /** - * Prevents the default action. It is equivalent to - * {@code e.preventDefault()}, but can be used as the callback argument of - * {@link goog.events.listen} without declaring another function. - * @param {!goog.events.Event} e An event. - */ -goog.events.Event.preventDefault = function(e) { - e.preventDefault(); + * @param {number} number Number to be formatted + * @param {number} width The desired width + * @param {number=} opt_precision Precision of the output string (i.e. number of decimal places) + * @returns {string} Formatted string +*/ +ol.string.padNumber = function(number, width, opt_precision) { + var numberString = opt_precision !== undefined ? number.toFixed(opt_precision) : '' + number; + var decimal = numberString.indexOf('.'); + decimal = decimal === -1 ? numberString.length : decimal; + return decimal > width ? numberString : new Array(1 + width - decimal).join('0') + numberString; }; -// Copyright 2010 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - /** - * @fileoverview Event Types. - * - * @author arv@google.com (Erik Arvidsson) + * Adapted from https://github.com/omichelsen/compare-versions/blob/master/index.js + * @param {string|number} v1 First version + * @param {string|number} v2 Second version + * @returns {number} Value */ +ol.string.compareVersions = function(v1, v2) { + var s1 = ('' + v1).split('.'); + var s2 = ('' + v2).split('.'); + for (var i = 0; i < Math.max(s1.length, s2.length); i++) { + var n1 = parseInt(s1[i] || '0', 10); + var n2 = parseInt(s2[i] || '0', 10); -goog.provide('goog.events.EventType'); - -goog.require('goog.userAgent'); - + if (n1 > n2) return 1; + if (n2 > n1) return -1; + } -/** - * Returns a prefixed event name for the current browser. - * @param {string} eventName The name of the event. - * @return {string} The prefixed event name. - * @suppress {missingRequire|missingProvide} - * @private - */ -goog.events.getVendorPrefixedName_ = function(eventName) { - return goog.userAgent.WEBKIT ? 'webkit' + eventName : - (goog.userAgent.OPERA ? 'o' + eventName.toLowerCase() : - eventName.toLowerCase()); + return 0; }; +goog.provide('ol.coordinate'); -/** - * Constants for event names. - * @enum {string} - */ -goog.events.EventType = { - // Mouse events - CLICK: 'click', - RIGHTCLICK: 'rightclick', - DBLCLICK: 'dblclick', - MOUSEDOWN: 'mousedown', - MOUSEUP: 'mouseup', - MOUSEOVER: 'mouseover', - MOUSEOUT: 'mouseout', - MOUSEMOVE: 'mousemove', - MOUSEENTER: 'mouseenter', - MOUSELEAVE: 'mouseleave', - // Select start is non-standard. - // See http://msdn.microsoft.com/en-us/library/ie/ms536969(v=vs.85).aspx. - SELECTSTART: 'selectstart', // IE, Safari, Chrome - - // Wheel events - // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents - WHEEL: 'wheel', - - // Key events - KEYPRESS: 'keypress', - KEYDOWN: 'keydown', - KEYUP: 'keyup', - - // Focus - BLUR: 'blur', - FOCUS: 'focus', - DEACTIVATE: 'deactivate', // IE only - // NOTE: The following two events are not stable in cross-browser usage. - // WebKit and Opera implement DOMFocusIn/Out. - // IE implements focusin/out. - // Gecko implements neither see bug at - // https://bugzilla.mozilla.org/show_bug.cgi?id=396927. - // The DOM Events Level 3 Draft deprecates DOMFocusIn in favor of focusin: - // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html - // You can use FOCUS in Capture phase until implementations converge. - FOCUSIN: goog.userAgent.IE ? 'focusin' : 'DOMFocusIn', - FOCUSOUT: goog.userAgent.IE ? 'focusout' : 'DOMFocusOut', - - // Forms - CHANGE: 'change', - RESET: 'reset', - SELECT: 'select', - SUBMIT: 'submit', - INPUT: 'input', - PROPERTYCHANGE: 'propertychange', // IE only - - // Drag and drop - DRAGSTART: 'dragstart', - DRAG: 'drag', - DRAGENTER: 'dragenter', - DRAGOVER: 'dragover', - DRAGLEAVE: 'dragleave', - DROP: 'drop', - DRAGEND: 'dragend', - - // Touch events - // Note that other touch events exist, but we should follow the W3C list here. - // http://www.w3.org/TR/touch-events/#list-of-touchevent-types - TOUCHSTART: 'touchstart', - TOUCHMOVE: 'touchmove', - TOUCHEND: 'touchend', - TOUCHCANCEL: 'touchcancel', - - // Misc - BEFOREUNLOAD: 'beforeunload', - CONSOLEMESSAGE: 'consolemessage', - CONTEXTMENU: 'contextmenu', - DOMCONTENTLOADED: 'DOMContentLoaded', - ERROR: 'error', - HELP: 'help', - LOAD: 'load', - LOSECAPTURE: 'losecapture', - ORIENTATIONCHANGE: 'orientationchange', - READYSTATECHANGE: 'readystatechange', - RESIZE: 'resize', - SCROLL: 'scroll', - UNLOAD: 'unload', - - // HTML 5 History events - // See http://www.w3.org/TR/html5/browsers.html#event-definitions-0 - HASHCHANGE: 'hashchange', - PAGEHIDE: 'pagehide', - PAGESHOW: 'pageshow', - POPSTATE: 'popstate', - - // Copy and Paste - // Support is limited. Make sure it works on your favorite browser - // before using. - // http://www.quirksmode.org/dom/events/cutcopypaste.html - COPY: 'copy', - PASTE: 'paste', - CUT: 'cut', - BEFORECOPY: 'beforecopy', - BEFORECUT: 'beforecut', - BEFOREPASTE: 'beforepaste', - - // HTML5 online/offline events. - // http://www.w3.org/TR/offline-webapps/#related - ONLINE: 'online', - OFFLINE: 'offline', - - // HTML 5 worker events - MESSAGE: 'message', - CONNECT: 'connect', - - // CSS animation events. - /** @suppress {missingRequire} */ - ANIMATIONSTART: goog.events.getVendorPrefixedName_('AnimationStart'), - /** @suppress {missingRequire} */ - ANIMATIONEND: goog.events.getVendorPrefixedName_('AnimationEnd'), - /** @suppress {missingRequire} */ - ANIMATIONITERATION: goog.events.getVendorPrefixedName_('AnimationIteration'), - - // CSS transition events. Based on the browser support described at: - // https://developer.mozilla.org/en/css/css_transitions#Browser_compatibility - /** @suppress {missingRequire} */ - TRANSITIONEND: goog.events.getVendorPrefixedName_('TransitionEnd'), - - // W3C Pointer Events - // http://www.w3.org/TR/pointerevents/ - POINTERDOWN: 'pointerdown', - POINTERUP: 'pointerup', - POINTERCANCEL: 'pointercancel', - POINTERMOVE: 'pointermove', - POINTEROVER: 'pointerover', - POINTEROUT: 'pointerout', - POINTERENTER: 'pointerenter', - POINTERLEAVE: 'pointerleave', - GOTPOINTERCAPTURE: 'gotpointercapture', - LOSTPOINTERCAPTURE: 'lostpointercapture', - - // IE specific events. - // See http://msdn.microsoft.com/en-us/library/ie/hh772103(v=vs.85).aspx - // Note: these events will be supplanted in IE11. - MSGESTURECHANGE: 'MSGestureChange', - MSGESTUREEND: 'MSGestureEnd', - MSGESTUREHOLD: 'MSGestureHold', - MSGESTURESTART: 'MSGestureStart', - MSGESTURETAP: 'MSGestureTap', - MSGOTPOINTERCAPTURE: 'MSGotPointerCapture', - MSINERTIASTART: 'MSInertiaStart', - MSLOSTPOINTERCAPTURE: 'MSLostPointerCapture', - MSPOINTERCANCEL: 'MSPointerCancel', - MSPOINTERDOWN: 'MSPointerDown', - MSPOINTERENTER: 'MSPointerEnter', - MSPOINTERHOVER: 'MSPointerHover', - MSPOINTERLEAVE: 'MSPointerLeave', - MSPOINTERMOVE: 'MSPointerMove', - MSPOINTEROUT: 'MSPointerOut', - MSPOINTEROVER: 'MSPointerOver', - MSPOINTERUP: 'MSPointerUp', - - // Native IMEs/input tools events. - TEXT: 'text', - TEXTINPUT: 'textInput', - COMPOSITIONSTART: 'compositionstart', - COMPOSITIONUPDATE: 'compositionupdate', - COMPOSITIONEND: 'compositionend', - - // Webview tag events - // See http://developer.chrome.com/dev/apps/webview_tag.html - EXIT: 'exit', - LOADABORT: 'loadabort', - LOADCOMMIT: 'loadcommit', - LOADREDIRECT: 'loadredirect', - LOADSTART: 'loadstart', - LOADSTOP: 'loadstop', - RESPONSIVE: 'responsive', - SIZECHANGED: 'sizechanged', - UNRESPONSIVE: 'unresponsive', - - // HTML5 Page Visibility API. See details at - // {@code goog.labs.dom.PageVisibilityMonitor}. - VISIBILITYCHANGE: 'visibilitychange', - - // LocalStorage event. - STORAGE: 'storage', - - // DOM Level 2 mutation events (deprecated). - DOMSUBTREEMODIFIED: 'DOMSubtreeModified', - DOMNODEINSERTED: 'DOMNodeInserted', - DOMNODEREMOVED: 'DOMNodeRemoved', - DOMNODEREMOVEDFROMDOCUMENT: 'DOMNodeRemovedFromDocument', - DOMNODEINSERTEDINTODOCUMENT: 'DOMNodeInsertedIntoDocument', - DOMATTRMODIFIED: 'DOMAttrModified', - DOMCHARACTERDATAMODIFIED: 'DOMCharacterDataModified', - - // Print events. - BEFOREPRINT: 'beforeprint', - AFTERPRINT: 'afterprint' -}; +goog.require('ol.math'); +goog.require('ol.string'); -// Copyright 2009 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. /** - * @fileoverview Useful compiler idioms. + * Add `delta` to `coordinate`. `coordinate` is modified in place and returned + * by the function. * - * @author johnlenz@google.com (John Lenz) - */ - -goog.provide('goog.reflect'); - - -/** - * Syntax for object literal casts. - * @see http://go/jscompiler-renaming - * @see https://github.com/google/closure-compiler/wiki/Type-Based-Property-Renaming + * Example: * - * Use this if you have an object literal whose keys need to have the same names - * as the properties of some class even after they are renamed by the compiler. + * var coord = [7.85, 47.983333]; + * ol.coordinate.add(coord, [-2, 4]); + * // coord is now [5.85, 51.983333] * - * @param {!Function} type Type to cast to. - * @param {Object} object Object literal to cast. - * @return {Object} The object literal. - */ -goog.reflect.object = function(type, object) { - return object; -}; - - -/** - * To assert to the compiler that an operation is needed when it would - * otherwise be stripped. For example: - * <code> - * // Force a layout - * goog.reflect.sinkValue(dialog.offsetHeight); - * </code> - * @type {!Function} - */ -goog.reflect.sinkValue = function(x) { - goog.reflect.sinkValue[' '](x); - return x; -}; - - -/** - * The compiler should optimize this function away iff no one ever uses - * goog.reflect.sinkValue. - */ -goog.reflect.sinkValue[' '] = goog.nullFunction; - - -/** - * Check if a property can be accessed without throwing an exception. - * @param {Object} obj The owner of the property. - * @param {string} prop The property name. - * @return {boolean} Whether the property is accessible. Will also return true - * if obj is null. + * @param {ol.Coordinate} coordinate Coordinate. + * @param {ol.Coordinate} delta Delta. + * @return {ol.Coordinate} The input coordinate adjusted by the given delta. + * @api stable */ -goog.reflect.canAccessProperty = function(obj, prop) { - /** @preserveTry */ - try { - goog.reflect.sinkValue(obj[prop]); - return true; - } catch (e) {} - return false; +ol.coordinate.add = function(coordinate, delta) { + coordinate[0] += delta[0]; + coordinate[1] += delta[1]; + return coordinate; }; -// Copyright 2005 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. /** - * @fileoverview A patched, standardized event object for browser events. - * - * <pre> - * The patched event object contains the following members: - * - type {string} Event type, e.g. 'click' - * - target {Object} The element that actually triggered the event - * - currentTarget {Object} The element the listener is attached to - * - relatedTarget {Object} For mouseover and mouseout, the previous object - * - offsetX {number} X-coordinate relative to target - * - offsetY {number} Y-coordinate relative to target - * - clientX {number} X-coordinate relative to viewport - * - clientY {number} Y-coordinate relative to viewport - * - screenX {number} X-coordinate relative to the edge of the screen - * - screenY {number} Y-coordinate relative to the edge of the screen - * - button {number} Mouse button. Use isButton() to test. - * - keyCode {number} Key-code - * - ctrlKey {boolean} Was ctrl key depressed - * - altKey {boolean} Was alt key depressed - * - shiftKey {boolean} Was shift key depressed - * - metaKey {boolean} Was meta key depressed - * - defaultPrevented {boolean} Whether the default action has been prevented - * - state {Object} History state object - * - * NOTE: The keyCode member contains the raw browser keyCode. For normalized - * key and character code use {@link goog.events.KeyHandler}. - * </pre> + * Calculates the point closest to the passed coordinate on the passed segment. + * This is the foot of the perpendicular of the coordinate to the segment when + * the foot is on the segment, or the closest segment coordinate when the foot + * is outside the segment. * - * @author arv@google.com (Erik Arvidsson) - */ - -goog.provide('goog.events.BrowserEvent'); -goog.provide('goog.events.BrowserEvent.MouseButton'); - -goog.require('goog.events.BrowserFeature'); -goog.require('goog.events.Event'); -goog.require('goog.events.EventType'); -goog.require('goog.reflect'); -goog.require('goog.userAgent'); - - - -/** - * Accepts a browser event object and creates a patched, cross browser event - * object. - * The content of this object will not be initialized if no event object is - * provided. If this is the case, init() needs to be invoked separately. - * @param {Event=} opt_e Browser event object. - * @param {EventTarget=} opt_currentTarget Current target for event. - * @constructor - * @extends {goog.events.Event} + * @param {ol.Coordinate} coordinate The coordinate. + * @param {Array.<ol.Coordinate>} segment The two coordinates of the segment. + * @return {ol.Coordinate} The foot of the perpendicular of the coordinate to + * the segment. */ -goog.events.BrowserEvent = function(opt_e, opt_currentTarget) { - goog.events.BrowserEvent.base(this, 'constructor', opt_e ? opt_e.type : ''); - - /** - * Target that fired the event. - * @override - * @type {Node} - */ - this.target = null; - - /** - * Node that had the listener attached. - * @override - * @type {Node|undefined} - */ - this.currentTarget = null; - - /** - * For mouseover and mouseout events, the related object for the event. - * @type {Node} - */ - this.relatedTarget = null; - - /** - * X-coordinate relative to target. - * @type {number} - */ - this.offsetX = 0; - - /** - * Y-coordinate relative to target. - * @type {number} - */ - this.offsetY = 0; - - /** - * X-coordinate relative to the window. - * @type {number} - */ - this.clientX = 0; - - /** - * Y-coordinate relative to the window. - * @type {number} - */ - this.clientY = 0; - - /** - * X-coordinate relative to the monitor. - * @type {number} - */ - this.screenX = 0; - - /** - * Y-coordinate relative to the monitor. - * @type {number} - */ - this.screenY = 0; - - /** - * Which mouse button was pressed. - * @type {number} - */ - this.button = 0; - - /** - * Keycode of key press. - * @type {number} - */ - this.keyCode = 0; - - /** - * Keycode of key press. - * @type {number} - */ - this.charCode = 0; - - /** - * Whether control was pressed at time of event. - * @type {boolean} - */ - this.ctrlKey = false; - - /** - * Whether alt was pressed at time of event. - * @type {boolean} - */ - this.altKey = false; - - /** - * Whether shift was pressed at time of event. - * @type {boolean} - */ - this.shiftKey = false; - - /** - * Whether the meta key was pressed at time of event. - * @type {boolean} - */ - this.metaKey = false; - - /** - * History state object, only set for PopState events where it's a copy of the - * state object provided to pushState or replaceState. - * @type {Object} - */ - this.state = null; - - /** - * Whether the default platform modifier key was pressed at time of event. - * (This is control for all platforms except Mac, where it's Meta.) - * @type {boolean} - */ - this.platformModifierKey = false; - - /** - * The browser event object. - * @private {Event} - */ - this.event_ = null; - - if (opt_e) { - this.init(opt_e, opt_currentTarget); +ol.coordinate.closestOnSegment = function(coordinate, segment) { + var x0 = coordinate[0]; + var y0 = coordinate[1]; + var start = segment[0]; + var end = segment[1]; + var x1 = start[0]; + var y1 = start[1]; + var x2 = end[0]; + var y2 = end[1]; + var dx = x2 - x1; + var dy = y2 - y1; + var along = (dx === 0 && dy === 0) ? 0 : + ((dx * (x0 - x1)) + (dy * (y0 - y1))) / ((dx * dx + dy * dy) || 0); + var x, y; + if (along <= 0) { + x = x1; + y = y1; + } else if (along >= 1) { + x = x2; + y = y2; + } else { + x = x1 + along * dx; + y = y1 + along * dy; } + return [x, y]; }; -goog.inherits(goog.events.BrowserEvent, goog.events.Event); /** - * Normalized button constants for the mouse. - * @enum {number} + * Returns a {@link ol.CoordinateFormatType} function that can be used to format + * a {ol.Coordinate} to a string. + * + * Example without specifying the fractional digits: + * + * var coord = [7.85, 47.983333]; + * var stringifyFunc = ol.coordinate.createStringXY(); + * var out = stringifyFunc(coord); + * // out is now '8, 48' + * + * Example with explicitly specifying 2 fractional digits: + * + * var coord = [7.85, 47.983333]; + * var stringifyFunc = ol.coordinate.createStringXY(2); + * var out = stringifyFunc(coord); + * // out is now '7.85, 47.98' + * + * @param {number=} opt_fractionDigits The number of digits to include + * after the decimal point. Default is `0`. + * @return {ol.CoordinateFormatType} Coordinate format. + * @api stable */ -goog.events.BrowserEvent.MouseButton = { - LEFT: 0, - MIDDLE: 1, - RIGHT: 2 +ol.coordinate.createStringXY = function(opt_fractionDigits) { + return ( + /** + * @param {ol.Coordinate|undefined} coordinate Coordinate. + * @return {string} String XY. + */ + function(coordinate) { + return ol.coordinate.toStringXY(coordinate, opt_fractionDigits); + }); }; /** - * Static data for mapping mouse buttons. - * @type {!Array<number>} - */ -goog.events.BrowserEvent.IEButtonMap = [ - 1, // LEFT - 4, // MIDDLE - 2 // RIGHT -]; - - -/** - * Accepts a browser event object and creates a patched, cross browser event - * object. - * @param {Event} e Browser event object. - * @param {EventTarget=} opt_currentTarget Current target for event. + * @private + * @param {number} degrees Degrees. + * @param {string} hemispheres Hemispheres. + * @param {number=} opt_fractionDigits The number of digits to include + * after the decimal point. Default is `0`. + * @return {string} String. */ -goog.events.BrowserEvent.prototype.init = function(e, opt_currentTarget) { - var type = this.type = e.type; - - /** - * On touch devices use the first "changed touch" as the relevant touch. - * @type {Touch} - */ - var relevantTouch = e.changedTouches ? e.changedTouches[0] : null; - - // TODO(nicksantos): Change this.target to type EventTarget. - this.target = /** @type {Node} */ (e.target) || e.srcElement; - - // TODO(nicksantos): Change this.currentTarget to type EventTarget. - this.currentTarget = /** @type {Node} */ (opt_currentTarget); - - var relatedTarget = /** @type {Node} */ (e.relatedTarget); - if (relatedTarget) { - // There's a bug in FireFox where sometimes, relatedTarget will be a - // chrome element, and accessing any property of it will get a permission - // denied exception. See: - // https://bugzilla.mozilla.org/show_bug.cgi?id=497780 - if (goog.userAgent.GECKO) { - if (!goog.reflect.canAccessProperty(relatedTarget, 'nodeName')) { - relatedTarget = null; - } - } - // TODO(arv): Use goog.events.EventType when it has been refactored into its - // own file. - } else if (type == goog.events.EventType.MOUSEOVER) { - relatedTarget = e.fromElement; - } else if (type == goog.events.EventType.MOUSEOUT) { - relatedTarget = e.toElement; - } - - this.relatedTarget = relatedTarget; - - if (!goog.isNull(relevantTouch)) { - this.clientX = relevantTouch.clientX !== undefined ? - relevantTouch.clientX : relevantTouch.pageX; - this.clientY = relevantTouch.clientY !== undefined ? - relevantTouch.clientY : relevantTouch.pageY; - this.screenX = relevantTouch.screenX || 0; - this.screenY = relevantTouch.screenY || 0; - } else { - // Webkit emits a lame warning whenever layerX/layerY is accessed. - // http://code.google.com/p/chromium/issues/detail?id=101733 - this.offsetX = (goog.userAgent.WEBKIT || e.offsetX !== undefined) ? - e.offsetX : e.layerX; - this.offsetY = (goog.userAgent.WEBKIT || e.offsetY !== undefined) ? - e.offsetY : e.layerY; - this.clientX = e.clientX !== undefined ? e.clientX : e.pageX; - this.clientY = e.clientY !== undefined ? e.clientY : e.pageY; - this.screenX = e.screenX || 0; - this.screenY = e.screenY || 0; - } - - this.button = e.button; - - this.keyCode = e.keyCode || 0; - this.charCode = e.charCode || (type == 'keypress' ? e.keyCode : 0); - this.ctrlKey = e.ctrlKey; - this.altKey = e.altKey; - this.shiftKey = e.shiftKey; - this.metaKey = e.metaKey; - this.platformModifierKey = goog.userAgent.MAC ? e.metaKey : e.ctrlKey; - this.state = e.state; - this.event_ = e; - if (e.defaultPrevented) { - this.preventDefault(); - } +ol.coordinate.degreesToStringHDMS_ = function(degrees, hemispheres, opt_fractionDigits) { + var normalizedDegrees = ol.math.modulo(degrees + 180, 360) - 180; + var x = Math.abs(3600 * normalizedDegrees); + var dflPrecision = opt_fractionDigits || 0; + return Math.floor(x / 3600) + '\u00b0 ' + + ol.string.padNumber(Math.floor((x / 60) % 60), 2) + '\u2032 ' + + ol.string.padNumber((x % 60), 2, dflPrecision) + '\u2033 ' + + hemispheres.charAt(normalizedDegrees < 0 ? 1 : 0); }; /** - * Tests to see which button was pressed during the event. This is really only - * useful in IE and Gecko browsers. And in IE, it's only useful for - * mousedown/mouseup events, because click only fires for the left mouse button. + * Transforms the given {@link ol.Coordinate} to a string using the given string + * template. The strings `{x}` and `{y}` in the template will be replaced with + * the first and second coordinate values respectively. * - * Safari 2 only reports the left button being clicked, and uses the value '1' - * instead of 0. Opera only reports a mousedown event for the middle button, and - * no mouse events for the right button. Opera has default behavior for left and - * middle click that can only be overridden via a configuration setting. + * Example without specifying the fractional digits: * - * There's a nice table of this mess at http://www.unixpapa.com/js/mouse.html. + * var coord = [7.85, 47.983333]; + * var template = 'Coordinate is ({x}|{y}).'; + * var out = ol.coordinate.format(coord, template); + * // out is now 'Coordinate is (8|48).' * - * @param {goog.events.BrowserEvent.MouseButton} button The button - * to test for. - * @return {boolean} True if button was pressed. - */ -goog.events.BrowserEvent.prototype.isButton = function(button) { - if (!goog.events.BrowserFeature.HAS_W3C_BUTTON) { - if (this.type == 'click') { - return button == goog.events.BrowserEvent.MouseButton.LEFT; - } else { - return !!(this.event_.button & - goog.events.BrowserEvent.IEButtonMap[button]); - } - } else { - return this.event_.button == button; - } -}; - - -/** - * Whether this has an "action"-producing mouse button. + * Example explicitly specifying the fractional digits: * - * By definition, this includes left-click on windows/linux, and left-click - * without the ctrl key on Macs. + * var coord = [7.85, 47.983333]; + * var template = 'Coordinate is ({x}|{y}).'; + * var out = ol.coordinate.format(coord, template, 2); + * // out is now 'Coordinate is (7.85|47.98).' * - * @return {boolean} The result. - */ -goog.events.BrowserEvent.prototype.isMouseActionButton = function() { - // Webkit does not ctrl+click to be a right-click, so we - // normalize it to behave like Gecko and Opera. - return this.isButton(goog.events.BrowserEvent.MouseButton.LEFT) && - !(goog.userAgent.WEBKIT && goog.userAgent.MAC && this.ctrlKey); -}; - - -/** - * @override + * @param {ol.Coordinate|undefined} coordinate Coordinate. + * @param {string} template A template string with `{x}` and `{y}` placeholders + * that will be replaced by first and second coordinate values. + * @param {number=} opt_fractionDigits The number of digits to include + * after the decimal point. Default is `0`. + * @return {string} Formatted coordinate. + * @api stable */ -goog.events.BrowserEvent.prototype.stopPropagation = function() { - goog.events.BrowserEvent.superClass_.stopPropagation.call(this); - if (this.event_.stopPropagation) { - this.event_.stopPropagation(); +ol.coordinate.format = function(coordinate, template, opt_fractionDigits) { + if (coordinate) { + return template + .replace('{x}', coordinate[0].toFixed(opt_fractionDigits)) + .replace('{y}', coordinate[1].toFixed(opt_fractionDigits)); } else { - this.event_.cancelBubble = true; + return ''; } }; /** - * @override + * @param {ol.Coordinate} coordinate1 First coordinate. + * @param {ol.Coordinate} coordinate2 Second coordinate. + * @return {boolean} Whether the passed coordinates are equal. */ -goog.events.BrowserEvent.prototype.preventDefault = function() { - goog.events.BrowserEvent.superClass_.preventDefault.call(this); - var be = this.event_; - if (!be.preventDefault) { - be.returnValue = false; - if (goog.events.BrowserFeature.SET_KEY_CODE_TO_PREVENT_DEFAULT) { - /** @preserveTry */ - try { - // Most keys can be prevented using returnValue. Some special keys - // require setting the keyCode to -1 as well: - // - // In IE7: - // F3, F5, F10, F11, Ctrl+P, Crtl+O, Ctrl+F (these are taken from IE6) - // - // In IE8: - // Ctrl+P, Crtl+O, Ctrl+F (F1-F12 cannot be stopped through the event) - // - // We therefore do this for all function keys as well as when Ctrl key - // is pressed. - var VK_F1 = 112; - var VK_F12 = 123; - if (be.ctrlKey || be.keyCode >= VK_F1 && be.keyCode <= VK_F12) { - be.keyCode = -1; - } - } catch (ex) { - // IE throws an 'access denied' exception when trying to change - // keyCode in some situations (e.g. srcElement is input[type=file], - // or srcElement is an anchor tag rewritten by parent's innerHTML). - // Do nothing in this case. - } +ol.coordinate.equals = function(coordinate1, coordinate2) { + var equals = true; + for (var i = coordinate1.length - 1; i >= 0; --i) { + if (coordinate1[i] != coordinate2[i]) { + equals = false; + break; } - } else { - be.preventDefault(); } + return equals; }; /** - * @return {Event} The underlying browser event object. - */ -goog.events.BrowserEvent.prototype.getBrowserEvent = function() { - return this.event_; -}; - -// Copyright 2012 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview An interface for a listenable JavaScript object. - * @author chrishenry@google.com (Chris Henry) - */ - -goog.provide('goog.events.Listenable'); -goog.provide('goog.events.ListenableKey'); - -/** @suppress {extraRequire} */ -goog.require('goog.events.EventId'); - - - -/** - * A listenable interface. A listenable is an object with the ability - * to dispatch/broadcast events to "event listeners" registered via - * listen/listenOnce. - * - * The interface allows for an event propagation mechanism similar - * to one offered by native browser event targets, such as - * capture/bubble mechanism, stopping propagation, and preventing - * default actions. Capture/bubble mechanism depends on the ancestor - * tree constructed via {@code #getParentEventTarget}; this tree - * must be directed acyclic graph. The meaning of default action(s) - * in preventDefault is specific to a particular use case. - * - * Implementations that do not support capture/bubble or can not have - * a parent listenable can simply not implement any ability to set the - * parent listenable (and have {@code #getParentEventTarget} return - * null). + * Rotate `coordinate` by `angle`. `coordinate` is modified in place and + * returned by the function. * - * Implementation of this class can be used with or independently from - * goog.events. + * Example: * - * Implementation must call {@code #addImplementation(implClass)}. + * var coord = [7.85, 47.983333]; + * var rotateRadians = Math.PI / 2; // 90 degrees + * ol.coordinate.rotate(coord, rotateRadians); + * // coord is now [-47.983333, 7.85] * - * @interface - * @see goog.events - * @see http://www.w3.org/TR/DOM-Level-2-Events/events.html + * @param {ol.Coordinate} coordinate Coordinate. + * @param {number} angle Angle in radian. + * @return {ol.Coordinate} Coordinate. + * @api stable */ -goog.events.Listenable = function() {}; +ol.coordinate.rotate = function(coordinate, angle) { + var cosAngle = Math.cos(angle); + var sinAngle = Math.sin(angle); + var x = coordinate[0] * cosAngle - coordinate[1] * sinAngle; + var y = coordinate[1] * cosAngle + coordinate[0] * sinAngle; + coordinate[0] = x; + coordinate[1] = y; + return coordinate; +}; /** - * An expando property to indicate that an object implements - * goog.events.Listenable. + * Scale `coordinate` by `scale`. `coordinate` is modified in place and returned + * by the function. * - * See addImplementation/isImplementedBy. + * Example: * - * @type {string} - * @const + * var coord = [7.85, 47.983333]; + * var scale = 1.2; + * ol.coordinate.scale(coord, scale); + * // coord is now [9.42, 57.5799996] + * + * @param {ol.Coordinate} coordinate Coordinate. + * @param {number} scale Scale factor. + * @return {ol.Coordinate} Coordinate. */ -goog.events.Listenable.IMPLEMENTED_BY_PROP = - 'closure_listenable_' + ((Math.random() * 1e6) | 0); +ol.coordinate.scale = function(coordinate, scale) { + coordinate[0] *= scale; + coordinate[1] *= scale; + return coordinate; +}; /** - * Marks a given class (constructor) as an implementation of - * Listenable, do that we can query that fact at runtime. The class - * must have already implemented the interface. - * @param {!Function} cls The class constructor. The corresponding - * class must have already implemented the interface. + * Subtract `delta` to `coordinate`. `coordinate` is modified in place and + * returned by the function. + * + * @param {ol.Coordinate} coordinate Coordinate. + * @param {ol.Coordinate} delta Delta. + * @return {ol.Coordinate} Coordinate. */ -goog.events.Listenable.addImplementation = function(cls) { - cls.prototype[goog.events.Listenable.IMPLEMENTED_BY_PROP] = true; +ol.coordinate.sub = function(coordinate, delta) { + coordinate[0] -= delta[0]; + coordinate[1] -= delta[1]; + return coordinate; }; /** - * @param {Object} obj The object to check. - * @return {boolean} Whether a given instance implements Listenable. The - * class/superclass of the instance must call addImplementation. + * @param {ol.Coordinate} coord1 First coordinate. + * @param {ol.Coordinate} coord2 Second coordinate. + * @return {number} Squared distance between coord1 and coord2. */ -goog.events.Listenable.isImplementedBy = function(obj) { - return !!(obj && obj[goog.events.Listenable.IMPLEMENTED_BY_PROP]); +ol.coordinate.squaredDistance = function(coord1, coord2) { + var dx = coord1[0] - coord2[0]; + var dy = coord1[1] - coord2[1]; + return dx * dx + dy * dy; }; /** - * Adds an event listener. A listener can only be added once to an - * object and if it is added again the key for the listener is - * returned. Note that if the existing listener is a one-off listener - * (registered via listenOnce), it will no longer be a one-off - * listener after a call to listen(). + * Calculate the squared distance from a coordinate to a line segment. * - * @param {string|!goog.events.EventId<EVENTOBJ>} type The event type id. - * @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener Callback - * method. - * @param {boolean=} opt_useCapture Whether to fire in capture phase - * (defaults to false). - * @param {SCOPE=} opt_listenerScope Object in whose scope to call the - * listener. - * @return {goog.events.ListenableKey} Unique key for the listener. - * @template SCOPE,EVENTOBJ + * @param {ol.Coordinate} coordinate Coordinate of the point. + * @param {Array.<ol.Coordinate>} segment Line segment (2 coordinates). + * @return {number} Squared distance from the point to the line segment. */ -goog.events.Listenable.prototype.listen; +ol.coordinate.squaredDistanceToSegment = function(coordinate, segment) { + return ol.coordinate.squaredDistance(coordinate, + ol.coordinate.closestOnSegment(coordinate, segment)); +}; /** - * Adds an event listener that is removed automatically after the - * listener fired once. + * Format a geographic coordinate with the hemisphere, degrees, minutes, and + * seconds. * - * If an existing listener already exists, listenOnce will do - * nothing. In particular, if the listener was previously registered - * via listen(), listenOnce() will not turn the listener into a - * one-off listener. Similarly, if there is already an existing - * one-off listener, listenOnce does not modify the listeners (it is - * still a once listener). + * Example without specifying fractional digits: * - * @param {string|!goog.events.EventId<EVENTOBJ>} type The event type id. - * @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener Callback - * method. - * @param {boolean=} opt_useCapture Whether to fire in capture phase - * (defaults to false). - * @param {SCOPE=} opt_listenerScope Object in whose scope to call the - * listener. - * @return {goog.events.ListenableKey} Unique key for the listener. - * @template SCOPE,EVENTOBJ - */ -goog.events.Listenable.prototype.listenOnce; - - -/** - * Removes an event listener which was added with listen() or listenOnce(). + * var coord = [7.85, 47.983333]; + * var out = ol.coordinate.toStringHDMS(coord); + * // out is now '47° 58′ 60″ N 7° 50′ 60″ E' * - * @param {string|!goog.events.EventId<EVENTOBJ>} type The event type id. - * @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener Callback - * method. - * @param {boolean=} opt_useCapture Whether to fire in capture phase - * (defaults to false). - * @param {SCOPE=} opt_listenerScope Object in whose scope to call - * the listener. - * @return {boolean} Whether any listener was removed. - * @template SCOPE,EVENTOBJ - */ -goog.events.Listenable.prototype.unlisten; - - -/** - * Removes an event listener which was added with listen() by the key - * returned by listen(). + * Example explicitly specifying 1 fractional digit: + * + * var coord = [7.85, 47.983333]; + * var out = ol.coordinate.toStringHDMS(coord, 1); + * // out is now '47° 58′ 60.0″ N 7° 50′ 60.0″ E' * - * @param {goog.events.ListenableKey} key The key returned by - * listen() or listenOnce(). - * @return {boolean} Whether any listener was removed. + * @param {ol.Coordinate|undefined} coordinate Coordinate. + * @param {number=} opt_fractionDigits The number of digits to include + * after the decimal point. Default is `0`. + * @return {string} Hemisphere, degrees, minutes and seconds. + * @api stable */ -goog.events.Listenable.prototype.unlistenByKey; +ol.coordinate.toStringHDMS = function(coordinate, opt_fractionDigits) { + if (coordinate) { + return ol.coordinate.degreesToStringHDMS_(coordinate[1], 'NS', opt_fractionDigits) + ' ' + + ol.coordinate.degreesToStringHDMS_(coordinate[0], 'EW', opt_fractionDigits); + } else { + return ''; + } +}; /** - * Dispatches an event (or event like object) and calls all listeners - * listening for events of this type. The type of the event is decided by the - * type property on the event object. + * Format a coordinate as a comma delimited string. * - * If any of the listeners returns false OR calls preventDefault then this - * function will return false. If one of the capture listeners calls - * stopPropagation, then the bubble listeners won't fire. + * Example without specifying fractional digits: * - * @param {goog.events.EventLike} e Event object. - * @return {boolean} If anyone called preventDefault on the event object (or - * if any of the listeners returns false) this will also return false. - */ -goog.events.Listenable.prototype.dispatchEvent; - - -/** - * Removes all listeners from this listenable. If type is specified, - * it will only remove listeners of the particular type. otherwise all - * registered listeners will be removed. + * var coord = [7.85, 47.983333]; + * var out = ol.coordinate.toStringXY(coord); + * // out is now '8, 48' * - * @param {string=} opt_type Type of event to remove, default is to - * remove all types. - * @return {number} Number of listeners removed. - */ -goog.events.Listenable.prototype.removeAllListeners; - - -/** - * Returns the parent of this event target to use for capture/bubble - * mechanism. + * Example explicitly specifying 1 fractional digit: * - * NOTE(chrishenry): The name reflects the original implementation of - * custom event target ({@code goog.events.EventTarget}). We decided - * that changing the name is not worth it. + * var coord = [7.85, 47.983333]; + * var out = ol.coordinate.toStringXY(coord, 1); + * // out is now '7.8, 48.0' * - * @return {goog.events.Listenable} The parent EventTarget or null if - * there is no parent. + * @param {ol.Coordinate|undefined} coordinate Coordinate. + * @param {number=} opt_fractionDigits The number of digits to include + * after the decimal point. Default is `0`. + * @return {string} XY. + * @api stable */ -goog.events.Listenable.prototype.getParentEventTarget; +ol.coordinate.toStringXY = function(coordinate, opt_fractionDigits) { + return ol.coordinate.format(coordinate, '{x}, {y}', opt_fractionDigits); +}; /** - * Fires all registered listeners in this listenable for the given - * type and capture mode, passing them the given eventObject. This - * does not perform actual capture/bubble. Only implementors of the - * interface should be using this. + * Create an ol.Coordinate from an Array and take into account axis order. * - * @param {string|!goog.events.EventId<EVENTOBJ>} type The type of the - * listeners to fire. - * @param {boolean} capture The capture mode of the listeners to fire. - * @param {EVENTOBJ} eventObject The event object to fire. - * @return {boolean} Whether all listeners succeeded without - * attempting to prevent default behavior. If any listener returns - * false or called goog.events.Event#preventDefault, this returns - * false. - * @template EVENTOBJ - */ -goog.events.Listenable.prototype.fireListeners; - - -/** - * Gets all listeners in this listenable for the given type and - * capture mode. + * Examples: * - * @param {string|!goog.events.EventId} type The type of the listeners to fire. - * @param {boolean} capture The capture mode of the listeners to fire. - * @return {!Array<goog.events.ListenableKey>} An array of registered - * listeners. - * @template EVENTOBJ - */ -goog.events.Listenable.prototype.getListeners; - - -/** - * Gets the goog.events.ListenableKey for the event or null if no such - * listener is in use. + * var northCoord = ol.coordinate.fromProjectedArray([1, 2], 'n'); + * // northCoord is now [2, 1] * - * @param {string|!goog.events.EventId<EVENTOBJ>} type The name of the event - * without the 'on' prefix. - * @param {function(this:SCOPE, EVENTOBJ):(boolean|undefined)} listener The - * listener function to get. - * @param {boolean} capture Whether the listener is a capturing listener. - * @param {SCOPE=} opt_listenerScope Object in whose scope to call the - * listener. - * @return {goog.events.ListenableKey} the found listener or null if not found. - * @template SCOPE,EVENTOBJ - */ -goog.events.Listenable.prototype.getListener; - - -/** - * Whether there is any active listeners matching the specified - * signature. If either the type or capture parameters are - * unspecified, the function will match on the remaining criteria. + * var eastCoord = ol.coordinate.fromProjectedArray([1, 2], 'e'); + * // eastCoord is now [1, 2] * - * @param {string|!goog.events.EventId<EVENTOBJ>=} opt_type Event type. - * @param {boolean=} opt_capture Whether to check for capture or bubble - * listeners. - * @return {boolean} Whether there is any active listeners matching - * the requested type and/or capture phase. - * @template EVENTOBJ - */ -goog.events.Listenable.prototype.hasListener; - - - -/** - * An interface that describes a single registered listener. - * @interface - */ -goog.events.ListenableKey = function() {}; - - -/** - * Counter used to create a unique key - * @type {number} - * @private - */ -goog.events.ListenableKey.counter_ = 0; - - -/** - * Reserves a key to be used for ListenableKey#key field. - * @return {number} A number to be used to fill ListenableKey#key - * field. - */ -goog.events.ListenableKey.reserveKey = function() { - return ++goog.events.ListenableKey.counter_; -}; - - -/** - * The source event target. - * @type {!(Object|goog.events.Listenable|goog.events.EventTarget)} - */ -goog.events.ListenableKey.prototype.src; - - -/** - * The event type the listener is listening to. - * @type {string} - */ -goog.events.ListenableKey.prototype.type; - - -/** - * The listener function. - * @type {function(?):?|{handleEvent:function(?):?}|null} - */ -goog.events.ListenableKey.prototype.listener; - - -/** - * Whether the listener works on capture phase. - * @type {boolean} - */ -goog.events.ListenableKey.prototype.capture; - - -/** - * The 'this' object for the listener function's scope. - * @type {Object} - */ -goog.events.ListenableKey.prototype.handler; - - -/** - * A globally unique number to identify the key. - * @type {number} - */ -goog.events.ListenableKey.prototype.key; - -// Copyright 2005 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Listener object. - * @see ../demos/events.html - */ - -goog.provide('goog.events.Listener'); - -goog.require('goog.events.ListenableKey'); - - - -/** - * Simple class that stores information about a listener - * @param {!Function} listener Callback function. - * @param {Function} proxy Wrapper for the listener that patches the event. - * @param {EventTarget|goog.events.Listenable} src Source object for - * the event. - * @param {string} type Event type. - * @param {boolean} capture Whether in capture or bubble phase. - * @param {Object=} opt_handler Object in whose context to execute the callback. - * @implements {goog.events.ListenableKey} - * @constructor + * @param {Array} array The array with coordinates. + * @param {string} axis the axis info. + * @return {ol.Coordinate} The coordinate created. */ -goog.events.Listener = function( - listener, proxy, src, type, capture, opt_handler) { - if (goog.events.Listener.ENABLE_MONITORING) { - this.creationStack = new Error().stack; +ol.coordinate.fromProjectedArray = function(array, axis) { + var firstAxis = axis.charAt(0); + if (firstAxis === 'n' || firstAxis === 's') { + return [array[1], array[0]]; + } else { + return array; } - - /** - * Callback function. - * @type {Function} - */ - this.listener = listener; - - /** - * A wrapper over the original listener. This is used solely to - * handle native browser events (it is used to simulate the capture - * phase and to patch the event object). - * @type {Function} - */ - this.proxy = proxy; - - /** - * Object or node that callback is listening to - * @type {EventTarget|goog.events.Listenable} - */ - this.src = src; - - /** - * The event type. - * @const {string} - */ - this.type = type; - - /** - * Whether the listener is being called in the capture or bubble phase - * @const {boolean} - */ - this.capture = !!capture; - - /** - * Optional object whose context to execute the listener in - * @type {Object|undefined} - */ - this.handler = opt_handler; - - /** - * The key of the listener. - * @const {number} - * @override - */ - this.key = goog.events.ListenableKey.reserveKey(); - - /** - * Whether to remove the listener after it has been called. - * @type {boolean} - */ - this.callOnce = false; - - /** - * Whether the listener has been removed. - * @type {boolean} - */ - this.removed = false; }; +goog.provide('ol.extent'); +goog.provide('ol.extent.Corner'); +goog.provide('ol.extent.Relationship'); -/** - * @define {boolean} Whether to enable the monitoring of the - * goog.events.Listener instances. Switching on the monitoring is only - * recommended for debugging because it has a significant impact on - * performance and memory usage. If switched off, the monitoring code - * compiles down to 0 bytes. - */ -goog.define('goog.events.Listener.ENABLE_MONITORING', false); +goog.require('goog.asserts'); /** - * If monitoring the goog.events.Listener instances is enabled, stores the - * creation stack trace of the Disposable instance. - * @type {string} + * Extent corner. + * @enum {string} */ -goog.events.Listener.prototype.creationStack; +ol.extent.Corner = { + BOTTOM_LEFT: 'bottom-left', + BOTTOM_RIGHT: 'bottom-right', + TOP_LEFT: 'top-left', + TOP_RIGHT: 'top-right' +}; /** - * Marks this listener as removed. This also remove references held by - * this listener object (such as listener and event source). + * Relationship to an extent. + * @enum {number} */ -goog.events.Listener.prototype.markAsRemoved = function() { - this.removed = true; - this.listener = null; - this.proxy = null; - this.src = null; - this.handler = null; +ol.extent.Relationship = { + UNKNOWN: 0, + INTERSECTING: 1, + ABOVE: 2, + RIGHT: 4, + BELOW: 8, + LEFT: 16 }; -// Copyright 2013 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. /** - * @fileoverview A map of listeners that provides utility functions to - * deal with listeners on an event target. Used by - * {@code goog.events.EventTarget}. - * - * WARNING: Do not use this class from outside goog.events package. + * Build an extent that includes all given coordinates. * - * @visibility {//closure/goog/bin/sizetests:__pkg__} - * @visibility {//closure/goog/events:__pkg__} - * @visibility {//closure/goog/labs/events:__pkg__} - */ - -goog.provide('goog.events.ListenerMap'); - -goog.require('goog.array'); -goog.require('goog.events.Listener'); -goog.require('goog.object'); - - - -/** - * Creates a new listener map. - * @param {EventTarget|goog.events.Listenable} src The src object. - * @constructor - * @final + * @param {Array.<ol.Coordinate>} coordinates Coordinates. + * @return {ol.Extent} Bounding extent. + * @api stable */ -goog.events.ListenerMap = function(src) { - /** @type {EventTarget|goog.events.Listenable} */ - this.src = src; - - /** - * Maps of event type to an array of listeners. - * @type {Object<string, !Array<!goog.events.Listener>>} - */ - this.listeners = {}; - - /** - * The count of types in this map that have registered listeners. - * @private {number} - */ - this.typeCount_ = 0; +ol.extent.boundingExtent = function(coordinates) { + var extent = ol.extent.createEmpty(); + for (var i = 0, ii = coordinates.length; i < ii; ++i) { + ol.extent.extendCoordinate(extent, coordinates[i]); + } + return extent; }; /** - * @return {number} The count of event types in this map that actually - * have registered listeners. + * @param {Array.<number>} xs Xs. + * @param {Array.<number>} ys Ys. + * @param {ol.Extent=} opt_extent Destination extent. + * @private + * @return {ol.Extent} Extent. */ -goog.events.ListenerMap.prototype.getTypeCount = function() { - return this.typeCount_; +ol.extent.boundingExtentXYs_ = function(xs, ys, opt_extent) { + goog.asserts.assert(xs.length > 0, 'xs length should be larger than 0'); + goog.asserts.assert(ys.length > 0, 'ys length should be larger than 0'); + var minX = Math.min.apply(null, xs); + var minY = Math.min.apply(null, ys); + var maxX = Math.max.apply(null, xs); + var maxY = Math.max.apply(null, ys); + return ol.extent.createOrUpdate(minX, minY, maxX, maxY, opt_extent); }; /** - * @return {number} Total number of registered listeners. + * Return extent increased by the provided value. + * @param {ol.Extent} extent Extent. + * @param {number} value The amount by which the extent should be buffered. + * @param {ol.Extent=} opt_extent Extent. + * @return {ol.Extent} Extent. + * @api stable */ -goog.events.ListenerMap.prototype.getListenerCount = function() { - var count = 0; - for (var type in this.listeners) { - count += this.listeners[type].length; +ol.extent.buffer = function(extent, value, opt_extent) { + if (opt_extent) { + opt_extent[0] = extent[0] - value; + opt_extent[1] = extent[1] - value; + opt_extent[2] = extent[2] + value; + opt_extent[3] = extent[3] + value; + return opt_extent; + } else { + return [ + extent[0] - value, + extent[1] - value, + extent[2] + value, + extent[3] + value + ]; } - return count; }; /** - * Adds an event listener. A listener can only be added once to an - * object and if it is added again the key for the listener is - * returned. - * - * Note that a one-off listener will not change an existing listener, - * if any. On the other hand a normal listener will change existing - * one-off listener to become a normal listener. + * Creates a clone of an extent. * - * @param {string|!goog.events.EventId} type The listener event type. - * @param {!Function} listener This listener callback method. - * @param {boolean} callOnce Whether the listener is a one-off - * listener. - * @param {boolean=} opt_useCapture The capture mode of the listener. - * @param {Object=} opt_listenerScope Object in whose scope to call the - * listener. - * @return {goog.events.ListenableKey} Unique key for the listener. + * @param {ol.Extent} extent Extent to clone. + * @param {ol.Extent=} opt_extent Extent. + * @return {ol.Extent} The clone. */ -goog.events.ListenerMap.prototype.add = function( - type, listener, callOnce, opt_useCapture, opt_listenerScope) { - var typeStr = type.toString(); - var listenerArray = this.listeners[typeStr]; - if (!listenerArray) { - listenerArray = this.listeners[typeStr] = []; - this.typeCount_++; - } - - var listenerObj; - var index = goog.events.ListenerMap.findListenerIndex_( - listenerArray, listener, opt_useCapture, opt_listenerScope); - if (index > -1) { - listenerObj = listenerArray[index]; - if (!callOnce) { - // Ensure that, if there is an existing callOnce listener, it is no - // longer a callOnce listener. - listenerObj.callOnce = false; - } +ol.extent.clone = function(extent, opt_extent) { + if (opt_extent) { + opt_extent[0] = extent[0]; + opt_extent[1] = extent[1]; + opt_extent[2] = extent[2]; + opt_extent[3] = extent[3]; + return opt_extent; } else { - listenerObj = new goog.events.Listener( - listener, null, this.src, typeStr, !!opt_useCapture, opt_listenerScope); - listenerObj.callOnce = callOnce; - listenerArray.push(listenerObj); + return extent.slice(); } - return listenerObj; }; /** - * Removes a matching listener. - * @param {string|!goog.events.EventId} type The listener event type. - * @param {!Function} listener This listener callback method. - * @param {boolean=} opt_useCapture The capture mode of the listener. - * @param {Object=} opt_listenerScope Object in whose scope to call the - * listener. - * @return {boolean} Whether any listener was removed. + * @param {ol.Extent} extent Extent. + * @param {number} x X. + * @param {number} y Y. + * @return {number} Closest squared distance. */ -goog.events.ListenerMap.prototype.remove = function( - type, listener, opt_useCapture, opt_listenerScope) { - var typeStr = type.toString(); - if (!(typeStr in this.listeners)) { - return false; +ol.extent.closestSquaredDistanceXY = function(extent, x, y) { + var dx, dy; + if (x < extent[0]) { + dx = extent[0] - x; + } else if (extent[2] < x) { + dx = x - extent[2]; + } else { + dx = 0; } - - var listenerArray = this.listeners[typeStr]; - var index = goog.events.ListenerMap.findListenerIndex_( - listenerArray, listener, opt_useCapture, opt_listenerScope); - if (index > -1) { - var listenerObj = listenerArray[index]; - listenerObj.markAsRemoved(); - goog.array.removeAt(listenerArray, index); - if (listenerArray.length == 0) { - delete this.listeners[typeStr]; - this.typeCount_--; - } - return true; + if (y < extent[1]) { + dy = extent[1] - y; + } else if (extent[3] < y) { + dy = y - extent[3]; + } else { + dy = 0; } - return false; + return dx * dx + dy * dy; }; /** - * Removes the given listener object. - * @param {goog.events.ListenableKey} listener The listener to remove. - * @return {boolean} Whether the listener is removed. + * Check if the passed coordinate is contained or on the edge of the extent. + * + * @param {ol.Extent} extent Extent. + * @param {ol.Coordinate} coordinate Coordinate. + * @return {boolean} The coordinate is contained in the extent. + * @api stable */ -goog.events.ListenerMap.prototype.removeByKey = function(listener) { - var type = listener.type; - if (!(type in this.listeners)) { - return false; - } - - var removed = goog.array.remove(this.listeners[type], listener); - if (removed) { - listener.markAsRemoved(); - if (this.listeners[type].length == 0) { - delete this.listeners[type]; - this.typeCount_--; - } - } - return removed; +ol.extent.containsCoordinate = function(extent, coordinate) { + return ol.extent.containsXY(extent, coordinate[0], coordinate[1]); }; /** - * Removes all listeners from this map. If opt_type is provided, only - * listeners that match the given type are removed. - * @param {string|!goog.events.EventId=} opt_type Type of event to remove. - * @return {number} Number of listeners removed. + * Check if one extent contains another. + * + * An extent is deemed contained if it lies completely within the other extent, + * including if they share one or more edges. + * + * @param {ol.Extent} extent1 Extent 1. + * @param {ol.Extent} extent2 Extent 2. + * @return {boolean} The second extent is contained by or on the edge of the + * first. + * @api stable */ -goog.events.ListenerMap.prototype.removeAll = function(opt_type) { - var typeStr = opt_type && opt_type.toString(); - var count = 0; - for (var type in this.listeners) { - if (!typeStr || type == typeStr) { - var listenerArray = this.listeners[type]; - for (var i = 0; i < listenerArray.length; i++) { - ++count; - listenerArray[i].markAsRemoved(); - } - delete this.listeners[type]; - this.typeCount_--; - } - } - return count; +ol.extent.containsExtent = function(extent1, extent2) { + return extent1[0] <= extent2[0] && extent2[2] <= extent1[2] && + extent1[1] <= extent2[1] && extent2[3] <= extent1[3]; }; /** - * Gets all listeners that match the given type and capture mode. The - * returned array is a copy (but the listener objects are not). - * @param {string|!goog.events.EventId} type The type of the listeners - * to retrieve. - * @param {boolean} capture The capture mode of the listeners to retrieve. - * @return {!Array<goog.events.ListenableKey>} An array of matching - * listeners. + * Check if the passed coordinate is contained or on the edge of the extent. + * + * @param {ol.Extent} extent Extent. + * @param {number} x X coordinate. + * @param {number} y Y coordinate. + * @return {boolean} The x, y values are contained in the extent. + * @api stable */ -goog.events.ListenerMap.prototype.getListeners = function(type, capture) { - var listenerArray = this.listeners[type.toString()]; - var rv = []; - if (listenerArray) { - for (var i = 0; i < listenerArray.length; ++i) { - var listenerObj = listenerArray[i]; - if (listenerObj.capture == capture) { - rv.push(listenerObj); - } - } - } - return rv; +ol.extent.containsXY = function(extent, x, y) { + return extent[0] <= x && x <= extent[2] && extent[1] <= y && y <= extent[3]; }; /** - * Gets the goog.events.ListenableKey for the event or null if no such - * listener is in use. - * - * @param {string|!goog.events.EventId} type The type of the listener - * to retrieve. - * @param {!Function} listener The listener function to get. - * @param {boolean} capture Whether the listener is a capturing listener. - * @param {Object=} opt_listenerScope Object in whose scope to call the - * listener. - * @return {goog.events.ListenableKey} the found listener or null if not found. + * Get the relationship between a coordinate and extent. + * @param {ol.Extent} extent The extent. + * @param {ol.Coordinate} coordinate The coordinate. + * @return {number} The relationship (bitwise compare with + * ol.extent.Relationship). */ -goog.events.ListenerMap.prototype.getListener = function( - type, listener, capture, opt_listenerScope) { - var listenerArray = this.listeners[type.toString()]; - var i = -1; - if (listenerArray) { - i = goog.events.ListenerMap.findListenerIndex_( - listenerArray, listener, capture, opt_listenerScope); +ol.extent.coordinateRelationship = function(extent, coordinate) { + var minX = extent[0]; + var minY = extent[1]; + var maxX = extent[2]; + var maxY = extent[3]; + var x = coordinate[0]; + var y = coordinate[1]; + var relationship = ol.extent.Relationship.UNKNOWN; + if (x < minX) { + relationship = relationship | ol.extent.Relationship.LEFT; + } else if (x > maxX) { + relationship = relationship | ol.extent.Relationship.RIGHT; + } + if (y < minY) { + relationship = relationship | ol.extent.Relationship.BELOW; + } else if (y > maxY) { + relationship = relationship | ol.extent.Relationship.ABOVE; + } + if (relationship === ol.extent.Relationship.UNKNOWN) { + relationship = ol.extent.Relationship.INTERSECTING; } - return i > -1 ? listenerArray[i] : null; + return relationship; }; /** - * Whether there is a matching listener. If either the type or capture - * parameters are unspecified, the function will match on the - * remaining criteria. - * - * @param {string|!goog.events.EventId=} opt_type The type of the listener. - * @param {boolean=} opt_capture The capture mode of the listener. - * @return {boolean} Whether there is an active listener matching - * the requested type and/or capture phase. + * Create an empty extent. + * @return {ol.Extent} Empty extent. + * @api stable */ -goog.events.ListenerMap.prototype.hasListener = function( - opt_type, opt_capture) { - var hasType = goog.isDef(opt_type); - var typeStr = hasType ? opt_type.toString() : ''; - var hasCapture = goog.isDef(opt_capture); - - return goog.object.some( - this.listeners, function(listenerArray, type) { - for (var i = 0; i < listenerArray.length; ++i) { - if ((!hasType || listenerArray[i].type == typeStr) && - (!hasCapture || listenerArray[i].capture == opt_capture)) { - return true; - } - } - - return false; - }); +ol.extent.createEmpty = function() { + return [Infinity, Infinity, -Infinity, -Infinity]; }; /** - * Finds the index of a matching goog.events.Listener in the given - * listenerArray. - * @param {!Array<!goog.events.Listener>} listenerArray Array of listener. - * @param {!Function} listener The listener function. - * @param {boolean=} opt_useCapture The capture flag for the listener. - * @param {Object=} opt_listenerScope The listener scope. - * @return {number} The index of the matching listener within the - * listenerArray. - * @private - */ -goog.events.ListenerMap.findListenerIndex_ = function( - listenerArray, listener, opt_useCapture, opt_listenerScope) { - for (var i = 0; i < listenerArray.length; ++i) { - var listenerObj = listenerArray[i]; - if (!listenerObj.removed && - listenerObj.listener == listener && - listenerObj.capture == !!opt_useCapture && - listenerObj.handler == opt_listenerScope) { - return i; - } + * Create a new extent or update the provided extent. + * @param {number} minX Minimum X. + * @param {number} minY Minimum Y. + * @param {number} maxX Maximum X. + * @param {number} maxY Maximum Y. + * @param {ol.Extent=} opt_extent Destination extent. + * @return {ol.Extent} Extent. + */ +ol.extent.createOrUpdate = function(minX, minY, maxX, maxY, opt_extent) { + if (opt_extent) { + opt_extent[0] = minX; + opt_extent[1] = minY; + opt_extent[2] = maxX; + opt_extent[3] = maxY; + return opt_extent; + } else { + return [minX, minY, maxX, maxY]; } - return -1; }; -// Copyright 2005 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview An event manager for both native browser event - * targets and custom JavaScript event targets - * ({@code goog.events.Listenable}). This provides an abstraction - * over browsers' event systems. - * - * It also provides a simulation of W3C event model's capture phase in - * Internet Explorer (IE 8 and below). Caveat: the simulation does not - * interact well with listeners registered directly on the elements - * (bypassing goog.events) or even with listeners registered via - * goog.events in a separate JS binary. In these cases, we provide - * no ordering guarantees. - * - * The listeners will receive a "patched" event object. Such event object - * contains normalized values for certain event properties that differs in - * different browsers. - * - * Example usage: - * <pre> - * goog.events.listen(myNode, 'click', function(e) { alert('woo') }); - * goog.events.listen(myNode, 'mouseover', mouseHandler, true); - * goog.events.unlisten(myNode, 'mouseover', mouseHandler, true); - * goog.events.removeAll(myNode); - * </pre> - * - * in IE and event object patching] - * @author arv@google.com (Erik Arvidsson) - * - * @see ../demos/events.html - * @see ../demos/event-propagation.html - * @see ../demos/stopevent.html - */ - -// IMPLEMENTATION NOTES: -// goog.events stores an auxiliary data structure on each EventTarget -// source being listened on. This allows us to take advantage of GC, -// having the data structure GC'd when the EventTarget is GC'd. This -// GC behavior is equivalent to using W3C DOM Events directly. - -goog.provide('goog.events'); -goog.provide('goog.events.CaptureSimulationMode'); -goog.provide('goog.events.Key'); -goog.provide('goog.events.ListenableType'); - -goog.require('goog.asserts'); -goog.require('goog.debug.entryPointRegistry'); -goog.require('goog.events.BrowserEvent'); -goog.require('goog.events.BrowserFeature'); -goog.require('goog.events.Listenable'); -goog.require('goog.events.ListenerMap'); - -goog.forwardDeclare('goog.debug.ErrorHandler'); -goog.forwardDeclare('goog.events.EventWrapper'); - - -/** - * @typedef {number|goog.events.ListenableKey} - */ -goog.events.Key; - - -/** - * @typedef {EventTarget|goog.events.Listenable} - */ -goog.events.ListenableType; - - -/** - * Property name on a native event target for the listener map - * associated with the event target. - * @private @const {string} - */ -goog.events.LISTENER_MAP_PROP_ = 'closure_lm_' + ((Math.random() * 1e6) | 0); - - -/** - * String used to prepend to IE event types. - * @const - * @private - */ -goog.events.onString_ = 'on'; - /** - * Map of computed "on<eventname>" strings for IE event types. Caching - * this removes an extra object allocation in goog.events.listen which - * improves IE6 performance. - * @const - * @dict - * @private - */ -goog.events.onStringMap_ = {}; - - -/** - * @enum {number} Different capture simulation mode for IE8-. + * Create a new empty extent or make the provided one empty. + * @param {ol.Extent=} opt_extent Extent. + * @return {ol.Extent} Extent. */ -goog.events.CaptureSimulationMode = { - /** - * Does not perform capture simulation. Will asserts in IE8- when you - * add capture listeners. - */ - OFF_AND_FAIL: 0, - - /** - * Does not perform capture simulation, silently ignore capture - * listeners. - */ - OFF_AND_SILENT: 1, - - /** - * Performs capture simulation. - */ - ON: 2 +ol.extent.createOrUpdateEmpty = function(opt_extent) { + return ol.extent.createOrUpdate( + Infinity, Infinity, -Infinity, -Infinity, opt_extent); }; /** - * @define {number} The capture simulation mode for IE8-. By default, - * this is ON. - */ -goog.define('goog.events.CAPTURE_SIMULATION_MODE', 2); - - -/** - * Estimated count of total native listeners. - * @private {number} + * @param {ol.Coordinate} coordinate Coordinate. + * @param {ol.Extent=} opt_extent Extent. + * @return {ol.Extent} Extent. */ -goog.events.listenerCountEstimate_ = 0; +ol.extent.createOrUpdateFromCoordinate = function(coordinate, opt_extent) { + var x = coordinate[0]; + var y = coordinate[1]; + return ol.extent.createOrUpdate(x, y, x, y, opt_extent); +}; /** - * Adds an event listener for a specific event on a native event - * target (such as a DOM element) or an object that has implemented - * {@link goog.events.Listenable}. A listener can only be added once - * to an object and if it is added again the key for the listener is - * returned. Note that if the existing listener is a one-off listener - * (registered via listenOnce), it will no longer be a one-off - * listener after a call to listen(). - * - * @param {EventTarget|goog.events.Listenable} src The node to listen - * to events on. - * @param {string|Array<string>| - * !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>} - * type Event type or array of event types. - * @param {function(this:T, EVENTOBJ):?|{handleEvent:function(?):?}|null} - * listener Callback method, or an object with a handleEvent function. - * WARNING: passing an Object is now softly deprecated. - * @param {boolean=} opt_capt Whether to fire in capture phase (defaults to - * false). - * @param {T=} opt_handler Element in whose scope to call the listener. - * @return {goog.events.Key} Unique key for the listener. - * @template T,EVENTOBJ + * @param {Array.<ol.Coordinate>} coordinates Coordinates. + * @param {ol.Extent=} opt_extent Extent. + * @return {ol.Extent} Extent. */ -goog.events.listen = function(src, type, listener, opt_capt, opt_handler) { - if (goog.isArray(type)) { - for (var i = 0; i < type.length; i++) { - goog.events.listen(src, type[i], listener, opt_capt, opt_handler); - } - return null; - } - - listener = goog.events.wrapListener(listener); - if (goog.events.Listenable.isImplementedBy(src)) { - return src.listen( - /** @type {string|!goog.events.EventId} */ (type), - listener, opt_capt, opt_handler); - } else { - return goog.events.listen_( - /** @type {!EventTarget} */ (src), - /** @type {string|!goog.events.EventId} */ (type), - listener, /* callOnce */ false, opt_capt, opt_handler); - } +ol.extent.createOrUpdateFromCoordinates = function(coordinates, opt_extent) { + var extent = ol.extent.createOrUpdateEmpty(opt_extent); + return ol.extent.extendCoordinates(extent, coordinates); }; /** - * Adds an event listener for a specific event on a native event - * target. A listener can only be added once to an object and if it - * is added again the key for the listener is returned. - * - * Note that a one-off listener will not change an existing listener, - * if any. On the other hand a normal listener will change existing - * one-off listener to become a normal listener. - * - * @param {EventTarget} src The node to listen to events on. - * @param {string|!goog.events.EventId} type Event type. - * @param {!Function} listener Callback function. - * @param {boolean} callOnce Whether the listener is a one-off - * listener or otherwise. - * @param {boolean=} opt_capt Whether to fire in capture phase (defaults to - * false). - * @param {Object=} opt_handler Element in whose scope to call the listener. - * @return {goog.events.ListenableKey} Unique key for the listener. - * @private + * @param {Array.<number>} flatCoordinates Flat coordinates. + * @param {number} offset Offset. + * @param {number} end End. + * @param {number} stride Stride. + * @param {ol.Extent=} opt_extent Extent. + * @return {ol.Extent} Extent. */ -goog.events.listen_ = function( - src, type, listener, callOnce, opt_capt, opt_handler) { - if (!type) { - throw Error('Invalid event type'); - } - - var capture = !!opt_capt; - if (capture && !goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT) { - if (goog.events.CAPTURE_SIMULATION_MODE == - goog.events.CaptureSimulationMode.OFF_AND_FAIL) { - goog.asserts.fail('Can not register capture listener in IE8-.'); - return null; - } else if (goog.events.CAPTURE_SIMULATION_MODE == - goog.events.CaptureSimulationMode.OFF_AND_SILENT) { - return null; - } - } - - var listenerMap = goog.events.getListenerMap_(src); - if (!listenerMap) { - src[goog.events.LISTENER_MAP_PROP_] = listenerMap = - new goog.events.ListenerMap(src); - } - - var listenerObj = listenerMap.add( - type, listener, callOnce, opt_capt, opt_handler); - - // If the listenerObj already has a proxy, it has been set up - // previously. We simply return. - if (listenerObj.proxy) { - return listenerObj; - } - - var proxy = goog.events.getProxy(); - listenerObj.proxy = proxy; - - proxy.src = src; - proxy.listener = listenerObj; - - // Attach the proxy through the browser's API - if (src.addEventListener) { - src.addEventListener(type.toString(), proxy, capture); - } else if (src.attachEvent) { - // The else if above used to be an unconditional else. It would call - // exception on IE11, spoiling the day of some callers. The previous - // incarnation of this code, from 2007, indicates that it replaced an - // earlier still version that caused excess allocations on IE6. - src.attachEvent(goog.events.getOnString_(type.toString()), proxy); - } else { - throw Error('addEventListener and attachEvent are unavailable.'); - } - - goog.events.listenerCountEstimate_++; - return listenerObj; +ol.extent.createOrUpdateFromFlatCoordinates = function(flatCoordinates, offset, end, stride, opt_extent) { + var extent = ol.extent.createOrUpdateEmpty(opt_extent); + return ol.extent.extendFlatCoordinates( + extent, flatCoordinates, offset, end, stride); }; /** - * Helper function for returning a proxy function. - * @return {!Function} A new or reused function object. + * @param {Array.<Array.<ol.Coordinate>>} rings Rings. + * @param {ol.Extent=} opt_extent Extent. + * @return {ol.Extent} Extent. */ -goog.events.getProxy = function() { - var proxyCallbackFunction = goog.events.handleBrowserEvent_; - // Use a local var f to prevent one allocation. - var f = goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT ? - function(eventObject) { - return proxyCallbackFunction.call(f.src, f.listener, eventObject); - } : - function(eventObject) { - var v = proxyCallbackFunction.call(f.src, f.listener, eventObject); - // NOTE(chrishenry): In IE, we hack in a capture phase. However, if - // there is inline event handler which tries to prevent default (for - // example <a href="..." onclick="return false">...</a>) in a - // descendant element, the prevent default will be overridden - // by this listener if this listener were to return true. Hence, we - // return undefined. - if (!v) return v; - }; - return f; +ol.extent.createOrUpdateFromRings = function(rings, opt_extent) { + var extent = ol.extent.createOrUpdateEmpty(opt_extent); + return ol.extent.extendRings(extent, rings); }; /** - * Adds an event listener for a specific event on a native event - * target (such as a DOM element) or an object that has implemented - * {@link goog.events.Listenable}. After the event has fired the event - * listener is removed from the target. - * - * If an existing listener already exists, listenOnce will do - * nothing. In particular, if the listener was previously registered - * via listen(), listenOnce() will not turn the listener into a - * one-off listener. Similarly, if there is already an existing - * one-off listener, listenOnce does not modify the listeners (it is - * still a once listener). - * - * @param {EventTarget|goog.events.Listenable} src The node to listen - * to events on. - * @param {string|Array<string>| - * !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>} - * type Event type or array of event types. - * @param {function(this:T, EVENTOBJ):?|{handleEvent:function(?):?}|null} - * listener Callback method. - * @param {boolean=} opt_capt Fire in capture phase?. - * @param {T=} opt_handler Element in whose scope to call the listener. - * @return {goog.events.Key} Unique key for the listener. - * @template T,EVENTOBJ + * Empty an extent in place. + * @param {ol.Extent} extent Extent. + * @return {ol.Extent} Extent. */ -goog.events.listenOnce = function(src, type, listener, opt_capt, opt_handler) { - if (goog.isArray(type)) { - for (var i = 0; i < type.length; i++) { - goog.events.listenOnce(src, type[i], listener, opt_capt, opt_handler); - } - return null; - } - - listener = goog.events.wrapListener(listener); - if (goog.events.Listenable.isImplementedBy(src)) { - return src.listenOnce( - /** @type {string|!goog.events.EventId} */ (type), - listener, opt_capt, opt_handler); - } else { - return goog.events.listen_( - /** @type {!EventTarget} */ (src), - /** @type {string|!goog.events.EventId} */ (type), - listener, /* callOnce */ true, opt_capt, opt_handler); - } +ol.extent.empty = function(extent) { + extent[0] = extent[1] = Infinity; + extent[2] = extent[3] = -Infinity; + return extent; }; /** - * Adds an event listener with a specific event wrapper on a DOM Node or an - * object that has implemented {@link goog.events.Listenable}. A listener can - * only be added once to an object. - * - * @param {EventTarget|goog.events.Listenable} src The target to - * listen to events on. - * @param {goog.events.EventWrapper} wrapper Event wrapper to use. - * @param {function(this:T, ?):?|{handleEvent:function(?):?}|null} listener - * Callback method, or an object with a handleEvent function. - * @param {boolean=} opt_capt Whether to fire in capture phase (defaults to - * false). - * @param {T=} opt_handler Element in whose scope to call the listener. - * @template T + * Determine if two extents are equivalent. + * @param {ol.Extent} extent1 Extent 1. + * @param {ol.Extent} extent2 Extent 2. + * @return {boolean} The two extents are equivalent. + * @api stable */ -goog.events.listenWithWrapper = function(src, wrapper, listener, opt_capt, - opt_handler) { - wrapper.listen(src, listener, opt_capt, opt_handler); +ol.extent.equals = function(extent1, extent2) { + return extent1[0] == extent2[0] && extent1[2] == extent2[2] && + extent1[1] == extent2[1] && extent1[3] == extent2[3]; }; /** - * Removes an event listener which was added with listen(). - * - * @param {EventTarget|goog.events.Listenable} src The target to stop - * listening to events on. - * @param {string|Array<string>| - * !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>} - * type Event type or array of event types to unlisten to. - * @param {function(?):?|{handleEvent:function(?):?}|null} listener The - * listener function to remove. - * @param {boolean=} opt_capt In DOM-compliant browsers, this determines - * whether the listener is fired during the capture or bubble phase of the - * event. - * @param {Object=} opt_handler Element in whose scope to call the listener. - * @return {?boolean} indicating whether the listener was there to remove. - * @template EVENTOBJ + * Modify an extent to include another extent. + * @param {ol.Extent} extent1 The extent to be modified. + * @param {ol.Extent} extent2 The extent that will be included in the first. + * @return {ol.Extent} A reference to the first (extended) extent. + * @api stable */ -goog.events.unlisten = function(src, type, listener, opt_capt, opt_handler) { - if (goog.isArray(type)) { - for (var i = 0; i < type.length; i++) { - goog.events.unlisten(src, type[i], listener, opt_capt, opt_handler); - } - return null; +ol.extent.extend = function(extent1, extent2) { + if (extent2[0] < extent1[0]) { + extent1[0] = extent2[0]; } - - listener = goog.events.wrapListener(listener); - if (goog.events.Listenable.isImplementedBy(src)) { - return src.unlisten( - /** @type {string|!goog.events.EventId} */ (type), - listener, opt_capt, opt_handler); + if (extent2[2] > extent1[2]) { + extent1[2] = extent2[2]; } - - if (!src) { - // TODO(chrishenry): We should tighten the API to only accept - // non-null objects, or add an assertion here. - return false; + if (extent2[1] < extent1[1]) { + extent1[1] = extent2[1]; } - - var capture = !!opt_capt; - var listenerMap = goog.events.getListenerMap_( - /** @type {!EventTarget} */ (src)); - if (listenerMap) { - var listenerObj = listenerMap.getListener( - /** @type {string|!goog.events.EventId} */ (type), - listener, capture, opt_handler); - if (listenerObj) { - return goog.events.unlistenByKey(listenerObj); - } + if (extent2[3] > extent1[3]) { + extent1[3] = extent2[3]; } - - return false; + return extent1; }; /** - * Removes an event listener which was added with listen() by the key - * returned by listen(). - * - * @param {goog.events.Key} key The key returned by listen() for this - * event listener. - * @return {boolean} indicating whether the listener was there to remove. + * @param {ol.Extent} extent Extent. + * @param {ol.Coordinate} coordinate Coordinate. */ -goog.events.unlistenByKey = function(key) { - // TODO(chrishenry): Remove this check when tests that rely on this - // are fixed. - if (goog.isNumber(key)) { - return false; - } - - var listener = key; - if (!listener || listener.removed) { - return false; +ol.extent.extendCoordinate = function(extent, coordinate) { + if (coordinate[0] < extent[0]) { + extent[0] = coordinate[0]; } - - var src = listener.src; - if (goog.events.Listenable.isImplementedBy(src)) { - return src.unlistenByKey(listener); + if (coordinate[0] > extent[2]) { + extent[2] = coordinate[0]; } - - var type = listener.type; - var proxy = listener.proxy; - if (src.removeEventListener) { - src.removeEventListener(type, proxy, listener.capture); - } else if (src.detachEvent) { - src.detachEvent(goog.events.getOnString_(type), proxy); + if (coordinate[1] < extent[1]) { + extent[1] = coordinate[1]; } - goog.events.listenerCountEstimate_--; - - var listenerMap = goog.events.getListenerMap_( - /** @type {!EventTarget} */ (src)); - // TODO(chrishenry): Try to remove this conditional and execute the - // first branch always. This should be safe. - if (listenerMap) { - listenerMap.removeByKey(listener); - if (listenerMap.getTypeCount() == 0) { - // Null the src, just because this is simple to do (and useful - // for IE <= 7). - listenerMap.src = null; - // We don't use delete here because IE does not allow delete - // on a window object. - src[goog.events.LISTENER_MAP_PROP_] = null; - } - } else { - listener.markAsRemoved(); + if (coordinate[1] > extent[3]) { + extent[3] = coordinate[1]; } - - return true; }; /** - * Removes an event listener which was added with listenWithWrapper(). - * - * @param {EventTarget|goog.events.Listenable} src The target to stop - * listening to events on. - * @param {goog.events.EventWrapper} wrapper Event wrapper to use. - * @param {function(?):?|{handleEvent:function(?):?}|null} listener The - * listener function to remove. - * @param {boolean=} opt_capt In DOM-compliant browsers, this determines - * whether the listener is fired during the capture or bubble phase of the - * event. - * @param {Object=} opt_handler Element in whose scope to call the listener. + * @param {ol.Extent} extent Extent. + * @param {Array.<ol.Coordinate>} coordinates Coordinates. + * @return {ol.Extent} Extent. */ -goog.events.unlistenWithWrapper = function(src, wrapper, listener, opt_capt, - opt_handler) { - wrapper.unlisten(src, listener, opt_capt, opt_handler); +ol.extent.extendCoordinates = function(extent, coordinates) { + var i, ii; + for (i = 0, ii = coordinates.length; i < ii; ++i) { + ol.extent.extendCoordinate(extent, coordinates[i]); + } + return extent; }; /** - * Removes all listeners from an object. You can also optionally - * remove listeners of a particular type. - * - * @param {Object|undefined} obj Object to remove listeners from. Must be an - * EventTarget or a goog.events.Listenable. - * @param {string|!goog.events.EventId=} opt_type Type of event to remove. - * Default is all types. - * @return {number} Number of listeners removed. + * @param {ol.Extent} extent Extent. + * @param {Array.<number>} flatCoordinates Flat coordinates. + * @param {number} offset Offset. + * @param {number} end End. + * @param {number} stride Stride. + * @return {ol.Extent} Extent. */ -goog.events.removeAll = function(obj, opt_type) { - // TODO(chrishenry): Change the type of obj to - // (!EventTarget|!goog.events.Listenable). - - if (!obj) { - return 0; - } - - if (goog.events.Listenable.isImplementedBy(obj)) { - return obj.removeAllListeners(opt_type); +ol.extent.extendFlatCoordinates = function(extent, flatCoordinates, offset, end, stride) { + for (; offset < end; offset += stride) { + ol.extent.extendXY( + extent, flatCoordinates[offset], flatCoordinates[offset + 1]); } + return extent; +}; - var listenerMap = goog.events.getListenerMap_( - /** @type {!EventTarget} */ (obj)); - if (!listenerMap) { - return 0; - } - var count = 0; - var typeStr = opt_type && opt_type.toString(); - for (var type in listenerMap.listeners) { - if (!typeStr || type == typeStr) { - // Clone so that we don't need to worry about unlistenByKey - // changing the content of the ListenerMap. - var listeners = listenerMap.listeners[type].concat(); - for (var i = 0; i < listeners.length; ++i) { - if (goog.events.unlistenByKey(listeners[i])) { - ++count; - } - } - } +/** + * @param {ol.Extent} extent Extent. + * @param {Array.<Array.<ol.Coordinate>>} rings Rings. + * @return {ol.Extent} Extent. + */ +ol.extent.extendRings = function(extent, rings) { + var i, ii; + for (i = 0, ii = rings.length; i < ii; ++i) { + ol.extent.extendCoordinates(extent, rings[i]); } - return count; + return extent; }; /** - * Gets the listeners for a given object, type and capture phase. - * - * @param {Object} obj Object to get listeners for. - * @param {string|!goog.events.EventId} type Event type. - * @param {boolean} capture Capture phase?. - * @return {Array<goog.events.Listener>} Array of listener objects. + * @param {ol.Extent} extent Extent. + * @param {number} x X. + * @param {number} y Y. */ -goog.events.getListeners = function(obj, type, capture) { - if (goog.events.Listenable.isImplementedBy(obj)) { - return obj.getListeners(type, capture); - } else { - if (!obj) { - // TODO(chrishenry): We should tighten the API to accept - // !EventTarget|goog.events.Listenable, and add an assertion here. - return []; - } - - var listenerMap = goog.events.getListenerMap_( - /** @type {!EventTarget} */ (obj)); - return listenerMap ? listenerMap.getListeners(type, capture) : []; - } +ol.extent.extendXY = function(extent, x, y) { + extent[0] = Math.min(extent[0], x); + extent[1] = Math.min(extent[1], y); + extent[2] = Math.max(extent[2], x); + extent[3] = Math.max(extent[3], y); }; /** - * Gets the goog.events.Listener for the event or null if no such listener is - * in use. - * - * @param {EventTarget|goog.events.Listenable} src The target from - * which to get listeners. - * @param {?string|!goog.events.EventId<EVENTOBJ>} type The type of the event. - * @param {function(EVENTOBJ):?|{handleEvent:function(?):?}|null} listener The - * listener function to get. - * @param {boolean=} opt_capt In DOM-compliant browsers, this determines - * whether the listener is fired during the - * capture or bubble phase of the event. - * @param {Object=} opt_handler Element in whose scope to call the listener. - * @return {goog.events.ListenableKey} the found listener or null if not found. - * @template EVENTOBJ + * This function calls `callback` for each corner of the extent. If the + * callback returns a truthy value the function returns that value + * immediately. Otherwise the function returns `false`. + * @param {ol.Extent} extent Extent. + * @param {function(this:T, ol.Coordinate): S} callback Callback. + * @param {T=} opt_this Value to use as `this` when executing `callback`. + * @return {S|boolean} Value. + * @template S, T */ -goog.events.getListener = function(src, type, listener, opt_capt, opt_handler) { - // TODO(chrishenry): Change type from ?string to string, or add assertion. - type = /** @type {string} */ (type); - listener = goog.events.wrapListener(listener); - var capture = !!opt_capt; - if (goog.events.Listenable.isImplementedBy(src)) { - return src.getListener(type, listener, capture, opt_handler); +ol.extent.forEachCorner = function(extent, callback, opt_this) { + var val; + val = callback.call(opt_this, ol.extent.getBottomLeft(extent)); + if (val) { + return val; } - - if (!src) { - // TODO(chrishenry): We should tighten the API to only accept - // non-null objects, or add an assertion here. - return null; + val = callback.call(opt_this, ol.extent.getBottomRight(extent)); + if (val) { + return val; } - - var listenerMap = goog.events.getListenerMap_( - /** @type {!EventTarget} */ (src)); - if (listenerMap) { - return listenerMap.getListener(type, listener, capture, opt_handler); + val = callback.call(opt_this, ol.extent.getTopRight(extent)); + if (val) { + return val; } - return null; + val = callback.call(opt_this, ol.extent.getTopLeft(extent)); + if (val) { + return val; + } + return false; }; /** - * Returns whether an event target has any active listeners matching the - * specified signature. If either the type or capture parameters are - * unspecified, the function will match on the remaining criteria. - * - * @param {EventTarget|goog.events.Listenable} obj Target to get - * listeners for. - * @param {string|!goog.events.EventId=} opt_type Event type. - * @param {boolean=} opt_capture Whether to check for capture or bubble-phase - * listeners. - * @return {boolean} Whether an event target has one or more listeners matching - * the requested type and/or capture phase. + * @param {ol.Extent} extent Extent. + * @return {number} Area. */ -goog.events.hasListener = function(obj, opt_type, opt_capture) { - if (goog.events.Listenable.isImplementedBy(obj)) { - return obj.hasListener(opt_type, opt_capture); +ol.extent.getArea = function(extent) { + var area = 0; + if (!ol.extent.isEmpty(extent)) { + area = ol.extent.getWidth(extent) * ol.extent.getHeight(extent); } - - var listenerMap = goog.events.getListenerMap_( - /** @type {!EventTarget} */ (obj)); - return !!listenerMap && listenerMap.hasListener(opt_type, opt_capture); + return area; }; /** - * Provides a nice string showing the normalized event objects public members - * @param {Object} e Event Object. - * @return {string} String of the public members of the normalized event object. + * Get the bottom left coordinate of an extent. + * @param {ol.Extent} extent Extent. + * @return {ol.Coordinate} Bottom left coordinate. + * @api stable */ -goog.events.expose = function(e) { - var str = []; - for (var key in e) { - if (e[key] && e[key].id) { - str.push(key + ' = ' + e[key] + ' (' + e[key].id + ')'); - } else { - str.push(key + ' = ' + e[key]); - } - } - return str.join('\n'); +ol.extent.getBottomLeft = function(extent) { + return [extent[0], extent[1]]; }; /** - * Returns a string with on prepended to the specified type. This is used for IE - * which expects "on" to be prepended. This function caches the string in order - * to avoid extra allocations in steady state. - * @param {string} type Event type. - * @return {string} The type string with 'on' prepended. - * @private + * Get the bottom right coordinate of an extent. + * @param {ol.Extent} extent Extent. + * @return {ol.Coordinate} Bottom right coordinate. + * @api stable */ -goog.events.getOnString_ = function(type) { - if (type in goog.events.onStringMap_) { - return goog.events.onStringMap_[type]; - } - return goog.events.onStringMap_[type] = goog.events.onString_ + type; +ol.extent.getBottomRight = function(extent) { + return [extent[2], extent[1]]; }; /** - * Fires an object's listeners of a particular type and phase - * - * @param {Object} obj Object whose listeners to call. - * @param {string|!goog.events.EventId} type Event type. - * @param {boolean} capture Which event phase. - * @param {Object} eventObject Event object to be passed to listener. - * @return {boolean} True if all listeners returned true else false. + * Get the center coordinate of an extent. + * @param {ol.Extent} extent Extent. + * @return {ol.Coordinate} Center. + * @api stable */ -goog.events.fireListeners = function(obj, type, capture, eventObject) { - if (goog.events.Listenable.isImplementedBy(obj)) { - return obj.fireListeners(type, capture, eventObject); - } - - return goog.events.fireListeners_(obj, type, capture, eventObject); +ol.extent.getCenter = function(extent) { + return [(extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2]; }; /** - * Fires an object's listeners of a particular type and phase. - * @param {Object} obj Object whose listeners to call. - * @param {string|!goog.events.EventId} type Event type. - * @param {boolean} capture Which event phase. - * @param {Object} eventObject Event object to be passed to listener. - * @return {boolean} True if all listeners returned true else false. - * @private + * Get a corner coordinate of an extent. + * @param {ol.Extent} extent Extent. + * @param {ol.extent.Corner} corner Corner. + * @return {ol.Coordinate} Corner coordinate. */ -goog.events.fireListeners_ = function(obj, type, capture, eventObject) { - /** @type {boolean} */ - var retval = true; - - var listenerMap = goog.events.getListenerMap_( - /** @type {EventTarget} */ (obj)); - if (listenerMap) { - // TODO(chrishenry): Original code avoids array creation when there - // is no listener, so we do the same. If this optimization turns - // out to be not required, we can replace this with - // listenerMap.getListeners(type, capture) instead, which is simpler. - var listenerArray = listenerMap.listeners[type.toString()]; - if (listenerArray) { - listenerArray = listenerArray.concat(); - for (var i = 0; i < listenerArray.length; i++) { - var listener = listenerArray[i]; - // We might not have a listener if the listener was removed. - if (listener && listener.capture == capture && !listener.removed) { - var result = goog.events.fireListener(listener, eventObject); - retval = retval && (result !== false); - } - } - } +ol.extent.getCorner = function(extent, corner) { + var coordinate; + if (corner === ol.extent.Corner.BOTTOM_LEFT) { + coordinate = ol.extent.getBottomLeft(extent); + } else if (corner === ol.extent.Corner.BOTTOM_RIGHT) { + coordinate = ol.extent.getBottomRight(extent); + } else if (corner === ol.extent.Corner.TOP_LEFT) { + coordinate = ol.extent.getTopLeft(extent); + } else if (corner === ol.extent.Corner.TOP_RIGHT) { + coordinate = ol.extent.getTopRight(extent); + } else { + goog.asserts.fail('Invalid corner: %s', corner); } - return retval; + goog.asserts.assert(coordinate, 'coordinate should be defined'); + return coordinate; }; /** - * Fires a listener with a set of arguments - * - * @param {goog.events.Listener} listener The listener object to call. - * @param {Object} eventObject The event object to pass to the listener. - * @return {boolean} Result of listener. + * @param {ol.Extent} extent1 Extent 1. + * @param {ol.Extent} extent2 Extent 2. + * @return {number} Enlarged area. */ -goog.events.fireListener = function(listener, eventObject) { - var listenerFn = listener.listener; - var listenerHandler = listener.handler || listener.src; - - if (listener.callOnce) { - goog.events.unlistenByKey(listener); - } - return listenerFn.call(listenerHandler, eventObject); +ol.extent.getEnlargedArea = function(extent1, extent2) { + var minX = Math.min(extent1[0], extent2[0]); + var minY = Math.min(extent1[1], extent2[1]); + var maxX = Math.max(extent1[2], extent2[2]); + var maxY = Math.max(extent1[3], extent2[3]); + return (maxX - minX) * (maxY - minY); }; /** - * Gets the total number of listeners currently in the system. - * @return {number} Number of listeners. - * @deprecated This returns estimated count, now that Closure no longer - * stores a central listener registry. We still return an estimation - * to keep existing listener-related tests passing. In the near future, - * this function will be removed. + * @param {ol.Coordinate} center Center. + * @param {number} resolution Resolution. + * @param {number} rotation Rotation. + * @param {ol.Size} size Size. + * @param {ol.Extent=} opt_extent Destination extent. + * @return {ol.Extent} Extent. */ -goog.events.getTotalListenerCount = function() { - return goog.events.listenerCountEstimate_; +ol.extent.getForViewAndSize = function(center, resolution, rotation, size, opt_extent) { + var dx = resolution * size[0] / 2; + var dy = resolution * size[1] / 2; + var cosRotation = Math.cos(rotation); + var sinRotation = Math.sin(rotation); + var xCos = dx * cosRotation; + var xSin = dx * sinRotation; + var yCos = dy * cosRotation; + var ySin = dy * sinRotation; + var x = center[0]; + var y = center[1]; + var x0 = x - xCos + ySin; + var x1 = x - xCos - ySin; + var x2 = x + xCos - ySin; + var x3 = x + xCos + ySin; + var y0 = y - xSin - yCos; + var y1 = y - xSin + yCos; + var y2 = y + xSin + yCos; + var y3 = y + xSin - yCos; + return ol.extent.createOrUpdate( + Math.min(x0, x1, x2, x3), Math.min(y0, y1, y2, y3), + Math.max(x0, x1, x2, x3), Math.max(y0, y1, y2, y3), + opt_extent); }; /** - * Dispatches an event (or event like object) and calls all listeners - * listening for events of this type. The type of the event is decided by the - * type property on the event object. - * - * If any of the listeners returns false OR calls preventDefault then this - * function will return false. If one of the capture listeners calls - * stopPropagation, then the bubble listeners won't fire. - * - * @param {goog.events.Listenable} src The event target. - * @param {goog.events.EventLike} e Event object. - * @return {boolean} If anyone called preventDefault on the event object (or - * if any of the handlers returns false) this will also return false. - * If there are no handlers, or if all handlers return true, this returns - * true. + * Get the height of an extent. + * @param {ol.Extent} extent Extent. + * @return {number} Height. + * @api stable */ -goog.events.dispatchEvent = function(src, e) { - goog.asserts.assert( - goog.events.Listenable.isImplementedBy(src), - 'Can not use goog.events.dispatchEvent with ' + - 'non-goog.events.Listenable instance.'); - return src.dispatchEvent(e); +ol.extent.getHeight = function(extent) { + return extent[3] - extent[1]; }; /** - * Installs exception protection for the browser event entry point using the - * given error handler. - * - * @param {goog.debug.ErrorHandler} errorHandler Error handler with which to - * protect the entry point. + * @param {ol.Extent} extent1 Extent 1. + * @param {ol.Extent} extent2 Extent 2. + * @return {number} Intersection area. */ -goog.events.protectBrowserEventEntryPoint = function(errorHandler) { - goog.events.handleBrowserEvent_ = errorHandler.protectEntryPoint( - goog.events.handleBrowserEvent_); +ol.extent.getIntersectionArea = function(extent1, extent2) { + var intersection = ol.extent.getIntersection(extent1, extent2); + return ol.extent.getArea(intersection); }; /** - * Handles an event and dispatches it to the correct listeners. This - * function is a proxy for the real listener the user specified. - * - * @param {goog.events.Listener} listener The listener object. - * @param {Event=} opt_evt Optional event object that gets passed in via the - * native event handlers. - * @return {boolean} Result of the event handler. - * @this {EventTarget} The object or Element that fired the event. - * @private + * Get the intersection of two extents. + * @param {ol.Extent} extent1 Extent 1. + * @param {ol.Extent} extent2 Extent 2. + * @param {ol.Extent=} opt_extent Optional extent to populate with intersection. + * @return {ol.Extent} Intersecting extent. + * @api stable */ -goog.events.handleBrowserEvent_ = function(listener, opt_evt) { - if (listener.removed) { - return true; - } - - // Synthesize event propagation if the browser does not support W3C - // event model. - if (!goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT) { - var ieEvent = opt_evt || - /** @type {Event} */ (goog.getObjectByName('window.event')); - var evt = new goog.events.BrowserEvent(ieEvent, this); - /** @type {boolean} */ - var retval = true; - - if (goog.events.CAPTURE_SIMULATION_MODE == - goog.events.CaptureSimulationMode.ON) { - // If we have not marked this event yet, we should perform capture - // simulation. - if (!goog.events.isMarkedIeEvent_(ieEvent)) { - goog.events.markIeEvent_(ieEvent); - - var ancestors = []; - for (var parent = evt.currentTarget; parent; - parent = parent.parentNode) { - ancestors.push(parent); - } - - // Fire capture listeners. - var type = listener.type; - for (var i = ancestors.length - 1; !evt.propagationStopped_ && i >= 0; - i--) { - evt.currentTarget = ancestors[i]; - var result = goog.events.fireListeners_(ancestors[i], type, true, evt); - retval = retval && result; - } - - // Fire bubble listeners. - // - // We can technically rely on IE to perform bubble event - // propagation. However, it turns out that IE fires events in - // opposite order of attachEvent registration, which broke - // some code and tests that rely on the order. (While W3C DOM - // Level 2 Events TR leaves the event ordering unspecified, - // modern browsers and W3C DOM Level 3 Events Working Draft - // actually specify the order as the registration order.) - for (var i = 0; !evt.propagationStopped_ && i < ancestors.length; i++) { - evt.currentTarget = ancestors[i]; - var result = goog.events.fireListeners_(ancestors[i], type, false, evt); - retval = retval && result; - } - } +ol.extent.getIntersection = function(extent1, extent2, opt_extent) { + var intersection = opt_extent ? opt_extent : ol.extent.createEmpty(); + if (ol.extent.intersects(extent1, extent2)) { + if (extent1[0] > extent2[0]) { + intersection[0] = extent1[0]; } else { - retval = goog.events.fireListener(listener, evt); + intersection[0] = extent2[0]; } - return retval; - } - - // Otherwise, simply fire the listener. - return goog.events.fireListener( - listener, new goog.events.BrowserEvent(opt_evt, this)); -}; - - -/** - * This is used to mark the IE event object so we do not do the Closure pass - * twice for a bubbling event. - * @param {Event} e The IE browser event. - * @private - */ -goog.events.markIeEvent_ = function(e) { - // Only the keyCode and the returnValue can be changed. We use keyCode for - // non keyboard events. - // event.returnValue is a bit more tricky. It is undefined by default. A - // boolean false prevents the default action. In a window.onbeforeunload and - // the returnValue is non undefined it will be alerted. However, we will only - // modify the returnValue for keyboard events. We can get a problem if non - // closure events sets the keyCode or the returnValue - - var useReturnValue = false; - - if (e.keyCode == 0) { - // We cannot change the keyCode in case that srcElement is input[type=file]. - // We could test that that is the case but that would allocate 3 objects. - // If we use try/catch we will only allocate extra objects in the case of a - // failure. - /** @preserveTry */ - try { - e.keyCode = -1; - return; - } catch (ex) { - useReturnValue = true; + if (extent1[1] > extent2[1]) { + intersection[1] = extent1[1]; + } else { + intersection[1] = extent2[1]; + } + if (extent1[2] < extent2[2]) { + intersection[2] = extent1[2]; + } else { + intersection[2] = extent2[2]; + } + if (extent1[3] < extent2[3]) { + intersection[3] = extent1[3]; + } else { + intersection[3] = extent2[3]; } } - - if (useReturnValue || - /** @type {boolean|undefined} */ (e.returnValue) == undefined) { - e.returnValue = true; - } + return intersection; }; /** - * This is used to check if an IE event has already been handled by the Closure - * system so we do not do the Closure pass twice for a bubbling event. - * @param {Event} e The IE browser event. - * @return {boolean} True if the event object has been marked. - * @private + * @param {ol.Extent} extent Extent. + * @return {number} Margin. */ -goog.events.isMarkedIeEvent_ = function(e) { - return e.keyCode < 0 || e.returnValue != undefined; +ol.extent.getMargin = function(extent) { + return ol.extent.getWidth(extent) + ol.extent.getHeight(extent); }; /** - * Counter to create unique event ids. - * @private {number} - */ -goog.events.uniqueIdCounter_ = 0; - - -/** - * Creates a unique event id. - * - * @param {string} identifier The identifier. - * @return {string} A unique identifier. - * @idGenerator + * Get the size (width, height) of an extent. + * @param {ol.Extent} extent The extent. + * @return {ol.Size} The extent size. + * @api stable */ -goog.events.getUniqueId = function(identifier) { - return identifier + '_' + goog.events.uniqueIdCounter_++; +ol.extent.getSize = function(extent) { + return [extent[2] - extent[0], extent[3] - extent[1]]; }; /** - * @param {EventTarget} src The source object. - * @return {goog.events.ListenerMap} A listener map for the given - * source object, or null if none exists. - * @private + * Get the top left coordinate of an extent. + * @param {ol.Extent} extent Extent. + * @return {ol.Coordinate} Top left coordinate. + * @api stable */ -goog.events.getListenerMap_ = function(src) { - var listenerMap = src[goog.events.LISTENER_MAP_PROP_]; - // IE serializes the property as well (e.g. when serializing outer - // HTML). So we must check that the value is of the correct type. - return listenerMap instanceof goog.events.ListenerMap ? listenerMap : null; +ol.extent.getTopLeft = function(extent) { + return [extent[0], extent[3]]; }; /** - * Expando property for listener function wrapper for Object with - * handleEvent. - * @private @const {string} + * Get the top right coordinate of an extent. + * @param {ol.Extent} extent Extent. + * @return {ol.Coordinate} Top right coordinate. + * @api stable */ -goog.events.LISTENER_WRAPPER_PROP_ = '__closure_events_fn_' + - ((Math.random() * 1e9) >>> 0); +ol.extent.getTopRight = function(extent) { + return [extent[2], extent[3]]; +}; /** - * @param {Object|Function} listener The listener function or an - * object that contains handleEvent method. - * @return {!Function} Either the original function or a function that - * calls obj.handleEvent. If the same listener is passed to this - * function more than once, the same function is guaranteed to be - * returned. + * Get the width of an extent. + * @param {ol.Extent} extent Extent. + * @return {number} Width. + * @api stable */ -goog.events.wrapListener = function(listener) { - goog.asserts.assert(listener, 'Listener can not be null.'); - - if (goog.isFunction(listener)) { - return listener; - } - - goog.asserts.assert( - listener.handleEvent, 'An object listener must have handleEvent method.'); - if (!listener[goog.events.LISTENER_WRAPPER_PROP_]) { - listener[goog.events.LISTENER_WRAPPER_PROP_] = - function(e) { return listener.handleEvent(e); }; - } - return listener[goog.events.LISTENER_WRAPPER_PROP_]; +ol.extent.getWidth = function(extent) { + return extent[2] - extent[0]; }; -// Register the browser event handler as an entry point, so that -// it can be monitored for exception handling, etc. -goog.debug.entryPointRegistry.register( - /** - * @param {function(!Function): !Function} transformer The transforming - * function. - */ - function(transformer) { - goog.events.handleBrowserEvent_ = transformer( - goog.events.handleBrowserEvent_); - }); - -// Copyright 2005 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - /** - * @fileoverview A disposable implementation of a custom - * listenable/event target. See also: documentation for - * {@code goog.events.Listenable}. - * - * @author arv@google.com (Erik Arvidsson) [Original implementation] - * @see ../demos/eventtarget.html - * @see goog.events.Listenable + * Determine if one extent intersects another. + * @param {ol.Extent} extent1 Extent 1. + * @param {ol.Extent} extent2 Extent. + * @return {boolean} The two extents intersect. + * @api stable */ - -goog.provide('goog.events.EventTarget'); - -goog.require('goog.Disposable'); -goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.Event'); -goog.require('goog.events.Listenable'); -goog.require('goog.events.ListenerMap'); -goog.require('goog.object'); - +ol.extent.intersects = function(extent1, extent2) { + return extent1[0] <= extent2[2] && + extent1[2] >= extent2[0] && + extent1[1] <= extent2[3] && + extent1[3] >= extent2[1]; +}; /** - * An implementation of {@code goog.events.Listenable} with full W3C - * EventTarget-like support (capture/bubble mechanism, stopping event - * propagation, preventing default actions). - * - * You may subclass this class to turn your class into a Listenable. - * - * Unless propagation is stopped, an event dispatched by an - * EventTarget will bubble to the parent returned by - * {@code getParentEventTarget}. To set the parent, call - * {@code setParentEventTarget}. Subclasses that don't support - * changing the parent can override the setter to throw an error. - * - * Example usage: - * <pre> - * var source = new goog.events.EventTarget(); - * function handleEvent(e) { - * alert('Type: ' + e.type + '; Target: ' + e.target); - * } - * source.listen('foo', handleEvent); - * // Or: goog.events.listen(source, 'foo', handleEvent); - * ... - * source.dispatchEvent('foo'); // will call handleEvent - * ... - * source.unlisten('foo', handleEvent); - * // Or: goog.events.unlisten(source, 'foo', handleEvent); - * </pre> - * - * @constructor - * @extends {goog.Disposable} - * @implements {goog.events.Listenable} + * Determine if an extent is empty. + * @param {ol.Extent} extent Extent. + * @return {boolean} Is empty. + * @api stable */ -goog.events.EventTarget = function() { - goog.Disposable.call(this); - - /** - * Maps of event type to an array of listeners. - * @private {!goog.events.ListenerMap} - */ - this.eventTargetListeners_ = new goog.events.ListenerMap(this); - - /** - * The object to use for event.target. Useful when mixing in an - * EventTarget to another object. - * @private {!Object} - */ - this.actualEventTarget_ = this; - - /** - * Parent event target, used during event bubbling. - * - * TODO(chrishenry): Change this to goog.events.Listenable. This - * currently breaks people who expect getParentEventTarget to return - * goog.events.EventTarget. - * - * @private {goog.events.EventTarget} - */ - this.parentEventTarget_ = null; +ol.extent.isEmpty = function(extent) { + return extent[2] < extent[0] || extent[3] < extent[1]; }; -goog.inherits(goog.events.EventTarget, goog.Disposable); -goog.events.Listenable.addImplementation(goog.events.EventTarget); /** - * An artificial cap on the number of ancestors you can have. This is mainly - * for loop detection. - * @const {number} - * @private + * @param {ol.Extent} extent Extent. + * @return {boolean} Is infinite. */ -goog.events.EventTarget.MAX_ANCESTORS_ = 1000; +ol.extent.isInfinite = function(extent) { + return extent[0] == -Infinity || extent[1] == -Infinity || + extent[2] == Infinity || extent[3] == Infinity; +}; /** - * Returns the parent of this event target to use for bubbling. - * - * @return {goog.events.EventTarget} The parent EventTarget or null if - * there is no parent. - * @override + * @param {ol.Extent} extent Extent. + * @param {ol.Coordinate} coordinate Coordinate. + * @return {ol.Coordinate} Coordinate. */ -goog.events.EventTarget.prototype.getParentEventTarget = function() { - return this.parentEventTarget_; +ol.extent.normalize = function(extent, coordinate) { + return [ + (coordinate[0] - extent[0]) / (extent[2] - extent[0]), + (coordinate[1] - extent[1]) / (extent[3] - extent[1]) + ]; }; /** - * Sets the parent of this event target to use for capture/bubble - * mechanism. - * @param {goog.events.EventTarget} parent Parent listenable (null if none). + * @param {ol.Extent} extent Extent. + * @param {ol.Extent=} opt_extent Extent. + * @return {ol.Extent} Extent. */ -goog.events.EventTarget.prototype.setParentEventTarget = function(parent) { - this.parentEventTarget_ = parent; +ol.extent.returnOrUpdate = function(extent, opt_extent) { + if (opt_extent) { + opt_extent[0] = extent[0]; + opt_extent[1] = extent[1]; + opt_extent[2] = extent[2]; + opt_extent[3] = extent[3]; + return opt_extent; + } else { + return extent; + } }; /** - * Adds an event listener to the event target. The same handler can only be - * added once per the type. Even if you add the same handler multiple times - * using the same type then it will only be called once when the event is - * dispatched. - * - * @param {string} type The type of the event to listen for. - * @param {function(?):?|{handleEvent:function(?):?}|null} handler The function - * to handle the event. The handler can also be an object that implements - * the handleEvent method which takes the event object as argument. - * @param {boolean=} opt_capture In DOM-compliant browsers, this determines - * whether the listener is fired during the capture or bubble phase - * of the event. - * @param {Object=} opt_handlerScope Object in whose scope to call - * the listener. - * @deprecated Use {@code #listen} instead, when possible. Otherwise, use - * {@code goog.events.listen} if you are passing Object - * (instead of Function) as handler. + * @param {ol.Extent} extent Extent. + * @param {number} value Value. */ -goog.events.EventTarget.prototype.addEventListener = function( - type, handler, opt_capture, opt_handlerScope) { - goog.events.listen(this, type, handler, opt_capture, opt_handlerScope); +ol.extent.scaleFromCenter = function(extent, value) { + var deltaX = ((extent[2] - extent[0]) / 2) * (value - 1); + var deltaY = ((extent[3] - extent[1]) / 2) * (value - 1); + extent[0] -= deltaX; + extent[2] += deltaX; + extent[1] -= deltaY; + extent[3] += deltaY; }; /** - * Removes an event listener from the event target. The handler must be the - * same object as the one added. If the handler has not been added then - * nothing is done. - * - * @param {string} type The type of the event to listen for. - * @param {function(?):?|{handleEvent:function(?):?}|null} handler The function - * to handle the event. The handler can also be an object that implements - * the handleEvent method which takes the event object as argument. - * @param {boolean=} opt_capture In DOM-compliant browsers, this determines - * whether the listener is fired during the capture or bubble phase - * of the event. - * @param {Object=} opt_handlerScope Object in whose scope to call - * the listener. - * @deprecated Use {@code #unlisten} instead, when possible. Otherwise, use - * {@code goog.events.unlisten} if you are passing Object - * (instead of Function) as handler. + * Determine if the segment between two coordinates intersects (crosses, + * touches, or is contained by) the provided extent. + * @param {ol.Extent} extent The extent. + * @param {ol.Coordinate} start Segment start coordinate. + * @param {ol.Coordinate} end Segment end coordinate. + * @return {boolean} The segment intersects the extent. */ -goog.events.EventTarget.prototype.removeEventListener = function( - type, handler, opt_capture, opt_handlerScope) { - goog.events.unlisten(this, type, handler, opt_capture, opt_handlerScope); -}; - - -/** @override */ -goog.events.EventTarget.prototype.dispatchEvent = function(e) { - this.assertInitialized_(); - - var ancestorsTree, ancestor = this.getParentEventTarget(); - if (ancestor) { - ancestorsTree = []; - var ancestorCount = 1; - for (; ancestor; ancestor = ancestor.getParentEventTarget()) { - ancestorsTree.push(ancestor); - goog.asserts.assert( - (++ancestorCount < goog.events.EventTarget.MAX_ANCESTORS_), - 'infinite loop'); +ol.extent.intersectsSegment = function(extent, start, end) { + var intersects = false; + var startRel = ol.extent.coordinateRelationship(extent, start); + var endRel = ol.extent.coordinateRelationship(extent, end); + if (startRel === ol.extent.Relationship.INTERSECTING || + endRel === ol.extent.Relationship.INTERSECTING) { + intersects = true; + } else { + var minX = extent[0]; + var minY = extent[1]; + var maxX = extent[2]; + var maxY = extent[3]; + var startX = start[0]; + var startY = start[1]; + var endX = end[0]; + var endY = end[1]; + var slope = (endY - startY) / (endX - startX); + var x, y; + if (!!(endRel & ol.extent.Relationship.ABOVE) && + !(startRel & ol.extent.Relationship.ABOVE)) { + // potentially intersects top + x = endX - ((endY - maxY) / slope); + intersects = x >= minX && x <= maxX; + } + if (!intersects && !!(endRel & ol.extent.Relationship.RIGHT) && + !(startRel & ol.extent.Relationship.RIGHT)) { + // potentially intersects right + y = endY - ((endX - maxX) * slope); + intersects = y >= minY && y <= maxY; + } + if (!intersects && !!(endRel & ol.extent.Relationship.BELOW) && + !(startRel & ol.extent.Relationship.BELOW)) { + // potentially intersects bottom + x = endX - ((endY - minY) / slope); + intersects = x >= minX && x <= maxX; + } + if (!intersects && !!(endRel & ol.extent.Relationship.LEFT) && + !(startRel & ol.extent.Relationship.LEFT)) { + // potentially intersects left + y = endY - ((endX - minX) * slope); + intersects = y >= minY && y <= maxY; } - } - return goog.events.EventTarget.dispatchEventInternal_( - this.actualEventTarget_, e, ancestorsTree); + } + return intersects; }; /** - * Removes listeners from this object. Classes that extend EventTarget may - * need to override this method in order to remove references to DOM Elements - * and additional listeners. - * @override + * @param {ol.Extent} extent1 Extent 1. + * @param {ol.Extent} extent2 Extent 2. + * @return {boolean} Touches. */ -goog.events.EventTarget.prototype.disposeInternal = function() { - goog.events.EventTarget.superClass_.disposeInternal.call(this); - - this.removeAllListeners(); - this.parentEventTarget_ = null; -}; - - -/** @override */ -goog.events.EventTarget.prototype.listen = function( - type, listener, opt_useCapture, opt_listenerScope) { - this.assertInitialized_(); - return this.eventTargetListeners_.add( - String(type), listener, false /* callOnce */, opt_useCapture, - opt_listenerScope); -}; - - -/** @override */ -goog.events.EventTarget.prototype.listenOnce = function( - type, listener, opt_useCapture, opt_listenerScope) { - return this.eventTargetListeners_.add( - String(type), listener, true /* callOnce */, opt_useCapture, - opt_listenerScope); -}; - - -/** @override */ -goog.events.EventTarget.prototype.unlisten = function( - type, listener, opt_useCapture, opt_listenerScope) { - return this.eventTargetListeners_.remove( - String(type), listener, opt_useCapture, opt_listenerScope); -}; - - -/** @override */ -goog.events.EventTarget.prototype.unlistenByKey = function(key) { - return this.eventTargetListeners_.removeByKey(key); -}; - - -/** @override */ -goog.events.EventTarget.prototype.removeAllListeners = function(opt_type) { - // TODO(chrishenry): Previously, removeAllListeners can be called on - // uninitialized EventTarget, so we preserve that behavior. We - // should remove this when usages that rely on that fact are purged. - if (!this.eventTargetListeners_) { - return 0; - } - return this.eventTargetListeners_.removeAll(opt_type); -}; - - -/** @override */ -goog.events.EventTarget.prototype.fireListeners = function( - type, capture, eventObject) { - // TODO(chrishenry): Original code avoids array creation when there - // is no listener, so we do the same. If this optimization turns - // out to be not required, we can replace this with - // getListeners(type, capture) instead, which is simpler. - var listenerArray = this.eventTargetListeners_.listeners[String(type)]; - if (!listenerArray) { - return true; - } - listenerArray = listenerArray.concat(); - - var rv = true; - for (var i = 0; i < listenerArray.length; ++i) { - var listener = listenerArray[i]; - // We might not have a listener if the listener was removed. - if (listener && !listener.removed && listener.capture == capture) { - var listenerFn = listener.listener; - var listenerHandler = listener.handler || listener.src; - - if (listener.callOnce) { - this.unlistenByKey(listener); - } - rv = listenerFn.call(listenerHandler, eventObject) !== false && rv; - } - } - - return rv && eventObject.returnValue_ != false; -}; - - -/** @override */ -goog.events.EventTarget.prototype.getListeners = function(type, capture) { - return this.eventTargetListeners_.getListeners(String(type), capture); -}; - - -/** @override */ -goog.events.EventTarget.prototype.getListener = function( - type, listener, capture, opt_listenerScope) { - return this.eventTargetListeners_.getListener( - String(type), listener, capture, opt_listenerScope); -}; - - -/** @override */ -goog.events.EventTarget.prototype.hasListener = function( - opt_type, opt_capture) { - var id = goog.isDef(opt_type) ? String(opt_type) : undefined; - return this.eventTargetListeners_.hasListener(id, opt_capture); +ol.extent.touches = function(extent1, extent2) { + var intersects = ol.extent.intersects(extent1, extent2); + return intersects && + (extent1[0] == extent2[2] || extent1[2] == extent2[0] || + extent1[1] == extent2[3] || extent1[3] == extent2[1]); }; /** - * Sets the target to be used for {@code event.target} when firing - * event. Mainly used for testing. For example, see - * {@code goog.testing.events.mixinListenable}. - * @param {!Object} target The target. + * Apply a transform function to the extent. + * @param {ol.Extent} extent Extent. + * @param {ol.TransformFunction} transformFn Transform function. Called with + * [minX, minY, maxX, maxY] extent coordinates. + * @param {ol.Extent=} opt_extent Destination extent. + * @return {ol.Extent} Extent. + * @api stable */ -goog.events.EventTarget.prototype.setTargetForTesting = function(target) { - this.actualEventTarget_ = target; +ol.extent.applyTransform = function(extent, transformFn, opt_extent) { + var coordinates = [ + extent[0], extent[1], + extent[0], extent[3], + extent[2], extent[1], + extent[2], extent[3] + ]; + transformFn(coordinates, coordinates, 2); + var xs = [coordinates[0], coordinates[2], coordinates[4], coordinates[6]]; + var ys = [coordinates[1], coordinates[3], coordinates[5], coordinates[7]]; + return ol.extent.boundingExtentXYs_(xs, ys, opt_extent); }; +goog.provide('ol.functions'); /** - * Asserts that the event target instance is initialized properly. - * @private + * Always returns true. + * @returns {boolean} true. */ -goog.events.EventTarget.prototype.assertInitialized_ = function() { - goog.asserts.assert( - this.eventTargetListeners_, - 'Event target is not initialized. Did you call the superclass ' + - '(goog.events.EventTarget) constructor?'); +ol.functions.TRUE = function() { + return true; }; - /** - * Dispatches the given event on the ancestorsTree. - * - * @param {!Object} target The target to dispatch on. - * @param {goog.events.Event|Object|string} e The event object. - * @param {Array<goog.events.Listenable>=} opt_ancestorsTree The ancestors - * tree of the target, in reverse order from the closest ancestor - * to the root event target. May be null if the target has no ancestor. - * @return {boolean} If anyone called preventDefault on the event object (or - * if any of the listeners returns false) this will also return false. - * @private + * Always returns false. + * @returns {boolean} false. */ -goog.events.EventTarget.dispatchEventInternal_ = function( - target, e, opt_ancestorsTree) { - var type = e.type || /** @type {string} */ (e); - - // If accepting a string or object, create a custom event object so that - // preventDefault and stopPropagation work with the event. - if (goog.isString(e)) { - e = new goog.events.Event(e, target); - } else if (!(e instanceof goog.events.Event)) { - var oldEvent = e; - e = new goog.events.Event(type, target); - goog.object.extend(e, oldEvent); - } else { - e.target = e.target || target; - } - - var rv = true, currentTarget; - - // Executes all capture listeners on the ancestors, if any. - if (opt_ancestorsTree) { - for (var i = opt_ancestorsTree.length - 1; !e.propagationStopped_ && i >= 0; - i--) { - currentTarget = e.currentTarget = opt_ancestorsTree[i]; - rv = currentTarget.fireListeners(type, true, e) && rv; - } - } - - // Executes capture and bubble listeners on the target. - if (!e.propagationStopped_) { - currentTarget = e.currentTarget = target; - rv = currentTarget.fireListeners(type, true, e) && rv; - if (!e.propagationStopped_) { - rv = currentTarget.fireListeners(type, false, e) && rv; - } - } - - // Executes all bubble listeners on the ancestors, if any. - if (opt_ancestorsTree) { - for (i = 0; !e.propagationStopped_ && i < opt_ancestorsTree.length; i++) { - currentTarget = e.currentTarget = opt_ancestorsTree[i]; - rv = currentTarget.fireListeners(type, false, e) && rv; - } - } - - return rv; +ol.functions.FALSE = function() { + return false; }; -goog.provide('ol.Observable'); +/** + * @license + * Latitude/longitude spherical geodesy formulae taken from + * http://www.movable-type.co.uk/scripts/latlong.html + * Licensed under CC-BY-3.0. + */ -goog.require('goog.events'); -goog.require('goog.events.EventTarget'); -goog.require('goog.events.EventType'); +goog.provide('ol.Sphere'); +goog.require('ol.math'); /** * @classdesc - * Abstract base class; normally only used for creating subclasses and not - * instantiated in apps. - * An event target providing convenient methods for listener registration - * and unregistration. A generic `change` event is always available through - * {@link ol.Observable#changed}. + * Class to create objects that can be used with {@link + * ol.geom.Polygon.circular}. + * + * For example to create a sphere whose radius is equal to the semi-major + * axis of the WGS84 ellipsoid: + * + * ```js + * var wgs84Sphere= new ol.Sphere(6378137); + * ``` * * @constructor - * @extends {goog.events.EventTarget} - * @fires change - * @struct - * @api stable + * @param {number} radius Radius. + * @api */ -ol.Observable = function() { - - goog.base(this); +ol.Sphere = function(radius) { /** - * @private * @type {number} */ - this.revision_ = 0; + this.radius = radius; }; -goog.inherits(ol.Observable, goog.events.EventTarget); /** - * Removes an event listener using the key returned by `on()` or `once()`. - * @param {goog.events.Key} key The key returned by `on()` or `once()`. - * @api stable + * Returns the geodesic area for a list of coordinates. + * + * [Reference](http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409) + * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for + * Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion + * Laboratory, Pasadena, CA, June 2007 + * + * @param {Array.<ol.Coordinate>} coordinates List of coordinates of a linear + * ring. If the ring is oriented clockwise, the area will be positive, + * otherwise it will be negative. + * @return {number} Area. + * @api */ -ol.Observable.unByKey = function(key) { - goog.events.unlistenByKey(key); +ol.Sphere.prototype.geodesicArea = function(coordinates) { + var area = 0, len = coordinates.length; + var x1 = coordinates[len - 1][0]; + var y1 = coordinates[len - 1][1]; + for (var i = 0; i < len; i++) { + var x2 = coordinates[i][0], y2 = coordinates[i][1]; + area += ol.math.toRadians(x2 - x1) * + (2 + Math.sin(ol.math.toRadians(y1)) + + Math.sin(ol.math.toRadians(y2))); + x1 = x2; + y1 = y2; + } + return area * this.radius * this.radius / 2.0; }; /** - * Increases the revision counter and dispatches a 'change' event. + * Returns the distance from c1 to c2 using the haversine formula. + * + * @param {ol.Coordinate} c1 Coordinate 1. + * @param {ol.Coordinate} c2 Coordinate 2. + * @return {number} Haversine distance. * @api */ -ol.Observable.prototype.changed = function() { - ++this.revision_; - this.dispatchEvent(goog.events.EventType.CHANGE); +ol.Sphere.prototype.haversineDistance = function(c1, c2) { + var lat1 = ol.math.toRadians(c1[1]); + var lat2 = ol.math.toRadians(c2[1]); + var deltaLatBy2 = (lat2 - lat1) / 2; + var deltaLonBy2 = ol.math.toRadians(c2[0] - c1[0]) / 2; + var a = Math.sin(deltaLatBy2) * Math.sin(deltaLatBy2) + + Math.sin(deltaLonBy2) * Math.sin(deltaLonBy2) * + Math.cos(lat1) * Math.cos(lat2); + return 2 * this.radius * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); }; /** - * Triggered when the revision counter is increased. - * @event change - * @api + * Returns the coordinate at the given distance and bearing from `c1`. + * + * @param {ol.Coordinate} c1 The origin point (`[lon, lat]` in degrees). + * @param {number} distance The great-circle distance between the origin + * point and the target point. + * @param {number} bearing The bearing (in radians). + * @return {ol.Coordinate} The target point. */ +ol.Sphere.prototype.offset = function(c1, distance, bearing) { + var lat1 = ol.math.toRadians(c1[1]); + var lon1 = ol.math.toRadians(c1[0]); + var dByR = distance / this.radius; + var lat = Math.asin( + Math.sin(lat1) * Math.cos(dByR) + + Math.cos(lat1) * Math.sin(dByR) * Math.cos(bearing)); + var lon = lon1 + Math.atan2( + Math.sin(bearing) * Math.sin(dByR) * Math.cos(lat1), + Math.cos(dByR) - Math.sin(lat1) * Math.sin(lat)); + return [ol.math.toDegrees(lon), ol.math.toDegrees(lat)]; +}; +goog.provide('ol.sphere.NORMAL'); -/** - * Dispatches an event and calls all listeners listening for events - * of this type. The event parameter can either be a string or an - * Object with a `type` property. - * - * @param {goog.events.EventLike} event Event object. - * @function - * @api - */ -ol.Observable.prototype.dispatchEvent; +goog.require('ol.Sphere'); /** - * Get the version number for this object. Each time the object is modified, - * its version number will be incremented. - * @return {number} Revision. - * @api + * The normal sphere. + * @const + * @type {ol.Sphere} */ -ol.Observable.prototype.getRevision = function() { - return this.revision_; -}; +ol.sphere.NORMAL = new ol.Sphere(6370997); +goog.provide('ol.proj'); +goog.provide('ol.proj.METERS_PER_UNIT'); +goog.provide('ol.proj.Projection'); +goog.provide('ol.proj.Units'); -/** - * Listen for a certain type of event. - * @param {string|Array.<string>} type The event type or array of event types. - * @param {function(?): ?} listener The listener function. - * @param {Object=} opt_this The object to use as `this` in `listener`. - * @return {goog.events.Key} Unique key for the listener. - * @api stable - */ -ol.Observable.prototype.on = function(type, listener, opt_this) { - return goog.events.listen(this, type, listener, false, opt_this); -}; +goog.require('goog.asserts'); +goog.require('ol'); +goog.require('ol.extent'); +goog.require('ol.object'); +goog.require('ol.sphere.NORMAL'); /** - * Listen once for a certain type of event. - * @param {string|Array.<string>} type The event type or array of event types. - * @param {function(?): ?} listener The listener function. - * @param {Object=} opt_this The object to use as `this` in `listener`. - * @return {goog.events.Key} Unique key for the listener. + * Projection units: `'degrees'`, `'ft'`, `'m'`, `'pixels'`, `'tile-pixels'` or + * `'us-ft'`. + * @enum {string} * @api stable */ -ol.Observable.prototype.once = function(type, listener, opt_this) { - return goog.events.listenOnce(this, type, listener, false, opt_this); +ol.proj.Units = { + DEGREES: 'degrees', + FEET: 'ft', + METERS: 'm', + PIXELS: 'pixels', + TILE_PIXELS: 'tile-pixels', + USFEET: 'us-ft' }; /** - * Unlisten for a certain type of event. - * @param {string|Array.<string>} type The event type or array of event types. - * @param {function(?): ?} listener The listener function. - * @param {Object=} opt_this The object which was used as `this` by the - * `listener`. + * Meters per unit lookup table. + * @const + * @type {Object.<ol.proj.Units, number>} * @api stable */ -ol.Observable.prototype.un = function(type, listener, opt_this) { - goog.events.unlisten(this, type, listener, false, opt_this); -}; +ol.proj.METERS_PER_UNIT = {}; +ol.proj.METERS_PER_UNIT[ol.proj.Units.DEGREES] = + 2 * Math.PI * ol.sphere.NORMAL.radius / 360; +ol.proj.METERS_PER_UNIT[ol.proj.Units.FEET] = 0.3048; +ol.proj.METERS_PER_UNIT[ol.proj.Units.METERS] = 1; +ol.proj.METERS_PER_UNIT[ol.proj.Units.USFEET] = 1200 / 3937; /** - * Removes an event listener using the key returned by `on()` or `once()`. - * Note that using the {@link ol.Observable.unByKey} static function is to - * be preferred. - * @param {goog.events.Key} key The key returned by `on()` or `once()`. - * @function + * @classdesc + * Projection definition class. One of these is created for each projection + * supported in the application and stored in the {@link ol.proj} namespace. + * You can use these in applications, but this is not required, as API params + * and options use {@link ol.proj.ProjectionLike} which means the simple string + * code will suffice. + * + * You can use {@link ol.proj.get} to retrieve the object for a particular + * projection. + * + * The library includes definitions for `EPSG:4326` and `EPSG:3857`, together + * with the following aliases: + * * `EPSG:4326`: CRS:84, urn:ogc:def:crs:EPSG:6.6:4326, + * urn:ogc:def:crs:OGC:1.3:CRS84, urn:ogc:def:crs:OGC:2:84, + * http://www.opengis.net/gml/srs/epsg.xml#4326, + * urn:x-ogc:def:crs:EPSG:4326 + * * `EPSG:3857`: EPSG:102100, EPSG:102113, EPSG:900913, + * urn:ogc:def:crs:EPSG:6.18:3:3857, + * http://www.opengis.net/gml/srs/epsg.xml#3857 + * + * If you use proj4js, aliases can be added using `proj4.defs()`; see + * [documentation](https://github.com/proj4js/proj4js). To set an alternative + * namespace for proj4, use {@link ol.proj.setProj4}. + * + * @constructor + * @param {olx.ProjectionOptions} options Projection options. + * @struct * @api stable */ -ol.Observable.prototype.unByKey = ol.Observable.unByKey; - -goog.provide('ol.Object'); -goog.provide('ol.ObjectEvent'); -goog.provide('ol.ObjectEventType'); - -goog.require('goog.events'); -goog.require('goog.events.Event'); -goog.require('ol.Observable'); - +ol.proj.Projection = function(options) { -/** - * @enum {string} - */ -ol.ObjectEventType = { /** - * Triggered when a property is changed. - * @event ol.ObjectEvent#propertychange - * @api stable + * @private + * @type {string} */ - PROPERTYCHANGE: 'propertychange' -}; + this.code_ = options.code; + /** + * @private + * @type {ol.proj.Units} + */ + this.units_ = /** @type {ol.proj.Units} */ (options.units); + /** + * @private + * @type {ol.Extent} + */ + this.extent_ = options.extent !== undefined ? options.extent : null; -/** - * @classdesc - * Events emitted by {@link ol.Object} instances are instances of this type. - * - * @param {string} type The event type. - * @param {string} key The property name. - * @param {*} oldValue The old value for `key`. - * @extends {goog.events.Event} - * @implements {oli.ObjectEvent} - * @constructor - */ -ol.ObjectEvent = function(type, key, oldValue) { - goog.base(this, type); + /** + * @private + * @type {ol.Extent} + */ + this.worldExtent_ = options.worldExtent !== undefined ? + options.worldExtent : null; /** - * The name of the property whose value is changing. + * @private * @type {string} - * @api stable */ - this.key = key; + this.axisOrientation_ = options.axisOrientation !== undefined ? + options.axisOrientation : 'enu'; /** - * The old value. To get the new value use `e.target.get(e.key)` where - * `e` is the event object. - * @type {*} - * @api stable + * @private + * @type {boolean} */ - this.oldValue = oldValue; - -}; -goog.inherits(ol.ObjectEvent, goog.events.Event); + this.global_ = options.global !== undefined ? options.global : false; + /** + * @private + * @type {boolean} + */ + this.canWrapX_ = !!(this.global_ && this.extent_); -/** - * @classdesc - * Abstract base class; normally only used for creating subclasses and not - * instantiated in apps. - * Most non-trivial classes inherit from this. - * - * This extends {@link ol.Observable} with observable properties, where each - * property is observable as well as the object as a whole. - * - * Classes that inherit from this have pre-defined properties, to which you can - * add your owns. The pre-defined properties are listed in this documentation as - * 'Observable Properties', and have their own accessors; for example, - * {@link ol.Map} has a `target` property, accessed with `getTarget()` and - * changed with `setTarget()`. Not all properties are however settable. There - * are also general-purpose accessors `get()` and `set()`. For example, - * `get('target')` is equivalent to `getTarget()`. - * - * The `set` accessors trigger a change event, and you can monitor this by - * registering a listener. For example, {@link ol.View} has a `center` - * property, so `view.on('change:center', function(evt) {...});` would call the - * function whenever the value of the center property changes. Within the - * function, `evt.target` would be the view, so `evt.target.getCenter()` would - * return the new center. - * - * You can add your own observable properties with - * `object.set('prop', 'value')`, and retrieve that with `object.get('prop')`. - * You can listen for changes on that property value with - * `object.on('change:prop', listener)`. You can get a list of all - * properties with {@link ol.Object#getProperties object.getProperties()}. - * - * Note that the observable properties are separate from standard JS properties. - * You can, for example, give your map object a title with - * `map.title='New title'` and with `map.set('title', 'Another title')`. The - * first will be a `hasOwnProperty`; the second will appear in - * `getProperties()`. Only the second is observable. - * - * Properties can be deleted by using the unset method. E.g. - * object.unset('foo'). - * - * @constructor - * @extends {ol.Observable} - * @param {Object.<string, *>=} opt_values An object with key-value pairs. - * @fires ol.ObjectEvent - * @api - */ -ol.Object = function(opt_values) { - goog.base(this); + /** + * @private + * @type {function(number, ol.Coordinate):number} + */ + this.getPointResolutionFunc_ = options.getPointResolution !== undefined ? + options.getPointResolution : this.getPointResolution_; - // Call goog.getUid to ensure that the order of objects' ids is the same as - // the order in which they were created. This also helps to ensure that - // object properties are always added in the same order, which helps many - // JavaScript engines generate faster code. - goog.getUid(this); + /** + * @private + * @type {ol.tilegrid.TileGrid} + */ + this.defaultTileGrid_ = null; /** * @private - * @type {!Object.<string, *>} + * @type {number|undefined} */ - this.values_ = {}; + this.metersPerUnit_ = options.metersPerUnit; - if (opt_values !== undefined) { - this.setProperties(opt_values); + var projections = ol.proj.projections_; + var code = options.code; + goog.asserts.assert(code !== undefined, + 'Option "code" is required for constructing instance'); + if (ol.ENABLE_PROJ4JS) { + var proj4js = ol.proj.proj4_ || ol.global['proj4']; + if (typeof proj4js == 'function' && projections[code] === undefined) { + var def = proj4js.defs(code); + if (def !== undefined) { + if (def.axis !== undefined && options.axisOrientation === undefined) { + this.axisOrientation_ = def.axis; + } + if (options.metersPerUnit === undefined) { + this.metersPerUnit_ = def.to_meter; + } + if (options.units === undefined) { + this.units_ = def.units; + } + var currentCode, currentDef, currentProj, proj4Transform; + for (currentCode in projections) { + currentDef = proj4js.defs(currentCode); + if (currentDef !== undefined) { + currentProj = ol.proj.get(currentCode); + if (currentDef === def) { + ol.proj.addEquivalentProjections([currentProj, this]); + } else { + proj4Transform = proj4js(currentCode, code); + ol.proj.addCoordinateTransforms(currentProj, this, + proj4Transform.forward, proj4Transform.inverse); + } + } + } + } + } } + }; -goog.inherits(ol.Object, ol.Observable); /** - * @private - * @type {Object.<string, string>} + * @return {boolean} The projection is suitable for wrapping the x-axis */ -ol.Object.changeEventTypeCache_ = {}; +ol.proj.Projection.prototype.canWrapX = function() { + return this.canWrapX_; +}; /** - * @param {string} key Key name. - * @return {string} Change name. + * Get the code for this projection, e.g. 'EPSG:4326'. + * @return {string} Code. + * @api stable */ -ol.Object.getChangeEventType = function(key) { - return ol.Object.changeEventTypeCache_.hasOwnProperty(key) ? - ol.Object.changeEventTypeCache_[key] : - (ol.Object.changeEventTypeCache_[key] = 'change:' + key); +ol.proj.Projection.prototype.getCode = function() { + return this.code_; }; /** - * Gets a value. - * @param {string} key Key name. - * @return {*} Value. + * Get the validity extent for this projection. + * @return {ol.Extent} Extent. * @api stable */ -ol.Object.prototype.get = function(key) { - var value; - if (this.values_.hasOwnProperty(key)) { - value = this.values_[key]; - } - return value; +ol.proj.Projection.prototype.getExtent = function() { + return this.extent_; }; /** - * Get a list of object property names. - * @return {Array.<string>} List of property names. + * Get the units of this projection. + * @return {ol.proj.Units} Units. * @api stable */ -ol.Object.prototype.getKeys = function() { - return Object.keys(this.values_); +ol.proj.Projection.prototype.getUnits = function() { + return this.units_; }; /** - * Get an object of all property names and values. - * @return {Object.<string, *>} Object. + * Get the amount of meters per unit of this projection. If the projection is + * not configured with `metersPerUnit` or a units identifier, the return is + * `undefined`. + * @return {number|undefined} Meters. * @api stable */ -ol.Object.prototype.getProperties = function() { - var properties = {}; - var key; - for (key in this.values_) { - properties[key] = this.values_[key]; - } - return properties; +ol.proj.Projection.prototype.getMetersPerUnit = function() { + return this.metersPerUnit_ || ol.proj.METERS_PER_UNIT[this.units_]; }; /** - * @param {string} key Key name. - * @param {*} oldValue Old value. + * Get the world extent for this projection. + * @return {ol.Extent} Extent. + * @api */ -ol.Object.prototype.notify = function(key, oldValue) { - var eventType; - eventType = ol.Object.getChangeEventType(key); - this.dispatchEvent(new ol.ObjectEvent(eventType, key, oldValue)); - eventType = ol.ObjectEventType.PROPERTYCHANGE; - this.dispatchEvent(new ol.ObjectEvent(eventType, key, oldValue)); +ol.proj.Projection.prototype.getWorldExtent = function() { + return this.worldExtent_; }; /** - * Sets a value. - * @param {string} key Key name. - * @param {*} value Value. - * @param {boolean=} opt_silent Update without triggering an event. - * @api stable + * Get the axis orientation of this projection. + * Example values are: + * enu - the default easting, northing, elevation. + * neu - northing, easting, up - useful for "lat/long" geographic coordinates, + * or south orientated transverse mercator. + * wnu - westing, northing, up - some planetary coordinate systems have + * "west positive" coordinate systems + * @return {string} Axis orientation. */ -ol.Object.prototype.set = function(key, value, opt_silent) { - if (opt_silent) { - this.values_[key] = value; - } else { - var oldValue = this.values_[key]; - this.values_[key] = value; - if (oldValue !== value) { - this.notify(key, oldValue); - } - } +ol.proj.Projection.prototype.getAxisOrientation = function() { + return this.axisOrientation_; }; /** - * Sets a collection of key-value pairs. Note that this changes any existing - * properties and adds new ones (it does not remove any existing properties). - * @param {Object.<string, *>} values Values. - * @param {boolean=} opt_silent Update without triggering an event. + * Is this projection a global projection which spans the whole world? + * @return {boolean} Whether the projection is global. * @api stable */ -ol.Object.prototype.setProperties = function(values, opt_silent) { - var key; - for (key in values) { - this.set(key, values[key], opt_silent); - } +ol.proj.Projection.prototype.isGlobal = function() { + return this.global_; }; /** - * Unsets a property. - * @param {string} key Key name. - * @param {boolean=} opt_silent Unset without triggering an event. - * @api stable - */ -ol.Object.prototype.unset = function(key, opt_silent) { - if (key in this.values_) { - var oldValue = this.values_[key]; - delete this.values_[key]; - if (!opt_silent) { - this.notify(key, oldValue); - } - } +* Set if the projection is a global projection which spans the whole world +* @param {boolean} global Whether the projection is global. +* @api stable +*/ +ol.proj.Projection.prototype.setGlobal = function(global) { + this.global_ = global; + this.canWrapX_ = !!(global && this.extent_); }; -goog.provide('ol.Size'); -goog.provide('ol.size'); - - -goog.require('goog.asserts'); - /** - * An array of numbers representing a size: `[width, height]`. - * @typedef {Array.<number>} - * @api stable + * @return {ol.tilegrid.TileGrid} The default tile grid. */ -ol.Size; +ol.proj.Projection.prototype.getDefaultTileGrid = function() { + return this.defaultTileGrid_; +}; /** - * Returns a buffered size. - * @param {ol.Size} size Size. - * @param {number} buffer Buffer. - * @param {ol.Size=} opt_size Optional reusable size array. - * @return {ol.Size} + * @param {ol.tilegrid.TileGrid} tileGrid The default tile grid. */ -ol.size.buffer = function(size, buffer, opt_size) { - if (opt_size === undefined) { - opt_size = [0, 0]; - } - opt_size[0] = size[0] + 2 * buffer; - opt_size[1] = size[1] + 2 * buffer; - return opt_size; +ol.proj.Projection.prototype.setDefaultTileGrid = function(tileGrid) { + this.defaultTileGrid_ = tileGrid; }; /** - * Compares sizes for equality. - * @param {ol.Size} a Size. - * @param {ol.Size} b Size. - * @return {boolean} Equals. + * Set the validity extent for this projection. + * @param {ol.Extent} extent Extent. + * @api stable */ -ol.size.equals = function(a, b) { - return a[0] == b[0] && a[1] == b[1]; +ol.proj.Projection.prototype.setExtent = function(extent) { + this.extent_ = extent; + this.canWrapX_ = !!(this.global_ && extent); }; /** - * Determines if a size has a positive area. - * @param {ol.Size} size The size to test. - * @return {boolean} The size has a positive area. + * Set the world extent for this projection. + * @param {ol.Extent} worldExtent World extent + * [minlon, minlat, maxlon, maxlat]. + * @api */ -ol.size.hasArea = function(size) { - return size[0] > 0 && size[1] > 0; +ol.proj.Projection.prototype.setWorldExtent = function(worldExtent) { + this.worldExtent_ = worldExtent; }; /** - * Returns a size scaled by a ratio. The result will be an array of integers. - * @param {ol.Size} size Size. - * @param {number} ratio Ratio. - * @param {ol.Size=} opt_size Optional reusable size array. - * @return {ol.Size} - */ -ol.size.scale = function(size, ratio, opt_size) { - if (opt_size === undefined) { - opt_size = [0, 0]; - } - opt_size[0] = (size[0] * ratio + 0.5) | 0; - opt_size[1] = (size[1] * ratio + 0.5) | 0; - return opt_size; +* Set the getPointResolution function for this projection. +* @param {function(number, ol.Coordinate):number} func Function +* @api +*/ +ol.proj.Projection.prototype.setGetPointResolution = function(func) { + this.getPointResolutionFunc_ = func; }; /** - * Returns an `ol.Size` array for the passed in number (meaning: square) or - * `ol.Size` array. - * (meaning: non-square), - * @param {number|ol.Size} size Width and height. - * @param {ol.Size=} opt_size Optional reusable size array. - * @return {ol.Size} Size. - * @api stable - */ -ol.size.toSize = function(size, opt_size) { - if (goog.isArray(size)) { - return size; +* Default version. +* Get the resolution of the point in degrees or distance units. +* For projections with degrees as the unit this will simply return the +* provided resolution. For other projections the point resolution is +* estimated by transforming the 'point' pixel to EPSG:4326, +* measuring its width and height on the normal sphere, +* and taking the average of the width and height. +* @param {number} resolution Nominal resolution in projection units. +* @param {ol.Coordinate} point Point to find adjusted resolution at. +* @return {number} Point resolution at point in projection units. +* @private +*/ +ol.proj.Projection.prototype.getPointResolution_ = function(resolution, point) { + var units = this.getUnits(); + if (units == ol.proj.Units.DEGREES) { + return resolution; } else { - goog.asserts.assert(goog.isNumber(size)); - if (opt_size === undefined) { - opt_size = [size, size]; - } else { - opt_size[0] = size; - opt_size[1] = size; + // Estimate point resolution by transforming the center pixel to EPSG:4326, + // measuring its width and height on the normal sphere, and taking the + // average of the width and height. + var toEPSG4326 = ol.proj.getTransformFromProjections( + this, ol.proj.get('EPSG:4326')); + var vertices = [ + point[0] - resolution / 2, point[1], + point[0] + resolution / 2, point[1], + point[0], point[1] - resolution / 2, + point[0], point[1] + resolution / 2 + ]; + vertices = toEPSG4326(vertices, vertices, 2); + var width = ol.sphere.NORMAL.haversineDistance( + vertices.slice(0, 2), vertices.slice(2, 4)); + var height = ol.sphere.NORMAL.haversineDistance( + vertices.slice(4, 6), vertices.slice(6, 8)); + var pointResolution = (width + height) / 2; + var metersPerUnit = this.getMetersPerUnit(); + if (metersPerUnit !== undefined) { + pointResolution /= metersPerUnit; } - return opt_size; + return pointResolution; } }; -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. /** - * @fileoverview Additional mathematical functions. + * Get the resolution of the point in degrees or distance units. + * For projections with degrees as the unit this will simply return the + * provided resolution. The default for other projections is to estimate + * the point resolution by transforming the 'point' pixel to EPSG:4326, + * measuring its width and height on the normal sphere, + * and taking the average of the width and height. + * An alternative implementation may be given when constructing a + * projection. For many local projections, + * such a custom function will return the resolution unchanged. + * @param {number} resolution Resolution in projection units. + * @param {ol.Coordinate} point Point. + * @return {number} Point resolution in projection units. + * @api */ +ol.proj.Projection.prototype.getPointResolution = function(resolution, point) { + return this.getPointResolutionFunc_(resolution, point); +}; -goog.provide('goog.math'); -goog.require('goog.array'); -goog.require('goog.asserts'); +/** + * @private + * @type {Object.<string, ol.proj.Projection>} + */ +ol.proj.projections_ = {}; /** - * Returns a random integer greater than or equal to 0 and less than {@code a}. - * @param {number} a The upper bound for the random integer (exclusive). - * @return {number} A random integer N such that 0 <= N < a. + * @private + * @type {Object.<string, Object.<string, ol.TransformFunction>>} */ -goog.math.randomInt = function(a) { - return Math.floor(Math.random() * a); -}; +ol.proj.transforms_ = {}; /** - * Returns a random number greater than or equal to {@code a} and less than - * {@code b}. - * @param {number} a The lower bound for the random number (inclusive). - * @param {number} b The upper bound for the random number (exclusive). - * @return {number} A random number N such that a <= N < b. + * @private + * @type {proj4} */ -goog.math.uniformRandom = function(a, b) { - return a + Math.random() * (b - a); -}; +ol.proj.proj4_ = null; + + +if (ol.ENABLE_PROJ4JS) { + /** + * Register proj4. If not explicitly registered, it will be assumed that + * proj4js will be loaded in the global namespace. For example in a + * browserify ES6 environment you could use: + * + * import ol from 'openlayers'; + * import proj4 from 'proj4'; + * ol.proj.setProj4(proj4); + * + * @param {proj4} proj4 Proj4. + * @api + */ + ol.proj.setProj4 = function(proj4) { + goog.asserts.assert(typeof proj4 == 'function', + 'proj4 argument should be a function'); + ol.proj.proj4_ = proj4; + }; +} /** - * Takes a number and clamps it to within the provided bounds. - * @param {number} value The input number. - * @param {number} min The minimum value to return. - * @param {number} max The maximum value to return. - * @return {number} The input number if it is within bounds, or the nearest - * number within the bounds. + * Registers transformation functions that don't alter coordinates. Those allow + * to transform between projections with equal meaning. + * + * @param {Array.<ol.proj.Projection>} projections Projections. + * @api */ -goog.math.clamp = function(value, min, max) { - return Math.min(Math.max(value, min), max); +ol.proj.addEquivalentProjections = function(projections) { + ol.proj.addProjections(projections); + projections.forEach(function(source) { + projections.forEach(function(destination) { + if (source !== destination) { + ol.proj.addTransform(source, destination, ol.proj.cloneTransform); + } + }); + }); }; /** - * The % operator in JavaScript returns the remainder of a / b, but differs from - * some other languages in that the result will have the same sign as the - * dividend. For example, -1 % 8 == -1, whereas in some other languages - * (such as Python) the result would be 7. This function emulates the more - * correct modulo behavior, which is useful for certain applications such as - * calculating an offset index in a circular list. + * Registers transformation functions to convert coordinates in any projection + * in projection1 to any projection in projection2. * - * @param {number} a The dividend. - * @param {number} b The divisor. - * @return {number} a % b where the result is between 0 and b (either 0 <= x < b - * or b < x <= 0, depending on the sign of b). + * @param {Array.<ol.proj.Projection>} projections1 Projections with equal + * meaning. + * @param {Array.<ol.proj.Projection>} projections2 Projections with equal + * meaning. + * @param {ol.TransformFunction} forwardTransform Transformation from any + * projection in projection1 to any projection in projection2. + * @param {ol.TransformFunction} inverseTransform Transform from any projection + * in projection2 to any projection in projection1.. */ -goog.math.modulo = function(a, b) { - var r = a % b; - // If r and b differ in sign, add b to wrap the result to the correct sign. - return (r * b < 0) ? r + b : r; +ol.proj.addEquivalentTransforms = function(projections1, projections2, forwardTransform, inverseTransform) { + projections1.forEach(function(projection1) { + projections2.forEach(function(projection2) { + ol.proj.addTransform(projection1, projection2, forwardTransform); + ol.proj.addTransform(projection2, projection1, inverseTransform); + }); + }); }; /** - * Performs linear interpolation between values a and b. Returns the value - * between a and b proportional to x (when x is between 0 and 1. When x is - * outside this range, the return value is a linear extrapolation). - * @param {number} a A number. - * @param {number} b A number. - * @param {number} x The proportion between a and b. - * @return {number} The interpolated value between a and b. + * Add a Projection object to the list of supported projections that can be + * looked up by their code. + * + * @param {ol.proj.Projection} projection Projection instance. + * @api stable */ -goog.math.lerp = function(a, b, x) { - return a + x * (b - a); +ol.proj.addProjection = function(projection) { + ol.proj.projections_[projection.getCode()] = projection; + ol.proj.addTransform(projection, projection, ol.proj.cloneTransform); }; /** - * Tests whether the two values are equal to each other, within a certain - * tolerance to adjust for floating point errors. - * @param {number} a A number. - * @param {number} b A number. - * @param {number=} opt_tolerance Optional tolerance range. Defaults - * to 0.000001. If specified, should be greater than 0. - * @return {boolean} Whether {@code a} and {@code b} are nearly equal. + * @param {Array.<ol.proj.Projection>} projections Projections. */ -goog.math.nearlyEquals = function(a, b, opt_tolerance) { - return Math.abs(a - b) <= (opt_tolerance || 0.000001); +ol.proj.addProjections = function(projections) { + var addedProjections = []; + projections.forEach(function(projection) { + addedProjections.push(ol.proj.addProjection(projection)); + }); }; -// TODO(user): Rename to normalizeAngle, retaining old name as deprecated -// alias. /** - * Normalizes an angle to be in range [0-360). Angles outside this range will - * be normalized to be the equivalent angle with that range. - * @param {number} angle Angle in degrees. - * @return {number} Standardized angle. + * FIXME empty description for jsdoc */ -goog.math.standardAngle = function(angle) { - return goog.math.modulo(angle, 360); +ol.proj.clearAllProjections = function() { + ol.proj.projections_ = {}; + ol.proj.transforms_ = {}; }; /** - * Normalizes an angle to be in range [0-2*PI). Angles outside this range will - * be normalized to be the equivalent angle with that range. - * @param {number} angle Angle in radians. - * @return {number} Standardized angle. + * @param {ol.proj.Projection|string|undefined} projection Projection. + * @param {string} defaultCode Default code. + * @return {ol.proj.Projection} Projection. */ -goog.math.standardAngleInRadians = function(angle) { - return goog.math.modulo(angle, 2 * Math.PI); +ol.proj.createProjection = function(projection, defaultCode) { + if (!projection) { + return ol.proj.get(defaultCode); + } else if (typeof projection === 'string') { + return ol.proj.get(projection); + } else { + goog.asserts.assertInstanceof(projection, ol.proj.Projection, + 'projection should be an ol.proj.Projection'); + return projection; + } }; /** - * Converts degrees to radians. - * @param {number} angleDegrees Angle in degrees. - * @return {number} Angle in radians. + * Registers a conversion function to convert coordinates from the source + * projection to the destination projection. + * + * @param {ol.proj.Projection} source Source. + * @param {ol.proj.Projection} destination Destination. + * @param {ol.TransformFunction} transformFn Transform. */ -goog.math.toRadians = function(angleDegrees) { - return angleDegrees * Math.PI / 180; +ol.proj.addTransform = function(source, destination, transformFn) { + var sourceCode = source.getCode(); + var destinationCode = destination.getCode(); + var transforms = ol.proj.transforms_; + if (!(sourceCode in transforms)) { + transforms[sourceCode] = {}; + } + transforms[sourceCode][destinationCode] = transformFn; }; /** - * Converts radians to degrees. - * @param {number} angleRadians Angle in radians. - * @return {number} Angle in degrees. + * Registers coordinate transform functions to convert coordinates between the + * source projection and the destination projection. + * The forward and inverse functions convert coordinate pairs; this function + * converts these into the functions used internally which also handle + * extents and coordinate arrays. + * + * @param {ol.proj.ProjectionLike} source Source projection. + * @param {ol.proj.ProjectionLike} destination Destination projection. + * @param {function(ol.Coordinate): ol.Coordinate} forward The forward transform + * function (that is, from the source projection to the destination + * projection) that takes a {@link ol.Coordinate} as argument and returns + * the transformed {@link ol.Coordinate}. + * @param {function(ol.Coordinate): ol.Coordinate} inverse The inverse transform + * function (that is, from the destination projection to the source + * projection) that takes a {@link ol.Coordinate} as argument and returns + * the transformed {@link ol.Coordinate}. + * @api stable */ -goog.math.toDegrees = function(angleRadians) { - return angleRadians * 180 / Math.PI; +ol.proj.addCoordinateTransforms = function(source, destination, forward, inverse) { + var sourceProj = ol.proj.get(source); + var destProj = ol.proj.get(destination); + ol.proj.addTransform(sourceProj, destProj, + ol.proj.createTransformFromCoordinateTransform(forward)); + ol.proj.addTransform(destProj, sourceProj, + ol.proj.createTransformFromCoordinateTransform(inverse)); }; /** - * For a given angle and radius, finds the X portion of the offset. - * @param {number} degrees Angle in degrees (zero points in +X direction). - * @param {number} radius Radius. - * @return {number} The x-distance for the angle and radius. + * Creates a {@link ol.TransformFunction} from a simple 2D coordinate transform + * function. + * @param {function(ol.Coordinate): ol.Coordinate} transform Coordinate + * transform. + * @return {ol.TransformFunction} Transform function. */ -goog.math.angleDx = function(degrees, radius) { - return radius * Math.cos(goog.math.toRadians(degrees)); +ol.proj.createTransformFromCoordinateTransform = function(transform) { + return ( + /** + * @param {Array.<number>} input Input. + * @param {Array.<number>=} opt_output Output. + * @param {number=} opt_dimension Dimension. + * @return {Array.<number>} Output. + */ + function(input, opt_output, opt_dimension) { + var length = input.length; + var dimension = opt_dimension !== undefined ? opt_dimension : 2; + var output = opt_output !== undefined ? opt_output : new Array(length); + var point, i, j; + for (i = 0; i < length; i += dimension) { + point = transform([input[i], input[i + 1]]); + output[i] = point[0]; + output[i + 1] = point[1]; + for (j = dimension - 1; j >= 2; --j) { + output[i + j] = input[i + j]; + } + } + return output; + }); }; /** - * For a given angle and radius, finds the Y portion of the offset. - * @param {number} degrees Angle in degrees (zero points in +X direction). - * @param {number} radius Radius. - * @return {number} The y-distance for the angle and radius. + * Unregisters the conversion function to convert coordinates from the source + * projection to the destination projection. This method is used to clean up + * cached transforms during testing. + * + * @param {ol.proj.Projection} source Source projection. + * @param {ol.proj.Projection} destination Destination projection. + * @return {ol.TransformFunction} transformFn The unregistered transform. */ -goog.math.angleDy = function(degrees, radius) { - return radius * Math.sin(goog.math.toRadians(degrees)); +ol.proj.removeTransform = function(source, destination) { + var sourceCode = source.getCode(); + var destinationCode = destination.getCode(); + var transforms = ol.proj.transforms_; + goog.asserts.assert(sourceCode in transforms, + 'sourceCode should be in transforms'); + goog.asserts.assert(destinationCode in transforms[sourceCode], + 'destinationCode should be in transforms of sourceCode'); + var transform = transforms[sourceCode][destinationCode]; + delete transforms[sourceCode][destinationCode]; + if (ol.object.isEmpty(transforms[sourceCode])) { + delete transforms[sourceCode]; + } + return transform; }; /** - * Computes the angle between two points (x1,y1) and (x2,y2). - * Angle zero points in the +X direction, 90 degrees points in the +Y - * direction (down) and from there we grow clockwise towards 360 degrees. - * @param {number} x1 x of first point. - * @param {number} y1 y of first point. - * @param {number} x2 x of second point. - * @param {number} y2 y of second point. - * @return {number} Standardized angle in degrees of the vector from - * x1,y1 to x2,y2. + * Transforms a coordinate from longitude/latitude to a different projection. + * @param {ol.Coordinate} coordinate Coordinate as longitude and latitude, i.e. + * an array with longitude as 1st and latitude as 2nd element. + * @param {ol.proj.ProjectionLike=} opt_projection Target projection. The + * default is Web Mercator, i.e. 'EPSG:3857'. + * @return {ol.Coordinate} Coordinate projected to the target projection. + * @api stable */ -goog.math.angle = function(x1, y1, x2, y2) { - return goog.math.standardAngle(goog.math.toDegrees(Math.atan2(y2 - y1, - x2 - x1))); +ol.proj.fromLonLat = function(coordinate, opt_projection) { + return ol.proj.transform(coordinate, 'EPSG:4326', + opt_projection !== undefined ? opt_projection : 'EPSG:3857'); }; /** - * Computes the difference between startAngle and endAngle (angles in degrees). - * @param {number} startAngle Start angle in degrees. - * @param {number} endAngle End angle in degrees. - * @return {number} The number of degrees that when added to - * startAngle will result in endAngle. Positive numbers mean that the - * direction is clockwise. Negative numbers indicate a counter-clockwise - * direction. - * The shortest route (clockwise vs counter-clockwise) between the angles - * is used. - * When the difference is 180 degrees, the function returns 180 (not -180) - * angleDifference(30, 40) is 10, and angleDifference(40, 30) is -10. - * angleDifference(350, 10) is 20, and angleDifference(10, 350) is -20. + * Transforms a coordinate to longitude/latitude. + * @param {ol.Coordinate} coordinate Projected coordinate. + * @param {ol.proj.ProjectionLike=} opt_projection Projection of the coordinate. + * The default is Web Mercator, i.e. 'EPSG:3857'. + * @return {ol.Coordinate} Coordinate as longitude and latitude, i.e. an array + * with longitude as 1st and latitude as 2nd element. + * @api stable */ -goog.math.angleDifference = function(startAngle, endAngle) { - var d = goog.math.standardAngle(endAngle) - - goog.math.standardAngle(startAngle); - if (d > 180) { - d = d - 360; - } else if (d <= -180) { - d = 360 + d; - } - return d; +ol.proj.toLonLat = function(coordinate, opt_projection) { + return ol.proj.transform(coordinate, + opt_projection !== undefined ? opt_projection : 'EPSG:3857', 'EPSG:4326'); }; /** - * Returns the sign of a number as per the "sign" or "signum" function. - * @param {number} x The number to take the sign of. - * @return {number} -1 when negative, 1 when positive, 0 when 0. Preserves - * signed zeros and NaN. + * Fetches a Projection object for the code specified. + * + * @param {ol.proj.ProjectionLike} projectionLike Either a code string which is + * a combination of authority and identifier such as "EPSG:4326", or an + * existing projection object, or undefined. + * @return {ol.proj.Projection} Projection object, or null if not in list. + * @api stable */ -goog.math.sign = Math.sign || function(x) { - if (x > 0) { - return 1; - } - if (x < 0) { - return -1; +ol.proj.get = function(projectionLike) { + var projection; + if (projectionLike instanceof ol.proj.Projection) { + projection = projectionLike; + } else if (typeof projectionLike === 'string') { + var code = projectionLike; + projection = ol.proj.projections_[code]; + if (ol.ENABLE_PROJ4JS) { + var proj4js = ol.proj.proj4_ || ol.global['proj4']; + if (projection === undefined && typeof proj4js == 'function' && + proj4js.defs(code) !== undefined) { + projection = new ol.proj.Projection({code: code}); + ol.proj.addProjection(projection); + } + } + } else { + projection = null; } - return x; // Preserves signed zeros and NaN. + return projection; }; /** - * JavaScript implementation of Longest Common Subsequence problem. - * http://en.wikipedia.org/wiki/Longest_common_subsequence - * - * Returns the longest possible array that is subarray of both of given arrays. + * Checks if two projections are the same, that is every coordinate in one + * projection does represent the same geographic point as the same coordinate in + * the other projection. * - * @param {Array<Object>} array1 First array of objects. - * @param {Array<Object>} array2 Second array of objects. - * @param {Function=} opt_compareFn Function that acts as a custom comparator - * for the array ojects. Function should return true if objects are equal, - * otherwise false. - * @param {Function=} opt_collectorFn Function used to decide what to return - * as a result subsequence. It accepts 2 arguments: index of common element - * in the first array and index in the second. The default function returns - * element from the first array. - * @return {!Array<Object>} A list of objects that are common to both arrays - * such that there is no common subsequence with size greater than the - * length of the list. + * @param {ol.proj.Projection} projection1 Projection 1. + * @param {ol.proj.Projection} projection2 Projection 2. + * @return {boolean} Equivalent. + * @api */ -goog.math.longestCommonSubsequence = function( - array1, array2, opt_compareFn, opt_collectorFn) { - - var compare = opt_compareFn || function(a, b) { - return a == b; - }; - - var collect = opt_collectorFn || function(i1, i2) { - return array1[i1]; - }; - - var length1 = array1.length; - var length2 = array2.length; - - var arr = []; - for (var i = 0; i < length1 + 1; i++) { - arr[i] = []; - arr[i][0] = 0; - } - - for (var j = 0; j < length2 + 1; j++) { - arr[0][j] = 0; - } - - for (i = 1; i <= length1; i++) { - for (j = 1; j <= length2; j++) { - if (compare(array1[i - 1], array2[j - 1])) { - arr[i][j] = arr[i - 1][j - 1] + 1; - } else { - arr[i][j] = Math.max(arr[i - 1][j], arr[i][j - 1]); - } - } +ol.proj.equivalent = function(projection1, projection2) { + if (projection1 === projection2) { + return true; } - - // Backtracking - var result = []; - var i = length1, j = length2; - while (i > 0 && j > 0) { - if (compare(array1[i - 1], array2[j - 1])) { - result.unshift(collect(i - 1, j - 1)); - i--; - j--; - } else { - if (arr[i - 1][j] > arr[i][j - 1]) { - i--; - } else { - j--; - } - } + var equalUnits = projection1.getUnits() === projection2.getUnits(); + if (projection1.getCode() === projection2.getCode()) { + return equalUnits; + } else { + var transformFn = ol.proj.getTransformFromProjections( + projection1, projection2); + return transformFn === ol.proj.cloneTransform && equalUnits; } - - return result; }; /** - * Returns the sum of the arguments. - * @param {...number} var_args Numbers to add. - * @return {number} The sum of the arguments (0 if no arguments were provided, - * {@code NaN} if any of the arguments is not a valid number). + * Given the projection-like objects, searches for a transformation + * function to convert a coordinates array from the source projection to the + * destination projection. + * + * @param {ol.proj.ProjectionLike} source Source. + * @param {ol.proj.ProjectionLike} destination Destination. + * @return {ol.TransformFunction} Transform function. + * @api stable */ -goog.math.sum = function(var_args) { - return /** @type {number} */ (goog.array.reduce(arguments, - function(sum, value) { - return sum + value; - }, 0)); +ol.proj.getTransform = function(source, destination) { + var sourceProjection = ol.proj.get(source); + var destinationProjection = ol.proj.get(destination); + return ol.proj.getTransformFromProjections( + sourceProjection, destinationProjection); }; /** - * Returns the arithmetic mean of the arguments. - * @param {...number} var_args Numbers to average. - * @return {number} The average of the arguments ({@code NaN} if no arguments - * were provided or any of the arguments is not a valid number). + * Searches in the list of transform functions for the function for converting + * coordinates from the source projection to the destination projection. + * + * @param {ol.proj.Projection} sourceProjection Source Projection object. + * @param {ol.proj.Projection} destinationProjection Destination Projection + * object. + * @return {ol.TransformFunction} Transform function. */ -goog.math.average = function(var_args) { - return goog.math.sum.apply(null, arguments) / arguments.length; +ol.proj.getTransformFromProjections = function(sourceProjection, destinationProjection) { + var transforms = ol.proj.transforms_; + var sourceCode = sourceProjection.getCode(); + var destinationCode = destinationProjection.getCode(); + var transform; + if (sourceCode in transforms && destinationCode in transforms[sourceCode]) { + transform = transforms[sourceCode][destinationCode]; + } + if (transform === undefined) { + goog.asserts.assert(transform !== undefined, 'transform should be defined'); + transform = ol.proj.identityTransform; + } + return transform; }; /** - * Returns the unbiased sample variance of the arguments. For a definition, - * see e.g. http://en.wikipedia.org/wiki/Variance - * @param {...number} var_args Number samples to analyze. - * @return {number} The unbiased sample variance of the arguments (0 if fewer - * than two samples were provided, or {@code NaN} if any of the samples is - * not a valid number). + * @param {Array.<number>} input Input coordinate array. + * @param {Array.<number>=} opt_output Output array of coordinate values. + * @param {number=} opt_dimension Dimension. + * @return {Array.<number>} Input coordinate array (same array as input). */ -goog.math.sampleVariance = function(var_args) { - var sampleSize = arguments.length; - if (sampleSize < 2) { - return 0; +ol.proj.identityTransform = function(input, opt_output, opt_dimension) { + if (opt_output !== undefined && input !== opt_output) { + // TODO: consider making this a warning instead + goog.asserts.fail('This should not be used internally.'); + for (var i = 0, ii = input.length; i < ii; ++i) { + opt_output[i] = input[i]; + } + input = opt_output; } - - var mean = goog.math.average.apply(null, arguments); - var variance = goog.math.sum.apply(null, goog.array.map(arguments, - function(val) { - return Math.pow(val - mean, 2); - })) / (sampleSize - 1); - - return variance; + return input; }; /** - * Returns the sample standard deviation of the arguments. For a definition of - * sample standard deviation, see e.g. - * http://en.wikipedia.org/wiki/Standard_deviation - * @param {...number} var_args Number samples to analyze. - * @return {number} The sample standard deviation of the arguments (0 if fewer - * than two samples were provided, or {@code NaN} if any of the samples is - * not a valid number). + * @param {Array.<number>} input Input coordinate array. + * @param {Array.<number>=} opt_output Output array of coordinate values. + * @param {number=} opt_dimension Dimension. + * @return {Array.<number>} Output coordinate array (new array, same coordinate + * values). */ -goog.math.standardDeviation = function(var_args) { - return Math.sqrt(goog.math.sampleVariance.apply(null, arguments)); +ol.proj.cloneTransform = function(input, opt_output, opt_dimension) { + var output; + if (opt_output !== undefined) { + for (var i = 0, ii = input.length; i < ii; ++i) { + opt_output[i] = input[i]; + } + output = opt_output; + } else { + output = input.slice(); + } + return output; }; /** - * Returns whether the supplied number represents an integer, i.e. that is has - * no fractional component. No range-checking is performed on the number. - * @param {number} num The number to test. - * @return {boolean} Whether {@code num} is an integer. + * Transforms a coordinate from source projection to destination projection. + * This returns a new coordinate (and does not modify the original). + * + * See {@link ol.proj.transformExtent} for extent transformation. + * See the transform method of {@link ol.geom.Geometry} and its subclasses for + * geometry transforms. + * + * @param {ol.Coordinate} coordinate Coordinate. + * @param {ol.proj.ProjectionLike} source Source projection-like. + * @param {ol.proj.ProjectionLike} destination Destination projection-like. + * @return {ol.Coordinate} Coordinate. + * @api stable */ -goog.math.isInt = function(num) { - return isFinite(num) && num % 1 == 0; +ol.proj.transform = function(coordinate, source, destination) { + var transformFn = ol.proj.getTransform(source, destination); + return transformFn(coordinate, undefined, coordinate.length); }; /** - * Returns whether the supplied number is finite and not NaN. - * @param {number} num The number to test. - * @return {boolean} Whether {@code num} is a finite number. + * Transforms an extent from source projection to destination projection. This + * returns a new extent (and does not modify the original). + * + * @param {ol.Extent} extent The extent to transform. + * @param {ol.proj.ProjectionLike} source Source projection-like. + * @param {ol.proj.ProjectionLike} destination Destination projection-like. + * @return {ol.Extent} The transformed extent. + * @api stable */ -goog.math.isFiniteNumber = function(num) { - return isFinite(num) && !isNaN(num); +ol.proj.transformExtent = function(extent, source, destination) { + var transformFn = ol.proj.getTransform(source, destination); + return ol.extent.applyTransform(extent, transformFn); }; /** - * @param {number} num The number to test. - * @return {boolean} Whether it is negative zero. + * Transforms the given point to the destination projection. + * + * @param {ol.Coordinate} point Point. + * @param {ol.proj.Projection} sourceProjection Source projection. + * @param {ol.proj.Projection} destinationProjection Destination projection. + * @return {ol.Coordinate} Point. */ -goog.math.isNegativeZero = function(num) { - return num == 0 && 1 / num < 0; +ol.proj.transformWithProjections = function(point, sourceProjection, destinationProjection) { + var transformFn = ol.proj.getTransformFromProjections( + sourceProjection, destinationProjection); + return transformFn(point); }; +goog.provide('ol.geom.Geometry'); +goog.provide('ol.geom.GeometryLayout'); +goog.provide('ol.geom.GeometryType'); + +goog.require('goog.asserts'); +goog.require('ol.functions'); +goog.require('ol.Object'); +goog.require('ol.extent'); +goog.require('ol.proj'); +goog.require('ol.proj.Units'); + /** - * Returns the precise value of floor(log10(num)). - * Simpler implementations didn't work because of floating point rounding - * errors. For example - * <ul> - * <li>Math.floor(Math.log(num) / Math.LN10) is off by one for num == 1e+3. - * <li>Math.floor(Math.log(num) * Math.LOG10E) is off by one for num == 1e+15. - * <li>Math.floor(Math.log10(num)) is off by one for num == 1e+15 - 1. - * </ul> - * @param {number} num A floating point number. - * @return {number} Its logarithm to base 10 rounded down to the nearest - * integer if num > 0. -Infinity if num == 0. NaN if num < 0. + * The geometry type. One of `'Point'`, `'LineString'`, `'LinearRing'`, + * `'Polygon'`, `'MultiPoint'`, `'MultiLineString'`, `'MultiPolygon'`, + * `'GeometryCollection'`, `'Circle'`. + * @enum {string} + * @api stable */ -goog.math.log10Floor = function(num) { - if (num > 0) { - var x = Math.round(Math.log(num) * Math.LOG10E); - return x - (parseFloat('1e' + x) > num); - } - return num == 0 ? -Infinity : NaN; +ol.geom.GeometryType = { + POINT: 'Point', + LINE_STRING: 'LineString', + LINEAR_RING: 'LinearRing', + POLYGON: 'Polygon', + MULTI_POINT: 'MultiPoint', + MULTI_LINE_STRING: 'MultiLineString', + MULTI_POLYGON: 'MultiPolygon', + GEOMETRY_COLLECTION: 'GeometryCollection', + CIRCLE: 'Circle' }; /** - * A tweaked variant of {@code Math.floor} which tolerates if the passed number - * is infinitesimally smaller than the closest integer. It often happens with - * the results of floating point calculations because of the finite precision - * of the intermediate results. For example {@code Math.floor(Math.log(1000) / - * Math.LN10) == 2}, not 3 as one would expect. - * @param {number} num A number. - * @param {number=} opt_epsilon An infinitesimally small positive number, the - * rounding error to tolerate. - * @return {number} The largest integer less than or equal to {@code num}. + * The coordinate layout for geometries, indicating whether a 3rd or 4th z ('Z') + * or measure ('M') coordinate is available. Supported values are `'XY'`, + * `'XYZ'`, `'XYM'`, `'XYZM'`. + * @enum {string} + * @api stable */ -goog.math.safeFloor = function(num, opt_epsilon) { - goog.asserts.assert(!goog.isDef(opt_epsilon) || opt_epsilon > 0); - return Math.floor(num + (opt_epsilon || 2e-15)); +ol.geom.GeometryLayout = { + XY: 'XY', + XYZ: 'XYZ', + XYM: 'XYM', + XYZM: 'XYZM' }; /** - * A tweaked variant of {@code Math.ceil}. See {@code goog.math.safeFloor} for - * details. - * @param {number} num A number. - * @param {number=} opt_epsilon An infinitesimally small positive number, the - * rounding error to tolerate. - * @return {number} The smallest integer greater than or equal to {@code num}. + * @classdesc + * Abstract base class; normally only used for creating subclasses and not + * instantiated in apps. + * Base class for vector geometries. + * + * To get notified of changes to the geometry, register a listener for the + * generic `change` event on your geometry instance. + * + * @constructor + * @extends {ol.Object} + * @api stable */ -goog.math.safeCeil = function(num, opt_epsilon) { - goog.asserts.assert(!goog.isDef(opt_epsilon) || opt_epsilon > 0); - return Math.ceil(num - (opt_epsilon || 2e-15)); -}; +ol.geom.Geometry = function() { -goog.provide('ol.Coordinate'); -goog.provide('ol.CoordinateFormatType'); -goog.provide('ol.coordinate'); + goog.base(this); -goog.require('goog.math'); -goog.require('goog.string'); + /** + * @private + * @type {ol.Extent} + */ + this.extent_ = ol.extent.createEmpty(); + + /** + * @private + * @type {number} + */ + this.extentRevision_ = -1; + + /** + * @protected + * @type {Object.<string, ol.geom.Geometry>} + */ + this.simplifiedGeometryCache = {}; + + /** + * @protected + * @type {number} + */ + this.simplifiedGeometryMaxMinSquaredTolerance = 0; + + /** + * @protected + * @type {number} + */ + this.simplifiedGeometryRevision = 0; + +}; +goog.inherits(ol.geom.Geometry, ol.Object); /** - * A function that takes a {@link ol.Coordinate} and transforms it into a - * `{string}`. - * - * @typedef {function((ol.Coordinate|undefined)): string} - * @api stable + * Make a complete copy of the geometry. + * @function + * @return {!ol.geom.Geometry} Clone. */ -ol.CoordinateFormatType; +ol.geom.Geometry.prototype.clone = goog.abstractMethod; /** - * An array of numbers representing an xy coordinate. Example: `[16, 48]`. - * @typedef {Array.<number>} ol.Coordinate - * @api stable + * @param {number} x X. + * @param {number} y Y. + * @param {ol.Coordinate} closestPoint Closest point. + * @param {number} minSquaredDistance Minimum squared distance. + * @return {number} Minimum squared distance. */ -ol.Coordinate; +ol.geom.Geometry.prototype.closestPointXY = goog.abstractMethod; /** - * Add `delta` to `coordinate`. `coordinate` is modified in place and returned - * by the function. - * - * Example: - * - * var coord = [7.85, 47.983333]; - * ol.coordinate.add(coord, [-2, 4]); - * // coord is now [5.85, 51.983333] - * - * @param {ol.Coordinate} coordinate Coordinate. - * @param {ol.Coordinate} delta Delta. - * @return {ol.Coordinate} The input coordinate adjusted by the given delta. + * Return the closest point of the geometry to the passed point as + * {@link ol.Coordinate coordinate}. + * @param {ol.Coordinate} point Point. + * @param {ol.Coordinate=} opt_closestPoint Closest point. + * @return {ol.Coordinate} Closest point. * @api stable */ -ol.coordinate.add = function(coordinate, delta) { - coordinate[0] += delta[0]; - coordinate[1] += delta[1]; - return coordinate; +ol.geom.Geometry.prototype.getClosestPoint = function(point, opt_closestPoint) { + var closestPoint = opt_closestPoint ? opt_closestPoint : [NaN, NaN]; + this.closestPointXY(point[0], point[1], closestPoint, Infinity); + return closestPoint; }; /** - * Calculates the point closest to the passed coordinate on the passed segment. - * This is the foot of the perpendicular of the coordinate to the segment when - * the foot is on the segment, or the closest segment coordinate when the foot - * is outside the segment. - * - * @param {ol.Coordinate} coordinate The coordinate. - * @param {Array.<ol.Coordinate>} segment The two coordinates of the segment. - * @return {ol.Coordinate} The foot of the perpendicular of the coordinate to - * the segment. + * @param {ol.Coordinate} coordinate Coordinate. + * @return {boolean} Contains coordinate. */ -ol.coordinate.closestOnSegment = function(coordinate, segment) { - var x0 = coordinate[0]; - var y0 = coordinate[1]; - var start = segment[0]; - var end = segment[1]; - var x1 = start[0]; - var y1 = start[1]; - var x2 = end[0]; - var y2 = end[1]; - var dx = x2 - x1; - var dy = y2 - y1; - var along = (dx === 0 && dy === 0) ? 0 : - ((dx * (x0 - x1)) + (dy * (y0 - y1))) / ((dx * dx + dy * dy) || 0); - var x, y; - if (along <= 0) { - x = x1; - y = y1; - } else if (along >= 1) { - x = x2; - y = y2; - } else { - x = x1 + along * dx; - y = y1 + along * dy; - } - return [x, y]; +ol.geom.Geometry.prototype.containsCoordinate = function(coordinate) { + return this.containsXY(coordinate[0], coordinate[1]); }; /** - * Returns a {@link ol.CoordinateFormatType} function that can be used to format - * a {ol.Coordinate} to a string. - * - * Example without specifying the fractional digits: - * - * var coord = [7.85, 47.983333]; - * var stringifyFunc = ol.coordinate.createStringXY(); - * var out = stringifyFunc(coord); - * // out is now '8, 48' - * - * Example with explicitly specifying 2 fractional digits: - * - * var coord = [7.85, 47.983333]; - * var stringifyFunc = ol.coordinate.createStringXY(2); - * var out = stringifyFunc(coord); - * // out is now '7.85, 47.98' - * - * @param {number=} opt_fractionDigits The number of digits to include - * after the decimal point. Default is `0`. - * @return {ol.CoordinateFormatType} Coordinate format. - * @api stable + * @param {ol.Extent} extent Extent. + * @protected + * @return {ol.Extent} extent Extent. */ -ol.coordinate.createStringXY = function(opt_fractionDigits) { - return ( - /** - * @param {ol.Coordinate|undefined} coordinate Coordinate. - * @return {string} String XY. - */ - function(coordinate) { - return ol.coordinate.toStringXY(coordinate, opt_fractionDigits); - }); -}; +ol.geom.Geometry.prototype.computeExtent = goog.abstractMethod; /** - * @private - * @param {number} degrees Degrees. - * @param {string} hemispheres Hemispheres. - * @return {string} String. + * @param {number} x X. + * @param {number} y Y. + * @return {boolean} Contains (x, y). */ -ol.coordinate.degreesToStringHDMS_ = function(degrees, hemispheres) { - var normalizedDegrees = goog.math.modulo(degrees + 180, 360) - 180; - var x = Math.abs(Math.round(3600 * normalizedDegrees)); - return Math.floor(x / 3600) + '\u00b0 ' + - goog.string.padNumber(Math.floor((x / 60) % 60), 2) + '\u2032 ' + - goog.string.padNumber(Math.floor(x % 60), 2) + '\u2033 ' + - hemispheres.charAt(normalizedDegrees < 0 ? 1 : 0); -}; +ol.geom.Geometry.prototype.containsXY = ol.functions.FALSE; /** - * Transforms the given {@link ol.Coordinate} to a string using the given string - * template. The strings `{x}` and `{y}` in the template will be replaced with - * the first and second coordinate values respectively. - * - * Example without specifying the fractional digits: - * - * var coord = [7.85, 47.983333]; - * var template = 'Coordinate is ({x}|{y}).'; - * var out = ol.coordinate.format(coord, template); - * // out is now 'Coordinate is (8|48).' - * - * Example explicitly specifying the fractional digits: - * - * var coord = [7.85, 47.983333]; - * var template = 'Coordinate is ({x}|{y}).'; - * var out = ol.coordinate.format(coord, template, 2); - * // out is now 'Coordinate is (7.85|47.98).' - * - * @param {ol.Coordinate|undefined} coordinate Coordinate. - * @param {string} template A template string with `{x}` and `{y}` placeholders - * that will be replaced by first and second coordinate values. - * @param {number=} opt_fractionDigits The number of digits to include - * after the decimal point. Default is `0`. - * @return {string} Formatted coordinate. + * Get the extent of the geometry. + * @param {ol.Extent=} opt_extent Extent. + * @return {ol.Extent} extent Extent. * @api stable */ -ol.coordinate.format = function(coordinate, template, opt_fractionDigits) { - if (coordinate) { - return template - .replace('{x}', coordinate[0].toFixed(opt_fractionDigits)) - .replace('{y}', coordinate[1].toFixed(opt_fractionDigits)); - } else { - return ''; +ol.geom.Geometry.prototype.getExtent = function(opt_extent) { + if (this.extentRevision_ != this.getRevision()) { + this.extent_ = this.computeExtent(this.extent_); + this.extentRevision_ = this.getRevision(); } + return ol.extent.returnOrUpdate(this.extent_, opt_extent); }; /** - * @param {ol.Coordinate} coordinate1 First coordinate. - * @param {ol.Coordinate} coordinate2 Second coordinate. - * @return {boolean} Whether the passed coordinates are equal. + * Rotate the geometry around a given coordinate. This modifies the geometry + * coordinates in place. + * @param {number} angle Rotation angle in radians. + * @param {ol.Coordinate} anchor The rotation center. + * @api + * @function */ -ol.coordinate.equals = function(coordinate1, coordinate2) { - var equals = true; - for (var i = coordinate1.length - 1; i >= 0; --i) { - if (coordinate1[i] != coordinate2[i]) { - equals = false; - break; - } - } - return equals; -}; +ol.geom.Geometry.prototype.rotate = goog.abstractMethod; /** - * Rotate `coordinate` by `angle`. `coordinate` is modified in place and - * returned by the function. - * - * Example: - * - * var coord = [7.85, 47.983333]; - * var rotateRadians = Math.PI / 2; // 90 degrees - * ol.coordinate.rotate(coord, rotateRadians); - * // coord is now [-47.983333, 7.85] - * - * @param {ol.Coordinate} coordinate Coordinate. - * @param {number} angle Angle in radian. - * @return {ol.Coordinate} Coordinate. - * @api stable + * Create a simplified version of this geometry. For linestrings, this uses + * the the {@link + * https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm + * Douglas Peucker} algorithm. For polygons, a quantization-based + * simplification is used to preserve topology. + * @function + * @param {number} tolerance The tolerance distance for simplification. + * @return {ol.geom.Geometry} A new, simplified version of the original + * geometry. + * @api */ -ol.coordinate.rotate = function(coordinate, angle) { - var cosAngle = Math.cos(angle); - var sinAngle = Math.sin(angle); - var x = coordinate[0] * cosAngle - coordinate[1] * sinAngle; - var y = coordinate[1] * cosAngle + coordinate[0] * sinAngle; - coordinate[0] = x; - coordinate[1] = y; - return coordinate; +ol.geom.Geometry.prototype.simplify = function(tolerance) { + return this.getSimplifiedGeometry(tolerance * tolerance); }; /** - * Scale `coordinate` by `scale`. `coordinate` is modified in place and returned - * by the function. - * - * Example: - * - * var coord = [7.85, 47.983333]; - * var scale = 1.2; - * ol.coordinate.scale(coord, scale); - * // coord is now [9.42, 57.5799996] - * - * @param {ol.Coordinate} coordinate Coordinate. - * @param {number} scale Scale factor. - * @return {ol.Coordinate} Coordinate. + * Create a simplified version of this geometry using the Douglas Peucker + * algorithm. + * @see https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm + * @function + * @param {number} squaredTolerance Squared tolerance. + * @return {ol.geom.Geometry} Simplified geometry. */ -ol.coordinate.scale = function(coordinate, scale) { - coordinate[0] *= scale; - coordinate[1] *= scale; - return coordinate; -}; +ol.geom.Geometry.prototype.getSimplifiedGeometry = goog.abstractMethod; /** - * Subtract `delta` to `coordinate`. `coordinate` is modified in place and - * returned by the function. - * - * @param {ol.Coordinate} coordinate Coordinate. - * @param {ol.Coordinate} delta Delta. - * @return {ol.Coordinate} Coordinate. + * Get the type of this geometry. + * @function + * @return {ol.geom.GeometryType} Geometry type. */ -ol.coordinate.sub = function(coordinate, delta) { - coordinate[0] -= delta[0]; - coordinate[1] -= delta[1]; - return coordinate; -}; +ol.geom.Geometry.prototype.getType = goog.abstractMethod; /** - * @param {ol.Coordinate} coord1 First coordinate. - * @param {ol.Coordinate} coord2 Second coordinate. - * @return {number} Squared distance between coord1 and coord2. + * Apply a transform function to each coordinate of the geometry. + * The geometry is modified in place. + * If you do not want the geometry modified in place, first `clone()` it and + * then use this function on the clone. + * @function + * @param {ol.TransformFunction} transformFn Transform. */ -ol.coordinate.squaredDistance = function(coord1, coord2) { - var dx = coord1[0] - coord2[0]; - var dy = coord1[1] - coord2[1]; - return dx * dx + dy * dy; -}; +ol.geom.Geometry.prototype.applyTransform = goog.abstractMethod; /** - * Calculate the squared distance from a coordinate to a line segment. - * - * @param {ol.Coordinate} coordinate Coordinate of the point. - * @param {Array.<ol.Coordinate>} segment Line segment (2 coordinates). - * @return {number} Squared distance from the point to the line segment. + * Test if the geometry and the passed extent intersect. + * @param {ol.Extent} extent Extent. + * @return {boolean} `true` if the geometry and the extent intersect. + * @function */ -ol.coordinate.squaredDistanceToSegment = function(coordinate, segment) { - return ol.coordinate.squaredDistance(coordinate, - ol.coordinate.closestOnSegment(coordinate, segment)); -}; +ol.geom.Geometry.prototype.intersectsExtent = goog.abstractMethod; /** - * Format a geographic coordinate with the hemisphere, degrees, minutes, and - * seconds. - * - * Example: - * - * var coord = [7.85, 47.983333]; - * var out = ol.coordinate.toStringHDMS(coord); - * // out is now '47° 59′ 0″ N 7° 51′ 0″ E' - * - * @param {ol.Coordinate|undefined} coordinate Coordinate. - * @return {string} Hemisphere, degrees, minutes and seconds. - * @api stable + * Translate the geometry. This modifies the geometry coordinates in place. If + * instead you want a new geometry, first `clone()` this geometry. + * @param {number} deltaX Delta X. + * @param {number} deltaY Delta Y. + * @function */ -ol.coordinate.toStringHDMS = function(coordinate) { - if (coordinate) { - return ol.coordinate.degreesToStringHDMS_(coordinate[1], 'NS') + ' ' + - ol.coordinate.degreesToStringHDMS_(coordinate[0], 'EW'); - } else { - return ''; - } -}; +ol.geom.Geometry.prototype.translate = goog.abstractMethod; /** - * Format a coordinate as a comma delimited string. - * - * Example without specifying fractional digits: - * - * var coord = [7.85, 47.983333]; - * var out = ol.coordinate.toStringXY(coord); - * // out is now '8, 48' - * - * Example explicitly specifying 1 fractional digit: - * - * var coord = [7.85, 47.983333]; - * var out = ol.coordinate.toStringXY(coord, 1); - * // out is now '7.8, 48.0' + * Transform each coordinate of the geometry from one coordinate reference + * system to another. The geometry is modified in place. + * For example, a line will be transformed to a line and a circle to a circle. + * If you do not want the geometry modified in place, first `clone()` it and + * then use this function on the clone. * - * @param {ol.Coordinate|undefined} coordinate Coordinate. - * @param {number=} opt_fractionDigits The number of digits to include - * after the decimal point. Default is `0`. - * @return {string} XY. + * @param {ol.proj.ProjectionLike} source The current projection. Can be a + * string identifier or a {@link ol.proj.Projection} object. + * @param {ol.proj.ProjectionLike} destination The desired projection. Can be a + * string identifier or a {@link ol.proj.Projection} object. + * @return {ol.geom.Geometry} This geometry. Note that original geometry is + * modified in place. * @api stable */ -ol.coordinate.toStringXY = function(coordinate, opt_fractionDigits) { - return ol.coordinate.format(coordinate, '{x}, {y}', opt_fractionDigits); -}; - - -/** - * Create an ol.Coordinate from an Array and take into account axis order. - * - * Examples: - * - * var northCoord = ol.coordinate.fromProjectedArray([1, 2], 'n'); - * // northCoord is now [2, 1] - * - * var eastCoord = ol.coordinate.fromProjectedArray([1, 2], 'e'); - * // eastCoord is now [1, 2] - * - * @param {Array} array The array with coordinates. - * @param {string} axis the axis info. - * @return {ol.Coordinate} The coordinate created. - */ -ol.coordinate.fromProjectedArray = function(array, axis) { - var firstAxis = axis.charAt(0); - if (firstAxis === 'n' || firstAxis === 's') { - return [array[1], array[0]]; - } else { - return array; - } +ol.geom.Geometry.prototype.transform = function(source, destination) { + goog.asserts.assert( + ol.proj.get(source).getUnits() !== ol.proj.Units.TILE_PIXELS && + ol.proj.get(destination).getUnits() !== ol.proj.Units.TILE_PIXELS, + 'cannot transform geometries with TILE_PIXELS units'); + this.applyTransform(ol.proj.getTransform(source, destination)); + return this; }; // Copyright 2011 The Closure Library Authors. All Rights Reserved. @@ -14149,6 +10034,7 @@ goog.provide('goog.vec.Float32Array'); * The length of the array, or an array to initialize the contents of the * new Float32Array. * @constructor + * @implements {IArrayLike<number>} * @final */ goog.vec.Float32Array = function(p0) { @@ -14212,14 +10098,18 @@ goog.vec.Float32Array.prototype.toString = Array.prototype.join; * goog.vec.Float32Array as Float32Array. */ if (typeof Float32Array == 'undefined') { - goog.exportProperty(goog.vec.Float32Array, 'BYTES_PER_ELEMENT', - goog.vec.Float32Array.BYTES_PER_ELEMENT); - goog.exportProperty(goog.vec.Float32Array.prototype, 'BYTES_PER_ELEMENT', - goog.vec.Float32Array.prototype.BYTES_PER_ELEMENT); - goog.exportProperty(goog.vec.Float32Array.prototype, 'set', - goog.vec.Float32Array.prototype.set); - goog.exportProperty(goog.vec.Float32Array.prototype, 'toString', - goog.vec.Float32Array.prototype.toString); + goog.exportProperty( + goog.vec.Float32Array, 'BYTES_PER_ELEMENT', + goog.vec.Float32Array.BYTES_PER_ELEMENT); + goog.exportProperty( + goog.vec.Float32Array.prototype, 'BYTES_PER_ELEMENT', + goog.vec.Float32Array.prototype.BYTES_PER_ELEMENT); + goog.exportProperty( + goog.vec.Float32Array.prototype, 'set', + goog.vec.Float32Array.prototype.set); + goog.exportProperty( + goog.vec.Float32Array.prototype, 'toString', + goog.vec.Float32Array.prototype.toString); goog.exportSymbol('Float32Array', goog.vec.Float32Array); } @@ -14261,6 +10151,7 @@ goog.provide('goog.vec.Float64Array'); * The length of the array, or an array to initialize the contents of the * new Float64Array. * @constructor + * @implements {IArrayLike<number>} * @final */ goog.vec.Float64Array = function(p0) { @@ -14325,20 +10216,24 @@ goog.vec.Float64Array.prototype.toString = Array.prototype.join; */ if (typeof Float64Array == 'undefined') { try { - goog.exportProperty(goog.vec.Float64Array, 'BYTES_PER_ELEMENT', - goog.vec.Float64Array.BYTES_PER_ELEMENT); + goog.exportProperty( + goog.vec.Float64Array, 'BYTES_PER_ELEMENT', + goog.vec.Float64Array.BYTES_PER_ELEMENT); } catch (float64ArrayError) { // Do nothing. This code is in place to fix b/7225850, in which an error // is incorrectly thrown for Google TV on an old Chrome. // TODO(user): remove after that version is retired. } - goog.exportProperty(goog.vec.Float64Array.prototype, 'BYTES_PER_ELEMENT', - goog.vec.Float64Array.prototype.BYTES_PER_ELEMENT); - goog.exportProperty(goog.vec.Float64Array.prototype, 'set', - goog.vec.Float64Array.prototype.set); - goog.exportProperty(goog.vec.Float64Array.prototype, 'toString', - goog.vec.Float64Array.prototype.toString); + goog.exportProperty( + goog.vec.Float64Array.prototype, 'BYTES_PER_ELEMENT', + goog.vec.Float64Array.prototype.BYTES_PER_ELEMENT); + goog.exportProperty( + goog.vec.Float64Array.prototype, 'set', + goog.vec.Float64Array.prototype.set); + goog.exportProperty( + goog.vec.Float64Array.prototype, 'toString', + goog.vec.Float64Array.prototype.toString); goog.exportSymbol('Float64Array', goog.vec.Float64Array); } @@ -14499,7 +10394,7 @@ goog.vec.Vec3.create = function() { /** - * Creates a new 3 element FLoat32 vector initialized with the value from the + * Creates a new 3 element Float32 vector initialized with the value from the * given array. * * @param {goog.vec.Vec3.AnyType} vec The source 3 element array. @@ -14955,8 +10850,8 @@ goog.vec.Vec3.min = function(vec0, limit, resultVec) { * @return {boolean} True if the vectors are equal, false otherwise. */ goog.vec.Vec3.equals = function(v0, v1) { - return v0.length == v1.length && - v0[0] == v1[0] && v0[1] == v1[1] && v0[2] == v1[2]; + return v0.length == v1.length && v0[0] == v1[0] && v0[1] == v1[1] && + v0[2] == v1[2]; }; // Copyright 2011 The Closure Library Authors. All Rights Reserved. @@ -15435,8 +11330,8 @@ goog.vec.Vec4.min = function(vec0, limit, resultVec) { * @return {boolean} True if the vectors are equal, false otherwise. */ goog.vec.Vec4.equals = function(v0, v1) { - return v0.length == v1.length && - v0[0] == v1[0] && v0[1] == v1[1] && v0[2] == v1[2] && v0[3] == v1[3]; + return v0.length == v1.length && v0[0] == v1[0] && v0[1] == v1[1] && + v0[2] == v1[2] && v0[3] == v1[3]; }; // Copyright 2011 The Closure Library Authors. All Rights Reserved. @@ -15512,11 +11407,8 @@ goog.vec.Mat4.createFloat64 = function() { */ goog.vec.Mat4.createNumber = function() { var a = new Array(16); - goog.vec.Mat4.setFromValues(a, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0); + goog.vec.Mat4.setFromValues( + a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); return a; }; @@ -15565,11 +11457,8 @@ goog.vec.Mat4.createFloat64Identity = function() { */ goog.vec.Mat4.createNumberIdentity = function() { var a = new Array(16); - goog.vec.Mat4.setFromValues(a, - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1); + goog.vec.Mat4.setFromValues( + a, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); return a; }; @@ -15622,10 +11511,8 @@ goog.vec.Mat4.createFloat32FromArray = function(matrix) { * @return {!goog.vec.Mat4.Float32} The new, 16 element array. */ goog.vec.Mat4.createFloat32FromValues = function( - v00, v10, v20, v30, - v01, v11, v21, v31, - v02, v12, v22, v32, - v03, v13, v23, v33) { + v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32, v03, v13, v23, + v33) { var newMatrix = goog.vec.Mat4.createFloat32(); goog.vec.Mat4.setFromValues( newMatrix, v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32, @@ -15679,10 +11566,8 @@ goog.vec.Mat4.createFloat64FromArray = function(matrix) { * @return {!goog.vec.Mat4.Float64} The new, 16 element array. */ goog.vec.Mat4.createFloat64FromValues = function( - v00, v10, v20, v30, - v01, v11, v21, v31, - v02, v12, v22, v32, - v03, v13, v23, v33) { + v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32, v03, v13, v23, + v33) { var newMatrix = goog.vec.Mat4.createFloat64(); goog.vec.Mat4.setFromValues( newMatrix, v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32, @@ -15738,13 +11623,11 @@ goog.vec.Mat4.createFromArray = function(matrix) { * @return {!goog.vec.Mat4.Type} The new, 16 element array. */ goog.vec.Mat4.createFromValues = function( - v00, v10, v20, v30, - v01, v11, v21, v31, - v02, v12, v22, v32, - v03, v13, v23, v33) { + v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32, v03, v13, v23, + v33) { return goog.vec.Mat4.createFloat32FromValues( - v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32, - v03, v13, v23, v33); + v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32, v03, v13, v23, + v33); }; @@ -15814,8 +11697,8 @@ goog.vec.Mat4.setElement = function(mat, row, column, value) { * chained together. */ goog.vec.Mat4.setFromValues = function( - mat, v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32, - v03, v13, v23, v33) { + mat, v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32, v03, v13, + v23, v33) { mat[0] = v00; mat[1] = v10; mat[2] = v20; @@ -16495,23 +12378,12 @@ goog.vec.Mat4.invert = function(mat, resultMat) { * @return {boolean} True if the the two matrices are equivalent. */ goog.vec.Mat4.equals = function(mat0, mat1) { - return mat0.length == mat1.length && - mat0[0] == mat1[0] && - mat0[1] == mat1[1] && - mat0[2] == mat1[2] && - mat0[3] == mat1[3] && - mat0[4] == mat1[4] && - mat0[5] == mat1[5] && - mat0[6] == mat1[6] && - mat0[7] == mat1[7] && - mat0[8] == mat1[8] && - mat0[9] == mat1[9] && - mat0[10] == mat1[10] && - mat0[11] == mat1[11] && - mat0[12] == mat1[12] && - mat0[13] == mat1[13] && - mat0[14] == mat1[14] && - mat0[15] == mat1[15]; + return mat0.length == mat1.length && mat0[0] == mat1[0] && + mat0[1] == mat1[1] && mat0[2] == mat1[2] && mat0[3] == mat1[3] && + mat0[4] == mat1[4] && mat0[5] == mat1[5] && mat0[6] == mat1[6] && + mat0[7] == mat1[7] && mat0[8] == mat1[8] && mat0[9] == mat1[9] && + mat0[10] == mat1[10] && mat0[11] == mat1[11] && mat0[12] == mat1[12] && + mat0[13] == mat1[13] && mat0[14] == mat1[14] && mat0[15] == mat1[15]; }; @@ -16652,21 +12524,12 @@ goog.vec.Mat4.makeRotate = function(mat, angle, ax, ay, az) { var d = 1 - c; var s = Math.sin(angle); - return goog.vec.Mat4.setFromValues(mat, - ax * ax * d + c, - ax * ay * d + az * s, - ax * az * d - ay * s, - 0, + return goog.vec.Mat4.setFromValues( + mat, ax * ax * d + c, ax * ay * d + az * s, ax * az * d - ay * s, 0, - ax * ay * d - az * s, - ay * ay * d + c, - ay * az * d + ax * s, - 0, + ax * ay * d - az * s, ay * ay * d + c, ay * az * d + ax * s, 0, - ax * az * d + ay * s, - ay * az * d - ax * s, - az * az * d + c, - 0, + ax * az * d + ay * s, ay * az * d - ax * s, az * az * d + c, 0, 0, 0, 0, 1); }; @@ -16744,12 +12607,8 @@ goog.vec.Mat4.makeFrustum = function(mat, left, right, bottom, top, near, far) { var c = -(far + near) / (far - near); var d = -(2 * far * near) / (far - near); - return goog.vec.Mat4.setFromValues(mat, - x, 0, 0, 0, - 0, y, 0, 0, - a, b, c, -1, - 0, 0, d, 0 - ); + return goog.vec.Mat4.setFromValues( + mat, x, 0, 0, 0, 0, y, 0, 0, a, b, c, -1, 0, 0, d, 0); }; @@ -16775,12 +12634,9 @@ goog.vec.Mat4.makePerspective = function(mat, fovy, aspect, near, far) { } var cot = Math.cos(angle) / sinAngle; - return goog.vec.Mat4.setFromValues(mat, - cot / aspect, 0, 0, 0, - 0, cot, 0, 0, - 0, 0, -(far + near) / dz, -1, - 0, 0, -(2 * near * far) / dz, 0 - ); + return goog.vec.Mat4.setFromValues( + mat, cot / aspect, 0, 0, 0, 0, cot, 0, 0, 0, 0, -(far + near) / dz, -1, 0, + 0, -(2 * near * far) / dz, 0); }; @@ -16805,12 +12661,8 @@ goog.vec.Mat4.makeOrtho = function(mat, left, right, bottom, top, near, far) { var b = -(top + bottom) / (top - bottom); var c = -(far + near) / (far - near); - return goog.vec.Mat4.setFromValues(mat, - x, 0, 0, 0, - 0, y, 0, 0, - 0, 0, z, 0, - a, b, c, 1 - ); + return goog.vec.Mat4.setFromValues( + mat, x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, a, b, c, 1); }; @@ -16854,8 +12706,7 @@ goog.vec.Mat4.makeLookAt = function(mat, eyePt, centerPt, worldUpVec) { goog.vec.Mat4.setRow(mat, 1, upVec); goog.vec.Mat4.setRow(mat, 2, fwdVec); goog.vec.Mat4.setRowValues(mat, 3, 0, 0, 0, 1); - goog.vec.Mat4.translate( - mat, -eyePt[0], -eyePt[1], -eyePt[2]); + goog.vec.Mat4.translate(mat, -eyePt[0], -eyePt[1], -eyePt[2]); return mat; }; @@ -17008,8 +12859,8 @@ goog.vec.Mat4.toEulerZXZ = function(mat, euler, opt_theta2IsNegative) { euler[2] = (euler[2] + Math.PI * 2) % (Math.PI * 2); // For theta2 we want the angle to be in [0, pi] or [-pi, 0] depending on // signTheta2. - euler[1] = ((euler[1] * signTheta2 + Math.PI * 2) % (Math.PI * 2)) * - signTheta2; + euler[1] = + ((euler[1] * signTheta2 + Math.PI * 2) % (Math.PI * 2)) * signTheta2; return euler; }; @@ -17031,8 +12882,7 @@ goog.vec.Mat4.toEulerZXZ = function(mat, euler, opt_theta2IsNegative) { */ goog.vec.Mat4.translate = function(mat, x, y, z) { return goog.vec.Mat4.setColumnValues( - mat, 3, - mat[0] * x + mat[4] * y + mat[8] * z + mat[12], + mat, 3, mat[0] * x + mat[4] * y + mat[8] * z + mat[12], mat[1] * x + mat[5] * y + mat[9] * z + mat[13], mat[2] * x + mat[6] * y + mat[10] * z + mat[14], mat[3] * x + mat[7] * y + mat[11] * z + mat[15]); @@ -17055,11 +12905,9 @@ goog.vec.Mat4.translate = function(mat, x, y, z) { */ goog.vec.Mat4.scale = function(mat, x, y, z) { return goog.vec.Mat4.setFromValues( - mat, - mat[0] * x, mat[1] * x, mat[2] * x, mat[3] * x, - mat[4] * y, mat[5] * y, mat[6] * y, mat[7] * y, - mat[8] * z, mat[9] * z, mat[10] * z, mat[11] * z, - mat[12], mat[13], mat[14], mat[15]); + mat, mat[0] * x, mat[1] * x, mat[2] * x, mat[3] * x, mat[4] * y, + mat[5] * y, mat[6] * y, mat[7] * y, mat[8] * z, mat[9] * z, mat[10] * z, + mat[11] * z, mat[12], mat[13], mat[14], mat[15]); }; @@ -17100,21 +12948,14 @@ goog.vec.Mat4.rotate = function(mat, angle, x, y, z) { var r22 = z * z * diffCosAngle + cosAngle; return goog.vec.Mat4.setFromValues( - mat, - m00 * r00 + m01 * r10 + m02 * r20, - m10 * r00 + m11 * r10 + m12 * r20, - m20 * r00 + m21 * r10 + m22 * r20, - m30 * r00 + m31 * r10 + m32 * r20, - - m00 * r01 + m01 * r11 + m02 * r21, - m10 * r01 + m11 * r11 + m12 * r21, - m20 * r01 + m21 * r11 + m22 * r21, - m30 * r01 + m31 * r11 + m32 * r21, - - m00 * r02 + m01 * r12 + m02 * r22, - m10 * r02 + m11 * r12 + m12 * r22, - m20 * r02 + m21 * r12 + m22 * r22, - m30 * r02 + m31 * r12 + m32 * r22, + mat, m00 * r00 + m01 * r10 + m02 * r20, m10 * r00 + m11 * r10 + m12 * r20, + m20 * r00 + m21 * r10 + m22 * r20, m30 * r00 + m31 * r10 + m32 * r20, + + m00 * r01 + m01 * r11 + m02 * r21, m10 * r01 + m11 * r11 + m12 * r21, + m20 * r01 + m21 * r11 + m22 * r21, m30 * r01 + m31 * r11 + m32 * r21, + + m00 * r02 + m01 * r12 + m02 * r22, m10 * r02 + m11 * r12 + m12 * r22, + m20 * r02 + m21 * r12 + m22 * r22, m30 * r02 + m31 * r12 + m32 * r22, m03, m13, m23, m33); }; @@ -17237,10 +13078,8 @@ goog.vec.Mat4.getTranslation = function(mat, translation) { * @type {!Array<!goog.vec.Vec3.Type>} * @private */ -goog.vec.Mat4.tmpVec3_ = [ - goog.vec.Vec3.createFloat64(), - goog.vec.Vec3.createFloat64() -]; +goog.vec.Mat4.tmpVec3_ = + [goog.vec.Vec3.createFloat64(), goog.vec.Vec3.createFloat64()]; /** @@ -17248,8 +13087,7 @@ goog.vec.Mat4.tmpVec3_ = [ * @private */ goog.vec.Mat4.tmpVec4_ = [ - goog.vec.Vec4.createFloat64(), - goog.vec.Vec4.createFloat64(), + goog.vec.Vec4.createFloat64(), goog.vec.Vec4.createFloat64(), goog.vec.Vec4.createFloat64() ]; @@ -17258,2610 +13096,70 @@ goog.vec.Mat4.tmpVec4_ = [ * @type {!Array<!goog.vec.Mat4.Type>} * @private */ -goog.vec.Mat4.tmpMat4_ = [ - goog.vec.Mat4.createFloat64() -]; - -goog.provide('ol.TransformFunction'); - +goog.vec.Mat4.tmpMat4_ = [goog.vec.Mat4.createFloat64()]; -/** - * A transform function accepts an array of input coordinate values, an optional - * output array, and an optional dimension (default should be 2). The function - * transforms the input coordinate values, populates the output array, and - * returns the output array. - * - * @typedef {function(Array.<number>, Array.<number>=, number=): Array.<number>} - * @api stable - */ -ol.TransformFunction; - -goog.provide('ol.Extent'); -goog.provide('ol.extent'); -goog.provide('ol.extent.Corner'); -goog.provide('ol.extent.Relationship'); +goog.provide('ol.geom.flat.transform'); -goog.require('goog.asserts'); goog.require('goog.vec.Mat4'); -goog.require('ol.Coordinate'); -goog.require('ol.Size'); -goog.require('ol.TransformFunction'); - - -/** - * An array of numbers representing an extent: `[minx, miny, maxx, maxy]`. - * @typedef {Array.<number>} - * @api stable - */ -ol.Extent; - - -/** - * Extent corner. - * @enum {string} - */ -ol.extent.Corner = { - BOTTOM_LEFT: 'bottom-left', - BOTTOM_RIGHT: 'bottom-right', - TOP_LEFT: 'top-left', - TOP_RIGHT: 'top-right' -}; - - -/** - * Relationship to an extent. - * @enum {number} - */ -ol.extent.Relationship = { - UNKNOWN: 0, - INTERSECTING: 1, - ABOVE: 2, - RIGHT: 4, - BELOW: 8, - LEFT: 16 -}; - - -/** - * Build an extent that includes all given coordinates. - * - * @param {Array.<ol.Coordinate>} coordinates Coordinates. - * @return {ol.Extent} Bounding extent. - * @api stable - */ -ol.extent.boundingExtent = function(coordinates) { - var extent = ol.extent.createEmpty(); - for (var i = 0, ii = coordinates.length; i < ii; ++i) { - ol.extent.extendCoordinate(extent, coordinates[i]); - } - return extent; -}; - - -/** - * @param {Array.<number>} xs Xs. - * @param {Array.<number>} ys Ys. - * @param {ol.Extent=} opt_extent Destination extent. - * @private - * @return {ol.Extent} Extent. - */ -ol.extent.boundingExtentXYs_ = function(xs, ys, opt_extent) { - goog.asserts.assert(xs.length > 0, 'xs length should be larger than 0'); - goog.asserts.assert(ys.length > 0, 'ys length should be larger than 0'); - var minX = Math.min.apply(null, xs); - var minY = Math.min.apply(null, ys); - var maxX = Math.max.apply(null, xs); - var maxY = Math.max.apply(null, ys); - return ol.extent.createOrUpdate(minX, minY, maxX, maxY, opt_extent); -}; - - -/** - * Return extent increased by the provided value. - * @param {ol.Extent} extent Extent. - * @param {number} value The amount by which the extent should be buffered. - * @param {ol.Extent=} opt_extent Extent. - * @return {ol.Extent} Extent. - * @api stable - */ -ol.extent.buffer = function(extent, value, opt_extent) { - if (opt_extent) { - opt_extent[0] = extent[0] - value; - opt_extent[1] = extent[1] - value; - opt_extent[2] = extent[2] + value; - opt_extent[3] = extent[3] + value; - return opt_extent; - } else { - return [ - extent[0] - value, - extent[1] - value, - extent[2] + value, - extent[3] + value - ]; - } -}; - - -/** - * Creates a clone of an extent. - * - * @param {ol.Extent} extent Extent to clone. - * @param {ol.Extent=} opt_extent Extent. - * @return {ol.Extent} The clone. - */ -ol.extent.clone = function(extent, opt_extent) { - if (opt_extent) { - opt_extent[0] = extent[0]; - opt_extent[1] = extent[1]; - opt_extent[2] = extent[2]; - opt_extent[3] = extent[3]; - return opt_extent; - } else { - return extent.slice(); - } -}; - - -/** - * @param {ol.Extent} extent Extent. - * @param {number} x X. - * @param {number} y Y. - * @return {number} Closest squared distance. - */ -ol.extent.closestSquaredDistanceXY = function(extent, x, y) { - var dx, dy; - if (x < extent[0]) { - dx = extent[0] - x; - } else if (extent[2] < x) { - dx = x - extent[2]; - } else { - dx = 0; - } - if (y < extent[1]) { - dy = extent[1] - y; - } else if (extent[3] < y) { - dy = y - extent[3]; - } else { - dy = 0; - } - return dx * dx + dy * dy; -}; - - -/** - * Check if the passed coordinate is contained or on the edge of the extent. - * - * @param {ol.Extent} extent Extent. - * @param {ol.Coordinate} coordinate Coordinate. - * @return {boolean} The coordinate is contained in the extent. - * @api stable - */ -ol.extent.containsCoordinate = function(extent, coordinate) { - return ol.extent.containsXY(extent, coordinate[0], coordinate[1]); -}; - - -/** - * Check if one extent contains another. - * - * An extent is deemed contained if it lies completely within the other extent, - * including if they share one or more edges. - * - * @param {ol.Extent} extent1 Extent 1. - * @param {ol.Extent} extent2 Extent 2. - * @return {boolean} The second extent is contained by or on the edge of the - * first. - * @api stable - */ -ol.extent.containsExtent = function(extent1, extent2) { - return extent1[0] <= extent2[0] && extent2[2] <= extent1[2] && - extent1[1] <= extent2[1] && extent2[3] <= extent1[3]; -}; - - -/** - * Check if the passed coordinate is contained or on the edge of the extent. - * - * @param {ol.Extent} extent Extent. - * @param {number} x X coordinate. - * @param {number} y Y coordinate. - * @return {boolean} The x, y values are contained in the extent. - * @api stable - */ -ol.extent.containsXY = function(extent, x, y) { - return extent[0] <= x && x <= extent[2] && extent[1] <= y && y <= extent[3]; -}; - - -/** - * Get the relationship between a coordinate and extent. - * @param {ol.Extent} extent The extent. - * @param {ol.Coordinate} coordinate The coordinate. - * @return {number} The relationship (bitwise compare with - * ol.extent.Relationship). - */ -ol.extent.coordinateRelationship = function(extent, coordinate) { - var minX = extent[0]; - var minY = extent[1]; - var maxX = extent[2]; - var maxY = extent[3]; - var x = coordinate[0]; - var y = coordinate[1]; - var relationship = ol.extent.Relationship.UNKNOWN; - if (x < minX) { - relationship = relationship | ol.extent.Relationship.LEFT; - } else if (x > maxX) { - relationship = relationship | ol.extent.Relationship.RIGHT; - } - if (y < minY) { - relationship = relationship | ol.extent.Relationship.BELOW; - } else if (y > maxY) { - relationship = relationship | ol.extent.Relationship.ABOVE; - } - if (relationship === ol.extent.Relationship.UNKNOWN) { - relationship = ol.extent.Relationship.INTERSECTING; - } - return relationship; -}; - - -/** - * Create an empty extent. - * @return {ol.Extent} Empty extent. - * @api stable - */ -ol.extent.createEmpty = function() { - return [Infinity, Infinity, -Infinity, -Infinity]; -}; - - -/** - * Create a new extent or update the provided extent. - * @param {number} minX Minimum X. - * @param {number} minY Minimum Y. - * @param {number} maxX Maximum X. - * @param {number} maxY Maximum Y. - * @param {ol.Extent=} opt_extent Destination extent. - * @return {ol.Extent} Extent. - */ -ol.extent.createOrUpdate = function(minX, minY, maxX, maxY, opt_extent) { - if (opt_extent) { - opt_extent[0] = minX; - opt_extent[1] = minY; - opt_extent[2] = maxX; - opt_extent[3] = maxY; - return opt_extent; - } else { - return [minX, minY, maxX, maxY]; - } -}; - - -/** - * Create a new empty extent or make the provided one empty. - * @param {ol.Extent=} opt_extent Extent. - * @return {ol.Extent} Extent. - */ -ol.extent.createOrUpdateEmpty = function(opt_extent) { - return ol.extent.createOrUpdate( - Infinity, Infinity, -Infinity, -Infinity, opt_extent); -}; - - -/** - * @param {ol.Coordinate} coordinate Coordinate. - * @param {ol.Extent=} opt_extent Extent. - * @return {ol.Extent} Extent. - */ -ol.extent.createOrUpdateFromCoordinate = function(coordinate, opt_extent) { - var x = coordinate[0]; - var y = coordinate[1]; - return ol.extent.createOrUpdate(x, y, x, y, opt_extent); -}; - - -/** - * @param {Array.<ol.Coordinate>} coordinates Coordinates. - * @param {ol.Extent=} opt_extent Extent. - * @return {ol.Extent} Extent. - */ -ol.extent.createOrUpdateFromCoordinates = function(coordinates, opt_extent) { - var extent = ol.extent.createOrUpdateEmpty(opt_extent); - return ol.extent.extendCoordinates(extent, coordinates); -}; - - -/** - * @param {Array.<number>} flatCoordinates Flat coordinates. - * @param {number} offset Offset. - * @param {number} end End. - * @param {number} stride Stride. - * @param {ol.Extent=} opt_extent Extent. - * @return {ol.Extent} Extent. - */ -ol.extent.createOrUpdateFromFlatCoordinates = - function(flatCoordinates, offset, end, stride, opt_extent) { - var extent = ol.extent.createOrUpdateEmpty(opt_extent); - return ol.extent.extendFlatCoordinates( - extent, flatCoordinates, offset, end, stride); -}; - - -/** - * @param {Array.<Array.<ol.Coordinate>>} rings Rings. - * @param {ol.Extent=} opt_extent Extent. - * @return {ol.Extent} Extent. - */ -ol.extent.createOrUpdateFromRings = function(rings, opt_extent) { - var extent = ol.extent.createOrUpdateEmpty(opt_extent); - return ol.extent.extendRings(extent, rings); -}; - - -/** - * Empty an extent in place. - * @param {ol.Extent} extent Extent. - * @return {ol.Extent} Extent. - */ -ol.extent.empty = function(extent) { - extent[0] = extent[1] = Infinity; - extent[2] = extent[3] = -Infinity; - return extent; -}; - - -/** - * Determine if two extents are equivalent. - * @param {ol.Extent} extent1 Extent 1. - * @param {ol.Extent} extent2 Extent 2. - * @return {boolean} The two extents are equivalent. - * @api stable - */ -ol.extent.equals = function(extent1, extent2) { - return extent1[0] == extent2[0] && extent1[2] == extent2[2] && - extent1[1] == extent2[1] && extent1[3] == extent2[3]; -}; - - -/** - * Modify an extent to include another extent. - * @param {ol.Extent} extent1 The extent to be modified. - * @param {ol.Extent} extent2 The extent that will be included in the first. - * @return {ol.Extent} A reference to the first (extended) extent. - * @api stable - */ -ol.extent.extend = function(extent1, extent2) { - if (extent2[0] < extent1[0]) { - extent1[0] = extent2[0]; - } - if (extent2[2] > extent1[2]) { - extent1[2] = extent2[2]; - } - if (extent2[1] < extent1[1]) { - extent1[1] = extent2[1]; - } - if (extent2[3] > extent1[3]) { - extent1[3] = extent2[3]; - } - return extent1; -}; - - -/** - * @param {ol.Extent} extent Extent. - * @param {ol.Coordinate} coordinate Coordinate. - */ -ol.extent.extendCoordinate = function(extent, coordinate) { - if (coordinate[0] < extent[0]) { - extent[0] = coordinate[0]; - } - if (coordinate[0] > extent[2]) { - extent[2] = coordinate[0]; - } - if (coordinate[1] < extent[1]) { - extent[1] = coordinate[1]; - } - if (coordinate[1] > extent[3]) { - extent[3] = coordinate[1]; - } -}; - - -/** - * @param {ol.Extent} extent Extent. - * @param {Array.<ol.Coordinate>} coordinates Coordinates. - * @return {ol.Extent} Extent. - */ -ol.extent.extendCoordinates = function(extent, coordinates) { - var i, ii; - for (i = 0, ii = coordinates.length; i < ii; ++i) { - ol.extent.extendCoordinate(extent, coordinates[i]); - } - return extent; -}; /** - * @param {ol.Extent} extent Extent. * @param {Array.<number>} flatCoordinates Flat coordinates. * @param {number} offset Offset. * @param {number} end End. * @param {number} stride Stride. - * @return {ol.Extent} Extent. - */ -ol.extent.extendFlatCoordinates = - function(extent, flatCoordinates, offset, end, stride) { - for (; offset < end; offset += stride) { - ol.extent.extendXY( - extent, flatCoordinates[offset], flatCoordinates[offset + 1]); - } - return extent; -}; - - -/** - * @param {ol.Extent} extent Extent. - * @param {Array.<Array.<ol.Coordinate>>} rings Rings. - * @return {ol.Extent} Extent. - */ -ol.extent.extendRings = function(extent, rings) { - var i, ii; - for (i = 0, ii = rings.length; i < ii; ++i) { - ol.extent.extendCoordinates(extent, rings[i]); - } - return extent; -}; - - -/** - * @param {ol.Extent} extent Extent. - * @param {number} x X. - * @param {number} y Y. - */ -ol.extent.extendXY = function(extent, x, y) { - extent[0] = Math.min(extent[0], x); - extent[1] = Math.min(extent[1], y); - extent[2] = Math.max(extent[2], x); - extent[3] = Math.max(extent[3], y); -}; - - -/** - * This function calls `callback` for each corner of the extent. If the - * callback returns a truthy value the function returns that value - * immediately. Otherwise the function returns `false`. - * @param {ol.Extent} extent Extent. - * @param {function(this:T, ol.Coordinate): S} callback Callback. - * @param {T=} opt_this Value to use as `this` when executing `callback`. - * @return {S|boolean} Value. - * @template S, T - */ -ol.extent.forEachCorner = function(extent, callback, opt_this) { - var val; - val = callback.call(opt_this, ol.extent.getBottomLeft(extent)); - if (val) { - return val; - } - val = callback.call(opt_this, ol.extent.getBottomRight(extent)); - if (val) { - return val; - } - val = callback.call(opt_this, ol.extent.getTopRight(extent)); - if (val) { - return val; - } - val = callback.call(opt_this, ol.extent.getTopLeft(extent)); - if (val) { - return val; - } - return false; -}; - - -/** - * @param {ol.Extent} extent Extent. - * @return {number} Area. - */ -ol.extent.getArea = function(extent) { - var area = 0; - if (!ol.extent.isEmpty(extent)) { - area = ol.extent.getWidth(extent) * ol.extent.getHeight(extent); - } - return area; -}; - - -/** - * Get the bottom left coordinate of an extent. - * @param {ol.Extent} extent Extent. - * @return {ol.Coordinate} Bottom left coordinate. - * @api stable - */ -ol.extent.getBottomLeft = function(extent) { - return [extent[0], extent[1]]; -}; - - -/** - * Get the bottom right coordinate of an extent. - * @param {ol.Extent} extent Extent. - * @return {ol.Coordinate} Bottom right coordinate. - * @api stable - */ -ol.extent.getBottomRight = function(extent) { - return [extent[2], extent[1]]; -}; - - -/** - * Get the center coordinate of an extent. - * @param {ol.Extent} extent Extent. - * @return {ol.Coordinate} Center. - * @api stable - */ -ol.extent.getCenter = function(extent) { - return [(extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2]; -}; - - -/** - * Get a corner coordinate of an extent. - * @param {ol.Extent} extent Extent. - * @param {ol.extent.Corner} corner Corner. - * @return {ol.Coordinate} Corner coordinate. - */ -ol.extent.getCorner = function(extent, corner) { - var coordinate; - if (corner === ol.extent.Corner.BOTTOM_LEFT) { - coordinate = ol.extent.getBottomLeft(extent); - } else if (corner === ol.extent.Corner.BOTTOM_RIGHT) { - coordinate = ol.extent.getBottomRight(extent); - } else if (corner === ol.extent.Corner.TOP_LEFT) { - coordinate = ol.extent.getTopLeft(extent); - } else if (corner === ol.extent.Corner.TOP_RIGHT) { - coordinate = ol.extent.getTopRight(extent); - } else { - goog.asserts.fail('Invalid corner: %s', corner); - } - goog.asserts.assert(coordinate, 'coordinate should be defined'); - return coordinate; -}; - - -/** - * @param {ol.Extent} extent1 Extent 1. - * @param {ol.Extent} extent2 Extent 2. - * @return {number} Enlarged area. - */ -ol.extent.getEnlargedArea = function(extent1, extent2) { - var minX = Math.min(extent1[0], extent2[0]); - var minY = Math.min(extent1[1], extent2[1]); - var maxX = Math.max(extent1[2], extent2[2]); - var maxY = Math.max(extent1[3], extent2[3]); - return (maxX - minX) * (maxY - minY); -}; - - -/** - * @param {ol.Coordinate} center Center. - * @param {number} resolution Resolution. - * @param {number} rotation Rotation. - * @param {ol.Size} size Size. - * @param {ol.Extent=} opt_extent Destination extent. - * @return {ol.Extent} Extent. - */ -ol.extent.getForViewAndSize = - function(center, resolution, rotation, size, opt_extent) { - var dx = resolution * size[0] / 2; - var dy = resolution * size[1] / 2; - var cosRotation = Math.cos(rotation); - var sinRotation = Math.sin(rotation); - /** @type {Array.<number>} */ - var xs = [-dx, -dx, dx, dx]; - /** @type {Array.<number>} */ - var ys = [-dy, dy, -dy, dy]; - var i, x, y; - for (i = 0; i < 4; ++i) { - x = xs[i]; - y = ys[i]; - xs[i] = center[0] + x * cosRotation - y * sinRotation; - ys[i] = center[1] + x * sinRotation + y * cosRotation; - } - return ol.extent.boundingExtentXYs_(xs, ys, opt_extent); -}; - - -/** - * Get the height of an extent. - * @param {ol.Extent} extent Extent. - * @return {number} Height. - * @api stable - */ -ol.extent.getHeight = function(extent) { - return extent[3] - extent[1]; -}; - - -/** - * @param {ol.Extent} extent1 Extent 1. - * @param {ol.Extent} extent2 Extent 2. - * @return {number} Intersection area. - */ -ol.extent.getIntersectionArea = function(extent1, extent2) { - var intersection = ol.extent.getIntersection(extent1, extent2); - return ol.extent.getArea(intersection); -}; - - -/** - * Get the intersection of two extents. - * @param {ol.Extent} extent1 Extent 1. - * @param {ol.Extent} extent2 Extent 2. - * @param {ol.Extent=} opt_extent Optional extent to populate with intersection. - * @return {ol.Extent} Intersecting extent. - * @api stable - */ -ol.extent.getIntersection = function(extent1, extent2, opt_extent) { - var intersection = opt_extent ? opt_extent : ol.extent.createEmpty(); - if (ol.extent.intersects(extent1, extent2)) { - if (extent1[0] > extent2[0]) { - intersection[0] = extent1[0]; - } else { - intersection[0] = extent2[0]; - } - if (extent1[1] > extent2[1]) { - intersection[1] = extent1[1]; - } else { - intersection[1] = extent2[1]; - } - if (extent1[2] < extent2[2]) { - intersection[2] = extent1[2]; - } else { - intersection[2] = extent2[2]; - } - if (extent1[3] < extent2[3]) { - intersection[3] = extent1[3]; - } else { - intersection[3] = extent2[3]; - } - } - return intersection; -}; - - -/** - * @param {ol.Extent} extent Extent. - * @return {number} Margin. - */ -ol.extent.getMargin = function(extent) { - return ol.extent.getWidth(extent) + ol.extent.getHeight(extent); -}; - - -/** - * Get the size (width, height) of an extent. - * @param {ol.Extent} extent The extent. - * @return {ol.Size} The extent size. - * @api stable - */ -ol.extent.getSize = function(extent) { - return [extent[2] - extent[0], extent[3] - extent[1]]; -}; - - -/** - * Get the top left coordinate of an extent. - * @param {ol.Extent} extent Extent. - * @return {ol.Coordinate} Top left coordinate. - * @api stable - */ -ol.extent.getTopLeft = function(extent) { - return [extent[0], extent[3]]; -}; - - -/** - * Get the top right coordinate of an extent. - * @param {ol.Extent} extent Extent. - * @return {ol.Coordinate} Top right coordinate. - * @api stable - */ -ol.extent.getTopRight = function(extent) { - return [extent[2], extent[3]]; -}; - - -/** - * Get the width of an extent. - * @param {ol.Extent} extent Extent. - * @return {number} Width. - * @api stable - */ -ol.extent.getWidth = function(extent) { - return extent[2] - extent[0]; -}; - - -/** - * Determine if one extent intersects another. - * @param {ol.Extent} extent1 Extent 1. - * @param {ol.Extent} extent2 Extent. - * @return {boolean} The two extents intersect. - * @api stable - */ -ol.extent.intersects = function(extent1, extent2) { - return extent1[0] <= extent2[2] && - extent1[2] >= extent2[0] && - extent1[1] <= extent2[3] && - extent1[3] >= extent2[1]; -}; - - -/** - * Determine if an extent is empty. - * @param {ol.Extent} extent Extent. - * @return {boolean} Is empty. - * @api stable - */ -ol.extent.isEmpty = function(extent) { - return extent[2] < extent[0] || extent[3] < extent[1]; -}; - - -/** - * @param {ol.Extent} extent Extent. - * @return {boolean} Is infinite. - */ -ol.extent.isInfinite = function(extent) { - return extent[0] == -Infinity || extent[1] == -Infinity || - extent[2] == Infinity || extent[3] == Infinity; -}; - - -/** - * @param {ol.Extent} extent Extent. - * @param {ol.Coordinate} coordinate Coordinate. - * @return {ol.Coordinate} Coordinate. - */ -ol.extent.normalize = function(extent, coordinate) { - return [ - (coordinate[0] - extent[0]) / (extent[2] - extent[0]), - (coordinate[1] - extent[1]) / (extent[3] - extent[1]) - ]; -}; - - -/** - * @param {ol.Extent} extent Extent. - * @param {ol.Extent=} opt_extent Extent. - * @return {ol.Extent} Extent. - */ -ol.extent.returnOrUpdate = function(extent, opt_extent) { - if (opt_extent) { - opt_extent[0] = extent[0]; - opt_extent[1] = extent[1]; - opt_extent[2] = extent[2]; - opt_extent[3] = extent[3]; - return opt_extent; - } else { - return extent; - } -}; - - -/** - * @param {ol.Extent} extent Extent. - * @param {number} value Value. - */ -ol.extent.scaleFromCenter = function(extent, value) { - var deltaX = ((extent[2] - extent[0]) / 2) * (value - 1); - var deltaY = ((extent[3] - extent[1]) / 2) * (value - 1); - extent[0] -= deltaX; - extent[2] += deltaX; - extent[1] -= deltaY; - extent[3] += deltaY; -}; - - -/** - * Determine if the segment between two coordinates intersects (crosses, - * touches, or is contained by) the provided extent. - * @param {ol.Extent} extent The extent. - * @param {ol.Coordinate} start Segment start coordinate. - * @param {ol.Coordinate} end Segment end coordinate. - * @return {boolean} The segment intersects the extent. - */ -ol.extent.intersectsSegment = function(extent, start, end) { - var intersects = false; - var startRel = ol.extent.coordinateRelationship(extent, start); - var endRel = ol.extent.coordinateRelationship(extent, end); - if (startRel === ol.extent.Relationship.INTERSECTING || - endRel === ol.extent.Relationship.INTERSECTING) { - intersects = true; - } else { - var minX = extent[0]; - var minY = extent[1]; - var maxX = extent[2]; - var maxY = extent[3]; - var startX = start[0]; - var startY = start[1]; - var endX = end[0]; - var endY = end[1]; - var slope = (endY - startY) / (endX - startX); - var x, y; - if (!!(endRel & ol.extent.Relationship.ABOVE) && - !(startRel & ol.extent.Relationship.ABOVE)) { - // potentially intersects top - x = endX - ((endY - maxY) / slope); - intersects = x >= minX && x <= maxX; - } - if (!intersects && !!(endRel & ol.extent.Relationship.RIGHT) && - !(startRel & ol.extent.Relationship.RIGHT)) { - // potentially intersects right - y = endY - ((endX - maxX) * slope); - intersects = y >= minY && y <= maxY; - } - if (!intersects && !!(endRel & ol.extent.Relationship.BELOW) && - !(startRel & ol.extent.Relationship.BELOW)) { - // potentially intersects bottom - x = endX - ((endY - minY) / slope); - intersects = x >= minX && x <= maxX; - } - if (!intersects && !!(endRel & ol.extent.Relationship.LEFT) && - !(startRel & ol.extent.Relationship.LEFT)) { - // potentially intersects left - y = endY - ((endX - minX) * slope); - intersects = y >= minY && y <= maxY; - } - - } - return intersects; -}; - - -/** - * @param {ol.Extent} extent1 Extent 1. - * @param {ol.Extent} extent2 Extent 2. - * @return {boolean} Touches. - */ -ol.extent.touches = function(extent1, extent2) { - var intersects = ol.extent.intersects(extent1, extent2); - return intersects && - (extent1[0] == extent2[2] || extent1[2] == extent2[0] || - extent1[1] == extent2[3] || extent1[3] == extent2[1]); -}; - - -/** - * Apply a transform function to the extent. - * @param {ol.Extent} extent Extent. - * @param {ol.TransformFunction} transformFn Transform function. Called with - * [minX, minY, maxX, maxY] extent coordinates. - * @param {ol.Extent=} opt_extent Destination extent. - * @return {ol.Extent} Extent. - * @api stable - */ -ol.extent.applyTransform = function(extent, transformFn, opt_extent) { - var coordinates = [ - extent[0], extent[1], - extent[0], extent[3], - extent[2], extent[1], - extent[2], extent[3] - ]; - transformFn(coordinates, coordinates, 2); - var xs = [coordinates[0], coordinates[2], coordinates[4], coordinates[6]]; - var ys = [coordinates[1], coordinates[3], coordinates[5], coordinates[7]]; - return ol.extent.boundingExtentXYs_(xs, ys, opt_extent); -}; - - -/** - * Apply a 2d transform to an extent. - * @param {ol.Extent} extent Input extent. - * @param {goog.vec.Mat4.Number} transform The transform matrix. - * @param {ol.Extent=} opt_extent Optional extent for return values. - * @return {ol.Extent} The transformed extent. + * @param {goog.vec.Mat4.Number} transform Transform. + * @param {Array.<number>=} opt_dest Destination. + * @return {Array.<number>} Transformed coordinates. */ -ol.extent.transform2D = function(extent, transform, opt_extent) { - var dest = opt_extent ? opt_extent : []; +ol.geom.flat.transform.transform2D = function(flatCoordinates, offset, end, stride, transform, opt_dest) { var m00 = goog.vec.Mat4.getElement(transform, 0, 0); var m10 = goog.vec.Mat4.getElement(transform, 1, 0); var m01 = goog.vec.Mat4.getElement(transform, 0, 1); var m11 = goog.vec.Mat4.getElement(transform, 1, 1); var m03 = goog.vec.Mat4.getElement(transform, 0, 3); var m13 = goog.vec.Mat4.getElement(transform, 1, 3); - var xi = [0, 2, 0, 2]; - var yi = [1, 1, 3, 3]; - var xs = []; - var ys = []; - var i, x, y; - for (i = 0; i < 4; ++i) { - x = extent[xi[i]]; - y = extent[yi[i]]; - xs[i] = m00 * x + m01 * y + m03; - ys[i] = m10 * x + m11 * y + m13; - } - dest[0] = Math.min.apply(null, xs); - dest[1] = Math.min.apply(null, ys); - dest[2] = Math.max.apply(null, xs); - dest[3] = Math.max.apply(null, ys); - return dest; -}; - -// Copyright 2008 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Utilities for creating functions. Loosely inspired by the - * java classes: http://goo.gl/GM0Hmu and http://goo.gl/6k7nI8. - * - * @author nicksantos@google.com (Nick Santos) - */ - - -goog.provide('goog.functions'); - - -/** - * Creates a function that always returns the same value. - * @param {T} retValue The value to return. - * @return {function():T} The new function. - * @template T - */ -goog.functions.constant = function(retValue) { - return function() { - return retValue; - }; -}; - - -/** - * Always returns false. - * @type {function(...): boolean} - */ -goog.functions.FALSE = goog.functions.constant(false); - - -/** - * Always returns true. - * @type {function(...): boolean} - */ -goog.functions.TRUE = goog.functions.constant(true); - - -/** - * Always returns NULL. - * @type {function(...): null} - */ -goog.functions.NULL = goog.functions.constant(null); - - -/** - * A simple function that returns the first argument of whatever is passed - * into it. - * @param {T=} opt_returnValue The single value that will be returned. - * @param {...*} var_args Optional trailing arguments. These are ignored. - * @return {T} The first argument passed in, or undefined if nothing was passed. - * @template T - */ -goog.functions.identity = function(opt_returnValue, var_args) { - return opt_returnValue; -}; - - -/** - * Creates a function that always throws an error with the given message. - * @param {string} message The error message. - * @return {!Function} The error-throwing function. - */ -goog.functions.error = function(message) { - return function() { - throw Error(message); - }; -}; - - -/** - * Creates a function that throws the given object. - * @param {*} err An object to be thrown. - * @return {!Function} The error-throwing function. - */ -goog.functions.fail = function(err) { - return function() { - throw err; - } -}; - - -/** - * Given a function, create a function that keeps opt_numArgs arguments and - * silently discards all additional arguments. - * @param {Function} f The original function. - * @param {number=} opt_numArgs The number of arguments to keep. Defaults to 0. - * @return {!Function} A version of f that only keeps the first opt_numArgs - * arguments. - */ -goog.functions.lock = function(f, opt_numArgs) { - opt_numArgs = opt_numArgs || 0; - return function() { - return f.apply(this, Array.prototype.slice.call(arguments, 0, opt_numArgs)); - }; -}; - - -/** - * Creates a function that returns its nth argument. - * @param {number} n The position of the return argument. - * @return {!Function} A new function. - */ -goog.functions.nth = function(n) { - return function() { - return arguments[n]; - }; -}; - - -/** - * Given a function, create a new function that swallows its return value - * and replaces it with a new one. - * @param {Function} f A function. - * @param {T} retValue A new return value. - * @return {function(...?):T} A new function. - * @template T - */ -goog.functions.withReturnValue = function(f, retValue) { - return goog.functions.sequence(f, goog.functions.constant(retValue)); -}; - - -/** - * Creates a function that returns whether its arguement equals the given value. - * - * Example: - * var key = goog.object.findKey(obj, goog.functions.equalTo('needle')); - * - * @param {*} value The value to compare to. - * @param {boolean=} opt_useLooseComparison Whether to use a loose (==) - * comparison rather than a strict (===) one. Defaults to false. - * @return {function(*):boolean} The new function. - */ -goog.functions.equalTo = function(value, opt_useLooseComparison) { - return function(other) { - return opt_useLooseComparison ? (value == other) : (value === other); - }; -}; - - -/** - * Creates the composition of the functions passed in. - * For example, (goog.functions.compose(f, g))(a) is equivalent to f(g(a)). - * @param {function(...?):T} fn The final function. - * @param {...Function} var_args A list of functions. - * @return {function(...?):T} The composition of all inputs. - * @template T - */ -goog.functions.compose = function(fn, var_args) { - var functions = arguments; - var length = functions.length; - return function() { - var result; - if (length) { - result = functions[length - 1].apply(this, arguments); - } - - for (var i = length - 2; i >= 0; i--) { - result = functions[i].call(this, result); - } - return result; - }; -}; - - -/** - * Creates a function that calls the functions passed in in sequence, and - * returns the value of the last function. For example, - * (goog.functions.sequence(f, g))(x) is equivalent to f(x),g(x). - * @param {...Function} var_args A list of functions. - * @return {!Function} A function that calls all inputs in sequence. - */ -goog.functions.sequence = function(var_args) { - var functions = arguments; - var length = functions.length; - return function() { - var result; - for (var i = 0; i < length; i++) { - result = functions[i].apply(this, arguments); - } - return result; - }; -}; - - -/** - * Creates a function that returns true if each of its components evaluates - * to true. The components are evaluated in order, and the evaluation will be - * short-circuited as soon as a function returns false. - * For example, (goog.functions.and(f, g))(x) is equivalent to f(x) && g(x). - * @param {...Function} var_args A list of functions. - * @return {function(...?):boolean} A function that ANDs its component - * functions. - */ -goog.functions.and = function(var_args) { - var functions = arguments; - var length = functions.length; - return function() { - for (var i = 0; i < length; i++) { - if (!functions[i].apply(this, arguments)) { - return false; - } - } - return true; - }; -}; - - -/** - * Creates a function that returns true if any of its components evaluates - * to true. The components are evaluated in order, and the evaluation will be - * short-circuited as soon as a function returns true. - * For example, (goog.functions.or(f, g))(x) is equivalent to f(x) || g(x). - * @param {...Function} var_args A list of functions. - * @return {function(...?):boolean} A function that ORs its component - * functions. - */ -goog.functions.or = function(var_args) { - var functions = arguments; - var length = functions.length; - return function() { - for (var i = 0; i < length; i++) { - if (functions[i].apply(this, arguments)) { - return true; - } - } - return false; - }; -}; - - -/** - * Creates a function that returns the Boolean opposite of a provided function. - * For example, (goog.functions.not(f))(x) is equivalent to !f(x). - * @param {!Function} f The original function. - * @return {function(...?):boolean} A function that delegates to f and returns - * opposite. - */ -goog.functions.not = function(f) { - return function() { - return !f.apply(this, arguments); - }; -}; - - -/** - * Generic factory function to construct an object given the constructor - * and the arguments. Intended to be bound to create object factories. - * - * Example: - * - * var factory = goog.partial(goog.functions.create, Class); - * - * @param {function(new:T, ...)} constructor The constructor for the Object. - * @param {...*} var_args The arguments to be passed to the constructor. - * @return {T} A new instance of the class given in {@code constructor}. - * @template T - */ -goog.functions.create = function(constructor, var_args) { - /** - * @constructor - * @final - */ - var temp = function() {}; - temp.prototype = constructor.prototype; - - // obj will have constructor's prototype in its chain and - // 'obj instanceof constructor' will be true. - var obj = new temp(); - - // obj is initialized by constructor. - // arguments is only array-like so lacks shift(), but can be used with - // the Array prototype function. - constructor.apply(obj, Array.prototype.slice.call(arguments, 1)); - return obj; -}; - - -/** - * @define {boolean} Whether the return value cache should be used. - * This should only be used to disable caches when testing. - */ -goog.define('goog.functions.CACHE_RETURN_VALUE', true); - - -/** - * Gives a wrapper function that caches the return value of a parameterless - * function when first called. - * - * When called for the first time, the given function is called and its - * return value is cached (thus this is only appropriate for idempotent - * functions). Subsequent calls will return the cached return value. This - * allows the evaluation of expensive functions to be delayed until first used. - * - * To cache the return values of functions with parameters, see goog.memoize. - * - * @param {!function():T} fn A function to lazily evaluate. - * @return {!function():T} A wrapped version the function. - * @template T - */ -goog.functions.cacheReturnValue = function(fn) { - var called = false; - var value; - - return function() { - if (!goog.functions.CACHE_RETURN_VALUE) { - return fn(); - } - - if (!called) { - value = fn(); - called = true; - } - - return value; - } -}; - - -/** - * Wraps a function to allow it to be called, at most, once. All - * additional calls are no-ops. - * - * This is particularly useful for initialization functions - * that should be called, at most, once. - * - * @param {function():*} f Function to call. - * @return {function():undefined} Wrapped function. - */ -goog.functions.once = function(f) { - // Keep a reference to the function that we null out when we're done with - // it -- that way, the function can be GC'd when we're done with it. - var inner = f; - return function() { - if (inner) { - var tmp = inner; - inner = null; - tmp(); - } - }; -}; - - -/** - * Wraps a function to allow it to be called, at most, once for each sequence of - * calls fired repeatedly so long as they are fired less than a specified - * interval apart (in milliseconds). Whether it receives one signal or multiple, - * it will always wait until a full interval has elapsed since the last signal - * before performing the action. - * - * This is particularly useful for bulking up repeated user actions (e.g. only - * refreshing a view once a user finishes typing rather than updating with every - * keystroke). For more stateful debouncing with support for pausing, resuming, - * and canceling debounced actions, use {@code goog.async.Debouncer}. - * - * @param {function(this:SCOPE):*} f Function to call. - * @param {number} interval Interval over which to debounce. The function will - * only be called after the full interval has elapsed since the last call. - * @param {SCOPE=} opt_scope Object in whose scope to call the function. - * @return {function():undefined} Wrapped function. - * @template SCOPE - */ -goog.functions.debounce = function(f, interval, opt_scope) { - if (opt_scope) { - f = goog.bind(f, opt_scope); - } - var timeout = null; - return function() { - goog.global.clearTimeout(timeout); - timeout = goog.global.setTimeout(f, interval); - }; -}; - - -/** - * Wraps a function to allow it to be called, at most, once per interval - * (specified in milliseconds). If it is called multiple times while it is - * waiting, it will only perform the action once at the end of the interval. - * - * This is particularly useful for limiting repeated user requests (e.g. - * preventing a user from spamming a server with frequent view refreshes). For - * more stateful throttling with support for pausing, resuming, and canceling - * throttled actions, use {@code goog.async.Throttle}. - * - * @param {function(this:SCOPE):*} f Function to call. - * @param {number} interval Interval over which to throttle. The function can - * only be called once per interval. - * @param {SCOPE=} opt_scope Object in whose scope to call the function. - * @return {function():undefined} Wrapped function. - * @template SCOPE - */ -goog.functions.throttle = function(f, interval, opt_scope) { - if (opt_scope) { - f = goog.bind(f, opt_scope); - } - var timeout = null; - var shouldFire = false; - var fire = function() { - timeout = goog.global.setTimeout(handleTimeout, interval); - f(); - }; - var handleTimeout = function() { - timeout = null; - if (shouldFire) { - shouldFire = false; - fire(); - } - }; - - return function() { - if (!timeout) { - fire(); - } else { - shouldFire = true; - } - }; -}; - -/** - * @license - * Latitude/longitude spherical geodesy formulae taken from - * http://www.movable-type.co.uk/scripts/latlong.html - * Licensed under CC-BY-3.0. - */ - -goog.provide('ol.Sphere'); - -goog.require('ol.math'); - - - -/** - * @classdesc - * Class to create objects that can be used with {@link - * ol.geom.Polygon.circular}. - * - * For example to create a sphere whose radius is equal to the semi-major - * axis of the WGS84 ellipsoid: - * - * ```js - * var wgs84Sphere= new ol.Sphere(6378137); - * ``` - * - * @constructor - * @param {number} radius Radius. - * @api - */ -ol.Sphere = function(radius) { - - /** - * @type {number} - */ - this.radius = radius; - -}; - - -/** - * Returns the geodesic area for a list of coordinates. - * - * [Reference](http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409) - * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for - * Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion - * Laboratory, Pasadena, CA, June 2007 - * - * @param {Array.<ol.Coordinate>} coordinates List of coordinates of a linear - * ring. If the ring is oriented clockwise, the area will be positive, - * otherwise it will be negative. - * @return {number} Area. - * @api - */ -ol.Sphere.prototype.geodesicArea = function(coordinates) { - var area = 0, len = coordinates.length; - var x1 = coordinates[len - 1][0]; - var y1 = coordinates[len - 1][1]; - for (var i = 0; i < len; i++) { - var x2 = coordinates[i][0], y2 = coordinates[i][1]; - area += ol.math.toRadians(x2 - x1) * - (2 + Math.sin(ol.math.toRadians(y1)) + - Math.sin(ol.math.toRadians(y2))); - x1 = x2; - y1 = y2; - } - return area * this.radius * this.radius / 2.0; -}; - - -/** - * Returns the distance from c1 to c2 using the haversine formula. - * - * @param {ol.Coordinate} c1 Coordinate 1. - * @param {ol.Coordinate} c2 Coordinate 2. - * @return {number} Haversine distance. - * @api - */ -ol.Sphere.prototype.haversineDistance = function(c1, c2) { - var lat1 = ol.math.toRadians(c1[1]); - var lat2 = ol.math.toRadians(c2[1]); - var deltaLatBy2 = (lat2 - lat1) / 2; - var deltaLonBy2 = ol.math.toRadians(c2[0] - c1[0]) / 2; - var a = Math.sin(deltaLatBy2) * Math.sin(deltaLatBy2) + - Math.sin(deltaLonBy2) * Math.sin(deltaLonBy2) * - Math.cos(lat1) * Math.cos(lat2); - return 2 * this.radius * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); -}; - - -/** - * Returns the coordinate at the given distance and bearing from `c1`. - * - * @param {ol.Coordinate} c1 The origin point (`[lon, lat]` in degrees). - * @param {number} distance The great-circle distance between the origin - * point and the target point. - * @param {number} bearing The bearing (in radians). - * @return {ol.Coordinate} The target point. - */ -ol.Sphere.prototype.offset = function(c1, distance, bearing) { - var lat1 = ol.math.toRadians(c1[1]); - var lon1 = ol.math.toRadians(c1[0]); - var dByR = distance / this.radius; - var lat = Math.asin( - Math.sin(lat1) * Math.cos(dByR) + - Math.cos(lat1) * Math.sin(dByR) * Math.cos(bearing)); - var lon = lon1 + Math.atan2( - Math.sin(bearing) * Math.sin(dByR) * Math.cos(lat1), - Math.cos(dByR) - Math.sin(lat1) * Math.sin(lat)); - return [ol.math.toDegrees(lon), ol.math.toDegrees(lat)]; -}; - -goog.provide('ol.sphere.NORMAL'); - -goog.require('ol.Sphere'); - - -/** - * The normal sphere. - * @const - * @type {ol.Sphere} - */ -ol.sphere.NORMAL = new ol.Sphere(6370997); - -goog.provide('ol.proj'); -goog.provide('ol.proj.METERS_PER_UNIT'); -goog.provide('ol.proj.Projection'); -goog.provide('ol.proj.ProjectionLike'); -goog.provide('ol.proj.Units'); - -goog.require('goog.asserts'); -goog.require('goog.object'); -goog.require('ol'); -goog.require('ol.Extent'); -goog.require('ol.TransformFunction'); -goog.require('ol.extent'); -goog.require('ol.sphere.NORMAL'); - - -/** - * A projection as {@link ol.proj.Projection}, SRS identifier string or - * undefined. - * @typedef {ol.proj.Projection|string|undefined} ol.proj.ProjectionLike - * @api stable - */ -ol.proj.ProjectionLike; - - -/** - * Projection units: `'degrees'`, `'ft'`, `'m'`, `'pixels'`, `'tile-pixels'` or - * `'us-ft'`. - * @enum {string} - * @api stable - */ -ol.proj.Units = { - DEGREES: 'degrees', - FEET: 'ft', - METERS: 'm', - PIXELS: 'pixels', - TILE_PIXELS: 'tile-pixels', - USFEET: 'us-ft' -}; - - -/** - * Meters per unit lookup table. - * @const - * @type {Object.<ol.proj.Units, number>} - * @api stable - */ -ol.proj.METERS_PER_UNIT = {}; -ol.proj.METERS_PER_UNIT[ol.proj.Units.DEGREES] = - 2 * Math.PI * ol.sphere.NORMAL.radius / 360; -ol.proj.METERS_PER_UNIT[ol.proj.Units.FEET] = 0.3048; -ol.proj.METERS_PER_UNIT[ol.proj.Units.METERS] = 1; -ol.proj.METERS_PER_UNIT[ol.proj.Units.USFEET] = 1200 / 3937; - - - -/** - * @classdesc - * Projection definition class. One of these is created for each projection - * supported in the application and stored in the {@link ol.proj} namespace. - * You can use these in applications, but this is not required, as API params - * and options use {@link ol.proj.ProjectionLike} which means the simple string - * code will suffice. - * - * You can use {@link ol.proj.get} to retrieve the object for a particular - * projection. - * - * The library includes definitions for `EPSG:4326` and `EPSG:3857`, together - * with the following aliases: - * * `EPSG:4326`: CRS:84, urn:ogc:def:crs:EPSG:6.6:4326, - * urn:ogc:def:crs:OGC:1.3:CRS84, urn:ogc:def:crs:OGC:2:84, - * http://www.opengis.net/gml/srs/epsg.xml#4326, - * urn:x-ogc:def:crs:EPSG:4326 - * * `EPSG:3857`: EPSG:102100, EPSG:102113, EPSG:900913, - * urn:ogc:def:crs:EPSG:6.18:3:3857, - * http://www.opengis.net/gml/srs/epsg.xml#3857 - * - * If you use proj4js, aliases can be added using `proj4.defs()`; see - * [documentation](https://github.com/proj4js/proj4js). - * - * @constructor - * @param {olx.ProjectionOptions} options Projection options. - * @struct - * @api stable - */ -ol.proj.Projection = function(options) { - - /** - * @private - * @type {string} - */ - this.code_ = options.code; - - /** - * @private - * @type {ol.proj.Units} - */ - this.units_ = /** @type {ol.proj.Units} */ (options.units); - - /** - * @private - * @type {ol.Extent} - */ - this.extent_ = options.extent !== undefined ? options.extent : null; - - /** - * @private - * @type {ol.Extent} - */ - this.worldExtent_ = options.worldExtent !== undefined ? - options.worldExtent : null; - - /** - * @private - * @type {string} - */ - this.axisOrientation_ = options.axisOrientation !== undefined ? - options.axisOrientation : 'enu'; - - /** - * @private - * @type {boolean} - */ - this.global_ = options.global !== undefined ? options.global : false; - - - /** - * @private - * @type {boolean} - */ - this.canWrapX_ = !!(this.global_ && this.extent_); - - /** - * @private - * @type {function(number, ol.Coordinate):number} - */ - this.getPointResolutionFunc_ = options.getPointResolution !== undefined ? - options.getPointResolution : this.getPointResolution_; - - /** - * @private - * @type {ol.tilegrid.TileGrid} - */ - this.defaultTileGrid_ = null; - - var projections = ol.proj.projections_; - var code = options.code; - goog.asserts.assert(code !== undefined, - 'Option "code" is required for constructing instance'); - if (ol.ENABLE_PROJ4JS && typeof proj4 == 'function' && - projections[code] === undefined) { - var def = proj4.defs(code); - if (def !== undefined) { - if (def.axis !== undefined && options.axisOrientation === undefined) { - this.axisOrientation_ = def.axis; - } - if (options.units === undefined) { - var units = def.units; - if (def.to_meter !== undefined) { - if (units === undefined || - ol.proj.METERS_PER_UNIT[units] === undefined) { - units = def.to_meter.toString(); - ol.proj.METERS_PER_UNIT[units] = def.to_meter; - } - } - this.units_ = units; - } - var currentCode, currentDef, currentProj, proj4Transform; - for (currentCode in projections) { - currentDef = proj4.defs(currentCode); - if (currentDef !== undefined) { - currentProj = ol.proj.get(currentCode); - if (currentDef === def) { - ol.proj.addEquivalentProjections([currentProj, this]); - } else { - proj4Transform = proj4(currentCode, code); - ol.proj.addCoordinateTransforms(currentProj, this, - proj4Transform.forward, proj4Transform.inverse); - } - } - } - } - } - -}; - - -/** - * @return {boolean} The projection is suitable for wrapping the x-axis - */ -ol.proj.Projection.prototype.canWrapX = function() { - return this.canWrapX_; -}; - - -/** - * Get the code for this projection, e.g. 'EPSG:4326'. - * @return {string} Code. - * @api stable - */ -ol.proj.Projection.prototype.getCode = function() { - return this.code_; -}; - - -/** - * Get the validity extent for this projection. - * @return {ol.Extent} Extent. - * @api stable - */ -ol.proj.Projection.prototype.getExtent = function() { - return this.extent_; -}; - - -/** - * Get the units of this projection. - * @return {ol.proj.Units} Units. - * @api stable - */ -ol.proj.Projection.prototype.getUnits = function() { - return this.units_; -}; - - -/** - * Get the amount of meters per unit of this projection. If the projection is - * not configured with a units identifier, the return is `undefined`. - * @return {number|undefined} Meters. - * @api stable - */ -ol.proj.Projection.prototype.getMetersPerUnit = function() { - return ol.proj.METERS_PER_UNIT[this.units_]; -}; - - -/** - * Get the world extent for this projection. - * @return {ol.Extent} Extent. - * @api - */ -ol.proj.Projection.prototype.getWorldExtent = function() { - return this.worldExtent_; -}; - - -/** - * Get the axis orientation of this projection. - * Example values are: - * enu - the default easting, northing, elevation. - * neu - northing, easting, up - useful for "lat/long" geographic coordinates, - * or south orientated transverse mercator. - * wnu - westing, northing, up - some planetary coordinate systems have - * "west positive" coordinate systems - * @return {string} Axis orientation. - */ -ol.proj.Projection.prototype.getAxisOrientation = function() { - return this.axisOrientation_; -}; - - -/** - * Is this projection a global projection which spans the whole world? - * @return {boolean} Whether the projection is global. - * @api stable - */ -ol.proj.Projection.prototype.isGlobal = function() { - return this.global_; -}; - - -/** -* Set if the projection is a global projection which spans the whole world -* @param {boolean} global Whether the projection is global. -* @api stable -*/ -ol.proj.Projection.prototype.setGlobal = function(global) { - this.global_ = global; - this.canWrapX_ = !!(global && this.extent_); -}; - - -/** - * @return {ol.tilegrid.TileGrid} The default tile grid. - */ -ol.proj.Projection.prototype.getDefaultTileGrid = function() { - return this.defaultTileGrid_; -}; - - -/** - * @param {ol.tilegrid.TileGrid} tileGrid The default tile grid. - */ -ol.proj.Projection.prototype.setDefaultTileGrid = function(tileGrid) { - this.defaultTileGrid_ = tileGrid; -}; - - -/** - * Set the validity extent for this projection. - * @param {ol.Extent} extent Extent. - * @api stable - */ -ol.proj.Projection.prototype.setExtent = function(extent) { - this.extent_ = extent; - this.canWrapX_ = !!(this.global_ && extent); -}; - - -/** - * Set the world extent for this projection. - * @param {ol.Extent} worldExtent World extent - * [minlon, minlat, maxlon, maxlat]. - * @api - */ -ol.proj.Projection.prototype.setWorldExtent = function(worldExtent) { - this.worldExtent_ = worldExtent; -}; - - -/** -* Set the getPointResolution function for this projection. -* @param {function(number, ol.Coordinate):number} func Function -* @api -*/ -ol.proj.Projection.prototype.setGetPointResolution = function(func) { - this.getPointResolutionFunc_ = func; -}; - - -/** -* Default version. -* Get the resolution of the point in degrees or distance units. -* For projections with degrees as the unit this will simply return the -* provided resolution. For other projections the point resolution is -* estimated by transforming the 'point' pixel to EPSG:4326, -* measuring its width and height on the normal sphere, -* and taking the average of the width and height. -* @param {number} resolution Nominal resolution in projection units. -* @param {ol.Coordinate} point Point to find adjusted resolution at. -* @return {number} Point resolution at point in projection units. -* @private -*/ -ol.proj.Projection.prototype.getPointResolution_ = function(resolution, point) { - var units = this.getUnits(); - if (units == ol.proj.Units.DEGREES) { - return resolution; - } else { - // Estimate point resolution by transforming the center pixel to EPSG:4326, - // measuring its width and height on the normal sphere, and taking the - // average of the width and height. - var toEPSG4326 = ol.proj.getTransformFromProjections( - this, ol.proj.get('EPSG:4326')); - var vertices = [ - point[0] - resolution / 2, point[1], - point[0] + resolution / 2, point[1], - point[0], point[1] - resolution / 2, - point[0], point[1] + resolution / 2 - ]; - vertices = toEPSG4326(vertices, vertices, 2); - var width = ol.sphere.NORMAL.haversineDistance( - vertices.slice(0, 2), vertices.slice(2, 4)); - var height = ol.sphere.NORMAL.haversineDistance( - vertices.slice(4, 6), vertices.slice(6, 8)); - var pointResolution = (width + height) / 2; - var metersPerUnit = this.getMetersPerUnit(); - if (metersPerUnit !== undefined) { - pointResolution /= metersPerUnit; - } - return pointResolution; - } -}; - - -/** - * Get the resolution of the point in degrees or distance units. - * For projections with degrees as the unit this will simply return the - * provided resolution. The default for other projections is to estimate - * the point resolution by transforming the 'point' pixel to EPSG:4326, - * measuring its width and height on the normal sphere, - * and taking the average of the width and height. - * An alternative implementation may be given when constructing a - * projection. For many local projections, - * such a custom function will return the resolution unchanged. - * @param {number} resolution Resolution in projection units. - * @param {ol.Coordinate} point Point. - * @return {number} Point resolution in projection units. - * @api - */ -ol.proj.Projection.prototype.getPointResolution = function(resolution, point) { - return this.getPointResolutionFunc_(resolution, point); -}; - - -/** - * @private - * @type {Object.<string, ol.proj.Projection>} - */ -ol.proj.projections_ = {}; - - -/** - * @private - * @type {Object.<string, Object.<string, ol.TransformFunction>>} - */ -ol.proj.transforms_ = {}; - - -/** - * Registers transformation functions that don't alter coordinates. Those allow - * to transform between projections with equal meaning. - * - * @param {Array.<ol.proj.Projection>} projections Projections. - * @api - */ -ol.proj.addEquivalentProjections = function(projections) { - ol.proj.addProjections(projections); - projections.forEach(function(source) { - projections.forEach(function(destination) { - if (source !== destination) { - ol.proj.addTransform(source, destination, ol.proj.cloneTransform); - } - }); - }); -}; - - -/** - * Registers transformation functions to convert coordinates in any projection - * in projection1 to any projection in projection2. - * - * @param {Array.<ol.proj.Projection>} projections1 Projections with equal - * meaning. - * @param {Array.<ol.proj.Projection>} projections2 Projections with equal - * meaning. - * @param {ol.TransformFunction} forwardTransform Transformation from any - * projection in projection1 to any projection in projection2. - * @param {ol.TransformFunction} inverseTransform Transform from any projection - * in projection2 to any projection in projection1.. - */ -ol.proj.addEquivalentTransforms = - function(projections1, projections2, forwardTransform, inverseTransform) { - projections1.forEach(function(projection1) { - projections2.forEach(function(projection2) { - ol.proj.addTransform(projection1, projection2, forwardTransform); - ol.proj.addTransform(projection2, projection1, inverseTransform); - }); - }); -}; - - -/** - * Add a Projection object to the list of supported projections that can be - * looked up by their code. - * - * @param {ol.proj.Projection} projection Projection instance. - * @api stable - */ -ol.proj.addProjection = function(projection) { - ol.proj.projections_[projection.getCode()] = projection; - ol.proj.addTransform(projection, projection, ol.proj.cloneTransform); -}; - - -/** - * @param {Array.<ol.proj.Projection>} projections Projections. - */ -ol.proj.addProjections = function(projections) { - var addedProjections = []; - projections.forEach(function(projection) { - addedProjections.push(ol.proj.addProjection(projection)); - }); -}; - - -/** - * FIXME empty description for jsdoc - */ -ol.proj.clearAllProjections = function() { - ol.proj.projections_ = {}; - ol.proj.transforms_ = {}; -}; - - -/** - * @param {ol.proj.Projection|string|undefined} projection Projection. - * @param {string} defaultCode Default code. - * @return {ol.proj.Projection} Projection. - */ -ol.proj.createProjection = function(projection, defaultCode) { - if (!projection) { - return ol.proj.get(defaultCode); - } else if (goog.isString(projection)) { - return ol.proj.get(projection); - } else { - goog.asserts.assertInstanceof(projection, ol.proj.Projection, - 'projection should be an ol.proj.Projection'); - return projection; - } -}; - - -/** - * Registers a conversion function to convert coordinates from the source - * projection to the destination projection. - * - * @param {ol.proj.Projection} source Source. - * @param {ol.proj.Projection} destination Destination. - * @param {ol.TransformFunction} transformFn Transform. - */ -ol.proj.addTransform = function(source, destination, transformFn) { - var sourceCode = source.getCode(); - var destinationCode = destination.getCode(); - var transforms = ol.proj.transforms_; - if (!(sourceCode in transforms)) { - transforms[sourceCode] = {}; - } - transforms[sourceCode][destinationCode] = transformFn; -}; - - -/** - * Registers coordinate transform functions to convert coordinates between the - * source projection and the destination projection. - * The forward and inverse functions convert coordinate pairs; this function - * converts these into the functions used internally which also handle - * extents and coordinate arrays. - * - * @param {ol.proj.ProjectionLike} source Source projection. - * @param {ol.proj.ProjectionLike} destination Destination projection. - * @param {function(ol.Coordinate): ol.Coordinate} forward The forward transform - * function (that is, from the source projection to the destination - * projection) that takes a {@link ol.Coordinate} as argument and returns - * the transformed {@link ol.Coordinate}. - * @param {function(ol.Coordinate): ol.Coordinate} inverse The inverse transform - * function (that is, from the destination projection to the source - * projection) that takes a {@link ol.Coordinate} as argument and returns - * the transformed {@link ol.Coordinate}. - * @api stable - */ -ol.proj.addCoordinateTransforms = - function(source, destination, forward, inverse) { - var sourceProj = ol.proj.get(source); - var destProj = ol.proj.get(destination); - ol.proj.addTransform(sourceProj, destProj, - ol.proj.createTransformFromCoordinateTransform(forward)); - ol.proj.addTransform(destProj, sourceProj, - ol.proj.createTransformFromCoordinateTransform(inverse)); -}; - - -/** - * Creates a {@link ol.TransformFunction} from a simple 2D coordinate transform - * function. - * @param {function(ol.Coordinate): ol.Coordinate} transform Coordinate - * transform. - * @return {ol.TransformFunction} Transform function. - */ -ol.proj.createTransformFromCoordinateTransform = function(transform) { - return ( - /** - * @param {Array.<number>} input Input. - * @param {Array.<number>=} opt_output Output. - * @param {number=} opt_dimension Dimension. - * @return {Array.<number>} Output. - */ - function(input, opt_output, opt_dimension) { - var length = input.length; - var dimension = opt_dimension !== undefined ? opt_dimension : 2; - var output = opt_output !== undefined ? opt_output : new Array(length); - var point, i, j; - for (i = 0; i < length; i += dimension) { - point = transform([input[i], input[i + 1]]); - output[i] = point[0]; - output[i + 1] = point[1]; - for (j = dimension - 1; j >= 2; --j) { - output[i + j] = input[i + j]; - } - } - return output; - }); -}; - - -/** - * Unregisters the conversion function to convert coordinates from the source - * projection to the destination projection. This method is used to clean up - * cached transforms during testing. - * - * @param {ol.proj.Projection} source Source projection. - * @param {ol.proj.Projection} destination Destination projection. - * @return {ol.TransformFunction} transformFn The unregistered transform. - */ -ol.proj.removeTransform = function(source, destination) { - var sourceCode = source.getCode(); - var destinationCode = destination.getCode(); - var transforms = ol.proj.transforms_; - goog.asserts.assert(sourceCode in transforms, - 'sourceCode should be in transforms'); - goog.asserts.assert(destinationCode in transforms[sourceCode], - 'destinationCode should be in transforms of sourceCode'); - var transform = transforms[sourceCode][destinationCode]; - delete transforms[sourceCode][destinationCode]; - if (goog.object.isEmpty(transforms[sourceCode])) { - delete transforms[sourceCode]; - } - return transform; -}; - - -/** - * Transforms a coordinate from longitude/latitude to a different projection. - * @param {ol.Coordinate} coordinate Coordinate as longitude and latitude, i.e. - * an array with longitude as 1st and latitude as 2nd element. - * @param {ol.proj.ProjectionLike=} opt_projection Target projection. The - * default is Web Mercator, i.e. 'EPSG:3857'. - * @return {ol.Coordinate} Coordinate projected to the target projection. - * @api stable - */ -ol.proj.fromLonLat = function(coordinate, opt_projection) { - return ol.proj.transform(coordinate, 'EPSG:4326', - opt_projection !== undefined ? opt_projection : 'EPSG:3857'); -}; - - -/** - * Transforms a coordinate to longitude/latitude. - * @param {ol.Coordinate} coordinate Projected coordinate. - * @param {ol.proj.ProjectionLike=} opt_projection Projection of the coordinate. - * The default is Web Mercator, i.e. 'EPSG:3857'. - * @return {ol.Coordinate} Coordinate as longitude and latitude, i.e. an array - * with longitude as 1st and latitude as 2nd element. - * @api stable - */ -ol.proj.toLonLat = function(coordinate, opt_projection) { - return ol.proj.transform(coordinate, - opt_projection !== undefined ? opt_projection : 'EPSG:3857', 'EPSG:4326'); -}; - - -/** - * Fetches a Projection object for the code specified. - * - * @param {ol.proj.ProjectionLike} projectionLike Either a code string which is - * a combination of authority and identifier such as "EPSG:4326", or an - * existing projection object, or undefined. - * @return {ol.proj.Projection} Projection object, or null if not in list. - * @api stable - */ -ol.proj.get = function(projectionLike) { - var projection; - if (projectionLike instanceof ol.proj.Projection) { - projection = projectionLike; - } else if (goog.isString(projectionLike)) { - var code = projectionLike; - projection = ol.proj.projections_[code]; - if (ol.ENABLE_PROJ4JS && projection === undefined && - typeof proj4 == 'function' && proj4.defs(code) !== undefined) { - projection = new ol.proj.Projection({code: code}); - ol.proj.addProjection(projection); - } - } else { - projection = null; - } - return projection; -}; - - -/** - * Checks if two projections are the same, that is every coordinate in one - * projection does represent the same geographic point as the same coordinate in - * the other projection. - * - * @param {ol.proj.Projection} projection1 Projection 1. - * @param {ol.proj.Projection} projection2 Projection 2. - * @return {boolean} Equivalent. - */ -ol.proj.equivalent = function(projection1, projection2) { - if (projection1 === projection2) { - return true; - } - var equalUnits = projection1.getUnits() === projection2.getUnits(); - if (projection1.getCode() === projection2.getCode()) { - return equalUnits; - } else { - var transformFn = ol.proj.getTransformFromProjections( - projection1, projection2); - return transformFn === ol.proj.cloneTransform && equalUnits; - } -}; - - -/** - * Given the projection-like objects, searches for a transformation - * function to convert a coordinates array from the source projection to the - * destination projection. - * - * @param {ol.proj.ProjectionLike} source Source. - * @param {ol.proj.ProjectionLike} destination Destination. - * @return {ol.TransformFunction} Transform function. - * @api stable - */ -ol.proj.getTransform = function(source, destination) { - var sourceProjection = ol.proj.get(source); - var destinationProjection = ol.proj.get(destination); - return ol.proj.getTransformFromProjections( - sourceProjection, destinationProjection); -}; - - -/** - * Searches in the list of transform functions for the function for converting - * coordinates from the source projection to the destination projection. - * - * @param {ol.proj.Projection} sourceProjection Source Projection object. - * @param {ol.proj.Projection} destinationProjection Destination Projection - * object. - * @return {ol.TransformFunction} Transform function. - */ -ol.proj.getTransformFromProjections = - function(sourceProjection, destinationProjection) { - var transforms = ol.proj.transforms_; - var sourceCode = sourceProjection.getCode(); - var destinationCode = destinationProjection.getCode(); - var transform; - if (sourceCode in transforms && destinationCode in transforms[sourceCode]) { - transform = transforms[sourceCode][destinationCode]; - } - if (transform === undefined) { - goog.asserts.assert(transform !== undefined, 'transform should be defined'); - transform = ol.proj.identityTransform; - } - return transform; -}; - - -/** - * @param {Array.<number>} input Input coordinate array. - * @param {Array.<number>=} opt_output Output array of coordinate values. - * @param {number=} opt_dimension Dimension. - * @return {Array.<number>} Input coordinate array (same array as input). - */ -ol.proj.identityTransform = function(input, opt_output, opt_dimension) { - if (opt_output !== undefined && input !== opt_output) { - // TODO: consider making this a warning instead - goog.asserts.fail('This should not be used internally.'); - for (var i = 0, ii = input.length; i < ii; ++i) { - opt_output[i] = input[i]; - } - input = opt_output; - } - return input; -}; - - -/** - * @param {Array.<number>} input Input coordinate array. - * @param {Array.<number>=} opt_output Output array of coordinate values. - * @param {number=} opt_dimension Dimension. - * @return {Array.<number>} Output coordinate array (new array, same coordinate - * values). - */ -ol.proj.cloneTransform = function(input, opt_output, opt_dimension) { - var output; - if (opt_output !== undefined) { - for (var i = 0, ii = input.length; i < ii; ++i) { - opt_output[i] = input[i]; - } - output = opt_output; - } else { - output = input.slice(); + var dest = opt_dest ? opt_dest : []; + var i = 0; + var j; + for (j = offset; j < end; j += stride) { + var x = flatCoordinates[j]; + var y = flatCoordinates[j + 1]; + dest[i++] = m00 * x + m01 * y + m03; + dest[i++] = m10 * x + m11 * y + m13; } - return output; -}; - - -/** - * Transforms a coordinate from source projection to destination projection. - * This returns a new coordinate (and does not modify the original). - * - * See {@link ol.proj.transformExtent} for extent transformation. - * See the transform method of {@link ol.geom.Geometry} and its subclasses for - * geometry transforms. - * - * @param {ol.Coordinate} coordinate Coordinate. - * @param {ol.proj.ProjectionLike} source Source projection-like. - * @param {ol.proj.ProjectionLike} destination Destination projection-like. - * @return {ol.Coordinate} Coordinate. - * @api stable - */ -ol.proj.transform = function(coordinate, source, destination) { - var transformFn = ol.proj.getTransform(source, destination); - return transformFn(coordinate, undefined, coordinate.length); -}; - - -/** - * Transforms an extent from source projection to destination projection. This - * returns a new extent (and does not modify the original). - * - * @param {ol.Extent} extent The extent to transform. - * @param {ol.proj.ProjectionLike} source Source projection-like. - * @param {ol.proj.ProjectionLike} destination Destination projection-like. - * @return {ol.Extent} The transformed extent. - * @api stable - */ -ol.proj.transformExtent = function(extent, source, destination) { - var transformFn = ol.proj.getTransform(source, destination); - return ol.extent.applyTransform(extent, transformFn); -}; - - -/** - * Transforms the given point to the destination projection. - * - * @param {ol.Coordinate} point Point. - * @param {ol.proj.Projection} sourceProjection Source projection. - * @param {ol.proj.Projection} destinationProjection Destination projection. - * @return {ol.Coordinate} Point. - */ -ol.proj.transformWithProjections = - function(point, sourceProjection, destinationProjection) { - var transformFn = ol.proj.getTransformFromProjections( - sourceProjection, destinationProjection); - return transformFn(point); -}; - -goog.provide('ol.geom.Geometry'); -goog.provide('ol.geom.GeometryLayout'); -goog.provide('ol.geom.GeometryType'); - -goog.require('goog.asserts'); -goog.require('goog.functions'); -goog.require('ol.Object'); -goog.require('ol.extent'); -goog.require('ol.proj'); -goog.require('ol.proj.Units'); - - -/** - * The geometry type. One of `'Point'`, `'LineString'`, `'LinearRing'`, - * `'Polygon'`, `'MultiPoint'`, `'MultiLineString'`, `'MultiPolygon'`, - * `'GeometryCollection'`, `'Circle'`. - * @enum {string} - * @api stable - */ -ol.geom.GeometryType = { - POINT: 'Point', - LINE_STRING: 'LineString', - LINEAR_RING: 'LinearRing', - POLYGON: 'Polygon', - MULTI_POINT: 'MultiPoint', - MULTI_LINE_STRING: 'MultiLineString', - MULTI_POLYGON: 'MultiPolygon', - GEOMETRY_COLLECTION: 'GeometryCollection', - CIRCLE: 'Circle' -}; - - -/** - * The coordinate layout for geometries, indicating whether a 3rd or 4th z ('Z') - * or measure ('M') coordinate is available. Supported values are `'XY'`, - * `'XYZ'`, `'XYM'`, `'XYZM'`. - * @enum {string} - * @api stable - */ -ol.geom.GeometryLayout = { - XY: 'XY', - XYZ: 'XYZ', - XYM: 'XYM', - XYZM: 'XYZM' -}; - - - -/** - * @classdesc - * Abstract base class; normally only used for creating subclasses and not - * instantiated in apps. - * Base class for vector geometries. - * - * To get notified of changes to the geometry, register a listener for the - * generic `change` event on your geometry instance. - * - * @constructor - * @extends {ol.Object} - * @api stable - */ -ol.geom.Geometry = function() { - - goog.base(this); - - /** - * @private - * @type {ol.Extent} - */ - this.extent_ = ol.extent.createEmpty(); - - /** - * @private - * @type {number} - */ - this.extentRevision_ = -1; - - /** - * @protected - * @type {Object.<string, ol.geom.Geometry>} - */ - this.simplifiedGeometryCache = {}; - - /** - * @protected - * @type {number} - */ - this.simplifiedGeometryMaxMinSquaredTolerance = 0; - - /** - * @protected - * @type {number} - */ - this.simplifiedGeometryRevision = 0; - -}; -goog.inherits(ol.geom.Geometry, ol.Object); - - -/** - * Make a complete copy of the geometry. - * @function - * @return {!ol.geom.Geometry} Clone. - */ -ol.geom.Geometry.prototype.clone = goog.abstractMethod; - - -/** - * @param {number} x X. - * @param {number} y Y. - * @param {ol.Coordinate} closestPoint Closest point. - * @param {number} minSquaredDistance Minimum squared distance. - * @return {number} Minimum squared distance. - */ -ol.geom.Geometry.prototype.closestPointXY = goog.abstractMethod; - - -/** - * Return the closest point of the geometry to the passed point as - * {@link ol.Coordinate coordinate}. - * @param {ol.Coordinate} point Point. - * @param {ol.Coordinate=} opt_closestPoint Closest point. - * @return {ol.Coordinate} Closest point. - * @api stable - */ -ol.geom.Geometry.prototype.getClosestPoint = function(point, opt_closestPoint) { - var closestPoint = opt_closestPoint ? opt_closestPoint : [NaN, NaN]; - this.closestPointXY(point[0], point[1], closestPoint, Infinity); - return closestPoint; -}; - - -/** - * @param {ol.Coordinate} coordinate Coordinate. - * @return {boolean} Contains coordinate. - */ -ol.geom.Geometry.prototype.containsCoordinate = function(coordinate) { - return this.containsXY(coordinate[0], coordinate[1]); -}; - - -/** - * @param {ol.Extent} extent Extent. - * @protected - * @return {ol.Extent} extent Extent. - */ -ol.geom.Geometry.prototype.computeExtent = goog.abstractMethod; - - -/** - * @param {number} x X. - * @param {number} y Y. - * @return {boolean} Contains (x, y). - */ -ol.geom.Geometry.prototype.containsXY = goog.functions.FALSE; - - -/** - * Get the extent of the geometry. - * @param {ol.Extent=} opt_extent Extent. - * @return {ol.Extent} extent Extent. - * @api stable - */ -ol.geom.Geometry.prototype.getExtent = function(opt_extent) { - if (this.extentRevision_ != this.getRevision()) { - this.extent_ = this.computeExtent(this.extent_); - this.extentRevision_ = this.getRevision(); + if (opt_dest && dest.length != i) { + dest.length = i; } - return ol.extent.returnOrUpdate(this.extent_, opt_extent); -}; - - -/** - * Create a simplified version of this geometry. For linestrings, this uses - * the the {@link - * https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm - * Douglas Peucker} algorithm. For polygons, a quantization-based - * simplification is used to preserve topology. - * @function - * @param {number} tolerance The tolerance distance for simplification. - * @return {ol.geom.Geometry} A new, simplified version of the original - * geometry. - * @api - */ -ol.geom.Geometry.prototype.simplify = function(tolerance) { - return this.getSimplifiedGeometry(tolerance * tolerance); -}; - - -/** - * Create a simplified version of this geometry using the Douglas Peucker - * algorithm. - * @see https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm - * @function - * @param {number} squaredTolerance Squared tolerance. - * @return {ol.geom.Geometry} Simplified geometry. - */ -ol.geom.Geometry.prototype.getSimplifiedGeometry = goog.abstractMethod; - - -/** - * Get the type of this geometry. - * @function - * @return {ol.geom.GeometryType} Geometry type. - */ -ol.geom.Geometry.prototype.getType = goog.abstractMethod; - - -/** - * Apply a transform function to each coordinate of the geometry. - * The geometry is modified in place. - * If you do not want the geometry modified in place, first clone() it and - * then use this function on the clone. - * @function - * @param {ol.TransformFunction} transformFn Transform. - */ -ol.geom.Geometry.prototype.applyTransform = goog.abstractMethod; - - -/** - * Test if the geometry and the passed extent intersect. - * @param {ol.Extent} extent Extent. - * @return {boolean} `true` if the geometry and the extent intersect. - * @function - */ -ol.geom.Geometry.prototype.intersectsExtent = goog.abstractMethod; - - -/** - * Translate the geometry. This modifies the geometry coordinates in place. If - * instead you want a new geometry, first `clone()` this geometry. - * @param {number} deltaX Delta X. - * @param {number} deltaY Delta Y. - * @function - */ -ol.geom.Geometry.prototype.translate = goog.abstractMethod; - - -/** - * Transform each coordinate of the geometry from one coordinate reference - * system to another. The geometry is modified in place. - * For example, a line will be transformed to a line and a circle to a circle. - * If you do not want the geometry modified in place, first clone() it and - * then use this function on the clone. - * - * @param {ol.proj.ProjectionLike} source The current projection. Can be a - * string identifier or a {@link ol.proj.Projection} object. - * @param {ol.proj.ProjectionLike} destination The desired projection. Can be a - * string identifier or a {@link ol.proj.Projection} object. - * @return {ol.geom.Geometry} This geometry. Note that original geometry is - * modified in place. - * @api stable - */ -ol.geom.Geometry.prototype.transform = function(source, destination) { - goog.asserts.assert( - ol.proj.get(source).getUnits() !== ol.proj.Units.TILE_PIXELS && - ol.proj.get(destination).getUnits() !== ol.proj.Units.TILE_PIXELS, - 'cannot transform geometries with TILE_PIXELS units'); - this.applyTransform(ol.proj.getTransform(source, destination)); - return this; + return dest; }; -goog.provide('ol.geom.flat.transform'); - -goog.require('goog.vec.Mat4'); - /** * @param {Array.<number>} flatCoordinates Flat coordinates. * @param {number} offset Offset. * @param {number} end End. * @param {number} stride Stride. - * @param {goog.vec.Mat4.Number} transform Transform. + * @param {number} angle Angle. + * @param {Array.<number>} anchor Rotation anchor point. * @param {Array.<number>=} opt_dest Destination. * @return {Array.<number>} Transformed coordinates. */ -ol.geom.flat.transform.transform2D = - function(flatCoordinates, offset, end, stride, transform, opt_dest) { - var m00 = goog.vec.Mat4.getElement(transform, 0, 0); - var m10 = goog.vec.Mat4.getElement(transform, 1, 0); - var m01 = goog.vec.Mat4.getElement(transform, 0, 1); - var m11 = goog.vec.Mat4.getElement(transform, 1, 1); - var m03 = goog.vec.Mat4.getElement(transform, 0, 3); - var m13 = goog.vec.Mat4.getElement(transform, 1, 3); +ol.geom.flat.transform.rotate = function(flatCoordinates, offset, end, stride, angle, anchor, opt_dest) { var dest = opt_dest ? opt_dest : []; + var cos = Math.cos(angle); + var sin = Math.sin(angle); + var anchorX = anchor[0]; + var anchorY = anchor[1]; var i = 0; - var j; - for (j = offset; j < end; j += stride) { - var x = flatCoordinates[j]; - var y = flatCoordinates[j + 1]; - dest[i++] = m00 * x + m01 * y + m03; - dest[i++] = m10 * x + m11 * y + m13; + for (var j = offset; j < end; j += stride) { + var deltaX = flatCoordinates[j] - anchorX; + var deltaY = flatCoordinates[j + 1] - anchorY; + dest[i++] = anchorX + deltaX * cos - deltaY * sin; + dest[i++] = anchorY + deltaX * sin + deltaY * cos; + for (var k = j + 2; k < j + stride; ++k) { + dest[i++] = flatCoordinates[k]; + } } if (opt_dest && dest.length != i) { dest.length = i; @@ -19880,8 +13178,7 @@ ol.geom.flat.transform.transform2D = * @param {Array.<number>=} opt_dest Destination. * @return {Array.<number>} Transformed coordinates. */ -ol.geom.flat.transform.translate = - function(flatCoordinates, offset, end, stride, deltaX, deltaY, opt_dest) { +ol.geom.flat.transform.translate = function(flatCoordinates, offset, end, stride, deltaX, deltaY, opt_dest) { var dest = opt_dest ? opt_dest : []; var i = 0; var j, k; @@ -19901,13 +13198,12 @@ ol.geom.flat.transform.translate = goog.provide('ol.geom.SimpleGeometry'); goog.require('goog.asserts'); -goog.require('goog.functions'); -goog.require('goog.object'); +goog.require('ol.functions'); goog.require('ol.extent'); goog.require('ol.geom.Geometry'); goog.require('ol.geom.GeometryLayout'); goog.require('ol.geom.flat.transform'); - +goog.require('ol.object'); /** @@ -19985,7 +13281,7 @@ ol.geom.SimpleGeometry.getStrideForLayout = function(layout) { /** * @inheritDoc */ -ol.geom.SimpleGeometry.prototype.containsXY = goog.functions.FALSE; +ol.geom.SimpleGeometry.prototype.containsXY = ol.functions.FALSE; /** @@ -20045,10 +13341,9 @@ ol.geom.SimpleGeometry.prototype.getLayout = function() { /** * @inheritDoc */ -ol.geom.SimpleGeometry.prototype.getSimplifiedGeometry = - function(squaredTolerance) { +ol.geom.SimpleGeometry.prototype.getSimplifiedGeometry = function(squaredTolerance) { if (this.simplifiedGeometryRevision != this.getRevision()) { - goog.object.clear(this.simplifiedGeometryCache); + ol.object.clear(this.simplifiedGeometryCache); this.simplifiedGeometryMaxMinSquaredTolerance = 0; this.simplifiedGeometryRevision = this.getRevision(); } @@ -20088,8 +13383,7 @@ ol.geom.SimpleGeometry.prototype.getSimplifiedGeometry = * @return {ol.geom.SimpleGeometry} Simplified geometry. * @protected */ -ol.geom.SimpleGeometry.prototype.getSimplifiedGeometryInternal = - function(squaredTolerance) { +ol.geom.SimpleGeometry.prototype.getSimplifiedGeometryInternal = function(squaredTolerance) { return this; }; @@ -20107,8 +13401,7 @@ ol.geom.SimpleGeometry.prototype.getStride = function() { * @param {Array.<number>} flatCoordinates Flat coordinates. * @protected */ -ol.geom.SimpleGeometry.prototype.setFlatCoordinatesInternal = - function(layout, flatCoordinates) { +ol.geom.SimpleGeometry.prototype.setFlatCoordinatesInternal = function(layout, flatCoordinates) { this.stride = ol.geom.SimpleGeometry.getStrideForLayout(layout); this.layout = layout; this.flatCoordinates = flatCoordinates; @@ -20128,8 +13421,7 @@ ol.geom.SimpleGeometry.prototype.setCoordinates = goog.abstractMethod; * @param {number} nesting Nesting. * @protected */ -ol.geom.SimpleGeometry.prototype.setLayout = - function(layout, coordinates, nesting) { +ol.geom.SimpleGeometry.prototype.setLayout = function(layout, coordinates, nesting) { /** @type {number} */ var stride; if (layout) { @@ -20145,7 +13437,7 @@ ol.geom.SimpleGeometry.prototype.setLayout = coordinates = /** @type {Array} */ (coordinates[0]); } } - stride = (/** @type {Array} */ (coordinates)).length; + stride = coordinates.length; layout = ol.geom.SimpleGeometry.getLayoutForStride_(stride); } this.layout = layout; @@ -20167,6 +13459,22 @@ ol.geom.SimpleGeometry.prototype.applyTransform = function(transformFn) { /** * @inheritDoc + * @api + */ +ol.geom.SimpleGeometry.prototype.rotate = function(angle, anchor) { + var flatCoordinates = this.getFlatCoordinates(); + if (flatCoordinates) { + var stride = this.getStride(); + ol.geom.flat.transform.rotate( + flatCoordinates, 0, flatCoordinates.length, + stride, angle, anchor, flatCoordinates); + this.changed(); + } +}; + + +/** + * @inheritDoc * @api stable */ ol.geom.SimpleGeometry.prototype.translate = function(deltaX, deltaY) { @@ -20187,8 +13495,7 @@ ol.geom.SimpleGeometry.prototype.translate = function(deltaX, deltaY) { * @param {Array.<number>=} opt_dest Destination. * @return {Array.<number>} Transformed flat coordinates. */ -ol.geom.transformSimpleGeometry2D = - function(simpleGeometry, transform, opt_dest) { +ol.geom.transformSimpleGeometry2D = function(simpleGeometry, transform, opt_dest) { var flatCoordinates = simpleGeometry.getFlatCoordinates(); if (!flatCoordinates) { return null; @@ -20232,8 +13539,7 @@ ol.geom.flat.area.linearRing = function(flatCoordinates, offset, end, stride) { * @param {number} stride Stride. * @return {number} Area. */ -ol.geom.flat.area.linearRings = - function(flatCoordinates, offset, ends, stride) { +ol.geom.flat.area.linearRings = function(flatCoordinates, offset, ends, stride) { var area = 0; var i, ii; for (i = 0, ii = ends.length; i < ii; ++i) { @@ -20252,8 +13558,7 @@ ol.geom.flat.area.linearRings = * @param {number} stride Stride. * @return {number} Area. */ -ol.geom.flat.area.linearRingss = - function(flatCoordinates, offset, endss, stride) { +ol.geom.flat.area.linearRingss = function(flatCoordinates, offset, endss, stride) { var area = 0; var i, ii; for (i = 0, ii = endss.length; i < ii; ++i) { @@ -20268,7 +13573,6 @@ ol.geom.flat.area.linearRingss = goog.provide('ol.geom.flat.closest'); goog.require('goog.asserts'); -goog.require('goog.math'); goog.require('ol.math'); @@ -20284,8 +13588,7 @@ goog.require('ol.math'); * @param {number} y Y. * @param {Array.<number>} closestPoint Closest point. */ -ol.geom.flat.closest.point = - function(flatCoordinates, offset1, offset2, stride, x, y, closestPoint) { +ol.geom.flat.closest.point = function(flatCoordinates, offset1, offset2, stride, x, y, closestPoint) { var x1 = flatCoordinates[offset1]; var y1 = flatCoordinates[offset1 + 1]; var dx = flatCoordinates[offset2] - x1; @@ -20299,7 +13602,7 @@ ol.geom.flat.closest.point = offset = offset2; } else if (t > 0) { for (i = 0; i < stride; ++i) { - closestPoint[i] = goog.math.lerp(flatCoordinates[offset1 + i], + closestPoint[i] = ol.math.lerp(flatCoordinates[offset1 + i], flatCoordinates[offset2 + i], t); } closestPoint.length = stride; @@ -20325,8 +13628,7 @@ ol.geom.flat.closest.point = * @param {number} maxSquaredDelta Max squared delta. * @return {number} Max squared delta. */ -ol.geom.flat.closest.getMaxSquaredDelta = - function(flatCoordinates, offset, end, stride, maxSquaredDelta) { +ol.geom.flat.closest.getMaxSquaredDelta = function(flatCoordinates, offset, end, stride, maxSquaredDelta) { var x1 = flatCoordinates[offset]; var y1 = flatCoordinates[offset + 1]; for (offset += stride; offset < end; offset += stride) { @@ -20351,8 +13653,7 @@ ol.geom.flat.closest.getMaxSquaredDelta = * @param {number} maxSquaredDelta Max squared delta. * @return {number} Max squared delta. */ -ol.geom.flat.closest.getsMaxSquaredDelta = - function(flatCoordinates, offset, ends, stride, maxSquaredDelta) { +ol.geom.flat.closest.getsMaxSquaredDelta = function(flatCoordinates, offset, ends, stride, maxSquaredDelta) { var i, ii; for (i = 0, ii = ends.length; i < ii; ++i) { var end = ends[i]; @@ -20372,8 +13673,7 @@ ol.geom.flat.closest.getsMaxSquaredDelta = * @param {number} maxSquaredDelta Max squared delta. * @return {number} Max squared delta. */ -ol.geom.flat.closest.getssMaxSquaredDelta = - function(flatCoordinates, offset, endss, stride, maxSquaredDelta) { +ol.geom.flat.closest.getssMaxSquaredDelta = function(flatCoordinates, offset, endss, stride, maxSquaredDelta) { var i, ii; for (i = 0, ii = endss.length; i < ii; ++i) { var ends = endss[i]; @@ -20538,8 +13838,7 @@ goog.require('goog.asserts'); * @param {number} stride Stride. * @return {number} offset Offset. */ -ol.geom.flat.deflate.coordinate = - function(flatCoordinates, offset, coordinate, stride) { +ol.geom.flat.deflate.coordinate = function(flatCoordinates, offset, coordinate, stride) { goog.asserts.assert(coordinate.length == stride, 'length of the coordinate array should match stride'); var i, ii; @@ -20557,8 +13856,7 @@ ol.geom.flat.deflate.coordinate = * @param {number} stride Stride. * @return {number} offset Offset. */ -ol.geom.flat.deflate.coordinates = - function(flatCoordinates, offset, coordinates, stride) { +ol.geom.flat.deflate.coordinates = function(flatCoordinates, offset, coordinates, stride) { var i, ii; for (i = 0, ii = coordinates.length; i < ii; ++i) { var coordinate = coordinates[i]; @@ -20581,8 +13879,7 @@ ol.geom.flat.deflate.coordinates = * @param {Array.<number>=} opt_ends Ends. * @return {Array.<number>} Ends. */ -ol.geom.flat.deflate.coordinatess = - function(flatCoordinates, offset, coordinatess, stride, opt_ends) { +ol.geom.flat.deflate.coordinatess = function(flatCoordinates, offset, coordinatess, stride, opt_ends) { var ends = opt_ends ? opt_ends : []; var i = 0; var j, jj; @@ -20605,8 +13902,7 @@ ol.geom.flat.deflate.coordinatess = * @param {Array.<Array.<number>>=} opt_endss Endss. * @return {Array.<Array.<number>>} Endss. */ -ol.geom.flat.deflate.coordinatesss = - function(flatCoordinates, offset, coordinatesss, stride, opt_endss) { +ol.geom.flat.deflate.coordinatesss = function(flatCoordinates, offset, coordinatesss, stride, opt_endss) { var endss = opt_endss ? opt_endss : []; var i = 0; var j, jj; @@ -20631,8 +13927,7 @@ goog.provide('ol.geom.flat.inflate'); * @param {Array.<ol.Coordinate>=} opt_coordinates Coordinates. * @return {Array.<ol.Coordinate>} Coordinates. */ -ol.geom.flat.inflate.coordinates = - function(flatCoordinates, offset, end, stride, opt_coordinates) { +ol.geom.flat.inflate.coordinates = function(flatCoordinates, offset, end, stride, opt_coordinates) { var coordinates = opt_coordinates !== undefined ? opt_coordinates : []; var i = 0; var j; @@ -20652,8 +13947,7 @@ ol.geom.flat.inflate.coordinates = * @param {Array.<Array.<ol.Coordinate>>=} opt_coordinatess Coordinatess. * @return {Array.<Array.<ol.Coordinate>>} Coordinatess. */ -ol.geom.flat.inflate.coordinatess = - function(flatCoordinates, offset, ends, stride, opt_coordinatess) { +ol.geom.flat.inflate.coordinatess = function(flatCoordinates, offset, ends, stride, opt_coordinatess) { var coordinatess = opt_coordinatess !== undefined ? opt_coordinatess : []; var i = 0; var j, jj; @@ -20677,8 +13971,7 @@ ol.geom.flat.inflate.coordinatess = * Coordinatesss. * @return {Array.<Array.<Array.<ol.Coordinate>>>} Coordinatesss. */ -ol.geom.flat.inflate.coordinatesss = - function(flatCoordinates, offset, endss, stride, opt_coordinatesss) { +ol.geom.flat.inflate.coordinatesss = function(flatCoordinates, offset, endss, stride, opt_coordinatesss) { var coordinatesss = opt_coordinatesss !== undefined ? opt_coordinatesss : []; var i = 0; var j, jj; @@ -21106,7 +14399,6 @@ goog.require('ol.geom.flat.inflate'); goog.require('ol.geom.flat.simplify'); - /** * @classdesc * Linear ring geometry. Only used as part of polygon; cannot be rendered @@ -21155,8 +14447,7 @@ ol.geom.LinearRing.prototype.clone = function() { /** * @inheritDoc */ -ol.geom.LinearRing.prototype.closestPointXY = - function(x, y, closestPoint, minSquaredDistance) { +ol.geom.LinearRing.prototype.closestPointXY = function(x, y, closestPoint, minSquaredDistance) { if (minSquaredDistance < ol.extent.closestSquaredDistanceXY(this.getExtent(), x, y)) { return minSquaredDistance; @@ -21197,8 +14488,7 @@ ol.geom.LinearRing.prototype.getCoordinates = function() { /** * @inheritDoc */ -ol.geom.LinearRing.prototype.getSimplifiedGeometryInternal = - function(squaredTolerance) { +ol.geom.LinearRing.prototype.getSimplifiedGeometryInternal = function(squaredTolerance) { var simplifiedFlatCoordinates = []; simplifiedFlatCoordinates.length = ol.geom.flat.simplify.douglasPeucker( this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, @@ -21225,8 +14515,7 @@ ol.geom.LinearRing.prototype.getType = function() { * @param {ol.geom.GeometryLayout=} opt_layout Layout. * @api stable */ -ol.geom.LinearRing.prototype.setCoordinates = - function(coordinates, opt_layout) { +ol.geom.LinearRing.prototype.setCoordinates = function(coordinates, opt_layout) { if (!coordinates) { this.setFlatCoordinates(ol.geom.GeometryLayout.XY, null); } else { @@ -21245,8 +14534,7 @@ ol.geom.LinearRing.prototype.setCoordinates = * @param {ol.geom.GeometryLayout} layout Layout. * @param {Array.<number>} flatCoordinates Flat coordinates. */ -ol.geom.LinearRing.prototype.setFlatCoordinates = - function(layout, flatCoordinates) { +ol.geom.LinearRing.prototype.setFlatCoordinates = function(layout, flatCoordinates) { this.setFlatCoordinatesInternal(layout, flatCoordinates); this.changed(); }; @@ -21261,7 +14549,6 @@ goog.require('ol.geom.flat.deflate'); goog.require('ol.math'); - /** * @classdesc * Point geometry. @@ -21294,8 +14581,7 @@ ol.geom.Point.prototype.clone = function() { /** * @inheritDoc */ -ol.geom.Point.prototype.closestPointXY = - function(x, y, closestPoint, minSquaredDistance) { +ol.geom.Point.prototype.closestPointXY = function(x, y, closestPoint, minSquaredDistance) { var flatCoordinates = this.flatCoordinates; var squaredDistance = ol.math.squaredDistance( x, y, flatCoordinates[0], flatCoordinates[1]); @@ -21394,11 +14680,11 @@ goog.require('ol.extent'); * @param {ol.Extent} extent Extent. * @return {boolean} Contains extent. */ -ol.geom.flat.contains.linearRingContainsExtent = - function(flatCoordinates, offset, end, stride, extent) { +ol.geom.flat.contains.linearRingContainsExtent = function(flatCoordinates, offset, end, stride, extent) { var outside = ol.extent.forEachCorner(extent, /** * @param {ol.Coordinate} coordinate Coordinate. + * @return {boolean} Contains (x, y). */ function(coordinate) { return !ol.geom.flat.contains.linearRingContainsXY(flatCoordinates, @@ -21417,8 +14703,7 @@ ol.geom.flat.contains.linearRingContainsExtent = * @param {number} y Y. * @return {boolean} Contains (x, y). */ -ol.geom.flat.contains.linearRingContainsXY = - function(flatCoordinates, offset, end, stride, x, y) { +ol.geom.flat.contains.linearRingContainsXY = function(flatCoordinates, offset, end, stride, x, y) { // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html var contains = false; var x1 = flatCoordinates[end - stride]; @@ -21447,8 +14732,7 @@ ol.geom.flat.contains.linearRingContainsXY = * @param {number} y Y. * @return {boolean} Contains (x, y). */ -ol.geom.flat.contains.linearRingsContainsXY = - function(flatCoordinates, offset, ends, stride, x, y) { +ol.geom.flat.contains.linearRingsContainsXY = function(flatCoordinates, offset, ends, stride, x, y) { goog.asserts.assert(ends.length > 0, 'ends should not be an empty array'); if (ends.length === 0) { return false; @@ -21477,8 +14761,7 @@ ol.geom.flat.contains.linearRingsContainsXY = * @param {number} y Y. * @return {boolean} Contains (x, y). */ -ol.geom.flat.contains.linearRingssContainsXY = - function(flatCoordinates, offset, endss, stride, x, y) { +ol.geom.flat.contains.linearRingssContainsXY = function(flatCoordinates, offset, endss, stride, x, y) { goog.asserts.assert(endss.length > 0, 'endss should not be an empty array'); if (endss.length === 0) { return false; @@ -21575,8 +14858,7 @@ ol.geom.flat.interiorpoint.linearRings = function(flatCoordinates, offset, * @param {Array.<number>} flatCenters Flat centers. * @return {Array.<number>} Interior points. */ -ol.geom.flat.interiorpoint.linearRingss = - function(flatCoordinates, offset, endss, stride, flatCenters) { +ol.geom.flat.interiorpoint.linearRingss = function(flatCoordinates, offset, endss, stride, flatCenters) { goog.asserts.assert(2 * endss.length == flatCenters.length, 'endss.length times 2 should be flatCenters.length'); var interiorPoints = []; @@ -21608,8 +14890,7 @@ goog.provide('ol.geom.flat.segments'); * @return {T|boolean} Value. * @template T,S */ -ol.geom.flat.segments.forEach = - function(flatCoordinates, offset, end, stride, callback, opt_this) { +ol.geom.flat.segments.forEach = function(flatCoordinates, offset, end, stride, callback, opt_this) { var point1 = [flatCoordinates[offset], flatCoordinates[offset + 1]]; var point2 = []; var ret; @@ -21642,8 +14923,7 @@ goog.require('ol.geom.flat.segments'); * @param {ol.Extent} extent Extent. * @return {boolean} True if the geometry and the extent intersect. */ -ol.geom.flat.intersectsextent.lineString = - function(flatCoordinates, offset, end, stride, extent) { +ol.geom.flat.intersectsextent.lineString = function(flatCoordinates, offset, end, stride, extent) { var coordinatesExtent = ol.extent.extendFlatCoordinates( ol.extent.createEmpty(), flatCoordinates, offset, end, stride); if (!ol.extent.intersects(extent, coordinatesExtent)) { @@ -21681,8 +14961,7 @@ ol.geom.flat.intersectsextent.lineString = * @param {ol.Extent} extent Extent. * @return {boolean} True if the geometry and the extent intersect. */ -ol.geom.flat.intersectsextent.lineStrings = - function(flatCoordinates, offset, ends, stride, extent) { +ol.geom.flat.intersectsextent.lineStrings = function(flatCoordinates, offset, ends, stride, extent) { var i, ii; for (i = 0, ii = ends.length; i < ii; ++i) { if (ol.geom.flat.intersectsextent.lineString( @@ -21703,8 +14982,7 @@ ol.geom.flat.intersectsextent.lineStrings = * @param {ol.Extent} extent Extent. * @return {boolean} True if the geometry and the extent intersect. */ -ol.geom.flat.intersectsextent.linearRing = - function(flatCoordinates, offset, end, stride, extent) { +ol.geom.flat.intersectsextent.linearRing = function(flatCoordinates, offset, end, stride, extent) { if (ol.geom.flat.intersectsextent.lineString( flatCoordinates, offset, end, stride, extent)) { return true; @@ -21737,8 +15015,7 @@ ol.geom.flat.intersectsextent.linearRing = * @param {ol.Extent} extent Extent. * @return {boolean} True if the geometry and the extent intersect. */ -ol.geom.flat.intersectsextent.linearRings = - function(flatCoordinates, offset, ends, stride, extent) { +ol.geom.flat.intersectsextent.linearRings = function(flatCoordinates, offset, ends, stride, extent) { goog.asserts.assert(ends.length > 0, 'ends should not be an empty array'); if (!ol.geom.flat.intersectsextent.linearRing( flatCoordinates, offset, ends[0], stride, extent)) { @@ -21766,8 +15043,7 @@ ol.geom.flat.intersectsextent.linearRings = * @param {ol.Extent} extent Extent. * @return {boolean} True if the geometry and the extent intersect. */ -ol.geom.flat.intersectsextent.linearRingss = - function(flatCoordinates, offset, endss, stride, extent) { +ol.geom.flat.intersectsextent.linearRingss = function(flatCoordinates, offset, endss, stride, extent) { goog.asserts.assert(endss.length > 0, 'endss should not be an empty array'); var i, ii; for (i = 0, ii = endss.length; i < ii; ++i) { @@ -21790,8 +15066,7 @@ goog.provide('ol.geom.flat.reverse'); * @param {number} end End. * @param {number} stride Stride. */ -ol.geom.flat.reverse.coordinates = - function(flatCoordinates, offset, end, stride) { +ol.geom.flat.reverse.coordinates = function(flatCoordinates, offset, end, stride) { while (offset < end - stride) { var i; for (i = 0; i < stride; ++i) { @@ -21817,8 +15092,7 @@ goog.require('ol.geom.flat.reverse'); * @param {number} stride Stride. * @return {boolean} Is clockwise. */ -ol.geom.flat.orient.linearRingIsClockwise = - function(flatCoordinates, offset, end, stride) { +ol.geom.flat.orient.linearRingIsClockwise = function(flatCoordinates, offset, end, stride) { // http://tinyurl.com/clockwise-method // https://github.com/OSGeo/gdal/blob/trunk/gdal/ogr/ogrlinearring.cpp var edge = 0; @@ -21848,8 +15122,7 @@ ol.geom.flat.orient.linearRingIsClockwise = * (counter-clockwise exterior ring and clockwise interior rings). * @return {boolean} Rings are correctly oriented. */ -ol.geom.flat.orient.linearRingsAreOriented = - function(flatCoordinates, offset, ends, stride, opt_right) { +ol.geom.flat.orient.linearRingsAreOriented = function(flatCoordinates, offset, ends, stride, opt_right) { var right = opt_right !== undefined ? opt_right : false; var i, ii; for (i = 0, ii = ends.length; i < ii; ++i) { @@ -21884,8 +15157,7 @@ ol.geom.flat.orient.linearRingsAreOriented = * (counter-clockwise exterior ring and clockwise interior rings). * @return {boolean} Rings are correctly oriented. */ -ol.geom.flat.orient.linearRingssAreOriented = - function(flatCoordinates, offset, endss, stride, opt_right) { +ol.geom.flat.orient.linearRingssAreOriented = function(flatCoordinates, offset, endss, stride, opt_right) { var i, ii; for (i = 0, ii = endss.length; i < ii; ++i) { if (!ol.geom.flat.orient.linearRingsAreOriented( @@ -21910,8 +15182,7 @@ ol.geom.flat.orient.linearRingssAreOriented = * @param {boolean=} opt_right Follow the right-hand rule for orientation. * @return {number} End. */ -ol.geom.flat.orient.orientLinearRings = - function(flatCoordinates, offset, ends, stride, opt_right) { +ol.geom.flat.orient.orientLinearRings = function(flatCoordinates, offset, ends, stride, opt_right) { var right = opt_right !== undefined ? opt_right : false; var i, ii; for (i = 0, ii = ends.length; i < ii; ++i) { @@ -21943,8 +15214,7 @@ ol.geom.flat.orient.orientLinearRings = * @param {boolean=} opt_right Follow the right-hand rule for orientation. * @return {number} End. */ -ol.geom.flat.orient.orientLinearRingss = - function(flatCoordinates, offset, endss, stride, opt_right) { +ol.geom.flat.orient.orientLinearRingss = function(flatCoordinates, offset, endss, stride, opt_right) { var i, ii; for (i = 0, ii = endss.length; i < ii; ++i) { offset = ol.geom.flat.orient.orientLinearRings( @@ -21955,10 +15225,9 @@ ol.geom.flat.orient.orientLinearRingss = goog.provide('ol.geom.Polygon'); -goog.require('goog.array'); goog.require('goog.asserts'); -goog.require('goog.math'); goog.require('ol'); +goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.geom.GeometryLayout'); goog.require('ol.geom.GeometryType'); @@ -21974,7 +15243,7 @@ goog.require('ol.geom.flat.interiorpoint'); goog.require('ol.geom.flat.intersectsextent'); goog.require('ol.geom.flat.orient'); goog.require('ol.geom.flat.simplify'); - +goog.require('ol.math'); /** @@ -22050,7 +15319,7 @@ ol.geom.Polygon.prototype.appendLinearRing = function(linearRing) { if (!this.flatCoordinates) { this.flatCoordinates = linearRing.getFlatCoordinates().slice(); } else { - goog.array.extend(this.flatCoordinates, linearRing.getFlatCoordinates()); + ol.array.extend(this.flatCoordinates, linearRing.getFlatCoordinates()); } this.ends_.push(this.flatCoordinates.length); this.changed(); @@ -22073,8 +15342,7 @@ ol.geom.Polygon.prototype.clone = function() { /** * @inheritDoc */ -ol.geom.Polygon.prototype.closestPointXY = - function(x, y, closestPoint, minSquaredDistance) { +ol.geom.Polygon.prototype.closestPointXY = function(x, y, closestPoint, minSquaredDistance) { if (minSquaredDistance < ol.extent.closestSquaredDistanceXY(this.getExtent(), x, y)) { return minSquaredDistance; @@ -22253,8 +15521,7 @@ ol.geom.Polygon.prototype.getOrientedFlatCoordinates = function() { /** * @inheritDoc */ -ol.geom.Polygon.prototype.getSimplifiedGeometryInternal = - function(squaredTolerance) { +ol.geom.Polygon.prototype.getSimplifiedGeometryInternal = function(squaredTolerance) { var simplifiedFlatCoordinates = []; var simplifiedEnds = []; simplifiedFlatCoordinates.length = ol.geom.flat.simplify.quantizes( @@ -22314,8 +15581,7 @@ ol.geom.Polygon.prototype.setCoordinates = function(coordinates, opt_layout) { * @param {Array.<number>} flatCoordinates Flat coordinates. * @param {Array.<number>} ends Ends. */ -ol.geom.Polygon.prototype.setFlatCoordinates = - function(layout, flatCoordinates, ends) { +ol.geom.Polygon.prototype.setFlatCoordinates = function(layout, flatCoordinates, ends) { if (!flatCoordinates) { goog.asserts.assert(ends && ends.length === 0, 'ends must be an empty array'); @@ -22349,7 +15615,7 @@ ol.geom.Polygon.circular = function(sphere, center, radius, opt_n) { var flatCoordinates = []; var i; for (i = 0; i < n; ++i) { - goog.array.extend( + ol.array.extend( flatCoordinates, sphere.offset(center, radius, 2 * Math.PI * i / n)); } flatCoordinates.push(flatCoordinates[0], flatCoordinates[1]); @@ -22394,7 +15660,11 @@ ol.geom.Polygon.fromCircle = function(circle, opt_sides, opt_angle) { var stride = circle.getStride(); var layout = circle.getLayout(); var polygon = new ol.geom.Polygon(null, layout); - var flatCoordinates = goog.array.repeat(0, stride * (sides + 1)); + var arrayLength = stride * (sides + 1); + var flatCoordinates = new Array(arrayLength); + for (var i = 0; i < arrayLength; i++) { + flatCoordinates[i] = 0; + } var ends = [flatCoordinates.length]; polygon.setFlatCoordinates(layout, flatCoordinates, ends); ol.geom.Polygon.makeRegular( @@ -22422,7 +15692,7 @@ ol.geom.Polygon.makeRegular = function(polygon, center, radius, opt_angle) { var angle, offset; for (var i = 0; i <= sides; ++i) { offset = i * stride; - angle = startAngle + (goog.math.modulo(i, sides) * 2 * Math.PI / sides); + angle = startAngle + (ol.math.modulo(i, sides) * 2 * Math.PI / sides); flatCoordinates[offset] = center[0] + (radius * Math.cos(angle)); flatCoordinates[offset + 1] = center[1] + (radius * Math.sin(angle)); } @@ -22440,8 +15710,6 @@ goog.require('ol.Constraints'); goog.require('ol.Object'); goog.require('ol.ResolutionConstraint'); goog.require('ol.RotationConstraint'); -goog.require('ol.RotationConstraintType'); -goog.require('ol.Size'); goog.require('ol.coordinate'); goog.require('ol.extent'); goog.require('ol.geom.Polygon'); @@ -22471,7 +15739,6 @@ ol.ViewHint = { }; - /** * @classdesc * An ol.View object represents a simple 2D view of the map. @@ -22570,6 +15837,12 @@ ol.View = function(opt_options) { /** * @private + * @type {Array.<number>|undefined} + */ + this.resolutions_ = options.resolutions; + + /** + * @private * @type {number} */ this.minZoom_ = resolutionConstraintInfo.minZoom; @@ -22688,10 +15961,17 @@ ol.View.prototype.getCenter = function() { /** + * @param {Array.<number>=} opt_hints Destination array. * @return {Array.<number>} Hint. */ -ol.View.prototype.getHints = function() { - return this.hints_.slice(); +ol.View.prototype.getHints = function(opt_hints) { + if (opt_hints !== undefined) { + opt_hints[0] = this.hints_[0]; + opt_hints[1] = this.hints_[1]; + return opt_hints; + } else { + return this.hints_.slice(); + } }; @@ -22741,6 +16021,17 @@ ol.View.prototype.getResolution = function() { /** + * Get the resolutions for the view. This returns the array of resolutions + * passed to the constructor of the {ol.View}, or undefined if none were given. + * @return {Array.<number>|undefined} The resolutions of the view. + * @api stable + */ +ol.View.prototype.getResolutions = function() { + return this.resolutions_; +}; + + +/** * Get the resolution for a provided extent (in map units) and size (in pixels). * @param {ol.Extent} extent Extent. * @param {ol.Size} size Box pixel size. @@ -22879,7 +16170,7 @@ ol.View.prototype.getZoom = function() { */ ol.View.prototype.fit = function(geometry, size, opt_options) { if (!(geometry instanceof ol.geom.SimpleGeometry)) { - goog.asserts.assert(goog.isArray(geometry), + goog.asserts.assert(Array.isArray(geometry), 'invalid extent or geometry'); goog.asserts.assert(!ol.extent.isEmpty(geometry), 'cannot fit empty extent'); @@ -23064,7 +16355,7 @@ ol.View.prototype.setZoom = function(zoom) { /** * @param {olx.ViewOptions} options View options. * @private - * @return {ol.CenterConstraintType} + * @return {ol.CenterConstraintType} The constraint. */ ol.View.createCenterConstraint_ = function(options) { if (options.extent !== undefined) { @@ -23079,7 +16370,7 @@ ol.View.createCenterConstraint_ = function(options) { * @private * @param {olx.ViewOptions} options View options. * @return {{constraint: ol.ResolutionConstraintType, maxResolution: number, - * minResolution: number}} + * minResolution: number}} The constraint. */ ol.View.createResolutionConstraint_ = function(options) { var resolutionConstraint; @@ -23113,7 +16404,7 @@ ol.View.createResolutionConstraint_ = function(options) { var size = !extent ? // use an extent that can fit the whole world if need be 360 * ol.proj.METERS_PER_UNIT[ol.proj.Units.DEGREES] / - ol.proj.METERS_PER_UNIT[projection.getUnits()] : + projection.getMetersPerUnit() : Math.max(ol.extent.getWidth(extent), ol.extent.getHeight(extent)); var defaultMaxResolution = size / ol.DEFAULT_TILE_SIZE / Math.pow( @@ -23249,7 +16540,6 @@ ol.easing.upAndDown = function(t) { goog.provide('ol.animation'); goog.require('ol'); -goog.require('ol.PreRenderFunction'); goog.require('ol.ViewHint'); goog.require('ol.coordinate'); goog.require('ol.easing'); @@ -23272,6 +16562,7 @@ ol.animation.bounce = function(options) { /** * @param {ol.Map} map Map. * @param {?olx.FrameState} frameState Frame state. + * @return {boolean} Run this function in the next frame. */ function(map, frameState) { if (frameState.time < start) { @@ -23310,6 +16601,7 @@ ol.animation.pan = function(options) { /** * @param {ol.Map} map Map. * @param {?olx.FrameState} frameState Frame state. + * @return {boolean} Run this function in the next frame. */ function(map, frameState) { if (frameState.time < start) { @@ -23351,6 +16643,7 @@ ol.animation.rotate = function(options) { /** * @param {ol.Map} map Map. * @param {?olx.FrameState} frameState Frame state. + * @return {boolean} Run this function in the next frame. */ function(map, frameState) { if (frameState.time < start) { @@ -23394,6 +16687,7 @@ ol.animation.zoom = function(options) { /** * @param {ol.Map} map Map. * @param {?olx.FrameState} frameState Frame state. + * @return {boolean} Run this function in the next frame. */ function(map, frameState) { if (frameState.time < start) { @@ -23414,174 +16708,9 @@ ol.animation.zoom = function(options) { }); }; -goog.provide('ol.TileCoord'); -goog.provide('ol.tilecoord'); - -goog.require('goog.asserts'); -goog.require('ol.extent'); - - -/** - * An array of three numbers representing the location of a tile in a tile - * grid. The order is `z`, `x`, and `y`. `z` is the zoom level. - * @typedef {Array.<number>} ol.TileCoord - * @api - */ -ol.TileCoord; - - -/** - * @enum {number} - */ -ol.QuadKeyCharCode = { - ZERO: '0'.charCodeAt(0), - ONE: '1'.charCodeAt(0), - TWO: '2'.charCodeAt(0), - THREE: '3'.charCodeAt(0) -}; - - -/** - * @param {string} str String that follows pattern “z/x/y” where x, y and z are - * numbers. - * @return {ol.TileCoord} Tile coord. - */ -ol.tilecoord.createFromString = function(str) { - var v = str.split('/'); - goog.asserts.assert(v.length === 3, - 'must provide a string in "z/x/y" format, got "%s"', str); - return v.map(function(e) { - return parseInt(e, 10); - }); -}; - - -/** - * @param {number} z Z. - * @param {number} x X. - * @param {number} y Y. - * @param {ol.TileCoord=} opt_tileCoord Tile coordinate. - * @return {ol.TileCoord} Tile coordinate. - */ -ol.tilecoord.createOrUpdate = function(z, x, y, opt_tileCoord) { - if (opt_tileCoord !== undefined) { - opt_tileCoord[0] = z; - opt_tileCoord[1] = x; - opt_tileCoord[2] = y; - return opt_tileCoord; - } else { - return [z, x, y]; - } -}; - - -/** - * @param {number} z Z. - * @param {number} x X. - * @param {number} y Y. - * @return {string} Key. - */ -ol.tilecoord.getKeyZXY = function(z, x, y) { - return z + '/' + x + '/' + y; -}; - - -/** - * @param {ol.TileCoord} tileCoord Tile coord. - * @return {number} Hash. - */ -ol.tilecoord.hash = function(tileCoord) { - return (tileCoord[1] << tileCoord[0]) + tileCoord[2]; -}; - - -/** - * @param {ol.TileCoord} tileCoord Tile coord. - * @return {string} Quad key. - */ -ol.tilecoord.quadKey = function(tileCoord) { - var z = tileCoord[0]; - var digits = new Array(z); - var mask = 1 << (z - 1); - var i, charCode; - for (i = 0; i < z; ++i) { - charCode = ol.QuadKeyCharCode.ZERO; - if (tileCoord[1] & mask) { - charCode += 1; - } - if (tileCoord[2] & mask) { - charCode += 2; - } - digits[i] = String.fromCharCode(charCode); - mask >>= 1; - } - return digits.join(''); -}; - - -/** - * @param {ol.TileCoord} tileCoord Tile coord. - * @return {string} String. - */ -ol.tilecoord.toString = function(tileCoord) { - return ol.tilecoord.getKeyZXY(tileCoord[0], tileCoord[1], tileCoord[2]); -}; - - -/** - * @param {ol.TileCoord} tileCoord Tile coordinate. - * @param {ol.tilegrid.TileGrid} tileGrid Tile grid. - * @param {ol.proj.Projection} projection Projection. - * @return {ol.TileCoord} Tile coordinate. - */ -ol.tilecoord.wrapX = function(tileCoord, tileGrid, projection) { - var z = tileCoord[0]; - var center = tileGrid.getTileCoordCenter(tileCoord); - var projectionExtent = ol.tilegrid.extentFromProjection(projection); - if (!ol.extent.containsCoordinate(projectionExtent, center)) { - var worldWidth = ol.extent.getWidth(projectionExtent); - var worldsAway = Math.ceil((projectionExtent[0] - center[0]) / worldWidth); - center[0] += worldWidth * worldsAway; - return tileGrid.getTileCoordForCoordAndZ(center, z); - } else { - return tileCoord; - } -}; - - -/** - * @param {ol.TileCoord} tileCoord Tile coordinate. - * @param {!ol.tilegrid.TileGrid} tileGrid Tile grid. - * @return {boolean} Tile coordinate is within extent and zoom level range. - */ -ol.tilecoord.withinExtentAndZ = function(tileCoord, tileGrid) { - var z = tileCoord[0]; - var x = tileCoord[1]; - var y = tileCoord[2]; - - if (tileGrid.getMinZoom() > z || z > tileGrid.getMaxZoom()) { - return false; - } - var extent = tileGrid.getExtent(); - var tileRange; - if (!extent) { - tileRange = tileGrid.getFullTileRange(z); - } else { - tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z); - } - if (!tileRange) { - return true; - } else { - return tileRange.containsXY(x, y); - } -}; - goog.provide('ol.TileRange'); goog.require('goog.asserts'); -goog.require('ol.Size'); -goog.require('ol.TileCoord'); - /** @@ -23764,9 +16893,8 @@ ol.TileRange.prototype.intersects = function(tileRange) { goog.provide('ol.Attribution'); -goog.require('goog.math'); goog.require('ol.TileRange'); - +goog.require('ol.math'); /** @@ -23823,8 +16951,7 @@ ol.Attribution.prototype.getHTML = function() { * @param {!ol.proj.Projection} projection Projection. * @return {boolean} Intersects any tile range. */ -ol.Attribution.prototype.intersectsAnyTileRange = - function(tileRanges, tileGrid, projection) { +ol.Attribution.prototype.intersectsAnyTileRange = function(tileRanges, tileGrid, projection) { if (!this.tileRanges_) { return true; } @@ -23841,13 +16968,13 @@ ol.Attribution.prototype.intersectsAnyTileRange = return true; } var extentTileRange = tileGrid.getTileRangeForExtentAndZ( - projection.getExtent(), parseInt(zKey, 10)); + ol.tilegrid.extentFromProjection(projection), parseInt(zKey, 10)); var width = extentTileRange.getWidth(); if (tileRange.minX < extentTileRange.minX || tileRange.maxX > extentTileRange.maxX) { if (testTileRange.intersects(new ol.TileRange( - goog.math.modulo(tileRange.minX, width), - goog.math.modulo(tileRange.maxX, width), + ol.math.modulo(tileRange.minX, width), + ol.math.modulo(tileRange.maxX, width), tileRange.minY, tileRange.maxY))) { return true; } @@ -23861,24 +16988,6 @@ ol.Attribution.prototype.intersectsAnyTileRange = return false; }; -goog.provide('ol.CanvasFunctionType'); - - -/** - * A function returning the canvas element (`{HTMLCanvasElement}`) - * used by the source as an image. The arguments passed to the function are: - * {@link ol.Extent} the image extent, `{number}` the image resolution, - * `{number}` the device pixel ratio, {@link ol.Size} the image size, and - * {@link ol.proj.Projection} the image projection. The canvas returned by - * this function is cached by the source. The this keyword inside the function - * references the {@link ol.source.ImageCanvas}. - * - * @typedef {function(this:ol.source.ImageCanvas, ol.Extent, number, - * number, ol.Size, ol.proj.Projection): HTMLCanvasElement} - * @api - */ -ol.CanvasFunctionType; - /** * An implementation of Google Maps' MVCArray. * @see https://developers.google.com/maps/documentation/javascript/reference @@ -23888,8 +16997,7 @@ goog.provide('ol.Collection'); goog.provide('ol.CollectionEvent'); goog.provide('ol.CollectionEventType'); -goog.require('goog.array'); -goog.require('goog.events.Event'); +goog.require('ol.events.Event'); goog.require('ol.Object'); @@ -23912,14 +17020,13 @@ ol.CollectionEventType = { }; - /** * @classdesc * Events emitted by {@link ol.Collection} instances are instances of this * type. * * @constructor - * @extends {goog.events.Event} + * @extends {ol.events.Event} * @implements {oli.CollectionEvent} * @param {ol.CollectionEventType} type Type. * @param {*=} opt_element Element. @@ -23937,7 +17044,7 @@ ol.CollectionEvent = function(type, opt_element, opt_target) { this.element = opt_element; }; -goog.inherits(ol.CollectionEvent, goog.events.Event); +goog.inherits(ol.CollectionEvent, ol.events.Event); /** @@ -23948,7 +17055,6 @@ ol.CollectionProperty = { }; - /** * @classdesc * An expanded version of standard JS Array, adding convenience methods for @@ -24063,7 +17169,7 @@ ol.Collection.prototype.getLength = function() { * @api stable */ ol.Collection.prototype.insertAt = function(index, elem) { - goog.array.insertAt(this.array_, elem, index); + this.array_.splice(index, 0, elem); this.updateLength_(); this.dispatchEvent( new ol.CollectionEvent(ol.CollectionEventType.ADD, elem, this)); @@ -24121,7 +17227,7 @@ ol.Collection.prototype.remove = function(elem) { */ ol.Collection.prototype.removeAt = function(index) { var prev = this.array_[index]; - goog.array.removeAt(this.array_, index); + this.array_.splice(index, 1); this.updateLength_(); this.dispatchEvent( new ol.CollectionEvent(ol.CollectionEventType.REMOVE, prev, this)); @@ -24355,6 +17461,2100 @@ goog.color.names = { // limitations under the License. /** + * @fileoverview Utilities for manipulating arrays. + * + * @author arv@google.com (Erik Arvidsson) + */ + + +goog.provide('goog.array'); + +goog.require('goog.asserts'); + + +/** + * @define {boolean} NATIVE_ARRAY_PROTOTYPES indicates whether the code should + * rely on Array.prototype functions, if available. + * + * The Array.prototype functions can be defined by external libraries like + * Prototype and setting this flag to false forces closure to use its own + * goog.array implementation. + * + * If your javascript can be loaded by a third party site and you are wary about + * relying on the prototype functions, specify + * "--define goog.NATIVE_ARRAY_PROTOTYPES=false" to the JSCompiler. + * + * Setting goog.TRUSTED_SITE to false will automatically set + * NATIVE_ARRAY_PROTOTYPES to false. + */ +goog.define('goog.NATIVE_ARRAY_PROTOTYPES', goog.TRUSTED_SITE); + + +/** + * @define {boolean} If true, JSCompiler will use the native implementation of + * array functions where appropriate (e.g., {@code Array#filter}) and remove the + * unused pure JS implementation. + */ +goog.define('goog.array.ASSUME_NATIVE_FUNCTIONS', false); + + +/** + * Returns the last element in an array without removing it. + * Same as goog.array.last. + * @param {IArrayLike<T>|string} array The array. + * @return {T} Last item in array. + * @template T + */ +goog.array.peek = function(array) { + return array[array.length - 1]; +}; + + +/** + * Returns the last element in an array without removing it. + * Same as goog.array.peek. + * @param {IArrayLike<T>|string} array The array. + * @return {T} Last item in array. + * @template T + */ +goog.array.last = goog.array.peek; + +// NOTE(arv): Since most of the array functions are generic it allows you to +// pass an array-like object. Strings have a length and are considered array- +// like. However, the 'in' operator does not work on strings so we cannot just +// use the array path even if the browser supports indexing into strings. We +// therefore end up splitting the string. + + +/** + * Returns the index of the first element of an array with a specified value, or + * -1 if the element is not present in the array. + * + * See {@link http://tinyurl.com/developer-mozilla-org-array-indexof} + * + * @param {IArrayLike<T>|string} arr The array to be searched. + * @param {T} obj The object for which we are searching. + * @param {number=} opt_fromIndex The index at which to start the search. If + * omitted the search starts at index 0. + * @return {number} The index of the first matching array element. + * @template T + */ +goog.array.indexOf = goog.NATIVE_ARRAY_PROTOTYPES && + (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.indexOf) ? + function(arr, obj, opt_fromIndex) { + goog.asserts.assert(arr.length != null); + + return Array.prototype.indexOf.call(arr, obj, opt_fromIndex); + } : + function(arr, obj, opt_fromIndex) { + var fromIndex = opt_fromIndex == null ? + 0 : + (opt_fromIndex < 0 ? Math.max(0, arr.length + opt_fromIndex) : + opt_fromIndex); + + if (goog.isString(arr)) { + // Array.prototype.indexOf uses === so only strings should be found. + if (!goog.isString(obj) || obj.length != 1) { + return -1; + } + return arr.indexOf(obj, fromIndex); + } + + for (var i = fromIndex; i < arr.length; i++) { + if (i in arr && arr[i] === obj) return i; + } + return -1; + }; + + +/** + * Returns the index of the last element of an array with a specified value, or + * -1 if the element is not present in the array. + * + * See {@link http://tinyurl.com/developer-mozilla-org-array-lastindexof} + * + * @param {!IArrayLike<T>|string} arr The array to be searched. + * @param {T} obj The object for which we are searching. + * @param {?number=} opt_fromIndex The index at which to start the search. If + * omitted the search starts at the end of the array. + * @return {number} The index of the last matching array element. + * @template T + */ +goog.array.lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES && + (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.lastIndexOf) ? + function(arr, obj, opt_fromIndex) { + goog.asserts.assert(arr.length != null); + + // Firefox treats undefined and null as 0 in the fromIndex argument which + // leads it to always return -1 + var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex; + return Array.prototype.lastIndexOf.call(arr, obj, fromIndex); + } : + function(arr, obj, opt_fromIndex) { + var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex; + + if (fromIndex < 0) { + fromIndex = Math.max(0, arr.length + fromIndex); + } + + if (goog.isString(arr)) { + // Array.prototype.lastIndexOf uses === so only strings should be found. + if (!goog.isString(obj) || obj.length != 1) { + return -1; + } + return arr.lastIndexOf(obj, fromIndex); + } + + for (var i = fromIndex; i >= 0; i--) { + if (i in arr && arr[i] === obj) return i; + } + return -1; + }; + + +/** + * Calls a function for each element in an array. Skips holes in the array. + * See {@link http://tinyurl.com/developer-mozilla-org-array-foreach} + * + * @param {IArrayLike<T>|string} arr Array or array like object over + * which to iterate. + * @param {?function(this: S, T, number, ?): ?} f The function to call for every + * element. This function takes 3 arguments (the element, the index and the + * array). The return value is ignored. + * @param {S=} opt_obj The object to be used as the value of 'this' within f. + * @template T,S + */ +goog.array.forEach = goog.NATIVE_ARRAY_PROTOTYPES && + (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.forEach) ? + function(arr, f, opt_obj) { + goog.asserts.assert(arr.length != null); + + Array.prototype.forEach.call(arr, f, opt_obj); + } : + function(arr, f, opt_obj) { + var l = arr.length; // must be fixed during loop... see docs + var arr2 = goog.isString(arr) ? arr.split('') : arr; + for (var i = 0; i < l; i++) { + if (i in arr2) { + f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr); + } + } + }; + + +/** + * Calls a function for each element in an array, starting from the last + * element rather than the first. + * + * @param {IArrayLike<T>|string} arr Array or array + * like object over which to iterate. + * @param {?function(this: S, T, number, ?): ?} f The function to call for every + * element. This function + * takes 3 arguments (the element, the index and the array). The return + * value is ignored. + * @param {S=} opt_obj The object to be used as the value of 'this' + * within f. + * @template T,S + */ +goog.array.forEachRight = function(arr, f, opt_obj) { + var l = arr.length; // must be fixed during loop... see docs + var arr2 = goog.isString(arr) ? arr.split('') : arr; + for (var i = l - 1; i >= 0; --i) { + if (i in arr2) { + f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr); + } + } +}; + + +/** + * Calls a function for each element in an array, and if the function returns + * true adds the element to a new array. + * + * See {@link http://tinyurl.com/developer-mozilla-org-array-filter} + * + * @param {IArrayLike<T>|string} arr Array or array + * like object over which to iterate. + * @param {?function(this:S, T, number, ?):boolean} f The function to call for + * every element. This function + * takes 3 arguments (the element, the index and the array) and must + * return a Boolean. If the return value is true the element is added to the + * result array. If it is false the element is not included. + * @param {S=} opt_obj The object to be used as the value of 'this' + * within f. + * @return {!Array<T>} a new array in which only elements that passed the test + * are present. + * @template T,S + */ +goog.array.filter = goog.NATIVE_ARRAY_PROTOTYPES && + (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.filter) ? + function(arr, f, opt_obj) { + goog.asserts.assert(arr.length != null); + + return Array.prototype.filter.call(arr, f, opt_obj); + } : + function(arr, f, opt_obj) { + var l = arr.length; // must be fixed during loop... see docs + var res = []; + var resLength = 0; + var arr2 = goog.isString(arr) ? arr.split('') : arr; + for (var i = 0; i < l; i++) { + if (i in arr2) { + var val = arr2[i]; // in case f mutates arr2 + if (f.call(/** @type {?} */ (opt_obj), val, i, arr)) { + res[resLength++] = val; + } + } + } + return res; + }; + + +/** + * Calls a function for each element in an array and inserts the result into a + * new array. + * + * See {@link http://tinyurl.com/developer-mozilla-org-array-map} + * + * @param {IArrayLike<VALUE>|string} arr Array or array like object + * over which to iterate. + * @param {function(this:THIS, VALUE, number, ?): RESULT} f The function to call + * for every element. This function takes 3 arguments (the element, + * the index and the array) and should return something. The result will be + * inserted into a new array. + * @param {THIS=} opt_obj The object to be used as the value of 'this' within f. + * @return {!Array<RESULT>} a new array with the results from f. + * @template THIS, VALUE, RESULT + */ +goog.array.map = goog.NATIVE_ARRAY_PROTOTYPES && + (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.map) ? + function(arr, f, opt_obj) { + goog.asserts.assert(arr.length != null); + + return Array.prototype.map.call(arr, f, opt_obj); + } : + function(arr, f, opt_obj) { + var l = arr.length; // must be fixed during loop... see docs + var res = new Array(l); + var arr2 = goog.isString(arr) ? arr.split('') : arr; + for (var i = 0; i < l; i++) { + if (i in arr2) { + res[i] = f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr); + } + } + return res; + }; + + +/** + * Passes every element of an array into a function and accumulates the result. + * + * See {@link http://tinyurl.com/developer-mozilla-org-array-reduce} + * + * For example: + * var a = [1, 2, 3, 4]; + * goog.array.reduce(a, function(r, v, i, arr) {return r + v;}, 0); + * returns 10 + * + * @param {IArrayLike<T>|string} arr Array or array + * like object over which to iterate. + * @param {function(this:S, R, T, number, ?) : R} f The function to call for + * every element. This function + * takes 4 arguments (the function's previous result or the initial value, + * the value of the current array element, the current array index, and the + * array itself) + * function(previousValue, currentValue, index, array). + * @param {?} val The initial value to pass into the function on the first call. + * @param {S=} opt_obj The object to be used as the value of 'this' + * within f. + * @return {R} Result of evaluating f repeatedly across the values of the array. + * @template T,S,R + */ +goog.array.reduce = goog.NATIVE_ARRAY_PROTOTYPES && + (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduce) ? + function(arr, f, val, opt_obj) { + goog.asserts.assert(arr.length != null); + if (opt_obj) { + f = goog.bind(f, opt_obj); + } + return Array.prototype.reduce.call(arr, f, val); + } : + function(arr, f, val, opt_obj) { + var rval = val; + goog.array.forEach(arr, function(val, index) { + rval = f.call(/** @type {?} */ (opt_obj), rval, val, index, arr); + }); + return rval; + }; + + +/** + * Passes every element of an array into a function and accumulates the result, + * starting from the last element and working towards the first. + * + * See {@link http://tinyurl.com/developer-mozilla-org-array-reduceright} + * + * For example: + * var a = ['a', 'b', 'c']; + * goog.array.reduceRight(a, function(r, v, i, arr) {return r + v;}, ''); + * returns 'cba' + * + * @param {IArrayLike<T>|string} arr Array or array + * like object over which to iterate. + * @param {?function(this:S, R, T, number, ?) : R} f The function to call for + * every element. This function + * takes 4 arguments (the function's previous result or the initial value, + * the value of the current array element, the current array index, and the + * array itself) + * function(previousValue, currentValue, index, array). + * @param {?} val The initial value to pass into the function on the first call. + * @param {S=} opt_obj The object to be used as the value of 'this' + * within f. + * @return {R} Object returned as a result of evaluating f repeatedly across the + * values of the array. + * @template T,S,R + */ +goog.array.reduceRight = goog.NATIVE_ARRAY_PROTOTYPES && + (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduceRight) ? + function(arr, f, val, opt_obj) { + goog.asserts.assert(arr.length != null); + goog.asserts.assert(f != null); + if (opt_obj) { + f = goog.bind(f, opt_obj); + } + return Array.prototype.reduceRight.call(arr, f, val); + } : + function(arr, f, val, opt_obj) { + var rval = val; + goog.array.forEachRight(arr, function(val, index) { + rval = f.call(/** @type {?} */ (opt_obj), rval, val, index, arr); + }); + return rval; + }; + + +/** + * Calls f for each element of an array. If any call returns true, some() + * returns true (without checking the remaining elements). If all calls + * return false, some() returns false. + * + * See {@link http://tinyurl.com/developer-mozilla-org-array-some} + * + * @param {IArrayLike<T>|string} arr Array or array + * like object over which to iterate. + * @param {?function(this:S, T, number, ?) : boolean} f The function to call for + * for every element. This function takes 3 arguments (the element, the + * index and the array) and should return a boolean. + * @param {S=} opt_obj The object to be used as the value of 'this' + * within f. + * @return {boolean} true if any element passes the test. + * @template T,S + */ +goog.array.some = goog.NATIVE_ARRAY_PROTOTYPES && + (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.some) ? + function(arr, f, opt_obj) { + goog.asserts.assert(arr.length != null); + + return Array.prototype.some.call(arr, f, opt_obj); + } : + function(arr, f, opt_obj) { + var l = arr.length; // must be fixed during loop... see docs + var arr2 = goog.isString(arr) ? arr.split('') : arr; + for (var i = 0; i < l; i++) { + if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) { + return true; + } + } + return false; + }; + + +/** + * Call f for each element of an array. If all calls return true, every() + * returns true. If any call returns false, every() returns false and + * does not continue to check the remaining elements. + * + * See {@link http://tinyurl.com/developer-mozilla-org-array-every} + * + * @param {IArrayLike<T>|string} arr Array or array + * like object over which to iterate. + * @param {?function(this:S, T, number, ?) : boolean} f The function to call for + * for every element. This function takes 3 arguments (the element, the + * index and the array) and should return a boolean. + * @param {S=} opt_obj The object to be used as the value of 'this' + * within f. + * @return {boolean} false if any element fails the test. + * @template T,S + */ +goog.array.every = goog.NATIVE_ARRAY_PROTOTYPES && + (goog.array.ASSUME_NATIVE_FUNCTIONS || Array.prototype.every) ? + function(arr, f, opt_obj) { + goog.asserts.assert(arr.length != null); + + return Array.prototype.every.call(arr, f, opt_obj); + } : + function(arr, f, opt_obj) { + var l = arr.length; // must be fixed during loop... see docs + var arr2 = goog.isString(arr) ? arr.split('') : arr; + for (var i = 0; i < l; i++) { + if (i in arr2 && !f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) { + return false; + } + } + return true; + }; + + +/** + * Counts the array elements that fulfill the predicate, i.e. for which the + * callback function returns true. Skips holes in the array. + * + * @param {!IArrayLike<T>|string} arr Array or array like object + * over which to iterate. + * @param {function(this: S, T, number, ?): boolean} f The function to call for + * every element. Takes 3 arguments (the element, the index and the array). + * @param {S=} opt_obj The object to be used as the value of 'this' within f. + * @return {number} The number of the matching elements. + * @template T,S + */ +goog.array.count = function(arr, f, opt_obj) { + var count = 0; + goog.array.forEach(arr, function(element, index, arr) { + if (f.call(/** @type {?} */ (opt_obj), element, index, arr)) { + ++count; + } + }, opt_obj); + return count; +}; + + +/** + * Search an array for the first element that satisfies a given condition and + * return that element. + * @param {IArrayLike<T>|string} arr Array or array + * like object over which to iterate. + * @param {?function(this:S, T, number, ?) : boolean} f The function to call + * for every element. This function takes 3 arguments (the element, the + * index and the array) and should return a boolean. + * @param {S=} opt_obj An optional "this" context for the function. + * @return {T|null} The first array element that passes the test, or null if no + * element is found. + * @template T,S + */ +goog.array.find = function(arr, f, opt_obj) { + var i = goog.array.findIndex(arr, f, opt_obj); + return i < 0 ? null : goog.isString(arr) ? arr.charAt(i) : arr[i]; +}; + + +/** + * Search an array for the first element that satisfies a given condition and + * return its index. + * @param {IArrayLike<T>|string} arr Array or array + * like object over which to iterate. + * @param {?function(this:S, T, number, ?) : boolean} f The function to call for + * every element. This function + * takes 3 arguments (the element, the index and the array) and should + * return a boolean. + * @param {S=} opt_obj An optional "this" context for the function. + * @return {number} The index of the first array element that passes the test, + * or -1 if no element is found. + * @template T,S + */ +goog.array.findIndex = function(arr, f, opt_obj) { + var l = arr.length; // must be fixed during loop... see docs + var arr2 = goog.isString(arr) ? arr.split('') : arr; + for (var i = 0; i < l; i++) { + if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) { + return i; + } + } + return -1; +}; + + +/** + * Search an array (in reverse order) for the last element that satisfies a + * given condition and return that element. + * @param {IArrayLike<T>|string} arr Array or array + * like object over which to iterate. + * @param {?function(this:S, T, number, ?) : boolean} f The function to call + * for every element. This function + * takes 3 arguments (the element, the index and the array) and should + * return a boolean. + * @param {S=} opt_obj An optional "this" context for the function. + * @return {T|null} The last array element that passes the test, or null if no + * element is found. + * @template T,S + */ +goog.array.findRight = function(arr, f, opt_obj) { + var i = goog.array.findIndexRight(arr, f, opt_obj); + return i < 0 ? null : goog.isString(arr) ? arr.charAt(i) : arr[i]; +}; + + +/** + * Search an array (in reverse order) for the last element that satisfies a + * given condition and return its index. + * @param {IArrayLike<T>|string} arr Array or array + * like object over which to iterate. + * @param {?function(this:S, T, number, ?) : boolean} f The function to call + * for every element. This function + * takes 3 arguments (the element, the index and the array) and should + * return a boolean. + * @param {S=} opt_obj An optional "this" context for the function. + * @return {number} The index of the last array element that passes the test, + * or -1 if no element is found. + * @template T,S + */ +goog.array.findIndexRight = function(arr, f, opt_obj) { + var l = arr.length; // must be fixed during loop... see docs + var arr2 = goog.isString(arr) ? arr.split('') : arr; + for (var i = l - 1; i >= 0; i--) { + if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) { + return i; + } + } + return -1; +}; + + +/** + * Whether the array contains the given object. + * @param {IArrayLike<?>|string} arr The array to test for the presence of the + * element. + * @param {*} obj The object for which to test. + * @return {boolean} true if obj is present. + */ +goog.array.contains = function(arr, obj) { + return goog.array.indexOf(arr, obj) >= 0; +}; + + +/** + * Whether the array is empty. + * @param {IArrayLike<?>|string} arr The array to test. + * @return {boolean} true if empty. + */ +goog.array.isEmpty = function(arr) { + return arr.length == 0; +}; + + +/** + * Clears the array. + * @param {IArrayLike<?>} arr Array or array like object to clear. + */ +goog.array.clear = function(arr) { + // For non real arrays we don't have the magic length so we delete the + // indices. + if (!goog.isArray(arr)) { + for (var i = arr.length - 1; i >= 0; i--) { + delete arr[i]; + } + } + arr.length = 0; +}; + + +/** + * Pushes an item into an array, if it's not already in the array. + * @param {Array<T>} arr Array into which to insert the item. + * @param {T} obj Value to add. + * @template T + */ +goog.array.insert = function(arr, obj) { + if (!goog.array.contains(arr, obj)) { + arr.push(obj); + } +}; + + +/** + * Inserts an object at the given index of the array. + * @param {IArrayLike<?>} arr The array to modify. + * @param {*} obj The object to insert. + * @param {number=} opt_i The index at which to insert the object. If omitted, + * treated as 0. A negative index is counted from the end of the array. + */ +goog.array.insertAt = function(arr, obj, opt_i) { + goog.array.splice(arr, opt_i, 0, obj); +}; + + +/** + * Inserts at the given index of the array, all elements of another array. + * @param {IArrayLike<?>} arr The array to modify. + * @param {IArrayLike<?>} elementsToAdd The array of elements to add. + * @param {number=} opt_i The index at which to insert the object. If omitted, + * treated as 0. A negative index is counted from the end of the array. + */ +goog.array.insertArrayAt = function(arr, elementsToAdd, opt_i) { + goog.partial(goog.array.splice, arr, opt_i, 0).apply(null, elementsToAdd); +}; + + +/** + * Inserts an object into an array before a specified object. + * @param {Array<T>} arr The array to modify. + * @param {T} obj The object to insert. + * @param {T=} opt_obj2 The object before which obj should be inserted. If obj2 + * is omitted or not found, obj is inserted at the end of the array. + * @template T + */ +goog.array.insertBefore = function(arr, obj, opt_obj2) { + var i; + if (arguments.length == 2 || (i = goog.array.indexOf(arr, opt_obj2)) < 0) { + arr.push(obj); + } else { + goog.array.insertAt(arr, obj, i); + } +}; + + +/** + * Removes the first occurrence of a particular value from an array. + * @param {IArrayLike<T>} arr Array from which to remove + * value. + * @param {T} obj Object to remove. + * @return {boolean} True if an element was removed. + * @template T + */ +goog.array.remove = function(arr, obj) { + var i = goog.array.indexOf(arr, obj); + var rv; + if ((rv = i >= 0)) { + goog.array.removeAt(arr, i); + } + return rv; +}; + + +/** + * Removes the last occurrence of a particular value from an array. + * @param {!IArrayLike<T>} arr Array from which to remove value. + * @param {T} obj Object to remove. + * @return {boolean} True if an element was removed. + * @template T + */ +goog.array.removeLast = function(arr, obj) { + var i = goog.array.lastIndexOf(arr, obj); + if (i >= 0) { + goog.array.removeAt(arr, i); + return true; + } + return false; +}; + + +/** + * Removes from an array the element at index i + * @param {IArrayLike<?>} arr Array or array like object from which to + * remove value. + * @param {number} i The index to remove. + * @return {boolean} True if an element was removed. + */ +goog.array.removeAt = function(arr, i) { + goog.asserts.assert(arr.length != null); + + // use generic form of splice + // splice returns the removed items and if successful the length of that + // will be 1 + return Array.prototype.splice.call(arr, i, 1).length == 1; +}; + + +/** + * Removes the first value that satisfies the given condition. + * @param {IArrayLike<T>} arr Array or array + * like object over which to iterate. + * @param {?function(this:S, T, number, ?) : boolean} f The function to call + * for every element. This function + * takes 3 arguments (the element, the index and the array) and should + * return a boolean. + * @param {S=} opt_obj An optional "this" context for the function. + * @return {boolean} True if an element was removed. + * @template T,S + */ +goog.array.removeIf = function(arr, f, opt_obj) { + var i = goog.array.findIndex(arr, f, opt_obj); + if (i >= 0) { + goog.array.removeAt(arr, i); + return true; + } + return false; +}; + + +/** + * Removes all values that satisfy the given condition. + * @param {IArrayLike<T>} arr Array or array + * like object over which to iterate. + * @param {?function(this:S, T, number, ?) : boolean} f The function to call + * for every element. This function + * takes 3 arguments (the element, the index and the array) and should + * return a boolean. + * @param {S=} opt_obj An optional "this" context for the function. + * @return {number} The number of items removed + * @template T,S + */ +goog.array.removeAllIf = function(arr, f, opt_obj) { + var removedCount = 0; + goog.array.forEachRight(arr, function(val, index) { + if (f.call(/** @type {?} */ (opt_obj), val, index, arr)) { + if (goog.array.removeAt(arr, index)) { + removedCount++; + } + } + }); + return removedCount; +}; + + +/** + * Returns a new array that is the result of joining the arguments. If arrays + * are passed then their items are added, however, if non-arrays are passed they + * will be added to the return array as is. + * + * Note that ArrayLike objects will be added as is, rather than having their + * items added. + * + * goog.array.concat([1, 2], [3, 4]) -> [1, 2, 3, 4] + * goog.array.concat(0, [1, 2]) -> [0, 1, 2] + * goog.array.concat([1, 2], null) -> [1, 2, null] + * + * There is bug in all current versions of IE (6, 7 and 8) where arrays created + * in an iframe become corrupted soon (not immediately) after the iframe is + * destroyed. This is common if loading data via goog.net.IframeIo, for example. + * This corruption only affects the concat method which will start throwing + * Catastrophic Errors (#-2147418113). + * + * See http://endoflow.com/scratch/corrupted-arrays.html for a test case. + * + * Internally goog.array should use this, so that all methods will continue to + * work on these broken array objects. + * + * @param {...*} var_args Items to concatenate. Arrays will have each item + * added, while primitives and objects will be added as is. + * @return {!Array<?>} The new resultant array. + */ +goog.array.concat = function(var_args) { + return Array.prototype.concat.apply(Array.prototype, arguments); +}; + + +/** + * Returns a new array that contains the contents of all the arrays passed. + * @param {...!Array<T>} var_args + * @return {!Array<T>} + * @template T + */ +goog.array.join = function(var_args) { + return Array.prototype.concat.apply(Array.prototype, arguments); +}; + + +/** + * Converts an object to an array. + * @param {IArrayLike<T>|string} object The object to convert to an + * array. + * @return {!Array<T>} The object converted into an array. If object has a + * length property, every property indexed with a non-negative number + * less than length will be included in the result. If object does not + * have a length property, an empty array will be returned. + * @template T + */ +goog.array.toArray = function(object) { + var length = object.length; + + // If length is not a number the following it false. This case is kept for + // backwards compatibility since there are callers that pass objects that are + // not array like. + if (length > 0) { + var rv = new Array(length); + for (var i = 0; i < length; i++) { + rv[i] = object[i]; + } + return rv; + } + return []; +}; + + +/** + * Does a shallow copy of an array. + * @param {IArrayLike<T>|string} arr Array or array-like object to + * clone. + * @return {!Array<T>} Clone of the input array. + * @template T + */ +goog.array.clone = goog.array.toArray; + + +/** + * Extends an array with another array, element, or "array like" object. + * This function operates 'in-place', it does not create a new Array. + * + * Example: + * var a = []; + * goog.array.extend(a, [0, 1]); + * a; // [0, 1] + * goog.array.extend(a, 2); + * a; // [0, 1, 2] + * + * @param {Array<VALUE>} arr1 The array to modify. + * @param {...(Array<VALUE>|VALUE)} var_args The elements or arrays of elements + * to add to arr1. + * @template VALUE + */ +goog.array.extend = function(arr1, var_args) { + for (var i = 1; i < arguments.length; i++) { + var arr2 = arguments[i]; + if (goog.isArrayLike(arr2)) { + var len1 = arr1.length || 0; + var len2 = arr2.length || 0; + arr1.length = len1 + len2; + for (var j = 0; j < len2; j++) { + arr1[len1 + j] = arr2[j]; + } + } else { + arr1.push(arr2); + } + } +}; + + +/** + * Adds or removes elements from an array. This is a generic version of Array + * splice. This means that it might work on other objects similar to arrays, + * such as the arguments object. + * + * @param {IArrayLike<T>} arr The array to modify. + * @param {number|undefined} index The index at which to start changing the + * array. If not defined, treated as 0. + * @param {number} howMany How many elements to remove (0 means no removal. A + * value below 0 is treated as zero and so is any other non number. Numbers + * are floored). + * @param {...T} var_args Optional, additional elements to insert into the + * array. + * @return {!Array<T>} the removed elements. + * @template T + */ +goog.array.splice = function(arr, index, howMany, var_args) { + goog.asserts.assert(arr.length != null); + + return Array.prototype.splice.apply(arr, goog.array.slice(arguments, 1)); +}; + + +/** + * Returns a new array from a segment of an array. This is a generic version of + * Array slice. This means that it might work on other objects similar to + * arrays, such as the arguments object. + * + * @param {IArrayLike<T>|string} arr The array from + * which to copy a segment. + * @param {number} start The index of the first element to copy. + * @param {number=} opt_end The index after the last element to copy. + * @return {!Array<T>} A new array containing the specified segment of the + * original array. + * @template T + */ +goog.array.slice = function(arr, start, opt_end) { + goog.asserts.assert(arr.length != null); + + // passing 1 arg to slice is not the same as passing 2 where the second is + // null or undefined (in that case the second argument is treated as 0). + // we could use slice on the arguments object and then use apply instead of + // testing the length + if (arguments.length <= 2) { + return Array.prototype.slice.call(arr, start); + } else { + return Array.prototype.slice.call(arr, start, opt_end); + } +}; + + +/** + * Removes all duplicates from an array (retaining only the first + * occurrence of each array element). This function modifies the + * array in place and doesn't change the order of the non-duplicate items. + * + * For objects, duplicates are identified as having the same unique ID as + * defined by {@link goog.getUid}. + * + * Alternatively you can specify a custom hash function that returns a unique + * value for each item in the array it should consider unique. + * + * Runtime: N, + * Worstcase space: 2N (no dupes) + * + * @param {IArrayLike<T>} arr The array from which to remove + * duplicates. + * @param {Array=} opt_rv An optional array in which to return the results, + * instead of performing the removal inplace. If specified, the original + * array will remain unchanged. + * @param {function(T):string=} opt_hashFn An optional function to use to + * apply to every item in the array. This function should return a unique + * value for each item in the array it should consider unique. + * @template T + */ +goog.array.removeDuplicates = function(arr, opt_rv, opt_hashFn) { + var returnArray = opt_rv || arr; + var defaultHashFn = function(item) { + // Prefix each type with a single character representing the type to + // prevent conflicting keys (e.g. true and 'true'). + return goog.isObject(item) ? 'o' + goog.getUid(item) : + (typeof item).charAt(0) + item; + }; + var hashFn = opt_hashFn || defaultHashFn; + + var seen = {}, cursorInsert = 0, cursorRead = 0; + while (cursorRead < arr.length) { + var current = arr[cursorRead++]; + var key = hashFn(current); + if (!Object.prototype.hasOwnProperty.call(seen, key)) { + seen[key] = true; + returnArray[cursorInsert++] = current; + } + } + returnArray.length = cursorInsert; +}; + + +/** + * Searches the specified array for the specified target using the binary + * search algorithm. If no opt_compareFn is specified, elements are compared + * using <code>goog.array.defaultCompare</code>, which compares the elements + * using the built in < and > operators. This will produce the expected + * behavior for homogeneous arrays of String(s) and Number(s). The array + * specified <b>must</b> be sorted in ascending order (as defined by the + * comparison function). If the array is not sorted, results are undefined. + * If the array contains multiple instances of the specified target value, any + * of these instances may be found. + * + * Runtime: O(log n) + * + * @param {IArrayLike<VALUE>} arr The array to be searched. + * @param {TARGET} target The sought value. + * @param {function(TARGET, VALUE): number=} opt_compareFn Optional comparison + * function by which the array is ordered. Should take 2 arguments to + * compare, and return a negative number, zero, or a positive number + * depending on whether the first argument is less than, equal to, or + * greater than the second. + * @return {number} Lowest index of the target value if found, otherwise + * (-(insertion point) - 1). The insertion point is where the value should + * be inserted into arr to preserve the sorted property. Return value >= 0 + * iff target is found. + * @template TARGET, VALUE + */ +goog.array.binarySearch = function(arr, target, opt_compareFn) { + return goog.array.binarySearch_( + arr, opt_compareFn || goog.array.defaultCompare, false /* isEvaluator */, + target); +}; + + +/** + * Selects an index in the specified array using the binary search algorithm. + * The evaluator receives an element and determines whether the desired index + * is before, at, or after it. The evaluator must be consistent (formally, + * goog.array.map(goog.array.map(arr, evaluator, opt_obj), goog.math.sign) + * must be monotonically non-increasing). + * + * Runtime: O(log n) + * + * @param {IArrayLike<VALUE>} arr The array to be searched. + * @param {function(this:THIS, VALUE, number, ?): number} evaluator + * Evaluator function that receives 3 arguments (the element, the index and + * the array). Should return a negative number, zero, or a positive number + * depending on whether the desired index is before, at, or after the + * element passed to it. + * @param {THIS=} opt_obj The object to be used as the value of 'this' + * within evaluator. + * @return {number} Index of the leftmost element matched by the evaluator, if + * such exists; otherwise (-(insertion point) - 1). The insertion point is + * the index of the first element for which the evaluator returns negative, + * or arr.length if no such element exists. The return value is non-negative + * iff a match is found. + * @template THIS, VALUE + */ +goog.array.binarySelect = function(arr, evaluator, opt_obj) { + return goog.array.binarySearch_( + arr, evaluator, true /* isEvaluator */, undefined /* opt_target */, + opt_obj); +}; + + +/** + * Implementation of a binary search algorithm which knows how to use both + * comparison functions and evaluators. If an evaluator is provided, will call + * the evaluator with the given optional data object, conforming to the + * interface defined in binarySelect. Otherwise, if a comparison function is + * provided, will call the comparison function against the given data object. + * + * This implementation purposefully does not use goog.bind or goog.partial for + * performance reasons. + * + * Runtime: O(log n) + * + * @param {IArrayLike<?>} arr The array to be searched. + * @param {function(?, ?, ?): number | function(?, ?): number} compareFn + * Either an evaluator or a comparison function, as defined by binarySearch + * and binarySelect above. + * @param {boolean} isEvaluator Whether the function is an evaluator or a + * comparison function. + * @param {?=} opt_target If the function is a comparison function, then + * this is the target to binary search for. + * @param {Object=} opt_selfObj If the function is an evaluator, this is an + * optional this object for the evaluator. + * @return {number} Lowest index of the target value if found, otherwise + * (-(insertion point) - 1). The insertion point is where the value should + * be inserted into arr to preserve the sorted property. Return value >= 0 + * iff target is found. + * @private + */ +goog.array.binarySearch_ = function( + arr, compareFn, isEvaluator, opt_target, opt_selfObj) { + var left = 0; // inclusive + var right = arr.length; // exclusive + var found; + while (left < right) { + var middle = (left + right) >> 1; + var compareResult; + if (isEvaluator) { + compareResult = compareFn.call(opt_selfObj, arr[middle], middle, arr); + } else { + // NOTE(dimvar): To avoid this cast, we'd have to use function overloading + // for the type of binarySearch_, which the type system can't express yet. + compareResult = /** @type {function(?, ?): number} */ (compareFn)( + opt_target, arr[middle]); + } + if (compareResult > 0) { + left = middle + 1; + } else { + right = middle; + // We are looking for the lowest index so we can't return immediately. + found = !compareResult; + } + } + // left is the index if found, or the insertion point otherwise. + // ~left is a shorthand for -left - 1. + return found ? left : ~left; +}; + + +/** + * Sorts the specified array into ascending order. If no opt_compareFn is + * specified, elements are compared using + * <code>goog.array.defaultCompare</code>, which compares the elements using + * the built in < and > operators. This will produce the expected behavior + * for homogeneous arrays of String(s) and Number(s), unlike the native sort, + * but will give unpredictable results for heterogenous lists of strings and + * numbers with different numbers of digits. + * + * This sort is not guaranteed to be stable. + * + * Runtime: Same as <code>Array.prototype.sort</code> + * + * @param {Array<T>} arr The array to be sorted. + * @param {?function(T,T):number=} opt_compareFn Optional comparison + * function by which the + * array is to be ordered. Should take 2 arguments to compare, and return a + * negative number, zero, or a positive number depending on whether the + * first argument is less than, equal to, or greater than the second. + * @template T + */ +goog.array.sort = function(arr, opt_compareFn) { + // TODO(arv): Update type annotation since null is not accepted. + arr.sort(opt_compareFn || goog.array.defaultCompare); +}; + + +/** + * Sorts the specified array into ascending order in a stable way. If no + * opt_compareFn is specified, elements are compared using + * <code>goog.array.defaultCompare</code>, which compares the elements using + * the built in < and > operators. This will produce the expected behavior + * for homogeneous arrays of String(s) and Number(s). + * + * Runtime: Same as <code>Array.prototype.sort</code>, plus an additional + * O(n) overhead of copying the array twice. + * + * @param {Array<T>} arr The array to be sorted. + * @param {?function(T, T): number=} opt_compareFn Optional comparison function + * by which the array is to be ordered. Should take 2 arguments to compare, + * and return a negative number, zero, or a positive number depending on + * whether the first argument is less than, equal to, or greater than the + * second. + * @template T + */ +goog.array.stableSort = function(arr, opt_compareFn) { + var compArr = new Array(arr.length); + for (var i = 0; i < arr.length; i++) { + compArr[i] = {index: i, value: arr[i]}; + } + var valueCompareFn = opt_compareFn || goog.array.defaultCompare; + function stableCompareFn(obj1, obj2) { + return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index; + } + goog.array.sort(compArr, stableCompareFn); + for (var i = 0; i < arr.length; i++) { + arr[i] = compArr[i].value; + } +}; + + +/** + * Sort the specified array into ascending order based on item keys + * returned by the specified key function. + * If no opt_compareFn is specified, the keys are compared in ascending order + * using <code>goog.array.defaultCompare</code>. + * + * Runtime: O(S(f(n)), where S is runtime of <code>goog.array.sort</code> + * and f(n) is runtime of the key function. + * + * @param {Array<T>} arr The array to be sorted. + * @param {function(T): K} keyFn Function taking array element and returning + * a key used for sorting this element. + * @param {?function(K, K): number=} opt_compareFn Optional comparison function + * by which the keys are to be ordered. Should take 2 arguments to compare, + * and return a negative number, zero, or a positive number depending on + * whether the first argument is less than, equal to, or greater than the + * second. + * @template T,K + */ +goog.array.sortByKey = function(arr, keyFn, opt_compareFn) { + var keyCompareFn = opt_compareFn || goog.array.defaultCompare; + goog.array.sort( + arr, function(a, b) { return keyCompareFn(keyFn(a), keyFn(b)); }); +}; + + +/** + * Sorts an array of objects by the specified object key and compare + * function. If no compare function is provided, the key values are + * compared in ascending order using <code>goog.array.defaultCompare</code>. + * This won't work for keys that get renamed by the compiler. So use + * {'foo': 1, 'bar': 2} rather than {foo: 1, bar: 2}. + * @param {Array<Object>} arr An array of objects to sort. + * @param {string} key The object key to sort by. + * @param {Function=} opt_compareFn The function to use to compare key + * values. + */ +goog.array.sortObjectsByKey = function(arr, key, opt_compareFn) { + goog.array.sortByKey(arr, function(obj) { return obj[key]; }, opt_compareFn); +}; + + +/** + * Tells if the array is sorted. + * @param {!Array<T>} arr The array. + * @param {?function(T,T):number=} opt_compareFn Function to compare the + * array elements. + * Should take 2 arguments to compare, and return a negative number, zero, + * or a positive number depending on whether the first argument is less + * than, equal to, or greater than the second. + * @param {boolean=} opt_strict If true no equal elements are allowed. + * @return {boolean} Whether the array is sorted. + * @template T + */ +goog.array.isSorted = function(arr, opt_compareFn, opt_strict) { + var compare = opt_compareFn || goog.array.defaultCompare; + for (var i = 1; i < arr.length; i++) { + var compareResult = compare(arr[i - 1], arr[i]); + if (compareResult > 0 || compareResult == 0 && opt_strict) { + return false; + } + } + return true; +}; + + +/** + * Compares two arrays for equality. Two arrays are considered equal if they + * have the same length and their corresponding elements are equal according to + * the comparison function. + * + * @param {IArrayLike<?>} arr1 The first array to compare. + * @param {IArrayLike<?>} arr2 The second array to compare. + * @param {Function=} opt_equalsFn Optional comparison function. + * Should take 2 arguments to compare, and return true if the arguments + * are equal. Defaults to {@link goog.array.defaultCompareEquality} which + * compares the elements using the built-in '===' operator. + * @return {boolean} Whether the two arrays are equal. + */ +goog.array.equals = function(arr1, arr2, opt_equalsFn) { + if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) || + arr1.length != arr2.length) { + return false; + } + var l = arr1.length; + var equalsFn = opt_equalsFn || goog.array.defaultCompareEquality; + for (var i = 0; i < l; i++) { + if (!equalsFn(arr1[i], arr2[i])) { + return false; + } + } + return true; +}; + + +/** + * 3-way array compare function. + * @param {!IArrayLike<VALUE>} arr1 The first array to + * compare. + * @param {!IArrayLike<VALUE>} arr2 The second array to + * compare. + * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison + * function by which the array is to be ordered. Should take 2 arguments to + * compare, and return a negative number, zero, or a positive number + * depending on whether the first argument is less than, equal to, or + * greater than the second. + * @return {number} Negative number, zero, or a positive number depending on + * whether the first argument is less than, equal to, or greater than the + * second. + * @template VALUE + */ +goog.array.compare3 = function(arr1, arr2, opt_compareFn) { + var compare = opt_compareFn || goog.array.defaultCompare; + var l = Math.min(arr1.length, arr2.length); + for (var i = 0; i < l; i++) { + var result = compare(arr1[i], arr2[i]); + if (result != 0) { + return result; + } + } + return goog.array.defaultCompare(arr1.length, arr2.length); +}; + + +/** + * Compares its two arguments for order, using the built in < and > + * operators. + * @param {VALUE} a The first object to be compared. + * @param {VALUE} b The second object to be compared. + * @return {number} A negative number, zero, or a positive number as the first + * argument is less than, equal to, or greater than the second, + * respectively. + * @template VALUE + */ +goog.array.defaultCompare = function(a, b) { + return a > b ? 1 : a < b ? -1 : 0; +}; + + +/** + * Compares its two arguments for inverse order, using the built in < and > + * operators. + * @param {VALUE} a The first object to be compared. + * @param {VALUE} b The second object to be compared. + * @return {number} A negative number, zero, or a positive number as the first + * argument is greater than, equal to, or less than the second, + * respectively. + * @template VALUE + */ +goog.array.inverseDefaultCompare = function(a, b) { + return -goog.array.defaultCompare(a, b); +}; + + +/** + * Compares its two arguments for equality, using the built in === operator. + * @param {*} a The first object to compare. + * @param {*} b The second object to compare. + * @return {boolean} True if the two arguments are equal, false otherwise. + */ +goog.array.defaultCompareEquality = function(a, b) { + return a === b; +}; + + +/** + * Inserts a value into a sorted array. The array is not modified if the + * value is already present. + * @param {IArrayLike<VALUE>} array The array to modify. + * @param {VALUE} value The object to insert. + * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison + * function by which the array is ordered. Should take 2 arguments to + * compare, and return a negative number, zero, or a positive number + * depending on whether the first argument is less than, equal to, or + * greater than the second. + * @return {boolean} True if an element was inserted. + * @template VALUE + */ +goog.array.binaryInsert = function(array, value, opt_compareFn) { + var index = goog.array.binarySearch(array, value, opt_compareFn); + if (index < 0) { + goog.array.insertAt(array, value, -(index + 1)); + return true; + } + return false; +}; + + +/** + * Removes a value from a sorted array. + * @param {!IArrayLike<VALUE>} array The array to modify. + * @param {VALUE} value The object to remove. + * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison + * function by which the array is ordered. Should take 2 arguments to + * compare, and return a negative number, zero, or a positive number + * depending on whether the first argument is less than, equal to, or + * greater than the second. + * @return {boolean} True if an element was removed. + * @template VALUE + */ +goog.array.binaryRemove = function(array, value, opt_compareFn) { + var index = goog.array.binarySearch(array, value, opt_compareFn); + return (index >= 0) ? goog.array.removeAt(array, index) : false; +}; + + +/** + * Splits an array into disjoint buckets according to a splitting function. + * @param {Array<T>} array The array. + * @param {function(this:S, T,number,Array<T>):?} sorter Function to call for + * every element. This takes 3 arguments (the element, the index and the + * array) and must return a valid object key (a string, number, etc), or + * undefined, if that object should not be placed in a bucket. + * @param {S=} opt_obj The object to be used as the value of 'this' within + * sorter. + * @return {!Object} An object, with keys being all of the unique return values + * of sorter, and values being arrays containing the items for + * which the splitter returned that key. + * @template T,S + */ +goog.array.bucket = function(array, sorter, opt_obj) { + var buckets = {}; + + for (var i = 0; i < array.length; i++) { + var value = array[i]; + var key = sorter.call(/** @type {?} */ (opt_obj), value, i, array); + if (goog.isDef(key)) { + // Push the value to the right bucket, creating it if necessary. + var bucket = buckets[key] || (buckets[key] = []); + bucket.push(value); + } + } + + return buckets; +}; + + +/** + * Creates a new object built from the provided array and the key-generation + * function. + * @param {IArrayLike<T>} arr Array or array like object over + * which to iterate whose elements will be the values in the new object. + * @param {?function(this:S, T, number, ?) : string} keyFunc The function to + * call for every element. This function takes 3 arguments (the element, the + * index and the array) and should return a string that will be used as the + * key for the element in the new object. If the function returns the same + * key for more than one element, the value for that key is + * implementation-defined. + * @param {S=} opt_obj The object to be used as the value of 'this' + * within keyFunc. + * @return {!Object<T>} The new object. + * @template T,S + */ +goog.array.toObject = function(arr, keyFunc, opt_obj) { + var ret = {}; + goog.array.forEach(arr, function(element, index) { + ret[keyFunc.call(/** @type {?} */ (opt_obj), element, index, arr)] = + element; + }); + return ret; +}; + + +/** + * Creates a range of numbers in an arithmetic progression. + * + * Range takes 1, 2, or 3 arguments: + * <pre> + * range(5) is the same as range(0, 5, 1) and produces [0, 1, 2, 3, 4] + * range(2, 5) is the same as range(2, 5, 1) and produces [2, 3, 4] + * range(-2, -5, -1) produces [-2, -3, -4] + * range(-2, -5, 1) produces [], since stepping by 1 wouldn't ever reach -5. + * </pre> + * + * @param {number} startOrEnd The starting value of the range if an end argument + * is provided. Otherwise, the start value is 0, and this is the end value. + * @param {number=} opt_end The optional end value of the range. + * @param {number=} opt_step The step size between range values. Defaults to 1 + * if opt_step is undefined or 0. + * @return {!Array<number>} An array of numbers for the requested range. May be + * an empty array if adding the step would not converge toward the end + * value. + */ +goog.array.range = function(startOrEnd, opt_end, opt_step) { + var array = []; + var start = 0; + var end = startOrEnd; + var step = opt_step || 1; + if (opt_end !== undefined) { + start = startOrEnd; + end = opt_end; + } + + if (step * (end - start) < 0) { + // Sign mismatch: start + step will never reach the end value. + return []; + } + + if (step > 0) { + for (var i = start; i < end; i += step) { + array.push(i); + } + } else { + for (var i = start; i > end; i += step) { + array.push(i); + } + } + return array; +}; + + +/** + * Returns an array consisting of the given value repeated N times. + * + * @param {VALUE} value The value to repeat. + * @param {number} n The repeat count. + * @return {!Array<VALUE>} An array with the repeated value. + * @template VALUE + */ +goog.array.repeat = function(value, n) { + var array = []; + for (var i = 0; i < n; i++) { + array[i] = value; + } + return array; +}; + + +/** + * Returns an array consisting of every argument with all arrays + * expanded in-place recursively. + * + * @param {...*} var_args The values to flatten. + * @return {!Array<?>} An array containing the flattened values. + */ +goog.array.flatten = function(var_args) { + var CHUNK_SIZE = 8192; + + var result = []; + for (var i = 0; i < arguments.length; i++) { + var element = arguments[i]; + if (goog.isArray(element)) { + for (var c = 0; c < element.length; c += CHUNK_SIZE) { + var chunk = goog.array.slice(element, c, c + CHUNK_SIZE); + var recurseResult = goog.array.flatten.apply(null, chunk); + for (var r = 0; r < recurseResult.length; r++) { + result.push(recurseResult[r]); + } + } + } else { + result.push(element); + } + } + return result; +}; + + +/** + * Rotates an array in-place. After calling this method, the element at + * index i will be the element previously at index (i - n) % + * array.length, for all values of i between 0 and array.length - 1, + * inclusive. + * + * For example, suppose list comprises [t, a, n, k, s]. After invoking + * rotate(array, 1) (or rotate(array, -4)), array will comprise [s, t, a, n, k]. + * + * @param {!Array<T>} array The array to rotate. + * @param {number} n The amount to rotate. + * @return {!Array<T>} The array. + * @template T + */ +goog.array.rotate = function(array, n) { + goog.asserts.assert(array.length != null); + + if (array.length) { + n %= array.length; + if (n > 0) { + Array.prototype.unshift.apply(array, array.splice(-n, n)); + } else if (n < 0) { + Array.prototype.push.apply(array, array.splice(0, -n)); + } + } + return array; +}; + + +/** + * Moves one item of an array to a new position keeping the order of the rest + * of the items. Example use case: keeping a list of JavaScript objects + * synchronized with the corresponding list of DOM elements after one of the + * elements has been dragged to a new position. + * @param {!IArrayLike<?>} arr The array to modify. + * @param {number} fromIndex Index of the item to move between 0 and + * {@code arr.length - 1}. + * @param {number} toIndex Target index between 0 and {@code arr.length - 1}. + */ +goog.array.moveItem = function(arr, fromIndex, toIndex) { + goog.asserts.assert(fromIndex >= 0 && fromIndex < arr.length); + goog.asserts.assert(toIndex >= 0 && toIndex < arr.length); + // Remove 1 item at fromIndex. + var removedItems = Array.prototype.splice.call(arr, fromIndex, 1); + // Insert the removed item at toIndex. + Array.prototype.splice.call(arr, toIndex, 0, removedItems[0]); + // We don't use goog.array.insertAt and goog.array.removeAt, because they're + // significantly slower than splice. +}; + + +/** + * Creates a new array for which the element at position i is an array of the + * ith element of the provided arrays. The returned array will only be as long + * as the shortest array provided; additional values are ignored. For example, + * the result of zipping [1, 2] and [3, 4, 5] is [[1,3], [2, 4]]. + * + * This is similar to the zip() function in Python. See {@link + * http://docs.python.org/library/functions.html#zip} + * + * @param {...!IArrayLike<?>} var_args Arrays to be combined. + * @return {!Array<!Array<?>>} A new array of arrays created from + * provided arrays. + */ +goog.array.zip = function(var_args) { + if (!arguments.length) { + return []; + } + var result = []; + var minLen = arguments[0].length; + for (var i = 1; i < arguments.length; i++) { + if (arguments[i].length < minLen) { + minLen = arguments[i].length; + } + } + for (var i = 0; i < minLen; i++) { + var value = []; + for (var j = 0; j < arguments.length; j++) { + value.push(arguments[j][i]); + } + result.push(value); + } + return result; +}; + + +/** + * Shuffles the values in the specified array using the Fisher-Yates in-place + * shuffle (also known as the Knuth Shuffle). By default, calls Math.random() + * and so resets the state of that random number generator. Similarly, may reset + * the state of the any other specified random number generator. + * + * Runtime: O(n) + * + * @param {!Array<?>} arr The array to be shuffled. + * @param {function():number=} opt_randFn Optional random function to use for + * shuffling. + * Takes no arguments, and returns a random number on the interval [0, 1). + * Defaults to Math.random() using JavaScript's built-in Math library. + */ +goog.array.shuffle = function(arr, opt_randFn) { + var randFn = opt_randFn || Math.random; + + for (var i = arr.length - 1; i > 0; i--) { + // Choose a random array index in [0, i] (inclusive with i). + var j = Math.floor(randFn() * (i + 1)); + + var tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + } +}; + + +/** + * Returns a new array of elements from arr, based on the indexes of elements + * provided by index_arr. For example, the result of index copying + * ['a', 'b', 'c'] with index_arr [1,0,0,2] is ['b', 'a', 'a', 'c']. + * + * @param {!Array<T>} arr The array to get a indexed copy from. + * @param {!Array<number>} index_arr An array of indexes to get from arr. + * @return {!Array<T>} A new array of elements from arr in index_arr order. + * @template T + */ +goog.array.copyByIndex = function(arr, index_arr) { + var result = []; + goog.array.forEach(index_arr, function(index) { result.push(arr[index]); }); + return result; +}; + +// Copyright 2006 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Additional mathematical functions. + */ + +goog.provide('goog.math'); + +goog.require('goog.array'); +goog.require('goog.asserts'); + + +/** + * Returns a random integer greater than or equal to 0 and less than {@code a}. + * @param {number} a The upper bound for the random integer (exclusive). + * @return {number} A random integer N such that 0 <= N < a. + */ +goog.math.randomInt = function(a) { + return Math.floor(Math.random() * a); +}; + + +/** + * Returns a random number greater than or equal to {@code a} and less than + * {@code b}. + * @param {number} a The lower bound for the random number (inclusive). + * @param {number} b The upper bound for the random number (exclusive). + * @return {number} A random number N such that a <= N < b. + */ +goog.math.uniformRandom = function(a, b) { + return a + Math.random() * (b - a); +}; + + +/** + * Takes a number and clamps it to within the provided bounds. + * @param {number} value The input number. + * @param {number} min The minimum value to return. + * @param {number} max The maximum value to return. + * @return {number} The input number if it is within bounds, or the nearest + * number within the bounds. + */ +goog.math.clamp = function(value, min, max) { + return Math.min(Math.max(value, min), max); +}; + + +/** + * The % operator in JavaScript returns the remainder of a / b, but differs from + * some other languages in that the result will have the same sign as the + * dividend. For example, -1 % 8 == -1, whereas in some other languages + * (such as Python) the result would be 7. This function emulates the more + * correct modulo behavior, which is useful for certain applications such as + * calculating an offset index in a circular list. + * + * @param {number} a The dividend. + * @param {number} b The divisor. + * @return {number} a % b where the result is between 0 and b (either 0 <= x < b + * or b < x <= 0, depending on the sign of b). + */ +goog.math.modulo = function(a, b) { + var r = a % b; + // If r and b differ in sign, add b to wrap the result to the correct sign. + return (r * b < 0) ? r + b : r; +}; + + +/** + * Performs linear interpolation between values a and b. Returns the value + * between a and b proportional to x (when x is between 0 and 1. When x is + * outside this range, the return value is a linear extrapolation). + * @param {number} a A number. + * @param {number} b A number. + * @param {number} x The proportion between a and b. + * @return {number} The interpolated value between a and b. + */ +goog.math.lerp = function(a, b, x) { + return a + x * (b - a); +}; + + +/** + * Tests whether the two values are equal to each other, within a certain + * tolerance to adjust for floating point errors. + * @param {number} a A number. + * @param {number} b A number. + * @param {number=} opt_tolerance Optional tolerance range. Defaults + * to 0.000001. If specified, should be greater than 0. + * @return {boolean} Whether {@code a} and {@code b} are nearly equal. + */ +goog.math.nearlyEquals = function(a, b, opt_tolerance) { + return Math.abs(a - b) <= (opt_tolerance || 0.000001); +}; + + +// TODO(user): Rename to normalizeAngle, retaining old name as deprecated +// alias. +/** + * Normalizes an angle to be in range [0-360). Angles outside this range will + * be normalized to be the equivalent angle with that range. + * @param {number} angle Angle in degrees. + * @return {number} Standardized angle. + */ +goog.math.standardAngle = function(angle) { + return goog.math.modulo(angle, 360); +}; + + +/** + * Normalizes an angle to be in range [0-2*PI). Angles outside this range will + * be normalized to be the equivalent angle with that range. + * @param {number} angle Angle in radians. + * @return {number} Standardized angle. + */ +goog.math.standardAngleInRadians = function(angle) { + return goog.math.modulo(angle, 2 * Math.PI); +}; + + +/** + * Converts degrees to radians. + * @param {number} angleDegrees Angle in degrees. + * @return {number} Angle in radians. + */ +goog.math.toRadians = function(angleDegrees) { + return angleDegrees * Math.PI / 180; +}; + + +/** + * Converts radians to degrees. + * @param {number} angleRadians Angle in radians. + * @return {number} Angle in degrees. + */ +goog.math.toDegrees = function(angleRadians) { + return angleRadians * 180 / Math.PI; +}; + + +/** + * For a given angle and radius, finds the X portion of the offset. + * @param {number} degrees Angle in degrees (zero points in +X direction). + * @param {number} radius Radius. + * @return {number} The x-distance for the angle and radius. + */ +goog.math.angleDx = function(degrees, radius) { + return radius * Math.cos(goog.math.toRadians(degrees)); +}; + + +/** + * For a given angle and radius, finds the Y portion of the offset. + * @param {number} degrees Angle in degrees (zero points in +X direction). + * @param {number} radius Radius. + * @return {number} The y-distance for the angle and radius. + */ +goog.math.angleDy = function(degrees, radius) { + return radius * Math.sin(goog.math.toRadians(degrees)); +}; + + +/** + * Computes the angle between two points (x1,y1) and (x2,y2). + * Angle zero points in the +X direction, 90 degrees points in the +Y + * direction (down) and from there we grow clockwise towards 360 degrees. + * @param {number} x1 x of first point. + * @param {number} y1 y of first point. + * @param {number} x2 x of second point. + * @param {number} y2 y of second point. + * @return {number} Standardized angle in degrees of the vector from + * x1,y1 to x2,y2. + */ +goog.math.angle = function(x1, y1, x2, y2) { + return goog.math.standardAngle( + goog.math.toDegrees(Math.atan2(y2 - y1, x2 - x1))); +}; + + +/** + * Computes the difference between startAngle and endAngle (angles in degrees). + * @param {number} startAngle Start angle in degrees. + * @param {number} endAngle End angle in degrees. + * @return {number} The number of degrees that when added to + * startAngle will result in endAngle. Positive numbers mean that the + * direction is clockwise. Negative numbers indicate a counter-clockwise + * direction. + * The shortest route (clockwise vs counter-clockwise) between the angles + * is used. + * When the difference is 180 degrees, the function returns 180 (not -180) + * angleDifference(30, 40) is 10, and angleDifference(40, 30) is -10. + * angleDifference(350, 10) is 20, and angleDifference(10, 350) is -20. + */ +goog.math.angleDifference = function(startAngle, endAngle) { + var d = + goog.math.standardAngle(endAngle) - goog.math.standardAngle(startAngle); + if (d > 180) { + d = d - 360; + } else if (d <= -180) { + d = 360 + d; + } + return d; +}; + + +/** + * Returns the sign of a number as per the "sign" or "signum" function. + * @param {number} x The number to take the sign of. + * @return {number} -1 when negative, 1 when positive, 0 when 0. Preserves + * signed zeros and NaN. + */ +goog.math.sign = Math.sign || function(x) { + if (x > 0) { + return 1; + } + if (x < 0) { + return -1; + } + return x; // Preserves signed zeros and NaN. +}; + + +/** + * JavaScript implementation of Longest Common Subsequence problem. + * http://en.wikipedia.org/wiki/Longest_common_subsequence + * + * Returns the longest possible array that is subarray of both of given arrays. + * + * @param {IArrayLike<S>} array1 First array of objects. + * @param {IArrayLike<T>} array2 Second array of objects. + * @param {Function=} opt_compareFn Function that acts as a custom comparator + * for the array ojects. Function should return true if objects are equal, + * otherwise false. + * @param {Function=} opt_collectorFn Function used to decide what to return + * as a result subsequence. It accepts 2 arguments: index of common element + * in the first array and index in the second. The default function returns + * element from the first array. + * @return {!Array<S|T>} A list of objects that are common to both arrays + * such that there is no common subsequence with size greater than the + * length of the list. + * @template S,T + */ +goog.math.longestCommonSubsequence = function( + array1, array2, opt_compareFn, opt_collectorFn) { + + var compare = opt_compareFn || function(a, b) { return a == b; }; + + var collect = opt_collectorFn || function(i1, i2) { return array1[i1]; }; + + var length1 = array1.length; + var length2 = array2.length; + + var arr = []; + for (var i = 0; i < length1 + 1; i++) { + arr[i] = []; + arr[i][0] = 0; + } + + for (var j = 0; j < length2 + 1; j++) { + arr[0][j] = 0; + } + + for (i = 1; i <= length1; i++) { + for (j = 1; j <= length2; j++) { + if (compare(array1[i - 1], array2[j - 1])) { + arr[i][j] = arr[i - 1][j - 1] + 1; + } else { + arr[i][j] = Math.max(arr[i - 1][j], arr[i][j - 1]); + } + } + } + + // Backtracking + var result = []; + var i = length1, j = length2; + while (i > 0 && j > 0) { + if (compare(array1[i - 1], array2[j - 1])) { + result.unshift(collect(i - 1, j - 1)); + i--; + j--; + } else { + if (arr[i - 1][j] > arr[i][j - 1]) { + i--; + } else { + j--; + } + } + } + + return result; +}; + + +/** + * Returns the sum of the arguments. + * @param {...number} var_args Numbers to add. + * @return {number} The sum of the arguments (0 if no arguments were provided, + * {@code NaN} if any of the arguments is not a valid number). + */ +goog.math.sum = function(var_args) { + return /** @type {number} */ ( + goog.array.reduce( + arguments, function(sum, value) { return sum + value; }, 0)); +}; + + +/** + * Returns the arithmetic mean of the arguments. + * @param {...number} var_args Numbers to average. + * @return {number} The average of the arguments ({@code NaN} if no arguments + * were provided or any of the arguments is not a valid number). + */ +goog.math.average = function(var_args) { + return goog.math.sum.apply(null, arguments) / arguments.length; +}; + + +/** + * Returns the unbiased sample variance of the arguments. For a definition, + * see e.g. http://en.wikipedia.org/wiki/Variance + * @param {...number} var_args Number samples to analyze. + * @return {number} The unbiased sample variance of the arguments (0 if fewer + * than two samples were provided, or {@code NaN} if any of the samples is + * not a valid number). + */ +goog.math.sampleVariance = function(var_args) { + var sampleSize = arguments.length; + if (sampleSize < 2) { + return 0; + } + + var mean = goog.math.average.apply(null, arguments); + var variance = + goog.math.sum.apply(null, goog.array.map(arguments, function(val) { + return Math.pow(val - mean, 2); + })) / (sampleSize - 1); + + return variance; +}; + + +/** + * Returns the sample standard deviation of the arguments. For a definition of + * sample standard deviation, see e.g. + * http://en.wikipedia.org/wiki/Standard_deviation + * @param {...number} var_args Number samples to analyze. + * @return {number} The sample standard deviation of the arguments (0 if fewer + * than two samples were provided, or {@code NaN} if any of the samples is + * not a valid number). + */ +goog.math.standardDeviation = function(var_args) { + return Math.sqrt(goog.math.sampleVariance.apply(null, arguments)); +}; + + +/** + * Returns whether the supplied number represents an integer, i.e. that is has + * no fractional component. No range-checking is performed on the number. + * @param {number} num The number to test. + * @return {boolean} Whether {@code num} is an integer. + */ +goog.math.isInt = function(num) { + return isFinite(num) && num % 1 == 0; +}; + + +/** + * Returns whether the supplied number is finite and not NaN. + * @param {number} num The number to test. + * @return {boolean} Whether {@code num} is a finite number. + */ +goog.math.isFiniteNumber = function(num) { + return isFinite(num) && !isNaN(num); +}; + + +/** + * @param {number} num The number to test. + * @return {boolean} Whether it is negative zero. + */ +goog.math.isNegativeZero = function(num) { + return num == 0 && 1 / num < 0; +}; + + +/** + * Returns the precise value of floor(log10(num)). + * Simpler implementations didn't work because of floating point rounding + * errors. For example + * <ul> + * <li>Math.floor(Math.log(num) / Math.LN10) is off by one for num == 1e+3. + * <li>Math.floor(Math.log(num) * Math.LOG10E) is off by one for num == 1e+15. + * <li>Math.floor(Math.log10(num)) is off by one for num == 1e+15 - 1. + * </ul> + * @param {number} num A floating point number. + * @return {number} Its logarithm to base 10 rounded down to the nearest + * integer if num > 0. -Infinity if num == 0. NaN if num < 0. + */ +goog.math.log10Floor = function(num) { + if (num > 0) { + var x = Math.round(Math.log(num) * Math.LOG10E); + return x - (parseFloat('1e' + x) > num ? 1 : 0); + } + return num == 0 ? -Infinity : NaN; +}; + + +/** + * A tweaked variant of {@code Math.floor} which tolerates if the passed number + * is infinitesimally smaller than the closest integer. It often happens with + * the results of floating point calculations because of the finite precision + * of the intermediate results. For example {@code Math.floor(Math.log(1000) / + * Math.LN10) == 2}, not 3 as one would expect. + * @param {number} num A number. + * @param {number=} opt_epsilon An infinitesimally small positive number, the + * rounding error to tolerate. + * @return {number} The largest integer less than or equal to {@code num}. + */ +goog.math.safeFloor = function(num, opt_epsilon) { + goog.asserts.assert(!goog.isDef(opt_epsilon) || opt_epsilon > 0); + return Math.floor(num + (opt_epsilon || 2e-15)); +}; + + +/** + * A tweaked variant of {@code Math.ceil}. See {@code goog.math.safeFloor} for + * details. + * @param {number} num A number. + * @param {number=} opt_epsilon An infinitesimally small positive number, the + * rounding error to tolerate. + * @return {number} The smallest integer greater than or equal to {@code num}. + */ +goog.math.safeCeil = function(num, opt_epsilon) { + goog.asserts.assert(!goog.isDef(opt_epsilon) || opt_epsilon > 0); + return Math.ceil(num - (opt_epsilon || 2e-15)); +}; + +// Copyright 2006 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** * @fileoverview Utilities related to color and color conversion. */ @@ -24439,9 +19639,10 @@ goog.color.parse = function(str) { */ goog.color.isValidColor = function(str) { var maybeHex = goog.color.prependHashIfNecessaryHelper(str); - return !!(goog.color.isValidHexColor_(maybeHex) || - goog.color.isValidRgbColor_(str).length || - goog.color.names && goog.color.names[str.toLowerCase()]); + return !!( + goog.color.isValidHexColor_(maybeHex) || + goog.color.isValidRgbColor_(str).length || + goog.color.names && goog.color.names[str.toLowerCase()]); }; @@ -24490,7 +19691,7 @@ goog.color.normalizeHex = function(hexColor) { if (!goog.color.isValidHexColor_(hexColor)) { throw Error("'" + hexColor + "' is not a valid hex color"); } - if (hexColor.length == 4) { // of the form #RGB + if (hexColor.length == 4) { // of the form #RGB hexColor = hexColor.replace(goog.color.hexTripletRe_, '#$1$1$2$2$3$3'); } return hexColor.toLowerCase(); @@ -24523,9 +19724,7 @@ goog.color.rgbToHex = function(r, g, b) { r = Number(r); g = Number(g); b = Number(b); - if (isNaN(r) || r < 0 || r > 255 || - isNaN(g) || g < 0 || g > 255 || - isNaN(b) || b < 0 || b > 255) { + if (r != (r & 255) || g != (g & 255) || b != (b & 255)) { throw Error('"(' + r + ',' + g + ',' + b + '") is not a valid RGB color'); } var hexR = goog.color.prependZeroIfNecessaryHelper(r.toString(16)); @@ -24636,7 +19835,7 @@ goog.color.hslToRgb = function(h, s, l) { var r = 0; var g = 0; var b = 0; - var normH = h / 360; // normalize h to fall in [0, 1] + var normH = h / 360; // normalize h to fall in [0, 1] if (s == 0) { r = g = b = l * 255; @@ -24737,9 +19936,7 @@ goog.color.isValidRgbColor_ = function(str) { var r = Number(regExpResultArray[1]); var g = Number(regExpResultArray[2]); var b = Number(regExpResultArray[3]); - if (r >= 0 && r <= 255 && - g >= 0 && g <= 255 && - b >= 0 && b <= 255) { + if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255) { return [r, g, b]; } } @@ -24998,8 +20195,8 @@ goog.color.hslDistance = function(hsl1, hsl2) { var h1 = hsl1[0] / 360.0; var h2 = hsl2[0] / 360.0; var dh = (h1 - h2) * 2.0 * Math.PI; - return (hsl1[2] - hsl2[2]) * (hsl1[2] - hsl2[2]) + - sl1 * sl1 + sl2 * sl2 - 2 * sl1 * sl2 * Math.cos(dh); + return (hsl1[2] - hsl2[2]) * (hsl1[2] - hsl2[2]) + sl1 * sl1 + sl2 * sl2 - + 2 * sl1 * sl2 * Math.cos(dh); }; @@ -25070,9 +20267,7 @@ goog.color.highContrast = function(prime, suggestions) { goog.color.colorDiff_(suggestions[i], prime) }); } - suggestionsWithDiff.sort(function(a, b) { - return b.diff - a.diff; - }); + suggestionsWithDiff.sort(function(a, b) { return b.diff - a.diff; }); return suggestionsWithDiff[0].color; }; @@ -25099,8 +20294,8 @@ goog.color.yiqBrightness_ = function(rgb) { * @private */ goog.color.yiqBrightnessDiff_ = function(rgb1, rgb2) { - return Math.abs(goog.color.yiqBrightness_(rgb1) - - goog.color.yiqBrightness_(rgb2)); + return Math.abs( + goog.color.yiqBrightness_(rgb1) - goog.color.yiqBrightness_(rgb2)); }; @@ -25122,28 +20317,16 @@ goog.color.colorDiff_ = function(rgb1, rgb2) { // causes occasional loss of precision and rounding errors, especially in the // alpha channel. -goog.provide('ol.Color'); goog.provide('ol.color'); goog.require('goog.asserts'); goog.require('goog.color'); goog.require('goog.color.names'); -goog.require('goog.vec.Mat4'); goog.require('ol'); goog.require('ol.math'); /** - * A color represented as a short array [red, green, blue, alpha]. - * red, green, and blue should be integers in the range 0..255 inclusive. - * alpha should be a float in the range 0..1 inclusive. - * @typedef {Array.<number>} - * @api - */ -ol.Color; - - -/** * This RegExp matches # followed by 3 or 6 hex digits. * @const * @type {RegExp} @@ -25173,48 +20356,6 @@ ol.color.rgbaColorRe_ = /** - * @param {ol.Color} dst Destination. - * @param {ol.Color} src Source. - * @param {ol.Color=} opt_color Color. - * @return {ol.Color} Color. - */ -ol.color.blend = function(dst, src, opt_color) { - // http://en.wikipedia.org/wiki/Alpha_compositing - // FIXME do we need to scale by 255? - var out = opt_color ? opt_color : []; - var dstA = dst[3]; - var srcA = src[3]; - if (dstA == 1) { - out[0] = (src[0] * srcA + dst[0] * (1 - srcA) + 0.5) | 0; - out[1] = (src[1] * srcA + dst[1] * (1 - srcA) + 0.5) | 0; - out[2] = (src[2] * srcA + dst[2] * (1 - srcA) + 0.5) | 0; - out[3] = 1; - } else if (srcA === 0) { - out[0] = dst[0]; - out[1] = dst[1]; - out[2] = dst[2]; - out[3] = dstA; - } else { - var outA = srcA + dstA * (1 - srcA); - if (outA === 0) { - out[0] = 0; - out[1] = 0; - out[2] = 0; - out[3] = 0; - } else { - out[0] = ((src[0] * srcA + dst[0] * dstA * (1 - srcA)) / outA + 0.5) | 0; - out[1] = ((src[1] * srcA + dst[1] * dstA * (1 - srcA)) / outA + 0.5) | 0; - out[2] = ((src[2] * srcA + dst[2] * dstA * (1 - srcA)) / outA + 0.5) | 0; - out[3] = outA; - } - } - goog.asserts.assert(ol.color.isValid(out), - 'Output color of blend should be a valid color'); - return out; -}; - - -/** * Return the color as an array. This function maintains a cache of calculated * arrays which means the result should not be modified. * @param {ol.Color|string} color Color. @@ -25222,10 +20363,10 @@ ol.color.blend = function(dst, src, opt_color) { * @api */ ol.color.asArray = function(color) { - if (goog.isArray(color)) { + if (Array.isArray(color)) { return color; } else { - goog.asserts.assert(goog.isString(color), 'Color should be a string'); + goog.asserts.assert(typeof color === 'string', 'Color should be a string'); return ol.color.fromString(color); } }; @@ -25238,35 +20379,20 @@ ol.color.asArray = function(color) { * @api */ ol.color.asString = function(color) { - if (goog.isString(color)) { + if (typeof color === 'string') { return color; } else { - goog.asserts.assert(goog.isArray(color), 'Color should be an array'); + goog.asserts.assert(Array.isArray(color), 'Color should be an array'); return ol.color.toString(color); } }; /** - * @param {ol.Color} color1 Color1. - * @param {ol.Color} color2 Color2. - * @return {boolean} Equals. - */ -ol.color.equals = function(color1, color2) { - return color1 === color2 || ( - color1[0] == color2[0] && color1[1] == color2[1] && - color1[2] == color2[2] && color1[3] == color2[3]); -}; - - -/** * @param {string} s String. * @return {ol.Color} Color. */ ol.color.fromString = ( - /** - * @return {function(string): ol.Color} - */ function() { // We maintain a small cache of parsed strings. To provide cheap LRU-like @@ -25415,44 +20541,2082 @@ ol.color.toString = function(color) { if (b != (b | 0)) { b = (b + 0.5) | 0; } - var a = color[3]; + var a = color[3] === undefined ? 1 : color[3]; return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')'; }; +goog.provide('ol.colorlike'); + +goog.require('ol.color'); + /** - * @param {!ol.Color} color Color. - * @param {goog.vec.Mat4.Number} transform Transform. - * @param {!ol.Color=} opt_color Color. - * @return {ol.Color} Transformed color. + * @param {ol.Color|ol.ColorLike} color Color. + * @return {ol.ColorLike} The color as an ol.ColorLike + * @api */ -ol.color.transform = function(color, transform, opt_color) { - var result = opt_color ? opt_color : []; - result = goog.vec.Mat4.multVec3(transform, color, result); - goog.asserts.assert(goog.isArray(result), 'result should be an array'); - result[3] = color[3]; - return ol.color.normalize(result, result); +ol.colorlike.asColorLike = function(color) { + if (ol.colorlike.isColorLike(color)) { + return /** @type {string|CanvasPattern|CanvasGradient} */ (color); + } else { + return ol.color.asString(/** @type {ol.Color} */ (color)); + } }; /** - * @param {ol.Color|string} color1 Color2. - * @param {ol.Color|string} color2 Color2. - * @return {boolean} Equals. + * @param {?} color The value that is potentially an ol.ColorLike + * @return {boolean} Whether the color is an ol.ColorLike */ -ol.color.stringOrColorEquals = function(color1, color2) { - if (color1 === color2 || color1 == color2) { - return true; +ol.colorlike.isColorLike = function(color) { + return ( + typeof color === 'string' || + color instanceof CanvasPattern || + color instanceof CanvasGradient + ); +}; + +// Copyright 2013 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Utilities used by goog.labs.userAgent tools. These functions + * should not be used outside of goog.labs.userAgent.*. + * + * + * @author nnaze@google.com (Nathan Naze) + */ + +goog.provide('goog.labs.userAgent.util'); + +goog.require('goog.string'); + + +/** + * Gets the native userAgent string from navigator if it exists. + * If navigator or navigator.userAgent string is missing, returns an empty + * string. + * @return {string} + * @private + */ +goog.labs.userAgent.util.getNativeUserAgentString_ = function() { + var navigator = goog.labs.userAgent.util.getNavigator_(); + if (navigator) { + var userAgent = navigator.userAgent; + if (userAgent) { + return userAgent; + } + } + return ''; +}; + + +/** + * Getter for the native navigator. + * This is a separate function so it can be stubbed out in testing. + * @return {Navigator} + * @private + */ +goog.labs.userAgent.util.getNavigator_ = function() { + return goog.global.navigator; +}; + + +/** + * A possible override for applications which wish to not check + * navigator.userAgent but use a specified value for detection instead. + * @private {string} + */ +goog.labs.userAgent.util.userAgent_ = + goog.labs.userAgent.util.getNativeUserAgentString_(); + + +/** + * Applications may override browser detection on the built in + * navigator.userAgent object by setting this string. Set to null to use the + * browser object instead. + * @param {?string=} opt_userAgent The User-Agent override. + */ +goog.labs.userAgent.util.setUserAgent = function(opt_userAgent) { + goog.labs.userAgent.util.userAgent_ = + opt_userAgent || goog.labs.userAgent.util.getNativeUserAgentString_(); +}; + + +/** + * @return {string} The user agent string. + */ +goog.labs.userAgent.util.getUserAgent = function() { + return goog.labs.userAgent.util.userAgent_; +}; + + +/** + * @param {string} str + * @return {boolean} Whether the user agent contains the given string, ignoring + * case. + */ +goog.labs.userAgent.util.matchUserAgent = function(str) { + var userAgent = goog.labs.userAgent.util.getUserAgent(); + return goog.string.contains(userAgent, str); +}; + + +/** + * @param {string} str + * @return {boolean} Whether the user agent contains the given string. + */ +goog.labs.userAgent.util.matchUserAgentIgnoreCase = function(str) { + var userAgent = goog.labs.userAgent.util.getUserAgent(); + return goog.string.caseInsensitiveContains(userAgent, str); +}; + + +/** + * Parses the user agent into tuples for each section. + * @param {string} userAgent + * @return {!Array<!Array<string>>} Tuples of key, version, and the contents + * of the parenthetical. + */ +goog.labs.userAgent.util.extractVersionTuples = function(userAgent) { + // Matches each section of a user agent string. + // Example UA: + // Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us) + // AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405 + // This has three version tuples: Mozilla, AppleWebKit, and Mobile. + + var versionRegExp = new RegExp( + // Key. Note that a key may have a space. + // (i.e. 'Mobile Safari' in 'Mobile Safari/5.0') + '(\\w[\\w ]+)' + + + '/' + // slash + '([^\\s]+)' + // version (i.e. '5.0b') + '\\s*' + // whitespace + '(?:\\((.*?)\\))?', // parenthetical info. parentheses not matched. + 'g'); + + var data = []; + var match; + + // Iterate and collect the version tuples. Each iteration will be the + // next regex match. + while (match = versionRegExp.exec(userAgent)) { + data.push([ + match[1], // key + match[2], // value + // || undefined as this is not undefined in IE7 and IE8 + match[3] || undefined // info + ]); + } + + return data; +}; + +// Copyright 2006 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Utilities for manipulating objects/maps/hashes. + * @author arv@google.com (Erik Arvidsson) + */ + +goog.provide('goog.object'); + + +/** + * Calls a function for each element in an object/map/hash. + * + * @param {Object<K,V>} obj The object over which to iterate. + * @param {function(this:T,V,?,Object<K,V>):?} f The function to call + * for every element. This function takes 3 arguments (the value, the + * key and the object) and the return value is ignored. + * @param {T=} opt_obj This is used as the 'this' object within f. + * @template T,K,V + */ +goog.object.forEach = function(obj, f, opt_obj) { + for (var key in obj) { + f.call(/** @type {?} */ (opt_obj), obj[key], key, obj); + } +}; + + +/** + * Calls a function for each element in an object/map/hash. If that call returns + * true, adds the element to a new object. + * + * @param {Object<K,V>} obj The object over which to iterate. + * @param {function(this:T,V,?,Object<K,V>):boolean} f The function to call + * for every element. This + * function takes 3 arguments (the value, the key and the object) + * and should return a boolean. If the return value is true the + * element is added to the result object. If it is false the + * element is not included. + * @param {T=} opt_obj This is used as the 'this' object within f. + * @return {!Object<K,V>} a new object in which only elements that passed the + * test are present. + * @template T,K,V + */ +goog.object.filter = function(obj, f, opt_obj) { + var res = {}; + for (var key in obj) { + if (f.call(/** @type {?} */ (opt_obj), obj[key], key, obj)) { + res[key] = obj[key]; + } + } + return res; +}; + + +/** + * For every element in an object/map/hash calls a function and inserts the + * result into a new object. + * + * @param {Object<K,V>} obj The object over which to iterate. + * @param {function(this:T,V,?,Object<K,V>):R} f The function to call + * for every element. This function + * takes 3 arguments (the value, the key and the object) + * and should return something. The result will be inserted + * into a new object. + * @param {T=} opt_obj This is used as the 'this' object within f. + * @return {!Object<K,R>} a new object with the results from f. + * @template T,K,V,R + */ +goog.object.map = function(obj, f, opt_obj) { + var res = {}; + for (var key in obj) { + res[key] = f.call(/** @type {?} */ (opt_obj), obj[key], key, obj); + } + return res; +}; + + +/** + * Calls a function for each element in an object/map/hash. If any + * call returns true, returns true (without checking the rest). If + * all calls return false, returns false. + * + * @param {Object<K,V>} obj The object to check. + * @param {function(this:T,V,?,Object<K,V>):boolean} f The function to + * call for every element. This function + * takes 3 arguments (the value, the key and the object) and should + * return a boolean. + * @param {T=} opt_obj This is used as the 'this' object within f. + * @return {boolean} true if any element passes the test. + * @template T,K,V + */ +goog.object.some = function(obj, f, opt_obj) { + for (var key in obj) { + if (f.call(/** @type {?} */ (opt_obj), obj[key], key, obj)) { + return true; + } + } + return false; +}; + + +/** + * Calls a function for each element in an object/map/hash. If + * all calls return true, returns true. If any call returns false, returns + * false at this point and does not continue to check the remaining elements. + * + * @param {Object<K,V>} obj The object to check. + * @param {?function(this:T,V,?,Object<K,V>):boolean} f The function to + * call for every element. This function + * takes 3 arguments (the value, the key and the object) and should + * return a boolean. + * @param {T=} opt_obj This is used as the 'this' object within f. + * @return {boolean} false if any element fails the test. + * @template T,K,V + */ +goog.object.every = function(obj, f, opt_obj) { + for (var key in obj) { + if (!f.call(/** @type {?} */ (opt_obj), obj[key], key, obj)) { + return false; + } + } + return true; +}; + + +/** + * Returns the number of key-value pairs in the object map. + * + * @param {Object} obj The object for which to get the number of key-value + * pairs. + * @return {number} The number of key-value pairs in the object map. + */ +goog.object.getCount = function(obj) { + // JS1.5 has __count__ but it has been deprecated so it raises a warning... + // in other words do not use. Also __count__ only includes the fields on the + // actual object and not in the prototype chain. + var rv = 0; + for (var key in obj) { + rv++; } - if (goog.isString(color1)) { - color1 = ol.color.fromString(color1); + return rv; +}; + + +/** + * Returns one key from the object map, if any exists. + * For map literals the returned key will be the first one in most of the + * browsers (a know exception is Konqueror). + * + * @param {Object} obj The object to pick a key from. + * @return {string|undefined} The key or undefined if the object is empty. + */ +goog.object.getAnyKey = function(obj) { + for (var key in obj) { + return key; } - if (goog.isString(color2)) { - color2 = ol.color.fromString(color2); +}; + + +/** + * Returns one value from the object map, if any exists. + * For map literals the returned value will be the first one in most of the + * browsers (a know exception is Konqueror). + * + * @param {Object<K,V>} obj The object to pick a value from. + * @return {V|undefined} The value or undefined if the object is empty. + * @template K,V + */ +goog.object.getAnyValue = function(obj) { + for (var key in obj) { + return obj[key]; } - return ol.color.equals(color1, color2); }; + +/** + * Whether the object/hash/map contains the given object as a value. + * An alias for goog.object.containsValue(obj, val). + * + * @param {Object<K,V>} obj The object in which to look for val. + * @param {V} val The object for which to check. + * @return {boolean} true if val is present. + * @template K,V + */ +goog.object.contains = function(obj, val) { + return goog.object.containsValue(obj, val); +}; + + +/** + * Returns the values of the object/map/hash. + * + * @param {Object<K,V>} obj The object from which to get the values. + * @return {!Array<V>} The values in the object/map/hash. + * @template K,V + */ +goog.object.getValues = function(obj) { + var res = []; + var i = 0; + for (var key in obj) { + res[i++] = obj[key]; + } + return res; +}; + + +/** + * Returns the keys of the object/map/hash. + * + * @param {Object} obj The object from which to get the keys. + * @return {!Array<string>} Array of property keys. + */ +goog.object.getKeys = function(obj) { + var res = []; + var i = 0; + for (var key in obj) { + res[i++] = key; + } + return res; +}; + + +/** + * Get a value from an object multiple levels deep. This is useful for + * pulling values from deeply nested objects, such as JSON responses. + * Example usage: getValueByKeys(jsonObj, 'foo', 'entries', 3) + * + * @param {!Object} obj An object to get the value from. Can be array-like. + * @param {...(string|number|!IArrayLike<number|string>)} + * var_args A number of keys + * (as strings, or numbers, for array-like objects). Can also be + * specified as a single array of keys. + * @return {*} The resulting value. If, at any point, the value for a key + * is undefined, returns undefined. + */ +goog.object.getValueByKeys = function(obj, var_args) { + var isArrayLike = goog.isArrayLike(var_args); + var keys = isArrayLike ? var_args : arguments; + + // Start with the 2nd parameter for the variable parameters syntax. + for (var i = isArrayLike ? 0 : 1; i < keys.length; i++) { + obj = obj[keys[i]]; + if (!goog.isDef(obj)) { + break; + } + } + + return obj; +}; + + +/** + * Whether the object/map/hash contains the given key. + * + * @param {Object} obj The object in which to look for key. + * @param {?} key The key for which to check. + * @return {boolean} true If the map contains the key. + */ +goog.object.containsKey = function(obj, key) { + return obj !== null && key in obj; +}; + + +/** + * Whether the object/map/hash contains the given value. This is O(n). + * + * @param {Object<K,V>} obj The object in which to look for val. + * @param {V} val The value for which to check. + * @return {boolean} true If the map contains the value. + * @template K,V + */ +goog.object.containsValue = function(obj, val) { + for (var key in obj) { + if (obj[key] == val) { + return true; + } + } + return false; +}; + + +/** + * Searches an object for an element that satisfies the given condition and + * returns its key. + * @param {Object<K,V>} obj The object to search in. + * @param {function(this:T,V,string,Object<K,V>):boolean} f The + * function to call for every element. Takes 3 arguments (the value, + * the key and the object) and should return a boolean. + * @param {T=} opt_this An optional "this" context for the function. + * @return {string|undefined} The key of an element for which the function + * returns true or undefined if no such element is found. + * @template T,K,V + */ +goog.object.findKey = function(obj, f, opt_this) { + for (var key in obj) { + if (f.call(/** @type {?} */ (opt_this), obj[key], key, obj)) { + return key; + } + } + return undefined; +}; + + +/** + * Searches an object for an element that satisfies the given condition and + * returns its value. + * @param {Object<K,V>} obj The object to search in. + * @param {function(this:T,V,string,Object<K,V>):boolean} f The function + * to call for every element. Takes 3 arguments (the value, the key + * and the object) and should return a boolean. + * @param {T=} opt_this An optional "this" context for the function. + * @return {V} The value of an element for which the function returns true or + * undefined if no such element is found. + * @template T,K,V + */ +goog.object.findValue = function(obj, f, opt_this) { + var key = goog.object.findKey(obj, f, opt_this); + return key && obj[key]; +}; + + +/** + * Whether the object/map/hash is empty. + * + * @param {Object} obj The object to test. + * @return {boolean} true if obj is empty. + */ +goog.object.isEmpty = function(obj) { + for (var key in obj) { + return false; + } + return true; +}; + + +/** + * Removes all key value pairs from the object/map/hash. + * + * @param {Object} obj The object to clear. + */ +goog.object.clear = function(obj) { + for (var i in obj) { + delete obj[i]; + } +}; + + +/** + * Removes a key-value pair based on the key. + * + * @param {Object} obj The object from which to remove the key. + * @param {?} key The key to remove. + * @return {boolean} Whether an element was removed. + */ +goog.object.remove = function(obj, key) { + var rv; + if (rv = key in /** @type {!Object} */ (obj)) { + delete obj[key]; + } + return rv; +}; + + +/** + * Adds a key-value pair to the object. Throws an exception if the key is + * already in use. Use set if you want to change an existing pair. + * + * @param {Object<K,V>} obj The object to which to add the key-value pair. + * @param {string} key The key to add. + * @param {V} val The value to add. + * @template K,V + */ +goog.object.add = function(obj, key, val) { + if (obj !== null && key in obj) { + throw Error('The object already contains the key "' + key + '"'); + } + goog.object.set(obj, key, val); +}; + + +/** + * Returns the value for the given key. + * + * @param {Object<K,V>} obj The object from which to get the value. + * @param {string} key The key for which to get the value. + * @param {R=} opt_val The value to return if no item is found for the given + * key (default is undefined). + * @return {V|R|undefined} The value for the given key. + * @template K,V,R + */ +goog.object.get = function(obj, key, opt_val) { + if (obj !== null && key in obj) { + return obj[key]; + } + return opt_val; +}; + + +/** + * Adds a key-value pair to the object/map/hash. + * + * @param {Object<K,V>} obj The object to which to add the key-value pair. + * @param {string} key The key to add. + * @param {V} value The value to add. + * @template K,V + */ +goog.object.set = function(obj, key, value) { + obj[key] = value; +}; + + +/** + * Adds a key-value pair to the object/map/hash if it doesn't exist yet. + * + * @param {Object<K,V>} obj The object to which to add the key-value pair. + * @param {string} key The key to add. + * @param {V} value The value to add if the key wasn't present. + * @return {V} The value of the entry at the end of the function. + * @template K,V + */ +goog.object.setIfUndefined = function(obj, key, value) { + return key in /** @type {!Object} */ (obj) ? obj[key] : (obj[key] = value); +}; + + +/** + * Sets a key and value to an object if the key is not set. The value will be + * the return value of the given function. If the key already exists, the + * object will not be changed and the function will not be called (the function + * will be lazily evaluated -- only called if necessary). + * + * This function is particularly useful for use with a map used a as a cache. + * + * @param {!Object<K,V>} obj The object to which to add the key-value pair. + * @param {string} key The key to add. + * @param {function():V} f The value to add if the key wasn't present. + * @return {V} The value of the entry at the end of the function. + * @template K,V + */ +goog.object.setWithReturnValueIfNotSet = function(obj, key, f) { + if (key in obj) { + return obj[key]; + } + + var val = f(); + obj[key] = val; + return val; +}; + + +/** + * Compares two objects for equality using === on the values. + * + * @param {!Object<K,V>} a + * @param {!Object<K,V>} b + * @return {boolean} + * @template K,V + */ +goog.object.equals = function(a, b) { + for (var k in a) { + if (!(k in b) || a[k] !== b[k]) { + return false; + } + } + for (var k in b) { + if (!(k in a)) { + return false; + } + } + return true; +}; + + +/** + * Does a flat clone of the object. + * + * @param {Object<K,V>} obj Object to clone. + * @return {!Object<K,V>} Clone of the input object. + * @template K,V + */ +goog.object.clone = function(obj) { + // We cannot use the prototype trick because a lot of methods depend on where + // the actual key is set. + + var res = {}; + for (var key in obj) { + res[key] = obj[key]; + } + return res; + // We could also use goog.mixin but I wanted this to be independent from that. +}; + + +/** + * Clones a value. The input may be an Object, Array, or basic type. Objects and + * arrays will be cloned recursively. + * + * WARNINGS: + * <code>goog.object.unsafeClone</code> does not detect reference loops. Objects + * that refer to themselves will cause infinite recursion. + * + * <code>goog.object.unsafeClone</code> is unaware of unique identifiers, and + * copies UIDs created by <code>getUid</code> into cloned results. + * + * @param {*} obj The value to clone. + * @return {*} A clone of the input value. + */ +goog.object.unsafeClone = function(obj) { + var type = goog.typeOf(obj); + if (type == 'object' || type == 'array') { + if (goog.isFunction(obj.clone)) { + return obj.clone(); + } + var clone = type == 'array' ? [] : {}; + for (var key in obj) { + clone[key] = goog.object.unsafeClone(obj[key]); + } + return clone; + } + + return obj; +}; + + +/** + * Returns a new object in which all the keys and values are interchanged + * (keys become values and values become keys). If multiple keys map to the + * same value, the chosen transposed value is implementation-dependent. + * + * @param {Object} obj The object to transpose. + * @return {!Object} The transposed object. + */ +goog.object.transpose = function(obj) { + var transposed = {}; + for (var key in obj) { + transposed[obj[key]] = key; + } + return transposed; +}; + + +/** + * The names of the fields that are defined on Object.prototype. + * @type {Array<string>} + * @private + */ +goog.object.PROTOTYPE_FIELDS_ = [ + 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', + 'toLocaleString', 'toString', 'valueOf' +]; + + +/** + * Extends an object with another object. + * This operates 'in-place'; it does not create a new Object. + * + * Example: + * var o = {}; + * goog.object.extend(o, {a: 0, b: 1}); + * o; // {a: 0, b: 1} + * goog.object.extend(o, {b: 2, c: 3}); + * o; // {a: 0, b: 2, c: 3} + * + * @param {Object} target The object to modify. Existing properties will be + * overwritten if they are also present in one of the objects in + * {@code var_args}. + * @param {...Object} var_args The objects from which values will be copied. + */ +goog.object.extend = function(target, var_args) { + var key, source; + for (var i = 1; i < arguments.length; i++) { + source = arguments[i]; + for (key in source) { + target[key] = source[key]; + } + + // For IE the for-in-loop does not contain any properties that are not + // enumerable on the prototype object (for example isPrototypeOf from + // Object.prototype) and it will also not include 'replace' on objects that + // extend String and change 'replace' (not that it is common for anyone to + // extend anything except Object). + + for (var j = 0; j < goog.object.PROTOTYPE_FIELDS_.length; j++) { + key = goog.object.PROTOTYPE_FIELDS_[j]; + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } +}; + + +/** + * Creates a new object built from the key-value pairs provided as arguments. + * @param {...*} var_args If only one argument is provided and it is an array + * then this is used as the arguments, otherwise even arguments are used as + * the property names and odd arguments are used as the property values. + * @return {!Object} The new object. + * @throws {Error} If there are uneven number of arguments or there is only one + * non array argument. + */ +goog.object.create = function(var_args) { + var argLength = arguments.length; + if (argLength == 1 && goog.isArray(arguments[0])) { + return goog.object.create.apply(null, arguments[0]); + } + + if (argLength % 2) { + throw Error('Uneven number of arguments'); + } + + var rv = {}; + for (var i = 0; i < argLength; i += 2) { + rv[arguments[i]] = arguments[i + 1]; + } + return rv; +}; + + +/** + * Creates a new object where the property names come from the arguments but + * the value is always set to true + * @param {...*} var_args If only one argument is provided and it is an array + * then this is used as the arguments, otherwise the arguments are used + * as the property names. + * @return {!Object} The new object. + */ +goog.object.createSet = function(var_args) { + var argLength = arguments.length; + if (argLength == 1 && goog.isArray(arguments[0])) { + return goog.object.createSet.apply(null, arguments[0]); + } + + var rv = {}; + for (var i = 0; i < argLength; i++) { + rv[arguments[i]] = true; + } + return rv; +}; + + +/** + * Creates an immutable view of the underlying object, if the browser + * supports immutable objects. + * + * In default mode, writes to this view will fail silently. In strict mode, + * they will throw an error. + * + * @param {!Object<K,V>} obj An object. + * @return {!Object<K,V>} An immutable view of that object, or the + * original object if this browser does not support immutables. + * @template K,V + */ +goog.object.createImmutableView = function(obj) { + var result = obj; + if (Object.isFrozen && !Object.isFrozen(obj)) { + result = Object.create(obj); + Object.freeze(result); + } + return result; +}; + + +/** + * @param {!Object} obj An object. + * @return {boolean} Whether this is an immutable view of the object. + */ +goog.object.isImmutableView = function(obj) { + return !!Object.isFrozen && Object.isFrozen(obj); +}; + +// Copyright 2013 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Closure user agent detection (Browser). + * @see <a href="http://www.useragentstring.com/">User agent strings</a> + * For more information on rendering engine, platform, or device see the other + * sub-namespaces in goog.labs.userAgent, goog.labs.userAgent.platform, + * goog.labs.userAgent.device respectively.) + * + * @author martone@google.com (Andy Martone) + */ + +goog.provide('goog.labs.userAgent.browser'); + +goog.require('goog.array'); +goog.require('goog.labs.userAgent.util'); +goog.require('goog.object'); +goog.require('goog.string'); + + +// TODO(nnaze): Refactor to remove excessive exclusion logic in matching +// functions. + + +/** + * @return {boolean} Whether the user's browser is Opera. + * @private + */ +goog.labs.userAgent.browser.matchOpera_ = function() { + return goog.labs.userAgent.util.matchUserAgent('Opera') || + goog.labs.userAgent.util.matchUserAgent('OPR'); +}; + + +/** + * @return {boolean} Whether the user's browser is IE. + * @private + */ +goog.labs.userAgent.browser.matchIE_ = function() { + return goog.labs.userAgent.util.matchUserAgent('Trident') || + goog.labs.userAgent.util.matchUserAgent('MSIE'); +}; + + +/** + * @return {boolean} Whether the user's browser is Edge. + * @private + */ +goog.labs.userAgent.browser.matchEdge_ = function() { + return goog.labs.userAgent.util.matchUserAgent('Edge'); +}; + + +/** + * @return {boolean} Whether the user's browser is Firefox. + * @private + */ +goog.labs.userAgent.browser.matchFirefox_ = function() { + return goog.labs.userAgent.util.matchUserAgent('Firefox'); +}; + + +/** + * @return {boolean} Whether the user's browser is Safari. + * @private + */ +goog.labs.userAgent.browser.matchSafari_ = function() { + return goog.labs.userAgent.util.matchUserAgent('Safari') && + !(goog.labs.userAgent.browser.matchChrome_() || + goog.labs.userAgent.browser.matchCoast_() || + goog.labs.userAgent.browser.matchOpera_() || + goog.labs.userAgent.browser.matchEdge_() || + goog.labs.userAgent.browser.isSilk() || + goog.labs.userAgent.util.matchUserAgent('Android')); +}; + + +/** + * @return {boolean} Whether the user's browser is Coast (Opera's Webkit-based + * iOS browser). + * @private + */ +goog.labs.userAgent.browser.matchCoast_ = function() { + return goog.labs.userAgent.util.matchUserAgent('Coast'); +}; + + +/** + * @return {boolean} Whether the user's browser is iOS Webview. + * @private + */ +goog.labs.userAgent.browser.matchIosWebview_ = function() { + // iOS Webview does not show up as Chrome or Safari. Also check for Opera's + // WebKit-based iOS browser, Coast. + return (goog.labs.userAgent.util.matchUserAgent('iPad') || + goog.labs.userAgent.util.matchUserAgent('iPhone')) && + !goog.labs.userAgent.browser.matchSafari_() && + !goog.labs.userAgent.browser.matchChrome_() && + !goog.labs.userAgent.browser.matchCoast_() && + goog.labs.userAgent.util.matchUserAgent('AppleWebKit'); +}; + + +/** + * @return {boolean} Whether the user's browser is Chrome. + * @private + */ +goog.labs.userAgent.browser.matchChrome_ = function() { + return (goog.labs.userAgent.util.matchUserAgent('Chrome') || + goog.labs.userAgent.util.matchUserAgent('CriOS')) && + !goog.labs.userAgent.browser.matchOpera_() && + !goog.labs.userAgent.browser.matchEdge_(); +}; + + +/** + * @return {boolean} Whether the user's browser is the Android browser. + * @private + */ +goog.labs.userAgent.browser.matchAndroidBrowser_ = function() { + // Android can appear in the user agent string for Chrome on Android. + // This is not the Android standalone browser if it does. + return goog.labs.userAgent.util.matchUserAgent('Android') && + !(goog.labs.userAgent.browser.isChrome() || + goog.labs.userAgent.browser.isFirefox() || + goog.labs.userAgent.browser.isOpera() || + goog.labs.userAgent.browser.isSilk()); +}; + + +/** + * @return {boolean} Whether the user's browser is Opera. + */ +goog.labs.userAgent.browser.isOpera = goog.labs.userAgent.browser.matchOpera_; + + +/** + * @return {boolean} Whether the user's browser is IE. + */ +goog.labs.userAgent.browser.isIE = goog.labs.userAgent.browser.matchIE_; + + +/** + * @return {boolean} Whether the user's browser is Edge. + */ +goog.labs.userAgent.browser.isEdge = goog.labs.userAgent.browser.matchEdge_; + + +/** + * @return {boolean} Whether the user's browser is Firefox. + */ +goog.labs.userAgent.browser.isFirefox = + goog.labs.userAgent.browser.matchFirefox_; + + +/** + * @return {boolean} Whether the user's browser is Safari. + */ +goog.labs.userAgent.browser.isSafari = goog.labs.userAgent.browser.matchSafari_; + + +/** + * @return {boolean} Whether the user's browser is Coast (Opera's Webkit-based + * iOS browser). + */ +goog.labs.userAgent.browser.isCoast = goog.labs.userAgent.browser.matchCoast_; + + +/** + * @return {boolean} Whether the user's browser is iOS Webview. + */ +goog.labs.userAgent.browser.isIosWebview = + goog.labs.userAgent.browser.matchIosWebview_; + + +/** + * @return {boolean} Whether the user's browser is Chrome. + */ +goog.labs.userAgent.browser.isChrome = goog.labs.userAgent.browser.matchChrome_; + + +/** + * @return {boolean} Whether the user's browser is the Android browser. + */ +goog.labs.userAgent.browser.isAndroidBrowser = + goog.labs.userAgent.browser.matchAndroidBrowser_; + + +/** + * For more information, see: + * http://docs.aws.amazon.com/silk/latest/developerguide/user-agent.html + * @return {boolean} Whether the user's browser is Silk. + */ +goog.labs.userAgent.browser.isSilk = function() { + return goog.labs.userAgent.util.matchUserAgent('Silk'); +}; + + +/** + * @return {string} The browser version or empty string if version cannot be + * determined. Note that for Internet Explorer, this returns the version of + * the browser, not the version of the rendering engine. (IE 8 in + * compatibility mode will return 8.0 rather than 7.0. To determine the + * rendering engine version, look at document.documentMode instead. See + * http://msdn.microsoft.com/en-us/library/cc196988(v=vs.85).aspx for more + * details.) + */ +goog.labs.userAgent.browser.getVersion = function() { + var userAgentString = goog.labs.userAgent.util.getUserAgent(); + // Special case IE since IE's version is inside the parenthesis and + // without the '/'. + if (goog.labs.userAgent.browser.isIE()) { + return goog.labs.userAgent.browser.getIEVersion_(userAgentString); + } + + var versionTuples = + goog.labs.userAgent.util.extractVersionTuples(userAgentString); + + // Construct a map for easy lookup. + var versionMap = {}; + goog.array.forEach(versionTuples, function(tuple) { + // Note that the tuple is of length three, but we only care about the + // first two. + var key = tuple[0]; + var value = tuple[1]; + versionMap[key] = value; + }); + + var versionMapHasKey = goog.partial(goog.object.containsKey, versionMap); + + // Gives the value with the first key it finds, otherwise empty string. + function lookUpValueWithKeys(keys) { + var key = goog.array.find(keys, versionMapHasKey); + return versionMap[key] || ''; + } + + // Check Opera before Chrome since Opera 15+ has "Chrome" in the string. + // See + // http://my.opera.com/ODIN/blog/2013/07/15/opera-user-agent-strings-opera-15-and-beyond + if (goog.labs.userAgent.browser.isOpera()) { + // Opera 10 has Version/10.0 but Opera/9.8, so look for "Version" first. + // Opera uses 'OPR' for more recent UAs. + return lookUpValueWithKeys(['Version', 'Opera', 'OPR']); + } + + // Check Edge before Chrome since it has Chrome in the string. + if (goog.labs.userAgent.browser.isEdge()) { + return lookUpValueWithKeys(['Edge']); + } + + if (goog.labs.userAgent.browser.isChrome()) { + return lookUpValueWithKeys(['Chrome', 'CriOS']); + } + + // Usually products browser versions are in the third tuple after "Mozilla" + // and the engine. + var tuple = versionTuples[2]; + return tuple && tuple[1] || ''; +}; + + +/** + * @param {string|number} version The version to check. + * @return {boolean} Whether the browser version is higher or the same as the + * given version. + */ +goog.labs.userAgent.browser.isVersionOrHigher = function(version) { + return goog.string.compareVersions( + goog.labs.userAgent.browser.getVersion(), version) >= 0; +}; + + +/** + * Determines IE version. More information: + * http://msdn.microsoft.com/en-us/library/ie/bg182625(v=vs.85).aspx#uaString + * http://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx + * http://blogs.msdn.com/b/ie/archive/2010/03/23/introducing-ie9-s-user-agent-string.aspx + * http://blogs.msdn.com/b/ie/archive/2009/01/09/the-internet-explorer-8-user-agent-string-updated-edition.aspx + * + * @param {string} userAgent the User-Agent. + * @return {string} + * @private + */ +goog.labs.userAgent.browser.getIEVersion_ = function(userAgent) { + // IE11 may identify itself as MSIE 9.0 or MSIE 10.0 due to an IE 11 upgrade + // bug. Example UA: + // Mozilla/5.0 (MSIE 9.0; Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) + // like Gecko. + // See http://www.whatismybrowser.com/developers/unknown-user-agent-fragments. + var rv = /rv: *([\d\.]*)/.exec(userAgent); + if (rv && rv[1]) { + return rv[1]; + } + + var version = ''; + var msie = /MSIE +([\d\.]+)/.exec(userAgent); + if (msie && msie[1]) { + // IE in compatibility mode usually identifies itself as MSIE 7.0; in this + // case, use the Trident version to determine the version of IE. For more + // details, see the links above. + var tridentVersion = /Trident\/(\d.\d)/.exec(userAgent); + if (msie[1] == '7.0') { + if (tridentVersion && tridentVersion[1]) { + switch (tridentVersion[1]) { + case '4.0': + version = '8.0'; + break; + case '5.0': + version = '9.0'; + break; + case '6.0': + version = '10.0'; + break; + case '7.0': + version = '11.0'; + break; + } + } else { + version = '7.0'; + } + } else { + version = msie[1]; + } + } + return version; +}; + +// Copyright 2013 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Closure user agent detection. + * @see http://en.wikipedia.org/wiki/User_agent + * For more information on browser brand, platform, or device see the other + * sub-namespaces in goog.labs.userAgent (browser, platform, and device). + * + */ + +goog.provide('goog.labs.userAgent.engine'); + +goog.require('goog.array'); +goog.require('goog.labs.userAgent.util'); +goog.require('goog.string'); + + +/** + * @return {boolean} Whether the rendering engine is Presto. + */ +goog.labs.userAgent.engine.isPresto = function() { + return goog.labs.userAgent.util.matchUserAgent('Presto'); +}; + + +/** + * @return {boolean} Whether the rendering engine is Trident. + */ +goog.labs.userAgent.engine.isTrident = function() { + // IE only started including the Trident token in IE8. + return goog.labs.userAgent.util.matchUserAgent('Trident') || + goog.labs.userAgent.util.matchUserAgent('MSIE'); +}; + + +/** + * @return {boolean} Whether the rendering engine is Edge. + */ +goog.labs.userAgent.engine.isEdge = function() { + return goog.labs.userAgent.util.matchUserAgent('Edge'); +}; + + +/** + * @return {boolean} Whether the rendering engine is WebKit. + */ +goog.labs.userAgent.engine.isWebKit = function() { + return goog.labs.userAgent.util.matchUserAgentIgnoreCase('WebKit') && + !goog.labs.userAgent.engine.isEdge(); +}; + + +/** + * @return {boolean} Whether the rendering engine is Gecko. + */ +goog.labs.userAgent.engine.isGecko = function() { + return goog.labs.userAgent.util.matchUserAgent('Gecko') && + !goog.labs.userAgent.engine.isWebKit() && + !goog.labs.userAgent.engine.isTrident() && + !goog.labs.userAgent.engine.isEdge(); +}; + + +/** + * @return {string} The rendering engine's version or empty string if version + * can't be determined. + */ +goog.labs.userAgent.engine.getVersion = function() { + var userAgentString = goog.labs.userAgent.util.getUserAgent(); + if (userAgentString) { + var tuples = goog.labs.userAgent.util.extractVersionTuples(userAgentString); + + var engineTuple = goog.labs.userAgent.engine.getEngineTuple_(tuples); + if (engineTuple) { + // In Gecko, the version string is either in the browser info or the + // Firefox version. See Gecko user agent string reference: + // http://goo.gl/mULqa + if (engineTuple[0] == 'Gecko') { + return goog.labs.userAgent.engine.getVersionForKey_(tuples, 'Firefox'); + } + + return engineTuple[1]; + } + + // MSIE has only one version identifier, and the Trident version is + // specified in the parenthetical. IE Edge is covered in the engine tuple + // detection. + var browserTuple = tuples[0]; + var info; + if (browserTuple && (info = browserTuple[2])) { + var match = /Trident\/([^\s;]+)/.exec(info); + if (match) { + return match[1]; + } + } + } + return ''; +}; + + +/** + * @param {!Array<!Array<string>>} tuples Extracted version tuples. + * @return {!Array<string>|undefined} The engine tuple or undefined if not + * found. + * @private + */ +goog.labs.userAgent.engine.getEngineTuple_ = function(tuples) { + if (!goog.labs.userAgent.engine.isEdge()) { + return tuples[1]; + } + for (var i = 0; i < tuples.length; i++) { + var tuple = tuples[i]; + if (tuple[0] == 'Edge') { + return tuple; + } + } +}; + + +/** + * @param {string|number} version The version to check. + * @return {boolean} Whether the rendering engine version is higher or the same + * as the given version. + */ +goog.labs.userAgent.engine.isVersionOrHigher = function(version) { + return goog.string.compareVersions( + goog.labs.userAgent.engine.getVersion(), version) >= 0; +}; + + +/** + * @param {!Array<!Array<string>>} tuples Version tuples. + * @param {string} key The key to look for. + * @return {string} The version string of the given key, if present. + * Otherwise, the empty string. + * @private + */ +goog.labs.userAgent.engine.getVersionForKey_ = function(tuples, key) { + // TODO(nnaze): Move to util if useful elsewhere. + + var pair = goog.array.find(tuples, function(pair) { return key == pair[0]; }); + + return pair && pair[1] || ''; +}; + +// Copyright 2013 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Closure user agent platform detection. + * @see <a href="http://www.useragentstring.com/">User agent strings</a> + * For more information on browser brand, rendering engine, or device see the + * other sub-namespaces in goog.labs.userAgent (browser, engine, and device + * respectively). + * + */ + +goog.provide('goog.labs.userAgent.platform'); + +goog.require('goog.labs.userAgent.util'); +goog.require('goog.string'); + + +/** + * @return {boolean} Whether the platform is Android. + */ +goog.labs.userAgent.platform.isAndroid = function() { + return goog.labs.userAgent.util.matchUserAgent('Android'); +}; + + +/** + * @return {boolean} Whether the platform is iPod. + */ +goog.labs.userAgent.platform.isIpod = function() { + return goog.labs.userAgent.util.matchUserAgent('iPod'); +}; + + +/** + * @return {boolean} Whether the platform is iPhone. + */ +goog.labs.userAgent.platform.isIphone = function() { + return goog.labs.userAgent.util.matchUserAgent('iPhone') && + !goog.labs.userAgent.util.matchUserAgent('iPod') && + !goog.labs.userAgent.util.matchUserAgent('iPad'); +}; + + +/** + * @return {boolean} Whether the platform is iPad. + */ +goog.labs.userAgent.platform.isIpad = function() { + return goog.labs.userAgent.util.matchUserAgent('iPad'); +}; + + +/** + * @return {boolean} Whether the platform is iOS. + */ +goog.labs.userAgent.platform.isIos = function() { + return goog.labs.userAgent.platform.isIphone() || + goog.labs.userAgent.platform.isIpad() || + goog.labs.userAgent.platform.isIpod(); +}; + + +/** + * @return {boolean} Whether the platform is Mac. + */ +goog.labs.userAgent.platform.isMacintosh = function() { + return goog.labs.userAgent.util.matchUserAgent('Macintosh'); +}; + + +/** + * Note: ChromeOS is not considered to be Linux as it does not report itself + * as Linux in the user agent string. + * @return {boolean} Whether the platform is Linux. + */ +goog.labs.userAgent.platform.isLinux = function() { + return goog.labs.userAgent.util.matchUserAgent('Linux'); +}; + + +/** + * @return {boolean} Whether the platform is Windows. + */ +goog.labs.userAgent.platform.isWindows = function() { + return goog.labs.userAgent.util.matchUserAgent('Windows'); +}; + + +/** + * @return {boolean} Whether the platform is ChromeOS. + */ +goog.labs.userAgent.platform.isChromeOS = function() { + return goog.labs.userAgent.util.matchUserAgent('CrOS'); +}; + + +/** + * The version of the platform. We only determine the version for Windows, + * Mac, and Chrome OS. It doesn't make much sense on Linux. For Windows, we only + * look at the NT version. Non-NT-based versions (e.g. 95, 98, etc.) are given + * version 0.0. + * + * @return {string} The platform version or empty string if version cannot be + * determined. + */ +goog.labs.userAgent.platform.getVersion = function() { + var userAgentString = goog.labs.userAgent.util.getUserAgent(); + var version = '', re; + if (goog.labs.userAgent.platform.isWindows()) { + re = /Windows (?:NT|Phone) ([0-9.]+)/; + var match = re.exec(userAgentString); + if (match) { + version = match[1]; + } else { + version = '0.0'; + } + } else if (goog.labs.userAgent.platform.isIos()) { + re = /(?:iPhone|iPod|iPad|CPU)\s+OS\s+(\S+)/; + var match = re.exec(userAgentString); + // Report the version as x.y.z and not x_y_z + version = match && match[1].replace(/_/g, '.'); + } else if (goog.labs.userAgent.platform.isMacintosh()) { + re = /Mac OS X ([0-9_.]+)/; + var match = re.exec(userAgentString); + // Note: some old versions of Camino do not report an OSX version. + // Default to 10. + version = match ? match[1].replace(/_/g, '.') : '10'; + } else if (goog.labs.userAgent.platform.isAndroid()) { + re = /Android\s+([^\);]+)(\)|;)/; + var match = re.exec(userAgentString); + version = match && match[1]; + } else if (goog.labs.userAgent.platform.isChromeOS()) { + re = /(?:CrOS\s+(?:i686|x86_64)\s+([0-9.]+))/; + var match = re.exec(userAgentString); + version = match && match[1]; + } + return version || ''; +}; + + +/** + * @param {string|number} version The version to check. + * @return {boolean} Whether the browser version is higher or the same as the + * given version. + */ +goog.labs.userAgent.platform.isVersionOrHigher = function(version) { + return goog.string.compareVersions( + goog.labs.userAgent.platform.getVersion(), version) >= 0; +}; + +// Copyright 2006 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Rendering engine detection. + * @see <a href="http://www.useragentstring.com/">User agent strings</a> + * For information on the browser brand (such as Safari versus Chrome), see + * goog.userAgent.product. + * @author arv@google.com (Erik Arvidsson) + * @see ../demos/useragent.html + */ + +goog.provide('goog.userAgent'); + +goog.require('goog.labs.userAgent.browser'); +goog.require('goog.labs.userAgent.engine'); +goog.require('goog.labs.userAgent.platform'); +goog.require('goog.labs.userAgent.util'); +goog.require('goog.string'); + + +/** + * @define {boolean} Whether we know at compile-time that the browser is IE. + */ +goog.define('goog.userAgent.ASSUME_IE', false); + + +/** + * @define {boolean} Whether we know at compile-time that the browser is EDGE. + */ +goog.define('goog.userAgent.ASSUME_EDGE', false); + + +/** + * @define {boolean} Whether we know at compile-time that the browser is GECKO. + */ +goog.define('goog.userAgent.ASSUME_GECKO', false); + + +/** + * @define {boolean} Whether we know at compile-time that the browser is WEBKIT. + */ +goog.define('goog.userAgent.ASSUME_WEBKIT', false); + + +/** + * @define {boolean} Whether we know at compile-time that the browser is a + * mobile device running WebKit e.g. iPhone or Android. + */ +goog.define('goog.userAgent.ASSUME_MOBILE_WEBKIT', false); + + +/** + * @define {boolean} Whether we know at compile-time that the browser is OPERA. + */ +goog.define('goog.userAgent.ASSUME_OPERA', false); + + +/** + * @define {boolean} Whether the + * {@code goog.userAgent.isVersionOrHigher} + * function will return true for any version. + */ +goog.define('goog.userAgent.ASSUME_ANY_VERSION', false); + + +/** + * Whether we know the browser engine at compile-time. + * @type {boolean} + * @private + */ +goog.userAgent.BROWSER_KNOWN_ = goog.userAgent.ASSUME_IE || + goog.userAgent.ASSUME_EDGE || goog.userAgent.ASSUME_GECKO || + goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.ASSUME_WEBKIT || + goog.userAgent.ASSUME_OPERA; + + +/** + * Returns the userAgent string for the current browser. + * + * @return {string} The userAgent string. + */ +goog.userAgent.getUserAgentString = function() { + return goog.labs.userAgent.util.getUserAgent(); +}; + + +/** + * TODO(nnaze): Change type to "Navigator" and update compilation targets. + * @return {Object} The native navigator object. + */ +goog.userAgent.getNavigator = function() { + // Need a local navigator reference instead of using the global one, + // to avoid the rare case where they reference different objects. + // (in a WorkerPool, for example). + return goog.global['navigator'] || null; +}; + + +/** + * Whether the user agent is Opera. + * @type {boolean} + */ +goog.userAgent.OPERA = goog.userAgent.BROWSER_KNOWN_ ? + goog.userAgent.ASSUME_OPERA : + goog.labs.userAgent.browser.isOpera(); + + +/** + * Whether the user agent is Internet Explorer. + * @type {boolean} + */ +goog.userAgent.IE = goog.userAgent.BROWSER_KNOWN_ ? + goog.userAgent.ASSUME_IE : + goog.labs.userAgent.browser.isIE(); + + +/** + * Whether the user agent is Microsoft Edge. + * @type {boolean} + */ +goog.userAgent.EDGE = goog.userAgent.BROWSER_KNOWN_ ? + goog.userAgent.ASSUME_EDGE : + goog.labs.userAgent.engine.isEdge(); + + +/** + * Whether the user agent is MS Internet Explorer or MS Edge. + * @type {boolean} + */ +goog.userAgent.EDGE_OR_IE = goog.userAgent.EDGE || goog.userAgent.IE; + + +/** + * Whether the user agent is Gecko. Gecko is the rendering engine used by + * Mozilla, Firefox, and others. + * @type {boolean} + */ +goog.userAgent.GECKO = goog.userAgent.BROWSER_KNOWN_ ? + goog.userAgent.ASSUME_GECKO : + goog.labs.userAgent.engine.isGecko(); + + +/** + * Whether the user agent is WebKit. WebKit is the rendering engine that + * Safari, Android and others use. + * @type {boolean} + */ +goog.userAgent.WEBKIT = goog.userAgent.BROWSER_KNOWN_ ? + goog.userAgent.ASSUME_WEBKIT || goog.userAgent.ASSUME_MOBILE_WEBKIT : + goog.labs.userAgent.engine.isWebKit(); + + +/** + * Whether the user agent is running on a mobile device. + * + * This is a separate function so that the logic can be tested. + * + * TODO(nnaze): Investigate swapping in goog.labs.userAgent.device.isMobile(). + * + * @return {boolean} Whether the user agent is running on a mobile device. + * @private + */ +goog.userAgent.isMobile_ = function() { + return goog.userAgent.WEBKIT && + goog.labs.userAgent.util.matchUserAgent('Mobile'); +}; + + +/** + * Whether the user agent is running on a mobile device. + * + * TODO(nnaze): Consider deprecating MOBILE when labs.userAgent + * is promoted as the gecko/webkit logic is likely inaccurate. + * + * @type {boolean} + */ +goog.userAgent.MOBILE = + goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.isMobile_(); + + +/** + * Used while transitioning code to use WEBKIT instead. + * @type {boolean} + * @deprecated Use {@link goog.userAgent.product.SAFARI} instead. + * TODO(nicksantos): Delete this from goog.userAgent. + */ +goog.userAgent.SAFARI = goog.userAgent.WEBKIT; + + +/** + * @return {string} the platform (operating system) the user agent is running + * on. Default to empty string because navigator.platform may not be defined + * (on Rhino, for example). + * @private + */ +goog.userAgent.determinePlatform_ = function() { + var navigator = goog.userAgent.getNavigator(); + return navigator && navigator.platform || ''; +}; + + +/** + * The platform (operating system) the user agent is running on. Default to + * empty string because navigator.platform may not be defined (on Rhino, for + * example). + * @type {string} + */ +goog.userAgent.PLATFORM = goog.userAgent.determinePlatform_(); + + +/** + * @define {boolean} Whether the user agent is running on a Macintosh operating + * system. + */ +goog.define('goog.userAgent.ASSUME_MAC', false); + + +/** + * @define {boolean} Whether the user agent is running on a Windows operating + * system. + */ +goog.define('goog.userAgent.ASSUME_WINDOWS', false); + + +/** + * @define {boolean} Whether the user agent is running on a Linux operating + * system. + */ +goog.define('goog.userAgent.ASSUME_LINUX', false); + + +/** + * @define {boolean} Whether the user agent is running on a X11 windowing + * system. + */ +goog.define('goog.userAgent.ASSUME_X11', false); + + +/** + * @define {boolean} Whether the user agent is running on Android. + */ +goog.define('goog.userAgent.ASSUME_ANDROID', false); + + +/** + * @define {boolean} Whether the user agent is running on an iPhone. + */ +goog.define('goog.userAgent.ASSUME_IPHONE', false); + + +/** + * @define {boolean} Whether the user agent is running on an iPad. + */ +goog.define('goog.userAgent.ASSUME_IPAD', false); + + +/** + * @type {boolean} + * @private + */ +goog.userAgent.PLATFORM_KNOWN_ = goog.userAgent.ASSUME_MAC || + goog.userAgent.ASSUME_WINDOWS || goog.userAgent.ASSUME_LINUX || + goog.userAgent.ASSUME_X11 || goog.userAgent.ASSUME_ANDROID || + goog.userAgent.ASSUME_IPHONE || goog.userAgent.ASSUME_IPAD; + + +/** + * Whether the user agent is running on a Macintosh operating system. + * @type {boolean} + */ +goog.userAgent.MAC = goog.userAgent.PLATFORM_KNOWN_ ? + goog.userAgent.ASSUME_MAC : + goog.labs.userAgent.platform.isMacintosh(); + + +/** + * Whether the user agent is running on a Windows operating system. + * @type {boolean} + */ +goog.userAgent.WINDOWS = goog.userAgent.PLATFORM_KNOWN_ ? + goog.userAgent.ASSUME_WINDOWS : + goog.labs.userAgent.platform.isWindows(); + + +/** + * Whether the user agent is Linux per the legacy behavior of + * goog.userAgent.LINUX, which considered ChromeOS to also be + * Linux. + * @return {boolean} + * @private + */ +goog.userAgent.isLegacyLinux_ = function() { + return goog.labs.userAgent.platform.isLinux() || + goog.labs.userAgent.platform.isChromeOS(); +}; + + +/** + * Whether the user agent is running on a Linux operating system. + * + * Note that goog.userAgent.LINUX considers ChromeOS to be Linux, + * while goog.labs.userAgent.platform considers ChromeOS and + * Linux to be different OSes. + * + * @type {boolean} + */ +goog.userAgent.LINUX = goog.userAgent.PLATFORM_KNOWN_ ? + goog.userAgent.ASSUME_LINUX : + goog.userAgent.isLegacyLinux_(); + + +/** + * @return {boolean} Whether the user agent is an X11 windowing system. + * @private + */ +goog.userAgent.isX11_ = function() { + var navigator = goog.userAgent.getNavigator(); + return !!navigator && + goog.string.contains(navigator['appVersion'] || '', 'X11'); +}; + + +/** + * Whether the user agent is running on a X11 windowing system. + * @type {boolean} + */ +goog.userAgent.X11 = goog.userAgent.PLATFORM_KNOWN_ ? + goog.userAgent.ASSUME_X11 : + goog.userAgent.isX11_(); + + +/** + * Whether the user agent is running on Android. + * @type {boolean} + */ +goog.userAgent.ANDROID = goog.userAgent.PLATFORM_KNOWN_ ? + goog.userAgent.ASSUME_ANDROID : + goog.labs.userAgent.platform.isAndroid(); + + +/** + * Whether the user agent is running on an iPhone. + * @type {boolean} + */ +goog.userAgent.IPHONE = goog.userAgent.PLATFORM_KNOWN_ ? + goog.userAgent.ASSUME_IPHONE : + goog.labs.userAgent.platform.isIphone(); + + +/** + * Whether the user agent is running on an iPad. + * @type {boolean} + */ +goog.userAgent.IPAD = goog.userAgent.PLATFORM_KNOWN_ ? + goog.userAgent.ASSUME_IPAD : + goog.labs.userAgent.platform.isIpad(); + + +/** + * @return {string} The string that describes the version number of the user + * agent. + * @private + */ +goog.userAgent.determineVersion_ = function() { + // All browsers have different ways to detect the version and they all have + // different naming schemes. + // version is a string rather than a number because it may contain 'b', 'a', + // and so on. + var version = ''; + var arr = goog.userAgent.getVersionRegexResult_(); + if (arr) { + version = arr ? arr[1] : ''; + } + + if (goog.userAgent.IE) { + // IE9 can be in document mode 9 but be reporting an inconsistent user agent + // version. If it is identifying as a version lower than 9 we take the + // documentMode as the version instead. IE8 has similar behavior. + // It is recommended to set the X-UA-Compatible header to ensure that IE9 + // uses documentMode 9. + var docMode = goog.userAgent.getDocumentMode_(); + if (docMode != null && docMode > parseFloat(version)) { + return String(docMode); + } + } + + return version; +}; + + +/** + * @return {?Array|undefined} The version regex matches from parsing the user + * agent string. These regex statements must be executed inline so they can + * be compiled out by the closure compiler with the rest of the useragent + * detection logic when ASSUME_* is specified. + * @private + */ +goog.userAgent.getVersionRegexResult_ = function() { + var userAgent = goog.userAgent.getUserAgentString(); + if (goog.userAgent.GECKO) { + return /rv\:([^\);]+)(\)|;)/.exec(userAgent); + } + if (goog.userAgent.EDGE) { + return /Edge\/([\d\.]+)/.exec(userAgent); + } + if (goog.userAgent.IE) { + return /\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(userAgent); + } + if (goog.userAgent.WEBKIT) { + // WebKit/125.4 + return /WebKit\/(\S+)/.exec(userAgent); + } + if (goog.userAgent.OPERA) { + // If none of the above browsers were detected but the browser is Opera, the + // only string that is of interest is 'Version/<number>'. + return /(?:Version)[ \/]?(\S+)/.exec(userAgent); + } + return undefined; +}; + + +/** + * @return {number|undefined} Returns the document mode (for testing). + * @private + */ +goog.userAgent.getDocumentMode_ = function() { + // NOTE(user): goog.userAgent may be used in context where there is no DOM. + var doc = goog.global['document']; + return doc ? doc['documentMode'] : undefined; +}; + + +/** + * The version of the user agent. This is a string because it might contain + * 'b' (as in beta) as well as multiple dots. + * @type {string} + */ +goog.userAgent.VERSION = goog.userAgent.determineVersion_(); + + +/** + * Compares two version numbers. + * + * @param {string} v1 Version of first item. + * @param {string} v2 Version of second item. + * + * @return {number} 1 if first argument is higher + * 0 if arguments are equal + * -1 if second argument is higher. + * @deprecated Use goog.string.compareVersions. + */ +goog.userAgent.compare = function(v1, v2) { + return goog.string.compareVersions(v1, v2); +}; + + +/** + * Cache for {@link goog.userAgent.isVersionOrHigher}. + * Calls to compareVersions are surprisingly expensive and, as a browser's + * version number is unlikely to change during a session, we cache the results. + * @const + * @private + */ +goog.userAgent.isVersionOrHigherCache_ = {}; + + +/** + * Whether the user agent version is higher or the same as the given version. + * NOTE: When checking the version numbers for Firefox and Safari, be sure to + * use the engine's version, not the browser's version number. For example, + * Firefox 3.0 corresponds to Gecko 1.9 and Safari 3.0 to Webkit 522.11. + * Opera and Internet Explorer versions match the product release number.<br> + * @see <a href="http://en.wikipedia.org/wiki/Safari_version_history"> + * Webkit</a> + * @see <a href="http://en.wikipedia.org/wiki/Gecko_engine">Gecko</a> + * + * @param {string|number} version The version to check. + * @return {boolean} Whether the user agent version is higher or the same as + * the given version. + */ +goog.userAgent.isVersionOrHigher = function(version) { + return goog.userAgent.ASSUME_ANY_VERSION || + goog.userAgent.isVersionOrHigherCache_[version] || + (goog.userAgent.isVersionOrHigherCache_[version] = + goog.string.compareVersions(goog.userAgent.VERSION, version) >= 0); +}; + + +/** + * Deprecated alias to {@code goog.userAgent.isVersionOrHigher}. + * @param {string|number} version The version to check. + * @return {boolean} Whether the user agent version is higher or the same as + * the given version. + * @deprecated Use goog.userAgent.isVersionOrHigher(). + */ +goog.userAgent.isVersion = goog.userAgent.isVersionOrHigher; + + +/** + * Whether the IE effective document mode is higher or the same as the given + * document mode version. + * NOTE: Only for IE, return false for another browser. + * + * @param {number} documentMode The document mode version to check. + * @return {boolean} Whether the IE effective document mode is higher or the + * same as the given version. + */ +goog.userAgent.isDocumentModeOrHigher = function(documentMode) { + return Number(goog.userAgent.DOCUMENT_MODE) >= documentMode; +}; + + +/** + * Deprecated alias to {@code goog.userAgent.isDocumentModeOrHigher}. + * @param {number} version The version to check. + * @return {boolean} Whether the IE effective document mode is higher or the + * same as the given version. + * @deprecated Use goog.userAgent.isDocumentModeOrHigher(). + */ +goog.userAgent.isDocumentMode = goog.userAgent.isDocumentModeOrHigher; + + +/** + * For IE version < 7, documentMode is undefined, so attempt to use the + * CSS1Compat property to see if we are in standards mode. If we are in + * standards mode, treat the browser version as the document mode. Otherwise, + * IE is emulating version 5. + * @type {number|undefined} + * @const + */ +goog.userAgent.DOCUMENT_MODE = (function() { + var doc = goog.global['document']; + var mode = goog.userAgent.getDocumentMode_(); + if (!doc || !goog.userAgent.IE) { + return undefined; + } + return mode || (doc['compatMode'] == 'CSS1Compat' ? + parseInt(goog.userAgent.VERSION, 10) : + 5); +})(); + // Copyright 2010 The Closure Library Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -25487,8 +22651,8 @@ goog.dom.BrowserFeature = { * Whether attributes 'name' and 'type' can be added to an element after it's * created. False in Internet Explorer prior to version 9. */ - CAN_ADD_NAME_OR_TYPE_ATTRIBUTES: !goog.userAgent.IE || - goog.userAgent.isDocumentModeOrHigher(9), + CAN_ADD_NAME_OR_TYPE_ATTRIBUTES: + !goog.userAgent.IE || goog.userAgent.isDocumentModeOrHigher(9), /** * Whether we can use element.children to access an element's Element @@ -25503,15 +22667,15 @@ goog.dom.BrowserFeature = { * Opera, Safari 3, and Internet Explorer 9 all support innerText but they * include text nodes in script and style tags. Not document-mode-dependent. */ - CAN_USE_INNER_TEXT: ( - goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9')), + CAN_USE_INNER_TEXT: + (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9')), /** * MSIE, Opera, and Safari>=4 support element.parentElement to access an * element's parent if it is an Element. */ - CAN_USE_PARENT_ELEMENT_PROPERTY: goog.userAgent.IE || goog.userAgent.OPERA || - goog.userAgent.WEBKIT, + CAN_USE_PARENT_ELEMENT_PROPERTY: + goog.userAgent.IE || goog.userAgent.OPERA || goog.userAgent.WEBKIT, /** * Whether NoScope elements need a scoped element written before them in @@ -25523,7 +22687,8 @@ goog.dom.BrowserFeature = { /** * Whether we use legacy IE range API. */ - LEGACY_IE_RANGES: goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9) + LEGACY_IE_RANGES: + goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9) }; // Copyright 2007 The Closure Library Authors. All Rights Reserved. @@ -25877,8 +23042,8 @@ goog.string.Const.prototype.getTypedStringValue = function() { */ goog.string.Const.prototype.toString = function() { return 'Const{' + - this.stringConstValueWithSecurityContract__googStringSecurityPrivate_ + - '}'; + this.stringConstValueWithSecurityContract__googStringSecurityPrivate_ + + '}'; }; @@ -25900,11 +23065,11 @@ goog.string.Const.unwrap = function(stringConst) { stringConst.constructor === goog.string.Const && stringConst.STRING_CONST_TYPE_MARKER__GOOG_STRING_SECURITY_PRIVATE_ === goog.string.Const.TYPE_MARKER_) { - return stringConst. - stringConstValueWithSecurityContract__googStringSecurityPrivate_; + return stringConst + .stringConstValueWithSecurityContract__googStringSecurityPrivate_; } else { - goog.asserts.fail('expected object of type Const, got \'' + - stringConst + '\''); + goog.asserts.fail( + 'expected object of type Const, got \'' + stringConst + '\''); return 'type_error:Const'; } }; @@ -26138,11 +23303,13 @@ goog.html.SafeStyle.fromConstant = function(style) { return goog.html.SafeStyle.EMPTY; } goog.html.SafeStyle.checkStyle_(styleString); - goog.asserts.assert(goog.string.endsWith(styleString, ';'), + goog.asserts.assert( + goog.string.endsWith(styleString, ';'), 'Last character of style string is not \';\': ' + styleString); - goog.asserts.assert(goog.string.contains(styleString, ':'), + goog.asserts.assert( + goog.string.contains(styleString, ':'), 'Style string must contain at least one \':\', to ' + - 'specify a "name: value" pair: ' + styleString); + 'specify a "name: value" pair: ' + styleString); return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse( styleString); }; @@ -26154,8 +23321,8 @@ goog.html.SafeStyle.fromConstant = function(style) { * @private */ goog.html.SafeStyle.checkStyle_ = function(style) { - goog.asserts.assert(!/[<>]/.test(style), - 'Forbidden characters in style string: ' + style); + goog.asserts.assert( + !/[<>]/.test(style), 'Forbidden characters in style string: ' + style); }; @@ -26196,8 +23363,8 @@ if (goog.DEBUG) { * @override */ goog.html.SafeStyle.prototype.toString = function() { - return 'SafeStyle{' + - this.privateDoNotAccessOrElseSafeStyleWrappedValue_ + '}'; + return 'SafeStyle{' + this.privateDoNotAccessOrElseSafeStyleWrappedValue_ + + '}'; }; } @@ -26229,8 +23396,8 @@ goog.html.SafeStyle.unwrap = function(safeStyle) { goog.html.SafeStyle.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) { return safeStyle.privateDoNotAccessOrElseSafeStyleWrappedValue_; } else { - goog.asserts.fail( - 'expected object of type SafeStyle, got \'' + safeStyle + '\''); + goog.asserts.fail('expected object of type SafeStyle, got \'' + + safeStyle + '\' of type ' + goog.typeOf(safeStyle)); return 'type_error:SafeStyle'; } }; @@ -26243,8 +23410,8 @@ goog.html.SafeStyle.unwrap = function(safeStyle) { * @return {!goog.html.SafeStyle} The initialized SafeStyle object. * @package */ -goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse = - function(style) { +goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse = function( + style) { return new goog.html.SafeStyle().initSecurityPrivateDoNotAccessOrElse_(style); }; @@ -26318,7 +23485,8 @@ goog.html.SafeStyle.create = function(map) { goog.asserts.assert(!/[{;}]/.test(value), 'Value does not allow [{;}].'); } else if (!goog.html.SafeStyle.VALUE_RE_.test(value)) { goog.asserts.fail( - 'String value allows only [-,."\'%_!# a-zA-Z0-9], got: ' + value); + 'String value allows only [-,."\'%_!# a-zA-Z0-9], rgb() and ' + + 'rgba(), got: ' + value); value = goog.html.SafeStyle.INNOCUOUS_STRING; } else if (!goog.html.SafeStyle.hasBalancedQuotes_(value)) { goog.asserts.fail('String value requires balanced quotes, got: ' + value); @@ -26370,10 +23538,14 @@ goog.html.SafeStyle.hasBalancedQuotes_ = function(value) { * ',' allows multiple values to be assigned to the same property * (e.g. background-attachment or font-family) and hence could allow * multiple values to get injected, but that should pose no risk of XSS. + * + * The rgb() and rgba() expression checks only for XSS safety, not for CSS + * validity. * @const {!RegExp} * @private */ -goog.html.SafeStyle.VALUE_RE_ = /^[-,."'%_!# a-zA-Z0-9]+$/; +goog.html.SafeStyle.VALUE_RE_ = + /^([-,."'%_!# a-zA-Z0-9]+|(?:rgb|hsl)a?\([0-9.%, ]+\))$/; /** @@ -26468,7 +23640,8 @@ goog.require('goog.string.TypedString'); * style element and {@code evil} would execute. Also note that within an HTML * style (raw text) element, HTML character references, such as * {@code &lt;}, are not allowed. See - * http://www.w3.org/TR/html5/scripting-1.html#restrictions-for-contents-of-script-elements + * + http://www.w3.org/TR/html5/scripting-1.html#restrictions-for-contents-of-script-elements * (similar considerations apply to the style element). * * @see goog.html.SafeStyleSheet#fromConstant @@ -26492,7 +23665,7 @@ goog.html.SafeStyleSheet = function() { * @const * @private */ - this.SAFE_SCRIPT_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = + this.SAFE_STYLE_SHEET_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = goog.html.SafeStyleSheet.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_; }; @@ -26558,10 +23731,11 @@ goog.html.SafeStyleSheet.fromConstant = function(styleSheet) { } // > is a valid character in CSS selectors and there's no strict need to // block it if we already block <. - goog.asserts.assert(!goog.string.contains(styleSheetString, '<'), + goog.asserts.assert( + !goog.string.contains(styleSheetString, '<'), "Forbidden '<' character in style sheet string: " + styleSheetString); - return goog.html.SafeStyleSheet. - createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(styleSheetString); + return goog.html.SafeStyleSheet + .createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(styleSheetString); }; @@ -26631,13 +23805,13 @@ goog.html.SafeStyleSheet.unwrap = function(safeStyleSheet) { // to stand out in code reviews. if (safeStyleSheet instanceof goog.html.SafeStyleSheet && safeStyleSheet.constructor === goog.html.SafeStyleSheet && - safeStyleSheet.SAFE_SCRIPT_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ === + safeStyleSheet + .SAFE_STYLE_SHEET_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ === goog.html.SafeStyleSheet.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) { return safeStyleSheet.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_; } else { - goog.asserts.fail( - "expected object of type SafeStyleSheet, got '" + safeStyleSheet + - "'"); + goog.asserts.fail('expected object of type SafeStyleSheet, got \'' + + safeStyleSheet + '\' of type ' + goog.typeOf(safeStyleSheet)); return 'type_error:SafeStyleSheet'; } }; @@ -26678,8 +23852,8 @@ goog.html.SafeStyleSheet.prototype.initSecurityPrivateDoNotAccessOrElse_ = * @const {!goog.html.SafeStyleSheet} */ goog.html.SafeStyleSheet.EMPTY = - goog.html.SafeStyleSheet. - createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(''); + goog.html.SafeStyleSheet + .createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(''); // Copyright 2015 The Closure Library Authors. All Rights Reserved. // @@ -26768,11 +23942,12 @@ goog.fs.url.findUrlObject_ = function() { if (goog.isDef(goog.global.URL) && goog.isDef(goog.global.URL.createObjectURL)) { return /** @type {goog.fs.url.UrlObject_} */ (goog.global.URL); - // This is what Chrome does (as of 10.0.648.6 dev) - } else if (goog.isDef(goog.global.webkitURL) && - goog.isDef(goog.global.webkitURL.createObjectURL)) { + // This is what Chrome does (as of 10.0.648.6 dev) + } else if ( + goog.isDef(goog.global.webkitURL) && + goog.isDef(goog.global.webkitURL.createObjectURL)) { return /** @type {goog.fs.url.UrlObject_} */ (goog.global.webkitURL); - // This is what the spec used to say to do + // This is what the spec used to say to do } else if (goog.isDef(goog.global.createObjectURL)) { return /** @type {goog.fs.url.UrlObject_} */ (goog.global); } else { @@ -26853,26 +24028,21 @@ goog.define('goog.i18n.bidi.FORCE_RTL', false); * TODO(user): write a test that checks that this is a compile-time constant. */ goog.i18n.bidi.IS_RTL = goog.i18n.bidi.FORCE_RTL || - ( - (goog.LOCALE.substring(0, 2).toLowerCase() == 'ar' || - goog.LOCALE.substring(0, 2).toLowerCase() == 'fa' || - goog.LOCALE.substring(0, 2).toLowerCase() == 'he' || - goog.LOCALE.substring(0, 2).toLowerCase() == 'iw' || - goog.LOCALE.substring(0, 2).toLowerCase() == 'ps' || - goog.LOCALE.substring(0, 2).toLowerCase() == 'sd' || - goog.LOCALE.substring(0, 2).toLowerCase() == 'ug' || - goog.LOCALE.substring(0, 2).toLowerCase() == 'ur' || - goog.LOCALE.substring(0, 2).toLowerCase() == 'yi') && - (goog.LOCALE.length == 2 || - goog.LOCALE.substring(2, 3) == '-' || - goog.LOCALE.substring(2, 3) == '_') - ) || ( - goog.LOCALE.length >= 3 && - goog.LOCALE.substring(0, 3).toLowerCase() == 'ckb' && - (goog.LOCALE.length == 3 || - goog.LOCALE.substring(3, 4) == '-' || - goog.LOCALE.substring(3, 4) == '_') - ); + ((goog.LOCALE.substring(0, 2).toLowerCase() == 'ar' || + goog.LOCALE.substring(0, 2).toLowerCase() == 'fa' || + goog.LOCALE.substring(0, 2).toLowerCase() == 'he' || + goog.LOCALE.substring(0, 2).toLowerCase() == 'iw' || + goog.LOCALE.substring(0, 2).toLowerCase() == 'ps' || + goog.LOCALE.substring(0, 2).toLowerCase() == 'sd' || + goog.LOCALE.substring(0, 2).toLowerCase() == 'ug' || + goog.LOCALE.substring(0, 2).toLowerCase() == 'ur' || + goog.LOCALE.substring(0, 2).toLowerCase() == 'yi') && + (goog.LOCALE.length == 2 || goog.LOCALE.substring(2, 3) == '-' || + goog.LOCALE.substring(2, 3) == '_')) || + (goog.LOCALE.length >= 3 && + goog.LOCALE.substring(0, 3).toLowerCase() == 'ckb' && + (goog.LOCALE.length == 3 || goog.LOCALE.substring(3, 4) == '-' || + goog.LOCALE.substring(3, 4) == '_')); /** @@ -26933,16 +24103,16 @@ goog.i18n.bidi.LEFT = 'left'; * 'left' if locale is RTL, 'right' if not. * @type {string} */ -goog.i18n.bidi.I18N_RIGHT = goog.i18n.bidi.IS_RTL ? goog.i18n.bidi.LEFT : - goog.i18n.bidi.RIGHT; +goog.i18n.bidi.I18N_RIGHT = + goog.i18n.bidi.IS_RTL ? goog.i18n.bidi.LEFT : goog.i18n.bidi.RIGHT; /** * 'right' if locale is RTL, 'left' if not. * @type {string} */ -goog.i18n.bidi.I18N_LEFT = goog.i18n.bidi.IS_RTL ? goog.i18n.bidi.RIGHT : - goog.i18n.bidi.LEFT; +goog.i18n.bidi.I18N_LEFT = + goog.i18n.bidi.IS_RTL ? goog.i18n.bidi.RIGHT : goog.i18n.bidi.LEFT; /** @@ -26965,9 +24135,9 @@ goog.i18n.bidi.I18N_LEFT = goog.i18n.bidi.IS_RTL ? goog.i18n.bidi.RIGHT : goog.i18n.bidi.toDir = function(givenDir, opt_noNeutral) { if (typeof givenDir == 'number') { // This includes the non-null goog.i18n.bidi.Dir case. - return givenDir > 0 ? goog.i18n.bidi.Dir.LTR : - givenDir < 0 ? goog.i18n.bidi.Dir.RTL : - opt_noNeutral ? null : goog.i18n.bidi.Dir.NEUTRAL; + return givenDir > 0 ? goog.i18n.bidi.Dir.LTR : givenDir < 0 ? + goog.i18n.bidi.Dir.RTL : + opt_noNeutral ? null : goog.i18n.bidi.Dir.NEUTRAL; } else if (givenDir == null) { return null; } else { @@ -27024,8 +24194,7 @@ goog.i18n.bidi.htmlSkipReg_ = /<[^>]*>|&[^;]+;/g; * @private */ goog.i18n.bidi.stripHtmlIfNeeded_ = function(str, opt_isStripNeeded) { - return opt_isStripNeeded ? str.replace(goog.i18n.bidi.htmlSkipReg_, '') : - str; + return opt_isStripNeeded ? str.replace(goog.i18n.bidi.htmlSkipReg_, '') : str; }; @@ -27053,8 +24222,8 @@ goog.i18n.bidi.ltrCharReg_ = new RegExp('[' + goog.i18n.bidi.ltrChars_ + ']'); * @return {boolean} Whether the string contains RTL characters. */ goog.i18n.bidi.hasAnyRtl = function(str, opt_isHtml) { - return goog.i18n.bidi.rtlCharReg_.test(goog.i18n.bidi.stripHtmlIfNeeded_( - str, opt_isHtml)); + return goog.i18n.bidi.rtlCharReg_.test( + goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml)); }; @@ -27075,8 +24244,8 @@ goog.i18n.bidi.hasRtlChar = goog.i18n.bidi.hasAnyRtl; * @return {boolean} Whether the string contains LTR characters. */ goog.i18n.bidi.hasAnyLtr = function(str, opt_isHtml) { - return goog.i18n.bidi.ltrCharReg_.test(goog.i18n.bidi.stripHtmlIfNeeded_( - str, opt_isHtml)); + return goog.i18n.bidi.ltrCharReg_.test( + goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml)); }; @@ -27157,8 +24326,8 @@ goog.i18n.bidi.rtlDirCheckRe_ = new RegExp( * strongly-directional character method. */ goog.i18n.bidi.startsWithRtl = function(str, opt_isHtml) { - return goog.i18n.bidi.rtlDirCheckRe_.test(goog.i18n.bidi.stripHtmlIfNeeded_( - str, opt_isHtml)); + return goog.i18n.bidi.rtlDirCheckRe_.test( + goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml)); }; @@ -27183,8 +24352,8 @@ goog.i18n.bidi.isRtlText = goog.i18n.bidi.startsWithRtl; * strongly-directional character method. */ goog.i18n.bidi.startsWithLtr = function(str, opt_isHtml) { - return goog.i18n.bidi.ltrDirCheckRe_.test(goog.i18n.bidi.stripHtmlIfNeeded_( - str, opt_isHtml)); + return goog.i18n.bidi.ltrDirCheckRe_.test( + goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml)); }; @@ -27306,8 +24475,8 @@ goog.i18n.bidi.isRtlExitText = goog.i18n.bidi.endsWithRtl; */ goog.i18n.bidi.rtlLocalesRe_ = new RegExp( '^(ar|ckb|dv|he|iw|fa|nqo|ps|sd|ug|ur|yi|' + - '.*[-_](Arab|Hebr|Thaa|Nkoo|Tfng))' + - '(?!.*[-_](Latn|Cyrl)($|-|_))($|-|_)', + '.*[-_](Arab|Hebr|Thaa|Nkoo|Tfng))' + + '(?!.*[-_](Latn|Cyrl)($|-|_))($|-|_)', 'i'); @@ -27339,15 +24508,6 @@ goog.i18n.bidi.isRtlLanguage = function(lang) { /** - * Regular expression for bracket guard replacement in html. - * @type {RegExp} - * @private - */ -goog.i18n.bidi.bracketGuardHtmlRe_ = - /(\(.*?\)+)|(\[.*?\]+)|(\{.*?\}+)|(<.*?(>)+)/g; - - -/** * Regular expression for bracket guard replacement in text. * @type {RegExp} * @private @@ -27357,38 +24517,19 @@ goog.i18n.bidi.bracketGuardTextRe_ = /** - * Apply bracket guard using html span tag. This is to address the problem of - * messy bracket display frequently happens in RTL layout. - * @param {string} s The string that need to be processed. - * @param {boolean=} opt_isRtlContext specifies default direction (usually - * direction of the UI). - * @return {string} The processed string, with all bracket guarded. - */ -goog.i18n.bidi.guardBracketInHtml = function(s, opt_isRtlContext) { - var useRtl = opt_isRtlContext === undefined ? - goog.i18n.bidi.hasAnyRtl(s) : opt_isRtlContext; - if (useRtl) { - return s.replace(goog.i18n.bidi.bracketGuardHtmlRe_, - '<span dir=rtl>$&</span>'); - } - return s.replace(goog.i18n.bidi.bracketGuardHtmlRe_, - '<span dir=ltr>$&</span>'); -}; - - -/** * Apply bracket guard using LRM and RLM. This is to address the problem of * messy bracket display frequently happens in RTL layout. - * This version works for both plain text and html. But it does not work as - * good as guardBracketInHtml in some cases. + * This function works for plain text, not for HTML. In HTML, the opening + * bracket might be in a different context than the closing bracket (such as + * an attribute value). * @param {string} s The string that need to be processed. * @param {boolean=} opt_isRtlContext specifies default direction (usually * direction of the UI). * @return {string} The processed string, with all bracket guarded. */ goog.i18n.bidi.guardBracketInText = function(s, opt_isRtlContext) { - var useRtl = opt_isRtlContext === undefined ? - goog.i18n.bidi.hasAnyRtl(s) : opt_isRtlContext; + var useRtl = opt_isRtlContext === undefined ? goog.i18n.bidi.hasAnyRtl(s) : + opt_isRtlContext; var mark = useRtl ? goog.i18n.bidi.Format.RLM : goog.i18n.bidi.Format.LRM; return s.replace(goog.i18n.bidi.bracketGuardTextRe_, mark + '$&' + mark); }; @@ -27496,12 +24637,14 @@ goog.i18n.bidi.tempRe_ = /%%%%/g; * @return {string} Processed CSS specification string. */ goog.i18n.bidi.mirrorCSS = function(cssStr) { - return cssStr. + return cssStr + . // reverse dimensions - replace(goog.i18n.bidi.dimensionsRe_, ':$1 $4 $3 $2'). - replace(goog.i18n.bidi.leftRe_, '%%%%'). // swap left and right - replace(goog.i18n.bidi.rightRe_, goog.i18n.bidi.LEFT). - replace(goog.i18n.bidi.tempRe_, goog.i18n.bidi.RIGHT); + replace(goog.i18n.bidi.dimensionsRe_, ':$1 $4 $3 $2') + .replace(goog.i18n.bidi.leftRe_, '%%%%') + . // swap left and right + replace(goog.i18n.bidi.rightRe_, goog.i18n.bidi.LEFT) + .replace(goog.i18n.bidi.tempRe_, goog.i18n.bidi.RIGHT); }; @@ -27530,9 +24673,8 @@ goog.i18n.bidi.singleQuoteSubstituteRe_ = /([\u0591-\u05f2])'/g; * @return {string} Processed string with double/single quote replaced. */ goog.i18n.bidi.normalizeHebrewQuote = function(str) { - return str. - replace(goog.i18n.bidi.doubleQuoteSubstituteRe_, '$1\u05f4'). - replace(goog.i18n.bidi.singleQuoteSubstituteRe_, '$1\u05f3'); + return str.replace(goog.i18n.bidi.doubleQuoteSubstituteRe_, '$1\u05f4') + .replace(goog.i18n.bidi.singleQuoteSubstituteRe_, '$1\u05f3'); }; @@ -27589,8 +24731,8 @@ goog.i18n.bidi.estimateDirection = function(str, opt_isHtml) { var rtlCount = 0; var totalCount = 0; var hasWeaklyLtr = false; - var tokens = goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml). - split(goog.i18n.bidi.wordSeparatorRe_); + var tokens = goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml) + .split(goog.i18n.bidi.wordSeparatorRe_); for (var i = 0; i < tokens.length; i++) { var token = tokens[i]; if (goog.i18n.bidi.startsWithRtl(token)) { @@ -27608,7 +24750,8 @@ goog.i18n.bidi.estimateDirection = function(str, opt_isHtml) { return totalCount == 0 ? (hasWeaklyLtr ? goog.i18n.bidi.Dir.LTR : goog.i18n.bidi.Dir.NEUTRAL) : (rtlCount / totalCount > goog.i18n.bidi.rtlDetectionThreshold_ ? - goog.i18n.bidi.Dir.RTL : goog.i18n.bidi.Dir.LTR); + goog.i18n.bidi.Dir.RTL : + goog.i18n.bidi.Dir.LTR); }; @@ -27642,9 +24785,9 @@ goog.i18n.bidi.setElementDirAndAlign = function(element, dir) { if (element) { dir = goog.i18n.bidi.toDir(dir); if (dir) { - element.style.textAlign = - dir == goog.i18n.bidi.Dir.RTL ? - goog.i18n.bidi.RIGHT : goog.i18n.bidi.LEFT; + element.style.textAlign = dir == goog.i18n.bidi.Dir.RTL ? + goog.i18n.bidi.RIGHT : + goog.i18n.bidi.LEFT; element.dir = dir == goog.i18n.bidi.Dir.RTL ? 'rtl' : 'ltr'; } } @@ -27690,8 +24833,8 @@ goog.i18n.bidi.DirectionalString = function() {}; * property to {@code true}. * @type {boolean} */ -goog.i18n.bidi.DirectionalString.prototype. - implementsGoogI18nBidiDirectionalString; +goog.i18n.bidi.DirectionalString.prototype + .implementsGoogI18nBidiDirectionalString; /** @@ -27726,6 +24869,7 @@ goog.require('goog.asserts'); goog.require('goog.fs.url'); goog.require('goog.i18n.bidi.Dir'); goog.require('goog.i18n.bidi.DirectionalString'); +goog.require('goog.string'); goog.require('goog.string.Const'); goog.require('goog.string.TypedString'); @@ -27918,9 +25062,8 @@ goog.html.SafeUrl.unwrap = function(safeUrl) { return safeUrl.privateDoNotAccessOrElseSafeHtmlWrappedValue_; } else { goog.asserts.fail('expected object of type SafeUrl, got \'' + - safeUrl + '\''); + safeUrl + '\' of type ' + goog.typeOf(safeUrl)); return 'type_error:SafeUrl'; - } }; @@ -27966,7 +25109,8 @@ goog.html.SAFE_MIME_TYPE_PATTERN_ = */ goog.html.SafeUrl.fromBlob = function(blob) { var url = goog.html.SAFE_MIME_TYPE_PATTERN_.test(blob.type) ? - goog.fs.url.createObjectUrl(blob) : goog.html.SafeUrl.INNOCUOUS_STRING; + goog.fs.url.createObjectUrl(blob) : + goog.html.SafeUrl.INNOCUOUS_STRING; return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url); }; @@ -28002,6 +25146,25 @@ goog.html.SafeUrl.fromDataUrl = function(dataUrl) { /** + * Creates a SafeUrl wrapping a tel: URL. + * + * @param {string} telUrl A tel URL. + * @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING} + * wrapped as a SafeUrl if it does not pass. + */ +goog.html.SafeUrl.fromTelUrl = function(telUrl) { + // There's a risk that a tel: URL could immediately place a call once + // clicked, without requiring user confirmation. For that reason it is + // handled in this separate function. + if (!goog.string.caseInsensitiveStartsWith(telUrl, 'tel:')) { + telUrl = goog.html.SafeUrl.INNOCUOUS_STRING; + } + return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse( + telUrl); +}; + + +/** * A pattern that recognizes a commonly useful subset of URLs that satisfy * the SafeUrl contract. * @@ -28036,26 +25199,12 @@ goog.html.SAFE_URL_PATTERN_ = /** * Creates a SafeUrl object from {@code url}. If {@code url} is a * goog.html.SafeUrl then it is simply returned. Otherwise the input string is - * validated to match a pattern of commonly used safe URLs. The string is - * converted to UTF-8 and non-whitelisted characters are percent-encoded. The - * string wrapped by the created SafeUrl will thus contain only ASCII printable - * characters. + * validated to match a pattern of commonly used safe URLs. * * {@code url} may be a URL with the http, https, mailto or ftp scheme, * or a relative URL (i.e., a URL without a scheme; specifically, a * scheme-relative, absolute-path-relative, or path-relative URL). * - * {@code url} is converted to UTF-8 and non-whitelisted characters are - * percent-encoded. Whitelisted characters are '%' and, from RFC 3986, - * unreserved characters and reserved characters, with the exception of '\'', - * '(' and ')'. This ensures the the SafeUrl contains only ASCII-printable - * characters and reduces the chance of security bugs were it to be - * interpolated into a specific context without the necessary escaping. - * - * If {@code url} fails validation or does not UTF-16 decode correctly - * (JavaScript strings are UTF-16 encoded), this function returns a SafeUrl - * object containing an innocuous string, goog.html.SafeUrl.INNOCUOUS_STRING. - * * @see http://url.spec.whatwg.org/#concept-relative-url * @param {string|!goog.string.TypedString} url The URL to validate. * @return {!goog.html.SafeUrl} The validated URL, wrapped as a SafeUrl. @@ -28063,8 +25212,7 @@ goog.html.SAFE_URL_PATTERN_ = goog.html.SafeUrl.sanitize = function(url) { if (url instanceof goog.html.SafeUrl) { return url; - } - else if (url.implementsGoogStringTypedString) { + } else if (url.implementsGoogStringTypedString) { url = url.getTypedStringValue(); } else { url = String(url); @@ -28099,6 +25247,15 @@ goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse = function( return safeUrl; }; + +/** + * A SafeUrl corresponding to the special about:blank url. + * @const {!goog.html.SafeUrl} + */ +goog.html.SafeUrl.ABOUT_BLANK = + goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse( + 'about:blank'); + // Copyright 2013 The Closure Library Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -28266,16 +25423,15 @@ goog.html.TrustedResourceUrl.unwrap = function(trustedResourceUrl) { if (trustedResourceUrl instanceof goog.html.TrustedResourceUrl && trustedResourceUrl.constructor === goog.html.TrustedResourceUrl && trustedResourceUrl - .TRUSTED_RESOURCE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ === - goog.html.TrustedResourceUrl - .TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) { + .TRUSTED_RESOURCE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ === + goog.html.TrustedResourceUrl + .TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) { return trustedResourceUrl .privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_; } else { goog.asserts.fail('expected object of type TrustedResourceUrl, got \'' + - trustedResourceUrl + '\''); + trustedResourceUrl + '\' of type ' + goog.typeOf(trustedResourceUrl)); return 'type_error:TrustedResourceUrl'; - } }; @@ -28299,6 +25455,27 @@ goog.html.TrustedResourceUrl.fromConstant = function(url) { /** + * Creates a TrustedResourceUrl object from a compile-time constant strings. + * + * Compile-time constant strings are inherently program-controlled and hence + * trusted. + * + * @param {!Array<!goog.string.Const>} parts Compile-time-constant strings from + * which to create a TrustedResourceUrl. + * @return {!goog.html.TrustedResourceUrl} A TrustedResourceUrl object + * initialized to concatenation of {@code parts}. + */ +goog.html.TrustedResourceUrl.fromConstants = function(parts) { + var unwrapped = ''; + for (var i = 0; i < parts.length; i++) { + unwrapped += goog.string.Const.unwrap(parts[i]); + } + return goog.html.TrustedResourceUrl + .createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(unwrapped); +}; + + +/** * Type marker for the TrustedResourceUrl type, used to implement additional * run-time type checking. * @const {!Object} @@ -28316,8 +25493,8 @@ goog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {}; * object. * @package */ -goog.html.TrustedResourceUrl. - createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse = function(url) { +goog.html.TrustedResourceUrl + .createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse = function(url) { var trustedResourceUrl = new goog.html.TrustedResourceUrl(); trustedResourceUrl.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_ = url; @@ -28357,6 +25534,7 @@ goog.require('goog.html.SafeUrl'); goog.require('goog.html.TrustedResourceUrl'); goog.require('goog.i18n.bidi.Dir'); goog.require('goog.i18n.bidi.DirectionalString'); +goog.require('goog.labs.userAgent.browser'); goog.require('goog.object'); goog.require('goog.string'); goog.require('goog.string.Const'); @@ -28437,7 +25615,7 @@ goog.html.SafeHtml.prototype.implementsGoogStringTypedString = true; /** - * Returns this SafeHtml's value a string. + * Returns this SafeHtml's value as string. * * IMPORTANT: In code where it is security relevant that an object's type is * indeed {@code SafeHtml}, use {@code goog.html.SafeHtml.unwrap} instead of @@ -28505,7 +25683,7 @@ goog.html.SafeHtml.unwrap = function(safeHtml) { return safeHtml.privateDoNotAccessOrElseSafeHtmlWrappedValue_; } else { goog.asserts.fail('expected object of type SafeHtml, got \'' + - safeHtml + '\''); + safeHtml + '\' of type ' + goog.typeOf(safeHtml)); return 'type_error:SafeHtml'; } }; @@ -28623,8 +25801,9 @@ goog.html.SafeHtml.VALID_NAMES_IN_TAG_ = /^[a-zA-Z0-9-]+$/; * http://www.w3.org/TR/html5/index.html#attributes-1. * @private @const {!Object<string,boolean>} */ -goog.html.SafeHtml.URL_ATTRIBUTES_ = goog.object.createSet('action', 'cite', - 'data', 'formaction', 'href', 'manifest', 'poster', 'src'); +goog.html.SafeHtml.URL_ATTRIBUTES_ = goog.object.createSet( + 'action', 'cite', 'data', 'formaction', 'href', 'manifest', 'poster', + 'src'); /** @@ -28635,17 +25814,17 @@ goog.html.SafeHtml.URL_ATTRIBUTES_ = goog.object.createSet('action', 'cite', * @private @const {!Object<string,boolean>} */ goog.html.SafeHtml.NOT_ALLOWED_TAG_NAMES_ = goog.object.createSet( - goog.dom.TagName.EMBED, goog.dom.TagName.IFRAME, goog.dom.TagName.LINK, - goog.dom.TagName.OBJECT, goog.dom.TagName.SCRIPT, goog.dom.TagName.STYLE, - goog.dom.TagName.TEMPLATE); + goog.dom.TagName.APPLET, goog.dom.TagName.BASE, goog.dom.TagName.EMBED, + goog.dom.TagName.IFRAME, goog.dom.TagName.LINK, goog.dom.TagName.MATH, + goog.dom.TagName.META, goog.dom.TagName.OBJECT, goog.dom.TagName.SCRIPT, + goog.dom.TagName.STYLE, goog.dom.TagName.SVG, goog.dom.TagName.TEMPLATE); /** * @typedef {string|number|goog.string.TypedString| * goog.html.SafeStyle.PropertyMap} - * @private */ -goog.html.SafeHtml.AttributeValue_; +goog.html.SafeHtml.AttributeValue; /** @@ -28679,16 +25858,17 @@ goog.html.SafeHtml.AttributeValue_; * - For attributes which are interpreted as URLs (e.g. src, href) a * goog.html.SafeUrl, goog.string.Const or string is required. If a string * is passed, it will be sanitized with SafeUrl.sanitize(). - * - For tags which can load code, more specific goog.html.SafeHtml.create*() - * functions must be used. Tags which can load code and are not supported by - * this function are embed, iframe, link, object, script, style, and template. + * - For tags which can load code or set security relevant page metadata, + * more specific goog.html.SafeHtml.create*() functions must be used. Tags + * which are not supported by this function are applet, base, embed, iframe, + * link, math, object, script, style, svg, and template. * * @param {string} tagName The name of the tag. Only tag names consisting of * [a-zA-Z0-9-] are allowed. Tag names documented above are disallowed. - * @param {!Object<string, goog.html.SafeHtml.AttributeValue_>=} - * opt_attributes Mapping from attribute names to their values. Only - * attribute names consisting of [a-zA-Z0-9-] are allowed. Value of null or - * undefined causes the attribute to be omitted. + * @param {!Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes + * Mapping from attribute names to their values. Only attribute names + * consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined causes + * the attribute to be omitted. * @param {!goog.html.SafeHtml.TextOrHtml_| * !Array<!goog.html.SafeHtml.TextOrHtml_>=} opt_content Content to * HTML-escape and put inside the tag. This must be empty for void tags @@ -28699,34 +25879,50 @@ goog.html.SafeHtml.AttributeValue_; * @throws {goog.asserts.AssertionError} If content for void tag is provided. */ goog.html.SafeHtml.create = function(tagName, opt_attributes, opt_content) { + goog.html.SafeHtml.verifyTagName(tagName); + return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse( + tagName, opt_attributes, opt_content); +}; + + +/** + * Verifies if the tag name is valid and if it doesn't change the context. + * E.g. STRONG is fine but SCRIPT throws because it changes context. See + * goog.html.SafeHtml.create for an explanation of allowed tags. + * @param {string} tagName + * @throws {Error} If invalid tag name is provided. + * @package + */ +goog.html.SafeHtml.verifyTagName = function(tagName) { if (!goog.html.SafeHtml.VALID_NAMES_IN_TAG_.test(tagName)) { throw Error('Invalid tag name <' + tagName + '>.'); } if (tagName.toUpperCase() in goog.html.SafeHtml.NOT_ALLOWED_TAG_NAMES_) { throw Error('Tag name <' + tagName + '> is not allowed for SafeHtml.'); } - return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse( - tagName, opt_attributes, opt_content); }; /** * Creates a SafeHtml representing an iframe tag. * - * By default the sandbox attribute is set to an empty value, which is the most - * secure option, as it confers the iframe the least privileges. If this - * is too restrictive then granting individual privileges is the preferable - * option. Unsetting the attribute entirely is the least secure option and - * should never be done unless it's stricly necessary. + * This by default restricts the iframe as much as possible by setting the + * sandbox attribute to the empty string. If the iframe requires less + * restrictions, set the sandbox attribute as tight as possible, but do not rely + * on the sandbox as a security feature because it is not supported by older + * browsers. If a sandbox is essential to security (e.g. for third-party + * frames), use createSandboxIframe which checks for browser support. + * + * @see https://developer.mozilla.org/en/docs/Web/HTML/Element/iframe#attr-sandbox * * @param {goog.html.TrustedResourceUrl=} opt_src The value of the src * attribute. If null or undefined src will not be set. * @param {goog.html.SafeHtml=} opt_srcdoc The value of the srcdoc attribute. * If null or undefined srcdoc will not be set. - * @param {!Object<string, goog.html.SafeHtml.AttributeValue_>=} - * opt_attributes Mapping from attribute names to their values. Only - * attribute names consisting of [a-zA-Z0-9-] are allowed. Value of null or - * undefined causes the attribute to be omitted. + * @param {!Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes + * Mapping from attribute names to their values. Only attribute names + * consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined causes + * the attribute to be omitted. * @param {!goog.html.SafeHtml.TextOrHtml_| * !Array<!goog.html.SafeHtml.TextOrHtml_>=} opt_content Content to * HTML-escape and put inside the tag. Array elements are concatenated. @@ -28736,9 +25932,15 @@ goog.html.SafeHtml.create = function(tagName, opt_attributes, opt_content) { */ goog.html.SafeHtml.createIframe = function( opt_src, opt_srcdoc, opt_attributes, opt_content) { + if (opt_src) { + // Check whether this is really TrustedResourceUrl. + goog.html.TrustedResourceUrl.unwrap(opt_src); + } + var fixedAttributes = {}; fixedAttributes['src'] = opt_src || null; - fixedAttributes['srcdoc'] = opt_srcdoc || null; + fixedAttributes['srcdoc'] = + opt_srcdoc && goog.html.SafeHtml.unwrap(opt_srcdoc); var defaultAttributes = {'sandbox': ''}; var attributes = goog.html.SafeHtml.combineAttributes( fixedAttributes, defaultAttributes, opt_attributes); @@ -28748,15 +25950,106 @@ goog.html.SafeHtml.createIframe = function( /** + * Creates a SafeHtml representing a sandboxed iframe tag. + * + * The sandbox attribute is enforced in its most restrictive mode, an empty + * string. Consequently, the security requirements for the src and srcdoc + * attributes are relaxed compared to SafeHtml.createIframe. This function + * will throw on browsers that do not support the sandbox attribute, as + * determined by SafeHtml.canUseSandboxIframe. + * + * The SafeHtml returned by this function can trigger downloads with no + * user interaction on Chrome (though only a few, further attempts are blocked). + * Firefox and IE will block all downloads from the sandbox. + * + * @see https://developer.mozilla.org/en/docs/Web/HTML/Element/iframe#attr-sandbox + * @see https://lists.w3.org/Archives/Public/public-whatwg-archive/2013Feb/0112.html + * + * @param {string|!goog.html.SafeUrl=} opt_src The value of the src + * attribute. If null or undefined src will not be set. + * @param {string=} opt_srcdoc The value of the srcdoc attribute. + * If null or undefined srcdoc will not be set. Will not be sanitized. + * @param {!Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes + * Mapping from attribute names to their values. Only attribute names + * consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined causes + * the attribute to be omitted. + * @param {!goog.html.SafeHtml.TextOrHtml_| + * !Array<!goog.html.SafeHtml.TextOrHtml_>=} opt_content Content to + * HTML-escape and put inside the tag. Array elements are concatenated. + * @return {!goog.html.SafeHtml} The SafeHtml content with the tag. + * @throws {Error} If invalid tag name, attribute name, or attribute value is + * provided. If opt_attributes contains the src, srcdoc or sandbox + * attributes. If browser does not support the sandbox attribute on iframe. + */ +goog.html.SafeHtml.createSandboxIframe = function( + opt_src, opt_srcdoc, opt_attributes, opt_content) { + if (!goog.html.SafeHtml.canUseSandboxIframe()) { + throw new Error('The browser does not support sandboxed iframes.'); + } + + var fixedAttributes = {}; + if (opt_src) { + // Note that sanitize is a no-op on SafeUrl. + fixedAttributes['src'] = + goog.html.SafeUrl.unwrap(goog.html.SafeUrl.sanitize(opt_src)); + } else { + fixedAttributes['src'] = null; + } + fixedAttributes['srcdoc'] = opt_srcdoc || null; + fixedAttributes['sandbox'] = ''; + var attributes = + goog.html.SafeHtml.combineAttributes(fixedAttributes, {}, opt_attributes); + return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse( + 'iframe', attributes, opt_content); +}; + + +/** + * Checks if the user agent supports sandboxed iframes. + * @return {boolean} + */ +goog.html.SafeHtml.canUseSandboxIframe = function() { + return goog.global['HTMLIFrameElement'] && + ('sandbox' in goog.global['HTMLIFrameElement'].prototype); +}; + + +/** + * Creates a SafeHtml representing a script tag with the src attribute. + * @param {!goog.html.TrustedResourceUrl} src The value of the src + * attribute. + * @param {!Object<string, ?goog.html.SafeHtml.AttributeValue>=} + * opt_attributes + * Mapping from attribute names to their values. Only attribute names + * consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined + * causes the attribute to be omitted. + * @return {!goog.html.SafeHtml} The SafeHtml content with the tag. + * @throws {Error} If invalid attribute name or value is provided. If + * opt_attributes contains the src attribute. + */ +goog.html.SafeHtml.createScriptSrc = function(src, opt_attributes) { + // Check whether this is really TrustedResourceUrl. + goog.html.TrustedResourceUrl.unwrap(src); + + var fixedAttributes = {'src': src}; + var defaultAttributes = {}; + var attributes = goog.html.SafeHtml.combineAttributes( + fixedAttributes, defaultAttributes, opt_attributes); + return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse( + 'script', attributes); +}; + + +/** * Creates a SafeHtml representing a style tag. The type attribute is set * to "text/css". * @param {!goog.html.SafeStyleSheet|!Array<!goog.html.SafeStyleSheet>} * styleSheet Content to put inside the tag. Array elements are * concatenated. - * @param {!Object<string, goog.html.SafeHtml.AttributeValue_>=} - * opt_attributes Mapping from attribute names to their values. Only - * attribute names consisting of [a-zA-Z0-9-] are allowed. Value of null or - * undefined causes the attribute to be omitted. + * @param {!Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes + * Mapping from attribute names to their values. Only attribute names + * consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined causes + * the attribute to be omitted. * @return {!goog.html.SafeHtml} The SafeHtml content with the tag. * @throws {Error} If invalid attribute name or attribute value is provided. If * opt_attributes contains the type attribute. @@ -28772,9 +26065,10 @@ goog.html.SafeHtml.createStyle = function(styleSheet, opt_attributes) { for (var i = 0; i < styleSheet.length; i++) { content += goog.html.SafeStyleSheet.unwrap(styleSheet[i]); } - // Convert to SafeHtml so that it's not HTML-escaped. - var htmlContent = goog.html.SafeHtml - .createSafeHtmlSecurityPrivateDoNotAccessOrElse( + // Convert to SafeHtml so that it's not HTML-escaped. This is safe because + // as part of its contract, SafeStyleSheet should have no dangerous '<'. + var htmlContent = + goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse( content, goog.i18n.bidi.Dir.NEUTRAL); return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse( 'style', attributes, htmlContent); @@ -28782,9 +26076,54 @@ goog.html.SafeHtml.createStyle = function(styleSheet, opt_attributes) { /** + * Creates a SafeHtml representing a meta refresh tag. + * @param {!goog.html.SafeUrl|string} url Where to redirect. If a string is + * passed, it will be sanitized with SafeUrl.sanitize(). + * @param {number=} opt_secs Number of seconds until the page should be + * reloaded. Will be set to 0 if unspecified. + * @return {!goog.html.SafeHtml} The SafeHtml content with the tag. + */ +goog.html.SafeHtml.createMetaRefresh = function(url, opt_secs) { + + // Note that sanitize is a no-op on SafeUrl. + var unwrappedUrl = goog.html.SafeUrl.unwrap(goog.html.SafeUrl.sanitize(url)); + + if (goog.labs.userAgent.browser.isIE() || + goog.labs.userAgent.browser.isEdge()) { + // IE/EDGE can't parse the content attribute if the url contains a + // semicolon. We can fix this by adding quotes around the url, but then we + // can't parse quotes in the URL correctly. Also, it seems that IE/EDGE + // did not unescape semicolons in these URLs at some point in the past. We + // take a best-effort approach. + // + // If the URL has semicolons (which may happen in some cases, see + // http://www.w3.org/TR/1999/REC-html401-19991224/appendix/notes.html#h-B.2 + // for instance), wrap it in single quotes to protect the semicolons. + // If the URL has semicolons and single quotes, url-encode the single quotes + // as well. + // + // This is imperfect. Notice that both ' and ; are reserved characters in + // URIs, so this could do the wrong thing, but at least it will do the wrong + // thing in only rare cases. + if (goog.string.contains(unwrappedUrl, ';')) { + unwrappedUrl = "'" + unwrappedUrl.replace(/'/g, '%27') + "'"; + } + } + var attributes = { + 'http-equiv': 'refresh', + 'content': (opt_secs || 0) + '; url=' + unwrappedUrl + }; + + // This function will handle the HTML escaping for attributes. + return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse( + 'meta', attributes); +}; + + +/** * @param {string} tagName The tag name. * @param {string} name The attribute name. - * @param {!goog.html.SafeHtml.AttributeValue_} value The attribute value. + * @param {!goog.html.SafeHtml.AttributeValue} value The attribute value. * @return {string} A "name=value" string. * @throws {Error} If attribute value is unsafe for the given tag and attribute. * @private @@ -28797,9 +26136,10 @@ goog.html.SafeHtml.getAttrNameAndValue_ = function(tagName, name, value) { value = goog.html.SafeHtml.getStyleValue_(value); } else if (/^on/i.test(name)) { // TODO(jakubvrana): Disallow more attributes with a special meaning. - throw Error('Attribute "' + name + - '" requires goog.string.Const value, "' + value + '" given.'); - // URL attributes handled differently accroding to tag. + throw Error( + 'Attribute "' + name + '" requires goog.string.Const value, "' + value + + '" given.'); + // URL attributes handled differently accroding to tag. } else if (name.toLowerCase() in goog.html.SafeHtml.URL_ATTRIBUTES_) { if (value instanceof goog.html.TrustedResourceUrl) { value = goog.html.TrustedResourceUrl.unwrap(value); @@ -28808,7 +26148,8 @@ goog.html.SafeHtml.getAttrNameAndValue_ = function(tagName, name, value) { } else if (goog.isString(value)) { value = goog.html.SafeUrl.sanitize(value).getTypedStringValue(); } else { - throw Error('Attribute "' + name + '" on tag "' + tagName + + throw Error( + 'Attribute "' + name + '" on tag "' + tagName + '" requires goog.html.SafeUrl, goog.string.Const, or string,' + ' value "' + value + '" given.'); } @@ -28822,16 +26163,17 @@ goog.html.SafeHtml.getAttrNameAndValue_ = function(tagName, name, value) { value = value.getTypedStringValue(); } - goog.asserts.assert(goog.isString(value) || goog.isNumber(value), - 'String or number value expected, got ' + - (typeof value) + ' with value: ' + value); + goog.asserts.assert( + goog.isString(value) || goog.isNumber(value), + 'String or number value expected, got ' + (typeof value) + + ' with value: ' + value); return name + '="' + goog.string.htmlEscape(String(value)) + '"'; }; /** * Gets value allowed in "style" attribute. - * @param {goog.html.SafeHtml.AttributeValue_} value It could be SafeStyle or a + * @param {!goog.html.SafeHtml.AttributeValue} value It could be SafeStyle or a * map which will be passed to goog.html.SafeStyle.create. * @return {string} Unwrapped value. * @throws {Error} If string value is given. @@ -28839,7 +26181,8 @@ goog.html.SafeHtml.getAttrNameAndValue_ = function(tagName, name, value) { */ goog.html.SafeHtml.getStyleValue_ = function(value) { if (!goog.isObject(value)) { - throw Error('The "style" attribute requires goog.html.SafeStyle or map ' + + throw Error( + 'The "style" attribute requires goog.html.SafeStyle or map ' + 'of style properties, ' + (typeof value) + ' given: ' + value); } if (!(value instanceof goog.html.SafeStyle)) { @@ -28855,13 +26198,13 @@ goog.html.SafeHtml.getStyleValue_ = function(value) { * optional attributes and optional content. * @param {!goog.i18n.bidi.Dir} dir Directionality. * @param {string} tagName - * @param {!Object<string, goog.html.SafeHtml.AttributeValue_>=} opt_attributes + * @param {!Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes * @param {!goog.html.SafeHtml.TextOrHtml_| * !Array<!goog.html.SafeHtml.TextOrHtml_>=} opt_content * @return {!goog.html.SafeHtml} The SafeHtml content with the tag. */ -goog.html.SafeHtml.createWithDir = function(dir, tagName, opt_attributes, - opt_content) { +goog.html.SafeHtml.createWithDir = function( + dir, tagName, opt_attributes, opt_content) { var html = goog.html.SafeHtml.create(tagName, opt_attributes, opt_content); html.dir_ = dir; return html; @@ -28965,7 +26308,7 @@ goog.html.SafeHtml.prototype.initSecurityPrivateDoNotAccessOrElse_ = function( * Like create() but does not restrict which tags can be constructed. * * @param {string} tagName Tag name. Set or validated by caller. - * @param {!Object<string, goog.html.SafeHtml.AttributeValue_>=} opt_attributes + * @param {!Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes * @param {(!goog.html.SafeHtml.TextOrHtml_| * !Array<!goog.html.SafeHtml.TextOrHtml_>)=} opt_content * @return {!goog.html.SafeHtml} @@ -28973,24 +26316,11 @@ goog.html.SafeHtml.prototype.initSecurityPrivateDoNotAccessOrElse_ = function( * @throws {goog.asserts.AssertionError} If content for void tag is provided. * @package */ -goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse = - function(tagName, opt_attributes, opt_content) { +goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse = function( + tagName, opt_attributes, opt_content) { var dir = null; var result = '<' + tagName; - - if (opt_attributes) { - for (var name in opt_attributes) { - if (!goog.html.SafeHtml.VALID_NAMES_IN_TAG_.test(name)) { - throw Error('Invalid attribute name "' + name + '".'); - } - var value = opt_attributes[name]; - if (!goog.isDefAndNotNull(value)) { - continue; - } - result += ' ' + - goog.html.SafeHtml.getAttrNameAndValue_(tagName, name, value); - } - } + result += goog.html.SafeHtml.stringifyAttributes(tagName, opt_attributes); var content = opt_content; if (!goog.isDefAndNotNull(content)) { @@ -29000,8 +26330,8 @@ goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse = } if (goog.dom.tags.isVoidTag(tagName.toLowerCase())) { - goog.asserts.assert(!content.length, - 'Void tag <' + tagName + '> does not allow content.'); + goog.asserts.assert( + !content.length, 'Void tag <' + tagName + '> does not allow content.'); result += '>'; } else { var html = goog.html.SafeHtml.concat(content); @@ -29026,11 +26356,39 @@ goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse = /** + * Creates a string with attributes to insert after tagName. + * @param {string} tagName + * @param {!Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes + * @return {string} Returns an empty string if there are no attributes, returns + * a string starting with a space otherwise. + * @throws {Error} If attribute value is unsafe for the given tag and attribute. + * @package + */ +goog.html.SafeHtml.stringifyAttributes = function(tagName, opt_attributes) { + var result = ''; + if (opt_attributes) { + for (var name in opt_attributes) { + if (!goog.html.SafeHtml.VALID_NAMES_IN_TAG_.test(name)) { + throw Error('Invalid attribute name "' + name + '".'); + } + var value = opt_attributes[name]; + if (!goog.isDefAndNotNull(value)) { + continue; + } + result += + ' ' + goog.html.SafeHtml.getAttrNameAndValue_(tagName, name, value); + } + } + return result; +} + + +/** * @param {!Object<string, string>} fixedAttributes * @param {!Object<string, string>} defaultAttributes - * @param {!Object<string, goog.html.SafeHtml.AttributeValue_>=} - * opt_attributes Optional attributes passed to create*(). - * @return {!Object<string, goog.html.SafeHtml.AttributeValue_>} + * @param {!Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes + * Optional attributes passed to create*(). + * @return {!Object<string, ?goog.html.SafeHtml.AttributeValue>} * @throws {Error} If opt_attributes contains an attribute with the same name * as an attribute in fixedAttributes. * @package @@ -29052,8 +26410,9 @@ goog.html.SafeHtml.combineAttributes = function( for (name in opt_attributes) { var nameLower = name.toLowerCase(); if (nameLower in fixedAttributes) { - throw Error('Cannot override "' + nameLower + '" attribute, got "' + - name + '" with value "' + opt_attributes[name] + '"'); + throw Error( + 'Cannot override "' + nameLower + '" attribute, got "' + name + + '" with value "' + opt_attributes[name] + '"'); } if (nameLower in defaultAttributes) { delete combinedAttributes[nameLower]; @@ -29082,6 +26441,15 @@ goog.html.SafeHtml.EMPTY = goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse( '', goog.i18n.bidi.Dir.NEUTRAL); + +/** + * A SafeHtml instance corresponding to the <br> tag. + * @const {!goog.html.SafeHtml} + */ +goog.html.SafeHtml.BR = + goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse( + '<br>', goog.i18n.bidi.Dir.NEUTRAL); + // Copyright 2013 The Closure Library Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -29215,6 +26583,30 @@ goog.dom.safe.setAnchorHref = function(anchor, url) { /** + * Safely assigns a URL to an image element's src property. + * + * If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to + * image's src property. If url is of type string however, it is first + * sanitized using goog.html.SafeUrl.sanitize. + * + * @param {!HTMLImageElement} imageElement The image element whose src property + * is to be assigned to. + * @param {string|!goog.html.SafeUrl} url The URL to assign. + * @see goog.html.SafeUrl#sanitize + */ +goog.dom.safe.setImageSrc = function(imageElement, url) { + /** @type {!goog.html.SafeUrl} */ + var safeUrl; + if (url instanceof goog.html.SafeUrl) { + safeUrl = url; + } else { + safeUrl = goog.html.SafeUrl.sanitize(url); + } + imageElement.src = goog.html.SafeUrl.unwrap(safeUrl); +}; + + +/** * Safely assigns a URL to an embed element's src property. * * Example usage: @@ -29421,13 +26813,192 @@ goog.dom.safe.openInWindow = function( safeUrl = goog.html.SafeUrl.sanitize(url); } var win = opt_openerWin || window; - return win.open(goog.html.SafeUrl.unwrap(safeUrl), + return win.open( + goog.html.SafeUrl.unwrap(safeUrl), // If opt_name is undefined, simply passing that in to open() causes IE to // reuse the current window instead of opening a new one. Thus we pass '' // in instead, which according to spec opens a new window. See // https://html.spec.whatwg.org/multipage/browsers.html#dom-open . - opt_name ? goog.string.Const.unwrap(opt_name) : '', - opt_specs, opt_replace); + opt_name ? goog.string.Const.unwrap(opt_name) : '', opt_specs, + opt_replace); +}; + +// Copyright 2013 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Transitional utilities to unsafely trust random strings as + * goog.html types. Intended for temporary use when upgrading a library that + * used to accept plain strings to use safe types, but where it's not + * practical to transitively update callers. + * + * IMPORTANT: No new code should use the conversion functions in this file, + * they are intended for refactoring old code to use goog.html types. New code + * should construct goog.html types via their APIs, template systems or + * sanitizers. If that’s not possible it should use + * goog.html.uncheckedconversions and undergo security review. + + * + * The semantics of the conversions in goog.html.legacyconversions are very + * different from the ones provided by goog.html.uncheckedconversions. The + * latter are for use in code where it has been established through manual + * security review that the value produced by a piece of code will always + * satisfy the SafeHtml contract (e.g., the output of a secure HTML sanitizer). + * In uses of goog.html.legacyconversions, this guarantee is not given -- the + * value in question originates in unreviewed legacy code and there is no + * guarantee that it satisfies the SafeHtml contract. + * + * There are only three valid uses of legacyconversions: + * + * 1. Introducing a goog.html version of a function which currently consumes + * string and passes that string to a DOM API which can execute script - and + * hence cause XSS - like innerHTML. For example, Dialog might expose a + * setContent method which takes a string and sets the innerHTML property of + * an element with it. In this case a setSafeHtmlContent function could be + * added, consuming goog.html.SafeHtml instead of string, and using + * goog.dom.safe.setInnerHtml instead of directly setting innerHTML. + * setContent could then internally use legacyconversions to create a SafeHtml + * from string and pass the SafeHtml to setSafeHtmlContent. In this scenario + * remember to document the use of legacyconversions in the modified setContent + * and consider deprecating it as well. + * + * 2. Automated refactoring of application code which handles HTML as string + * but needs to call a function which only takes goog.html types. For example, + * in the Dialog scenario from (1) an alternative option would be to refactor + * setContent to accept goog.html.SafeHtml instead of string and then refactor + * all current callers to use legacyconversions to pass SafeHtml. This is + * generally preferable to (1) because it keeps the library clean of + * legacyconversions, and makes code sites in application code that are + * potentially vulnerable to XSS more apparent. + * + * 3. Old code which needs to call APIs which consume goog.html types and for + * which it is prohibitively expensive to refactor to use goog.html types. + * Generally, this is code where safety from XSS is either hopeless or + * unimportant. + * + * @visibility {//closure/goog/html:approved_for_legacy_conversion} + * @visibility {//closure/goog/bin/sizetests:__pkg__} + */ + + +goog.provide('goog.html.legacyconversions'); + +goog.require('goog.html.SafeHtml'); +goog.require('goog.html.SafeStyle'); +goog.require('goog.html.SafeStyleSheet'); +goog.require('goog.html.SafeUrl'); +goog.require('goog.html.TrustedResourceUrl'); + + +/** + * Performs an "unchecked conversion" from string to SafeHtml for legacy API + * purposes. + * + * Please read fileoverview documentation before using. + * + * @param {string} html A string to be converted to SafeHtml. + * @return {!goog.html.SafeHtml} The value of html, wrapped in a SafeHtml + * object. + */ +goog.html.legacyconversions.safeHtmlFromString = function(html) { + goog.html.legacyconversions.reportCallback_(); + return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse( + html, null /* dir */); +}; + + +/** + * Performs an "unchecked conversion" from string to SafeStyle for legacy API + * purposes. + * + * Please read fileoverview documentation before using. + * + * @param {string} style A string to be converted to SafeStyle. + * @return {!goog.html.SafeStyle} The value of style, wrapped in a SafeStyle + * object. + */ +goog.html.legacyconversions.safeStyleFromString = function(style) { + goog.html.legacyconversions.reportCallback_(); + return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse( + style); +}; + + +/** + * Performs an "unchecked conversion" from string to SafeStyleSheet for legacy + * API purposes. + * + * Please read fileoverview documentation before using. + * + * @param {string} styleSheet A string to be converted to SafeStyleSheet. + * @return {!goog.html.SafeStyleSheet} The value of style sheet, wrapped in + * a SafeStyleSheet object. + */ +goog.html.legacyconversions.safeStyleSheetFromString = function(styleSheet) { + goog.html.legacyconversions.reportCallback_(); + return goog.html.SafeStyleSheet + .createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(styleSheet); +}; + + +/** + * Performs an "unchecked conversion" from string to SafeUrl for legacy API + * purposes. + * + * Please read fileoverview documentation before using. + * + * @param {string} url A string to be converted to SafeUrl. + * @return {!goog.html.SafeUrl} The value of url, wrapped in a SafeUrl + * object. + */ +goog.html.legacyconversions.safeUrlFromString = function(url) { + goog.html.legacyconversions.reportCallback_(); + return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url); +}; + + +/** + * Performs an "unchecked conversion" from string to TrustedResourceUrl for + * legacy API purposes. + * + * Please read fileoverview documentation before using. + * + * @param {string} url A string to be converted to TrustedResourceUrl. + * @return {!goog.html.TrustedResourceUrl} The value of url, wrapped in a + * TrustedResourceUrl object. + */ +goog.html.legacyconversions.trustedResourceUrlFromString = function(url) { + goog.html.legacyconversions.reportCallback_(); + return goog.html.TrustedResourceUrl + .createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(url); +}; + +/** + * @private {function(): undefined} + */ +goog.html.legacyconversions.reportCallback_ = goog.nullFunction; + + +/** + * Sets a function that will be called every time a legacy conversion is + * performed. The function is called with no parameters but it can use + * goog.debug.getStacktrace to get a stacktrace. + * + * @param {function(): undefined} callback Error callback as defined above. + */ +goog.html.legacyconversions.setReportCallback = function(callback) { + goog.html.legacyconversions.reportCallback_ = callback; }; // Copyright 2006 The Closure Library Authors. All Rights Reserved. @@ -29641,7 +27212,7 @@ goog.math.Coordinate.prototype.translate = function(tx, opt_ty) { this.x += tx.x; this.y += tx.y; } else { - this.x += tx; + this.x += Number(tx); if (goog.isNumber(opt_ty)) { this.y += opt_ty; } @@ -29969,6 +27540,7 @@ goog.require('goog.dom.NodeType'); goog.require('goog.dom.TagName'); goog.require('goog.dom.safe'); goog.require('goog.html.SafeHtml'); +goog.require('goog.html.legacyconversions'); goog.require('goog.math.Coordinate'); goog.require('goog.math.Size'); goog.require('goog.object'); @@ -30010,13 +27582,13 @@ goog.dom.getDomHelper = function(opt_element) { return opt_element ? new goog.dom.DomHelper(goog.dom.getOwnerDocument(opt_element)) : (goog.dom.defaultDomHelper_ || - (goog.dom.defaultDomHelper_ = new goog.dom.DomHelper())); + (goog.dom.defaultDomHelper_ = new goog.dom.DomHelper())); }; /** * Cached default DOM helper. - * @type {goog.dom.DomHelper} + * @type {!goog.dom.DomHelper|undefined} * @private */ goog.dom.defaultDomHelper_; @@ -30053,9 +27625,7 @@ goog.dom.getElement = function(element) { * @private */ goog.dom.getElementHelper_ = function(doc, element) { - return goog.isString(element) ? - doc.getElementById(element) : - element; + return goog.isString(element) ? doc.getElementById(element) : element; }; @@ -30085,8 +27655,8 @@ goog.dom.getRequiredElementHelper_ = function(doc, id) { // To prevent users passing in Elements as is permitted in getElement(). goog.asserts.assertString(id); var element = goog.dom.getElementHelper_(doc, id); - element = goog.asserts.assertElement(element, - 'No element found with id: ' + id); + element = + goog.asserts.assertElement(element, 'No element found with id: ' + id); return element; }; @@ -30122,12 +27692,12 @@ goog.dom.$ = goog.dom.getElement; * @param {?string=} opt_tag Element tag name. * @param {?string=} opt_class Optional class name. * @param {(Document|Element)=} opt_el Optional element to look in. - * @return { {length: number} } Array-like list of elements (only a length + * @return {!IArrayLike<!Element>} Array-like list of elements (only a length * property and numerical indices are guaranteed to exist). */ goog.dom.getElementsByTagNameAndClass = function(opt_tag, opt_class, opt_el) { - return goog.dom.getElementsByTagNameAndClass_(document, opt_tag, opt_class, - opt_el); + return goog.dom.getElementsByTagNameAndClass_( + document, opt_tag, opt_class, opt_el); }; @@ -30137,7 +27707,7 @@ goog.dom.getElementsByTagNameAndClass = function(opt_tag, opt_class, opt_el) { * @see {goog.dom.query} * @param {string} className the name of the class to look for. * @param {(Document|Element)=} opt_el Optional element to look in. - * @return { {length: number} } The items found with the class name provided. + * @return {!IArrayLike<!Element>} The items found with the class name provided. */ goog.dom.getElementsByClass = function(className, opt_el) { var parent = opt_el || document; @@ -30183,8 +27753,8 @@ goog.dom.getElementByClass = function(className, opt_el) { */ goog.dom.getRequiredElementByClass = function(className, opt_root) { var retValue = goog.dom.getElementByClass(className, opt_root); - return goog.asserts.assert(retValue, - 'No element found with className: ' + className); + return goog.asserts.assert( + retValue, 'No element found with className: ' + className); }; @@ -30206,17 +27776,16 @@ goog.dom.canUseQuerySelector_ = function(parent) { * @param {?string=} opt_tag Element tag name. * @param {?string=} opt_class Optional class name. * @param {(Document|Element)=} opt_el Optional element to look in. - * @return { {length: number} } Array-like list of elements (only a length + * @return {!IArrayLike<!Element>} Array-like list of elements (only a length * property and numerical indices are guaranteed to exist). * @private */ -goog.dom.getElementsByTagNameAndClass_ = function(doc, opt_tag, opt_class, - opt_el) { +goog.dom.getElementsByTagNameAndClass_ = function( + doc, opt_tag, opt_class, opt_el) { var parent = opt_el || doc; var tagName = (opt_tag && opt_tag != '*') ? opt_tag.toUpperCase() : ''; - if (goog.dom.canUseQuerySelector_(parent) && - (tagName || opt_class)) { + if (goog.dom.canUseQuerySelector_(parent) && (tagName || opt_class)) { var query = tagName + (opt_class ? '.' + opt_class : ''); return parent.querySelectorAll(query); } @@ -30239,7 +27808,7 @@ goog.dom.getElementsByTagNameAndClass_ = function(doc, opt_tag, opt_class, } arrayLike.length = len; - return arrayLike; + return /** @type {!IArrayLike<!Element>} */ (arrayLike); } else { return els; } @@ -30259,7 +27828,7 @@ goog.dom.getElementsByTagNameAndClass_ = function(doc, opt_tag, opt_class, } } arrayLike.length = len; - return arrayLike; + return /** @type {!IArrayLike<!Element>} */ (arrayLike); } else { return els; } @@ -30271,7 +27840,7 @@ goog.dom.getElementsByTagNameAndClass_ = function(doc, opt_tag, opt_class, * @param {?string=} opt_tag Element tag name. * @param {?string=} opt_class Optional class name. * @param {Element=} opt_el Optional element to look in. - * @return { {length: number} } Array-like list of elements (only a length + * @return {!IArrayLike<!Element>} Array-like list of elements (only a length * property and numerical indices are guaranteed to exist). * @deprecated Use {@link goog.dom.getElementsByTagNameAndClass} instead. */ @@ -30293,7 +27862,8 @@ goog.dom.setProperties = function(element, properties) { element.htmlFor = val; } else if (goog.dom.DIRECT_ATTRIBUTE_MAP_.hasOwnProperty(key)) { element.setAttribute(goog.dom.DIRECT_ATTRIBUTE_MAP_[key], val); - } else if (goog.string.startsWith(key, 'aria-') || + } else if ( + goog.string.startsWith(key, 'aria-') || goog.string.startsWith(key, 'data-')) { element.setAttribute(key, val); } else { @@ -30318,6 +27888,7 @@ goog.dom.DIRECT_ATTRIBUTE_MAP_ = { 'frameborder': 'frameBorder', 'height': 'height', 'maxlength': 'maxLength', + 'nonce': 'nonce', 'role': 'role', 'rowspan': 'rowSpan', 'type': 'type', @@ -30420,6 +27991,15 @@ goog.dom.getDocumentHeight = function() { return goog.dom.getDocumentHeight_(window); }; +/** + * Calculates the height of the document of the given window. + * + * @param {!Window} win The window whose document height to retrieve. + * @return {number} The height of the document of the given window. + */ +goog.dom.getDocumentHeightForWindow = function(win) { + return goog.dom.getDocumentHeight_(win); +}; /** * Calculates the height of the document of the given window. @@ -30463,8 +28043,8 @@ goog.dom.getDocumentHeight_ = function(win) { // document.documentElement.offsetHeight // Based on studying the values output by different browsers, // use the value that's NOT equal to the viewport height found above. - height = docEl.scrollHeight != vh ? - docEl.scrollHeight : docEl.offsetHeight; + height = + docEl.scrollHeight != vh ? docEl.scrollHeight : docEl.offsetHeight; } else { // In Quirks mode: // documentElement.clientHeight is equal to documentElement.offsetHeight @@ -30538,8 +28118,8 @@ goog.dom.getDocumentScroll_ = function(doc) { // offsets. return new goog.math.Coordinate(el.scrollLeft, el.scrollTop); } - return new goog.math.Coordinate(win.pageXOffset || el.scrollLeft, - win.pageYOffset || el.scrollTop); + return new goog.math.Coordinate( + win.pageXOffset || el.scrollLeft, win.pageYOffset || el.scrollTop); }; @@ -30694,8 +28274,8 @@ goog.dom.append_ = function(doc, parent, args, startIndex) { function childHandler(child) { // TODO(user): More coercion, ala MochiKit? if (child) { - parent.appendChild(goog.isString(child) ? - doc.createTextNode(child) : child); + parent.appendChild( + goog.isString(child) ? doc.createTextNode(child) : child); } } @@ -30705,8 +28285,8 @@ goog.dom.append_ = function(doc, parent, args, startIndex) { if (goog.isArrayLike(arg) && !goog.dom.isNodeLike(arg)) { // If the argument is a node list, not a real array, use a clone, // because forEach can't be used to mutate a NodeList. - goog.array.forEach(goog.dom.isNodeList(arg) ? - goog.array.toArray(arg) : arg, + goog.array.forEach( + goog.dom.isNodeList(arg) ? goog.array.toArray(arg) : arg, childHandler); } else { childHandler(arg); @@ -30817,8 +28397,8 @@ goog.dom.safeHtmlToNode = function(html) { goog.dom.safeHtmlToNode_ = function(doc, html) { var tempDiv = doc.createElement(goog.dom.TagName.DIV); if (goog.dom.BrowserFeature.INNER_HTML_NEEDS_SCOPED_ELEMENT) { - goog.dom.safe.setInnerHtml(tempDiv, - goog.html.SafeHtml.concat(goog.html.SafeHtml.create('br'), html)); + goog.dom.safe.setInnerHtml( + tempDiv, goog.html.SafeHtml.concat(goog.html.SafeHtml.BR, html)); tempDiv.removeChild(tempDiv.firstChild); } else { goog.dom.safe.setInnerHtml(tempDiv, html); @@ -30839,35 +28419,17 @@ goog.dom.safeHtmlToNode_ = function(doc, html) { * * @param {string} htmlString The HTML string to convert. * @return {!Node} The resulting document fragment. + * @deprecated Use {@link goog.dom.safeHtmlToNode} instead. */ goog.dom.htmlToDocumentFragment = function(htmlString) { - return goog.dom.htmlToDocumentFragment_(document, htmlString); -}; - - -// TODO(jakubvrana): Merge with {@code safeHtmlToNode_}. -/** - * Helper for {@code htmlToDocumentFragment}. - * - * @param {!Document} doc The document. - * @param {string} htmlString The HTML string to convert. - * @return {!Node} The resulting document fragment. - * @private - */ -goog.dom.htmlToDocumentFragment_ = function(doc, htmlString) { - var tempDiv = doc.createElement(goog.dom.TagName.DIV); - if (goog.dom.BrowserFeature.INNER_HTML_NEEDS_SCOPED_ELEMENT) { - tempDiv.innerHTML = '<br>' + htmlString; - tempDiv.removeChild(tempDiv.firstChild); - } else { - tempDiv.innerHTML = htmlString; - } - return goog.dom.childrenToNode_(doc, tempDiv); + return goog.dom.safeHtmlToNode_(document, + // For now, we are blindly trusting that the HTML is safe. + goog.html.legacyconversions.safeHtmlFromString(htmlString)); }; /** - * Helper for {@code htmlToDocumentFragment_}. + * Helper for {@code safeHtmlToNode_}. * @param {!Document} doc The document. * @param {!Node} tempDiv The input node. * @return {!Node} The resulting node. @@ -31109,8 +28671,8 @@ goog.dom.flattenElement = function(element) { /** * Returns an array containing just the element children of the given element. * @param {Element} element The element whose element children we want. - * @return {!(Array|NodeList)} An array or array-like list of just the element - * children of the given element. + * @return {!(Array<!Element>|NodeList<!Element>)} An array or array-like list + * of just the element children of the given element. */ goog.dom.getChildren = function(element) { // We check if the children attribute is supported for child elements @@ -31133,7 +28695,7 @@ goog.dom.getChildren = function(element) { */ goog.dom.getFirstElementChild = function(node) { if (goog.isDef(node.firstElementChild)) { - return /** @type {!Element} */(node).firstElementChild; + return /** @type {!Element} */ (node).firstElementChild; } return goog.dom.getNextElementNode_(node.firstChild, true); }; @@ -31146,7 +28708,7 @@ goog.dom.getFirstElementChild = function(node) { */ goog.dom.getLastElementChild = function(node) { if (goog.isDef(node.lastElementChild)) { - return /** @type {!Element} */(node).lastElementChild; + return /** @type {!Element} */ (node).lastElementChild; } return goog.dom.getNextElementNode_(node.lastChild, false); }; @@ -31159,7 +28721,7 @@ goog.dom.getLastElementChild = function(node) { */ goog.dom.getNextElementSibling = function(node) { if (goog.isDef(node.nextElementSibling)) { - return /** @type {!Element} */(node).nextElementSibling; + return /** @type {!Element} */ (node).nextElementSibling; } return goog.dom.getNextElementNode_(node.nextSibling, true); }; @@ -31173,7 +28735,7 @@ goog.dom.getNextElementSibling = function(node) { */ goog.dom.getPreviousElementSibling = function(node) { if (goog.isDef(node.previousElementSibling)) { - return /** @type {!Element} */(node).previousElementSibling; + return /** @type {!Element} */ (node).previousElementSibling; } return goog.dom.getNextElementNode_(node.previousSibling, false); }; @@ -31282,13 +28844,12 @@ goog.dom.isWindow = function(obj) { goog.dom.getParentElement = function(element) { var parent; if (goog.dom.BrowserFeature.CAN_USE_PARENT_ELEMENT_PROPERTY) { - var isIe9 = goog.userAgent.IE && - goog.userAgent.isVersionOrHigher('9') && + var isIe9 = goog.userAgent.IE && goog.userAgent.isVersionOrHigher('9') && !goog.userAgent.isVersionOrHigher('10'); // SVG elements in IE9 can't use the parentElement property. // goog.global['SVGElement'] is not defined in IE9 quirks mode. if (!(isIe9 && goog.global['SVGElement'] && - element instanceof goog.global['SVGElement'])) { + element instanceof goog.global['SVGElement'])) { parent = element.parentElement; if (parent) { return parent; @@ -31302,11 +28863,14 @@ goog.dom.getParentElement = function(element) { /** * Whether a node contains another node. - * @param {Node} parent The node that should contain the other node. - * @param {Node} descendant The node to test presence of. + * @param {?Node} parent The node that should contain the other node. + * @param {?Node} descendant The node to test presence of. * @return {boolean} Whether the parent node contains the descendent node. */ goog.dom.contains = function(parent, descendant) { + if (!parent || !descendant) { + return false; + } // We use browser specific methods for this if available since it is faster // that way. @@ -31390,7 +28954,7 @@ goog.dom.compareNodeOrder = function(node1, node2) { } return (isElement1 ? node1.sourceIndex : parent1.sourceIndex) - - (isElement2 ? node2.sourceIndex : parent2.sourceIndex); + (isElement2 ? node2.sourceIndex : parent2.sourceIndex); } } @@ -31406,8 +28970,8 @@ goog.dom.compareNodeOrder = function(node1, node2) { range2.selectNode(node2); range2.collapse(true); - return range1.compareBoundaryPoints(goog.global['Range'].START_TO_END, - range2); + return range1.compareBoundaryPoints( + goog.global['Range'].START_TO_END, range2); }; @@ -31509,8 +29073,8 @@ goog.dom.getOwnerDocument = function(node) { // TODO(nnaze): Update param signature to be non-nullable. goog.asserts.assert(node, 'Node cannot be null or undefined.'); return /** @type {!Document} */ ( - node.nodeType == goog.dom.NodeType.DOCUMENT ? node : - node.ownerDocument || node.document); + node.nodeType == goog.dom.NodeType.DOCUMENT ? node : node.ownerDocument || + node.document); }; @@ -31520,19 +29084,29 @@ goog.dom.getOwnerDocument = function(node) { * @return {!Document} The frame content document. */ goog.dom.getFrameContentDocument = function(frame) { - var doc = frame.contentDocument || frame.contentWindow.document; - return doc; + return frame.contentDocument || + /** @type {!HTMLFrameElement} */ (frame).contentWindow.document; }; /** * Cross-browser function for getting the window of a frame or iframe. * @param {Element} frame Frame element. - * @return {Window} The window associated with the given frame. + * @return {Window} The window associated with the given frame, or null if none + * exists. */ goog.dom.getFrameContentWindow = function(frame) { - return frame.contentWindow || - goog.dom.getWindow(goog.dom.getFrameContentDocument(frame)); + try { + return frame.contentWindow || + (frame.contentDocument ? goog.dom.getWindow(frame.contentDocument) : + null); + } catch (e) { + // NOTE(user): In IE8, checking the contentWindow or contentDocument + // properties will throw a "Unspecified Error" exception if the iframe is + // not inserted in the DOM. If we get this we can be sure that no window + // exists, so return null. + } + return null; }; @@ -31542,15 +29116,16 @@ goog.dom.getFrameContentWindow = function(frame) { * @param {string|number} text The value that should replace the node's content. */ goog.dom.setTextContent = function(node, text) { - goog.asserts.assert(node != null, + goog.asserts.assert( + node != null, 'goog.dom.setTextContent expects a non-null value for node'); if ('textContent' in node) { node.textContent = text; } else if (node.nodeType == goog.dom.NodeType.TEXT) { node.data = text; - } else if (node.firstChild && - node.firstChild.nodeType == goog.dom.NodeType.TEXT) { + } else if ( + node.firstChild && node.firstChild.nodeType == goog.dom.NodeType.TEXT) { // If the first child is a text node we just change its data and remove the // rest of the children. while (node.lastChild != node.firstChild) { @@ -31572,6 +29147,9 @@ goog.dom.setTextContent = function(node, text) { * @return {string} The outerHTML of the given element. */ goog.dom.getOuterHtml = function(element) { + goog.asserts.assert( + element !== null, + 'goog.dom.getOuterHtml expects a non-null value for element'); // IE, Opera and WebKit all have outerHTML. if ('outerHTML' in element) { return element.outerHTML; @@ -31673,7 +29251,10 @@ goog.dom.TAGS_TO_IGNORE_ = { * @private {!Object<string, string>} * @const */ -goog.dom.PREDEFINED_TAG_VALUES_ = {'IMG': ' ', 'BR': '\n'}; +goog.dom.PREDEFINED_TAG_VALUES_ = { + 'IMG': ' ', + 'BR': '\n' +}; /** @@ -31683,11 +29264,10 @@ goog.dom.PREDEFINED_TAG_VALUES_ = {'IMG': ' ', 'BR': '\n'}; * @param {!Element} element Element to check. * @return {boolean} Whether the element has a tab index that allows keyboard * focus. - * @see http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ */ goog.dom.isFocusableTabIndex = function(element) { return goog.dom.hasSpecifiedTabIndex_(element) && - goog.dom.isTabIndexFocusable_(element); + goog.dom.isTabIndexFocusable_(element); }; @@ -31709,7 +29289,7 @@ goog.dom.setFocusableTabIndex = function(element, enable) { // without setting it to -1 first, the element remains keyboard focusable // despite not having a tabIndex attribute anymore. element.tabIndex = -1; - element.removeAttribute('tabIndex'); // Must be camelCase! + element.removeAttribute('tabIndex'); // Must be camelCase! } }; @@ -31736,7 +29316,8 @@ goog.dom.isFocusable = function(element) { // IE requires elements to be visible in order to focus them. return focusable && goog.userAgent.IE ? - goog.dom.hasNonZeroBoundingRect_(element) : focusable; + goog.dom.hasNonZeroBoundingRect_(/** @type {!HTMLElement} */ (element)) : + focusable; }; @@ -31750,7 +29331,7 @@ goog.dom.hasSpecifiedTabIndex_ = function(element) { // IE returns 0 for an unset tabIndex, so we must use getAttributeNode(), // which returns an object with a 'specified' property if tabIndex is // specified. This works on other browsers, too. - var attrNode = element.getAttributeNode('tabindex'); // Must be lowercase! + var attrNode = element.getAttributeNode('tabindex'); // Must be lowercase! return goog.isDefAndNotNull(attrNode) && attrNode.specified; }; @@ -31762,7 +29343,7 @@ goog.dom.hasSpecifiedTabIndex_ = function(element) { * @private */ goog.dom.isTabIndexFocusable_ = function(element) { - var index = element.tabIndex; + var index = /** @type {!HTMLElement} */ (element).tabIndex; // NOTE: IE9 puts tabIndex in 16-bit int, e.g. -2 is 65534. return goog.isNumber(index) && index >= 0 && index < 32768; }; @@ -31776,24 +29357,29 @@ goog.dom.isTabIndexFocusable_ = function(element) { */ goog.dom.nativelySupportsFocus_ = function(element) { return element.tagName == goog.dom.TagName.A || - element.tagName == goog.dom.TagName.INPUT || - element.tagName == goog.dom.TagName.TEXTAREA || - element.tagName == goog.dom.TagName.SELECT || - element.tagName == goog.dom.TagName.BUTTON; + element.tagName == goog.dom.TagName.INPUT || + element.tagName == goog.dom.TagName.TEXTAREA || + element.tagName == goog.dom.TagName.SELECT || + element.tagName == goog.dom.TagName.BUTTON; }; /** * Returns true if the element has a bounding rectangle that would be visible * (i.e. its width and height are greater than zero). - * @param {!Element} element Element to check. + * @param {!HTMLElement} element Element to check. * @return {boolean} Whether the element has a non-zero bounding rectangle. * @private */ goog.dom.hasNonZeroBoundingRect_ = function(element) { - var rect = goog.isFunction(element['getBoundingClientRect']) ? - element.getBoundingClientRect() : - {'height': element.offsetHeight, 'width': element.offsetWidth}; + var rect; + if (!goog.isFunction(element['getBoundingClientRect']) || + // In IE, getBoundingClientRect throws on detached nodes. + (goog.userAgent.IE && element.parentElement == null)) { + rect = {'height': element.offsetHeight, 'width': element.offsetWidth}; + } else { + rect = element.getBoundingClientRect(); + } return goog.isDefAndNotNull(rect) && rect.height > 0 && rect.width > 0; }; @@ -31813,7 +29399,8 @@ goog.dom.getTextContent = function(node) { var textContent; // Note(arv): IE9, Opera, and Safari 3 support innerText but they include // text nodes in script tags. So we revert to use a user agent test here. - if (goog.dom.BrowserFeature.CAN_USE_INNER_TEXT && ('innerText' in node)) { + if (goog.dom.BrowserFeature.CAN_USE_INNER_TEXT && node !== null && + ('innerText' in node)) { textContent = goog.string.canonicalizeNewlines(node.innerText); // Unfortunately .innerText() returns text with ­ symbols // We need to filter it out and then remove duplicate whitespaces @@ -32007,18 +29594,18 @@ goog.dom.isNodeList = function(val) { * @return {Element} The first ancestor that matches the passed criteria, or * null if no match is found. */ -goog.dom.getAncestorByTagNameAndClass = function(element, opt_tag, opt_class, - opt_maxSearchSteps) { +goog.dom.getAncestorByTagNameAndClass = function( + element, opt_tag, opt_class, opt_maxSearchSteps) { if (!opt_tag && !opt_class) { return null; } var tagName = opt_tag ? opt_tag.toUpperCase() : null; - return /** @type {Element} */ (goog.dom.getAncestor(element, - function(node) { - return (!tagName || node.nodeName == tagName) && - (!opt_class || goog.isString(node.className) && - goog.array.contains(node.className.split(/\s+/), opt_class)); - }, true, opt_maxSearchSteps)); + return /** @type {Element} */ (goog.dom.getAncestor(element, function(node) { + return (!tagName || node.nodeName == tagName) && + (!opt_class || + goog.isString(node.className) && + goog.array.contains(node.className.split(/\s+/), opt_class)); + }, true, opt_maxSearchSteps)); }; @@ -32034,8 +29621,8 @@ goog.dom.getAncestorByTagNameAndClass = function(element, opt_tag, opt_class, * null if none match. */ goog.dom.getAncestorByClass = function(element, className, opt_maxSearchSteps) { - return goog.dom.getAncestorByTagNameAndClass(element, null, className, - opt_maxSearchSteps); + return goog.dom.getAncestorByTagNameAndClass( + element, null, className, opt_maxSearchSteps); }; @@ -32058,9 +29645,9 @@ goog.dom.getAncestor = function( if (!opt_includeNode) { element = element.parentNode; } - var ignoreSearchSteps = opt_maxSearchSteps == null; var steps = 0; - while (element && (ignoreSearchSteps || steps <= opt_maxSearchSteps)) { + while (element && + (opt_maxSearchSteps == null || steps <= opt_maxSearchSteps)) { goog.asserts.assert(element.name != 'parentNode'); if (matcher(element)) { return element; @@ -32115,9 +29702,8 @@ goog.dom.getPixelRatio = function() { return win.devicePixelRatio; } else if (win.matchMedia) { return goog.dom.matchesPixelRatio_(.75) || - goog.dom.matchesPixelRatio_(1.5) || - goog.dom.matchesPixelRatio_(2) || - goog.dom.matchesPixelRatio_(3) || 1; + goog.dom.matchesPixelRatio_(1.5) || goog.dom.matchesPixelRatio_(2) || + goog.dom.matchesPixelRatio_(3) || 1; } return 1; }; @@ -32132,9 +29718,10 @@ goog.dom.getPixelRatio = function() { */ goog.dom.matchesPixelRatio_ = function(pixelRatio) { var win = goog.dom.getWindow(); - var query = ('(-webkit-min-device-pixel-ratio: ' + pixelRatio + '),' + - '(min--moz-device-pixel-ratio: ' + pixelRatio + '),' + - '(min-resolution: ' + pixelRatio + 'dppx)'); + var query = + ('(-webkit-min-device-pixel-ratio: ' + pixelRatio + '),' + + '(min--moz-device-pixel-ratio: ' + pixelRatio + '),' + + '(min-resolution: ' + pixelRatio + 'dppx)'); return win.matchMedia(query).matches ? pixelRatio : 0; }; @@ -32227,14 +29814,13 @@ goog.dom.DomHelper.prototype.$ = goog.dom.DomHelper.prototype.getElement; * @param {?string=} opt_tag Element tag name or * for all tags. * @param {?string=} opt_class Optional class name. * @param {(Document|Element)=} opt_el Optional element to look in. - * @return { {length: number} } Array-like list of elements (only a length + * @return {!IArrayLike<!Element>} Array-like list of elements (only a length * property and numerical indices are guaranteed to exist). */ -goog.dom.DomHelper.prototype.getElementsByTagNameAndClass = function(opt_tag, - opt_class, - opt_el) { - return goog.dom.getElementsByTagNameAndClass_(this.document_, opt_tag, - opt_class, opt_el); +goog.dom.DomHelper.prototype.getElementsByTagNameAndClass = function( + opt_tag, opt_class, opt_el) { + return goog.dom.getElementsByTagNameAndClass_( + this.document_, opt_tag, opt_class, opt_el); }; @@ -32243,7 +29829,7 @@ goog.dom.DomHelper.prototype.getElementsByTagNameAndClass = function(opt_tag, * @see {goog.dom.query} * @param {string} className the name of the class to look for. * @param {Element|Document=} opt_el Optional element to look in. - * @return { {length: number} } The items found with the class name provided. + * @return {!IArrayLike<!Element>} The items found with the class name provided. */ goog.dom.DomHelper.prototype.getElementsByClass = function(className, opt_el) { var doc = opt_el || this.document_; @@ -32274,8 +29860,8 @@ goog.dom.DomHelper.prototype.getElementByClass = function(className, opt_el) { * @return {!Element} The first item found with the class name provided. * @throws {goog.asserts.AssertionError} Thrown if no element is found. */ -goog.dom.DomHelper.prototype.getRequiredElementByClass = function(className, - opt_root) { +goog.dom.DomHelper.prototype.getRequiredElementByClass = function( + className, opt_root) { var root = opt_root || this.document_; return goog.dom.getRequiredElementByClass(className, root); }; @@ -32289,7 +29875,7 @@ goog.dom.DomHelper.prototype.getRequiredElementByClass = function(className, * @param {?string=} opt_tag Element tag name. * @param {?string=} opt_class Optional class name. * @param {Element=} opt_el Optional element to look in. - * @return { {length: number} } Array-like list of elements (only a length + * @return {!IArrayLike<!Element>} Array-like list of elements (only a length * property and numerical indices are guaranteed to exist). */ goog.dom.DomHelper.prototype.$$ = @@ -32358,9 +29944,8 @@ goog.dom.Appendable; * NodeList, its elements will be added as childNodes instead. * @return {!Element} Reference to a DOM node. */ -goog.dom.DomHelper.prototype.createDom = function(tagName, - opt_attributes, - var_args) { +goog.dom.DomHelper.prototype.createDom = function( + tagName, opt_attributes, var_args) { return goog.dom.createDom_(this.document_, arguments); }; @@ -32408,10 +29993,10 @@ goog.dom.DomHelper.prototype.createTextNode = function(content) { * {@code goog.string.Unicode.NBSP} characters. * @return {!HTMLElement} The created table. */ -goog.dom.DomHelper.prototype.createTable = function(rows, columns, - opt_fillWithNbsp) { - return goog.dom.createTable_(this.document_, rows, columns, - !!opt_fillWithNbsp); +goog.dom.DomHelper.prototype.createTable = function( + rows, columns, opt_fillWithNbsp) { + return goog.dom.createTable_( + this.document_, rows, columns, !!opt_fillWithNbsp); }; @@ -32435,9 +30020,11 @@ goog.dom.DomHelper.prototype.safeHtmlToNode = function(html) { * * @param {string} htmlString The HTML string to convert. * @return {!Node} The resulting node. + * @deprecated Use {@link goog.dom.DomHelper.prototype.safeHtmlToNode} instead. */ goog.dom.DomHelper.prototype.htmlToDocumentFragment = function(htmlString) { - return goog.dom.htmlToDocumentFragment_(this.document_, htmlString); + return goog.dom.safeHtmlToNode_(this.document_, + goog.html.legacyconversions.safeHtmlFromString(htmlString)); }; @@ -32584,8 +30171,8 @@ goog.dom.DomHelper.prototype.flattenElement = goog.dom.flattenElement; /** * Returns an array containing just the element children of the given element. * @param {Element} element The element whose element children we want. - * @return {!(Array|NodeList)} An array or array-like list of just the element - * children of the given element. + * @return {!(Array<!Element>|NodeList<!Element>)} An array or array-like list + * of just the element children of the given element. */ goog.dom.DomHelper.prototype.getChildren = goog.dom.getChildren; @@ -32899,8 +30486,7 @@ goog.dom.DomHelper.prototype.getAncestorByTagNameAndClass = * @return {Element} The first ancestor that matches the passed criteria, or * null if none match. */ -goog.dom.DomHelper.prototype.getAncestorByClass = - goog.dom.getAncestorByClass; +goog.dom.DomHelper.prototype.getAncestorByClass = goog.dom.getAncestorByClass; /** @@ -32934,284 +30520,6 @@ goog.dom.DomHelper.prototype.getAncestor = goog.dom.getAncestor; // limitations under the License. /** - * @fileoverview Utilities for detecting, adding and removing classes. Prefer - * this over goog.dom.classes for new code since it attempts to use classList - * (DOMTokenList: http://dom.spec.whatwg.org/#domtokenlist) which is faster - * and requires less code. - * - * Note: these utilities are meant to operate on HTMLElements - * and may have unexpected behavior on elements with differing interfaces - * (such as SVGElements). - */ - - -goog.provide('goog.dom.classlist'); - -goog.require('goog.array'); - - -/** - * Override this define at build-time if you know your target supports it. - * @define {boolean} Whether to use the classList property (DOMTokenList). - */ -goog.define('goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST', false); - - -/** - * Gets an array-like object of class names on an element. - * @param {Element} element DOM node to get the classes of. - * @return {!goog.array.ArrayLike} Class names on {@code element}. - */ -goog.dom.classlist.get = function(element) { - if (goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST || element.classList) { - return element.classList; - } - - var className = element.className; - // Some types of elements don't have a className in IE (e.g. iframes). - // Furthermore, in Firefox, className is not a string when the element is - // an SVG element. - return goog.isString(className) && className.match(/\S+/g) || []; -}; - - -/** - * Sets the entire class name of an element. - * @param {Element} element DOM node to set class of. - * @param {string} className Class name(s) to apply to element. - */ -goog.dom.classlist.set = function(element, className) { - element.className = className; -}; - - -/** - * Returns true if an element has a class. This method may throw a DOM - * exception for an invalid or empty class name if DOMTokenList is used. - * @param {Element} element DOM node to test. - * @param {string} className Class name to test for. - * @return {boolean} Whether element has the class. - */ -goog.dom.classlist.contains = function(element, className) { - if (goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST || element.classList) { - return element.classList.contains(className); - } - return goog.array.contains(goog.dom.classlist.get(element), className); -}; - - -/** - * Adds a class to an element. Does not add multiples of class names. This - * method may throw a DOM exception for an invalid or empty class name if - * DOMTokenList is used. - * @param {Element} element DOM node to add class to. - * @param {string} className Class name to add. - */ -goog.dom.classlist.add = function(element, className) { - if (goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST || element.classList) { - element.classList.add(className); - return; - } - - if (!goog.dom.classlist.contains(element, className)) { - // Ensure we add a space if this is not the first class name added. - element.className += element.className.length > 0 ? - (' ' + className) : className; - } -}; - - -/** - * Convenience method to add a number of class names at once. - * @param {Element} element The element to which to add classes. - * @param {goog.array.ArrayLike<string>} classesToAdd An array-like object - * containing a collection of class names to add to the element. - * This method may throw a DOM exception if classesToAdd contains invalid - * or empty class names. - */ -goog.dom.classlist.addAll = function(element, classesToAdd) { - if (goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST || element.classList) { - goog.array.forEach(classesToAdd, function(className) { - goog.dom.classlist.add(element, className); - }); - return; - } - - var classMap = {}; - - // Get all current class names into a map. - goog.array.forEach(goog.dom.classlist.get(element), - function(className) { - classMap[className] = true; - }); - - // Add new class names to the map. - goog.array.forEach(classesToAdd, - function(className) { - classMap[className] = true; - }); - - // Flatten the keys of the map into the className. - element.className = ''; - for (var className in classMap) { - element.className += element.className.length > 0 ? - (' ' + className) : className; - } -}; - - -/** - * Removes a class from an element. This method may throw a DOM exception - * for an invalid or empty class name if DOMTokenList is used. - * @param {Element} element DOM node to remove class from. - * @param {string} className Class name to remove. - */ -goog.dom.classlist.remove = function(element, className) { - if (goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST || element.classList) { - element.classList.remove(className); - return; - } - - if (goog.dom.classlist.contains(element, className)) { - // Filter out the class name. - element.className = goog.array.filter( - goog.dom.classlist.get(element), - function(c) { - return c != className; - }).join(' '); - } -}; - - -/** - * Removes a set of classes from an element. Prefer this call to - * repeatedly calling {@code goog.dom.classlist.remove} if you want to remove - * a large set of class names at once. - * @param {Element} element The element from which to remove classes. - * @param {goog.array.ArrayLike<string>} classesToRemove An array-like object - * containing a collection of class names to remove from the element. - * This method may throw a DOM exception if classesToRemove contains invalid - * or empty class names. - */ -goog.dom.classlist.removeAll = function(element, classesToRemove) { - if (goog.dom.classlist.ALWAYS_USE_DOM_TOKEN_LIST || element.classList) { - goog.array.forEach(classesToRemove, function(className) { - goog.dom.classlist.remove(element, className); - }); - return; - } - // Filter out those classes in classesToRemove. - element.className = goog.array.filter( - goog.dom.classlist.get(element), - function(className) { - // If this class is not one we are trying to remove, - // add it to the array of new class names. - return !goog.array.contains(classesToRemove, className); - }).join(' '); -}; - - -/** - * Adds or removes a class depending on the enabled argument. This method - * may throw a DOM exception for an invalid or empty class name if DOMTokenList - * is used. - * @param {Element} element DOM node to add or remove the class on. - * @param {string} className Class name to add or remove. - * @param {boolean} enabled Whether to add or remove the class (true adds, - * false removes). - */ -goog.dom.classlist.enable = function(element, className, enabled) { - if (enabled) { - goog.dom.classlist.add(element, className); - } else { - goog.dom.classlist.remove(element, className); - } -}; - - -/** - * Adds or removes a set of classes depending on the enabled argument. This - * method may throw a DOM exception for an invalid or empty class name if - * DOMTokenList is used. - * @param {!Element} element DOM node to add or remove the class on. - * @param {goog.array.ArrayLike<string>} classesToEnable An array-like object - * containing a collection of class names to add or remove from the element. - * @param {boolean} enabled Whether to add or remove the classes (true adds, - * false removes). - */ -goog.dom.classlist.enableAll = function(element, classesToEnable, enabled) { - var f = enabled ? goog.dom.classlist.addAll : - goog.dom.classlist.removeAll; - f(element, classesToEnable); -}; - - -/** - * Switches a class on an element from one to another without disturbing other - * classes. If the fromClass isn't removed, the toClass won't be added. This - * method may throw a DOM exception if the class names are empty or invalid. - * @param {Element} element DOM node to swap classes on. - * @param {string} fromClass Class to remove. - * @param {string} toClass Class to add. - * @return {boolean} Whether classes were switched. - */ -goog.dom.classlist.swap = function(element, fromClass, toClass) { - if (goog.dom.classlist.contains(element, fromClass)) { - goog.dom.classlist.remove(element, fromClass); - goog.dom.classlist.add(element, toClass); - return true; - } - return false; -}; - - -/** - * Removes a class if an element has it, and adds it the element doesn't have - * it. Won't affect other classes on the node. This method may throw a DOM - * exception if the class name is empty or invalid. - * @param {Element} element DOM node to toggle class on. - * @param {string} className Class to toggle. - * @return {boolean} True if class was added, false if it was removed - * (in other words, whether element has the class after this function has - * been called). - */ -goog.dom.classlist.toggle = function(element, className) { - var add = !goog.dom.classlist.contains(element, className); - goog.dom.classlist.enable(element, className, add); - return add; -}; - - -/** - * Adds and removes a class of an element. Unlike - * {@link goog.dom.classlist.swap}, this method adds the classToAdd regardless - * of whether the classToRemove was present and had been removed. This method - * may throw a DOM exception if the class names are empty or invalid. - * - * @param {Element} element DOM node to swap classes on. - * @param {string} classToRemove Class to remove. - * @param {string} classToAdd Class to add. - */ -goog.dom.classlist.addRemove = function(element, classToRemove, classToAdd) { - goog.dom.classlist.remove(element, classToRemove); - goog.dom.classlist.add(element, classToAdd); -}; - -// Copyright 2012 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** * @fileoverview Vendor prefix getters. */ @@ -33279,7 +30587,8 @@ goog.dom.vendor.getPrefixedPropertyName = function(propertyName, opt_object) { prefix = prefix.toLowerCase(); var prefixedPropertyName = prefix + goog.string.toTitleCase(propertyName); return (!goog.isDef(opt_object) || prefixedPropertyName in opt_object) ? - prefixedPropertyName : null; + prefixedPropertyName : + null; } return null; }; @@ -33315,6 +30624,7 @@ goog.dom.vendor.getPrefixedEventType = function(eventType) { goog.provide('goog.math.Box'); +goog.require('goog.asserts'); goog.require('goog.math.Coordinate'); @@ -33367,8 +30677,8 @@ goog.math.Box = function(top, right, bottom, left) { * @return {!goog.math.Box} A Box containing all the specified Coordinates. */ goog.math.Box.boundingBox = function(var_args) { - var box = new goog.math.Box(arguments[0].y, arguments[0].x, - arguments[0].y, arguments[0].x); + var box = new goog.math.Box( + arguments[0].y, arguments[0].x, arguments[0].y, arguments[0].x); for (var i = 1; i < arguments.length; i++) { box.expandToIncludeCoordinate(arguments[i]); } @@ -33409,7 +30719,7 @@ if (goog.DEBUG) { */ goog.math.Box.prototype.toString = function() { return '(' + this.top + 't, ' + this.right + 'r, ' + this.bottom + 'b, ' + - this.left + 'l)'; + this.left + 'l)'; }; } @@ -33434,18 +30744,18 @@ goog.math.Box.prototype.contains = function(other) { * @param {number=} opt_left Left margin. * @return {!goog.math.Box} A reference to this Box. */ -goog.math.Box.prototype.expand = function(top, opt_right, opt_bottom, - opt_left) { +goog.math.Box.prototype.expand = function( + top, opt_right, opt_bottom, opt_left) { if (goog.isObject(top)) { this.top -= top.top; this.right += top.right; this.bottom += top.bottom; this.left -= top.left; } else { - this.top -= top; - this.right += opt_right; - this.bottom += opt_bottom; - this.left -= opt_left; + this.top -= /** @type {number} */ (top); + this.right += Number(opt_right); + this.bottom += Number(opt_bottom); + this.left -= Number(opt_left); } return this; @@ -33493,8 +30803,8 @@ goog.math.Box.equals = function(a, b) { if (!a || !b) { return false; } - return a.top == b.top && a.right == b.right && - a.bottom == b.bottom && a.left == b.left; + return a.top == b.top && a.right == b.right && a.bottom == b.bottom && + a.left == b.left; }; @@ -33516,8 +30826,8 @@ goog.math.Box.contains = function(box, other) { } // other is a Coordinate. - return other.x >= box.left && other.x <= box.right && - other.y >= box.top && other.y <= box.bottom; + return other.x >= box.left && other.x <= box.right && other.y >= box.top && + other.y <= box.bottom; }; @@ -33584,8 +30894,9 @@ goog.math.Box.distance = function(box, coord) { * @return {boolean} Whether the boxes intersect. */ goog.math.Box.intersects = function(a, b) { - return (a.left <= b.right && b.left <= a.right && - a.top <= b.bottom && b.top <= a.bottom); + return ( + a.left <= b.right && b.left <= a.right && a.top <= b.bottom && + b.top <= a.bottom); }; @@ -33598,8 +30909,9 @@ goog.math.Box.intersects = function(a, b) { * @return {boolean} Whether the boxes intersect. */ goog.math.Box.intersectsWithPadding = function(a, b, padding) { - return (a.left <= b.right + padding && b.left <= a.right + padding && - a.top <= b.bottom + padding && b.top <= a.bottom + padding); + return ( + a.left <= b.right + padding && b.left <= a.right + padding && + a.top <= b.bottom + padding && b.top <= a.bottom + padding); }; @@ -33664,6 +30976,7 @@ goog.math.Box.prototype.translate = function(tx, opt_ty) { this.top += tx.y; this.bottom += tx.y; } else { + goog.asserts.assertNumber(tx); this.left += tx; this.right += tx; if (goog.isNumber(opt_ty)) { @@ -33713,6 +31026,7 @@ goog.math.Box.prototype.scale = function(sx, opt_sy) { goog.provide('goog.math.Rect'); +goog.require('goog.asserts'); goog.require('goog.math.Box'); goog.require('goog.math.Coordinate'); goog.require('goog.math.Size'); @@ -33759,10 +31073,7 @@ goog.math.Rect.prototype.clone = function() { goog.math.Rect.prototype.toBox = function() { var right = this.left + this.width; var bottom = this.top + this.height; - return new goog.math.Box(this.top, - right, - bottom, - this.left); + return new goog.math.Box(this.top, right, bottom, this.left); }; @@ -33786,8 +31097,8 @@ goog.math.Rect.createFromPositionAndSize = function(position, size) { * and size. */ goog.math.Rect.createFromBox = function(box) { - return new goog.math.Rect(box.left, box.top, - box.right - box.left, box.bottom - box.top); + return new goog.math.Rect( + box.left, box.top, box.right - box.left, box.bottom - box.top); }; @@ -33799,7 +31110,7 @@ if (goog.DEBUG) { */ goog.math.Rect.prototype.toString = function() { return '(' + this.left + ', ' + this.top + ' - ' + this.width + 'w x ' + - this.height + 'h)'; + this.height + 'h)'; }; } @@ -33818,8 +31129,8 @@ goog.math.Rect.equals = function(a, b) { if (!a || !b) { return false; } - return a.left == b.left && a.width == b.width && - a.top == b.top && a.height == b.height; + return a.left == b.left && a.width == b.width && a.top == b.top && + a.height == b.height; }; @@ -33888,7 +31199,8 @@ goog.math.Rect.intersection = function(a, b) { * @return {boolean} Whether a and b intersect. */ goog.math.Rect.intersects = function(a, b) { - return (a.left <= b.left + b.width && b.left <= a.left + a.width && + return ( + a.left <= b.left + b.width && b.left <= a.left + a.width && a.top <= b.top + b.height && b.top <= a.top + a.height); }; @@ -34015,14 +31327,12 @@ goog.math.Rect.boundingRect = function(a, b) { goog.math.Rect.prototype.contains = function(another) { if (another instanceof goog.math.Rect) { return this.left <= another.left && - this.left + this.width >= another.left + another.width && - this.top <= another.top && - this.top + this.height >= another.top + another.height; - } else { // (another instanceof goog.math.Coordinate) - return another.x >= this.left && - another.x <= this.left + this.width && - another.y >= this.top && - another.y <= this.top + this.height; + this.left + this.width >= another.left + another.width && + this.top <= another.top && + this.top + this.height >= another.top + another.height; + } else { // (another instanceof goog.math.Coordinate) + return another.x >= this.left && another.x <= this.left + this.width && + another.y >= this.top && another.y <= this.top + this.height; } }; @@ -34035,9 +31345,10 @@ goog.math.Rect.prototype.contains = function(another) { */ goog.math.Rect.prototype.squaredDistance = function(point) { var dx = point.x < this.left ? - this.left - point.x : Math.max(point.x - (this.left + this.width), 0); - var dy = point.y < this.top ? - this.top - point.y : Math.max(point.y - (this.top + this.height), 0); + this.left - point.x : + Math.max(point.x - (this.left + this.width), 0); + var dy = point.y < this.top ? this.top - point.y : + Math.max(point.y - (this.top + this.height), 0); return dx * dx + dy * dy; }; @@ -34143,7 +31454,7 @@ goog.math.Rect.prototype.translate = function(tx, opt_ty) { this.left += tx.x; this.top += tx.y; } else { - this.left += tx; + this.left += goog.asserts.assertNumber(tx); if (goog.isNumber(opt_ty)) { this.top += opt_ty; } @@ -34170,6 +31481,126 @@ goog.math.Rect.prototype.scale = function(sx, opt_sy) { return this; }; +// Copyright 2009 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Useful compiler idioms. + * + * @author johnlenz@google.com (John Lenz) + */ + +goog.provide('goog.reflect'); + + +/** + * Syntax for object literal casts. + * @see http://go/jscompiler-renaming + * @see https://goo.gl/CRs09P + * + * Use this if you have an object literal whose keys need to have the same names + * as the properties of some class even after they are renamed by the compiler. + * + * @param {!Function} type Type to cast to. + * @param {Object} object Object literal to cast. + * @return {Object} The object literal. + */ +goog.reflect.object = function(type, object) { + return object; +}; + + +/** + * To assert to the compiler that an operation is needed when it would + * otherwise be stripped. For example: + * <code> + * // Force a layout + * goog.reflect.sinkValue(dialog.offsetHeight); + * </code> + * @param {T} x + * @return {T} + * @template T + */ +goog.reflect.sinkValue = function(x) { + goog.reflect.sinkValue[' '](x); + return x; +}; + + +/** + * The compiler should optimize this function away iff no one ever uses + * goog.reflect.sinkValue. + */ +goog.reflect.sinkValue[' '] = goog.nullFunction; + + +/** + * Check if a property can be accessed without throwing an exception. + * @param {Object} obj The owner of the property. + * @param {string} prop The property name. + * @return {boolean} Whether the property is accessible. Will also return true + * if obj is null. + */ +goog.reflect.canAccessProperty = function(obj, prop) { + /** @preserveTry */ + try { + goog.reflect.sinkValue(obj[prop]); + return true; + } catch (e) { + } + return false; +}; + + +/** + * Retrieves a value from a cache given a key. The compiler provides special + * consideration for this call such that it is generally considered side-effect + * free. However, if the {@code opt_keyFn} or {@code valueFn} have side-effects + * then the entire call is considered to have side-effects. + * + * Conventionally storing the value on the cache would be considered a + * side-effect and preclude unused calls from being pruned, ie. even if + * the value was never used, it would still always be stored in the cache. + * + * Providing a side-effect free {@code valueFn} and {@code opt_keyFn} + * allows unused calls to {@code goog.cache} to be pruned. + * + * @param {!Object<K, V>} cacheObj The object that contains the cached values. + * @param {?} key The key to lookup in the cache. If it is not string or number + * then a {@code opt_keyFn} should be provided. The key is also used as the + * parameter to the {@code valueFn}. + * @param {!function(?):V} valueFn The value provider to use to calculate the + * value to store in the cache. This function should be side-effect free + * to take advantage of the optimization. + * @param {function(?):K=} opt_keyFn The key provider to determine the cache + * map key. This should be used if the given key is not a string or number. + * If not provided then the given key is used. This function should be + * side-effect free to take advantage of the optimization. + * @return {V} The cached or calculated value. + * @template K + * @template V + */ +goog.reflect.cache = function(cacheObj, key, valueFn, opt_keyFn) { + var storedKey = opt_keyFn ? opt_keyFn(key) : key; + + if (storedKey in cacheObj) { + return cacheObj[storedKey]; + } + + return (cacheObj[storedKey] = valueFn(key)); +}; + // Copyright 2006 The Closure Library Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -34203,11 +31634,14 @@ goog.require('goog.dom'); goog.require('goog.dom.NodeType'); goog.require('goog.dom.TagName'); goog.require('goog.dom.vendor'); +goog.require('goog.html.SafeStyleSheet'); +goog.require('goog.html.legacyconversions'); goog.require('goog.math.Box'); goog.require('goog.math.Coordinate'); goog.require('goog.math.Rect'); goog.require('goog.math.Size'); goog.require('goog.object'); +goog.require('goog.reflect'); goog.require('goog.string'); goog.require('goog.userAgent'); @@ -34407,8 +31841,8 @@ goog.style.getCascadedStyle = function(element, style) { */ goog.style.getStyle_ = function(element, style) { return goog.style.getComputedStyle(element, style) || - goog.style.getCascadedStyle(element, style) || - (element.style && element.style[style]); + goog.style.getCascadedStyle(element, style) || + (element.style && element.style[style]); }; @@ -34631,7 +32065,6 @@ goog.style.getBoundingClientRect_ = function(el) { // Patch the result in IE only, so that this function can be inlined if // compiled for non-IE. if (goog.userAgent.IE && el.ownerDocument.body) { - // In IE, most of the time, 2 extra pixels are added to the top and left // due to the implicit 2-pixel inset border. In IE6/7 quirks mode and // IE6 standards mode, this border can be overridden by setting the @@ -34663,6 +32096,7 @@ goog.style.getOffsetParent = function(element) { // browsers it only includes elements with position absolute, relative or // fixed, not elements with overflow set to auto or scroll. if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(8)) { + goog.asserts.assert(element && 'offsetParent' in element); return element.offsetParent; } @@ -34672,19 +32106,18 @@ goog.style.getOffsetParent = function(element) { for (var parent = element.parentNode; parent && parent != doc; parent = parent.parentNode) { // Skip shadowDOM roots. - if (parent.nodeType == goog.dom.NodeType.DOCUMENT_FRAGMENT && - parent.host) { + if (parent.nodeType == goog.dom.NodeType.DOCUMENT_FRAGMENT && parent.host) { parent = parent.host; } positionStyle = goog.style.getStyle_(/** @type {!Element} */ (parent), 'position'); skipStatic = skipStatic && positionStyle == 'static' && - parent != doc.documentElement && parent != doc.body; - if (!skipStatic && (parent.scrollWidth > parent.clientWidth || - parent.scrollHeight > parent.clientHeight || - positionStyle == 'fixed' || - positionStyle == 'absolute' || - positionStyle == 'relative')) { + parent != doc.documentElement && parent != doc.body; + if (!skipStatic && + (parent.scrollWidth > parent.clientWidth || + parent.scrollHeight > parent.clientHeight || + positionStyle == 'fixed' || positionStyle == 'absolute' || + positionStyle == 'relative')) { return /** @type {!Element} */ (parent); } } @@ -34710,7 +32143,7 @@ goog.style.getVisibleRectForElement = function(element) { // Determine the size of the visible rect by climbing the dom accounting for // all scrollable containers. - for (var el = element; el = goog.style.getOffsetParent(el); ) { + for (var el = element; el = goog.style.getOffsetParent(el);) { // clientWidth is zero for inline block elements in IE. // on WEBKIT, body element can have clientHeight = 0 and scrollHeight > 0 if ((!goog.userAgent.IE || el.clientWidth != 0) && @@ -34719,17 +32152,16 @@ goog.style.getVisibleRectForElement = function(element) { // viewport. In some browsers, el.offsetParent may be // document.documentElement, so check for that too. (el != body && el != documentElement && - goog.style.getStyle_(el, 'overflow') != 'visible')) { + goog.style.getStyle_(el, 'overflow') != 'visible')) { var pos = goog.style.getPageOffset(el); var client = goog.style.getClientLeftTop(el); pos.x += client.x; pos.y += client.y; visibleRect.top = Math.max(visibleRect.top, pos.y); - visibleRect.right = Math.min(visibleRect.right, - pos.x + el.clientWidth); - visibleRect.bottom = Math.min(visibleRect.bottom, - pos.y + el.clientHeight); + visibleRect.right = Math.min(visibleRect.right, pos.x + el.clientWidth); + visibleRect.bottom = + Math.min(visibleRect.bottom, pos.y + el.clientHeight); visibleRect.left = Math.max(visibleRect.left, pos.x); } } @@ -34742,9 +32174,10 @@ goog.style.getVisibleRectForElement = function(element) { visibleRect.right = Math.min(visibleRect.right, scrollX + winSize.width); visibleRect.bottom = Math.min(visibleRect.bottom, scrollY + winSize.height); return visibleRect.top >= 0 && visibleRect.left >= 0 && - visibleRect.bottom > visibleRect.top && - visibleRect.right > visibleRect.left ? - visibleRect : null; + visibleRect.bottom > visibleRect.top && + visibleRect.right > visibleRect.left ? + visibleRect : + null; }; @@ -34762,8 +32195,8 @@ goog.style.getVisibleRectForElement = function(element) { * @return {!goog.math.Coordinate} The new scroll position of the container, * in form of goog.math.Coordinate(scrollLeft, scrollTop). */ -goog.style.getContainerOffsetToScrollInto = - function(element, opt_container, opt_center) { +goog.style.getContainerOffsetToScrollInto = function( + element, opt_container, opt_center) { var container = opt_container || goog.dom.getDocumentScrollElement(); // Absolute position of the element's border's top left corner. var elementPos = goog.style.getPageOffset(element); @@ -34829,8 +32262,8 @@ goog.style.getContainerOffsetToScrollInto = * @param {boolean=} opt_center Whether to center the element in the container. * Defaults to false. */ -goog.style.scrollIntoContainerView = - function(element, opt_container, opt_center) { +goog.style.scrollIntoContainerView = function( + element, opt_container, opt_center) { var container = opt_container || goog.dom.getDocumentScrollElement(); var offset = goog.style.getContainerOffsetToScrollInto(element, container, opt_center); @@ -34930,6 +32363,13 @@ goog.style.getFramedPageOffset = function(el, relativeWin) { // Iterate up the ancestor frame chain, keeping track of the current window // and the current element in that window. var currentWin = goog.dom.getWindow(goog.dom.getOwnerDocument(el)); + + // MS Edge throws when accessing "parent" if el's containing iframe has been + // deleted. + if (!goog.reflect.canAccessProperty(currentWin, 'parent')) { + return position; + } + var currentEl = el; do { // if we're at the top window, we want to get the page offset. @@ -34938,15 +32378,14 @@ goog.style.getFramedPageOffset = function(el, relativeWin) { // the outer window. var offset = currentWin == relativeWin ? goog.style.getPageOffset(currentEl) : - goog.style.getClientPositionForElement_( - goog.asserts.assert(currentEl)); + goog.style.getClientPositionForElement_(goog.asserts.assert(currentEl)); position.x += offset.x; position.y += offset.y; } while (currentWin && currentWin != relativeWin && - currentWin != currentWin.parent && - (currentEl = currentWin.frameElement) && - (currentWin = currentWin.parent)); + currentWin != currentWin.parent && + (currentEl = currentWin.frameElement) && + (currentWin = currentWin.parent)); return position; }; @@ -35025,9 +32464,7 @@ goog.style.getClientPosition = function(el) { /** @type {!Element} */ (el)); } else { var targetEvent = el.changedTouches ? el.changedTouches[0] : el; - return new goog.math.Coordinate( - targetEvent.clientX, - targetEvent.clientY); + return new goog.math.Coordinate(targetEvent.clientX, targetEvent.clientY); } }; @@ -35053,12 +32490,13 @@ goog.style.setPageOffset = function(el, x, opt_y) { // require us to manually transform between different units // Work out deltas - var dx = x - cur.x; - var dy = opt_y - cur.y; + var dx = goog.asserts.assertNumber(x) - cur.x; + var dy = Number(opt_y) - cur.y; // Set position to current left/top + delta - goog.style.setPosition(el, /** @type {!HTMLElement} */ (el).offsetLeft + dx, - /** @type {!HTMLElement} */ (el).offsetTop + dy); + goog.style.setPosition( + el, /** @type {!HTMLElement} */ (el).offsetLeft + dx, + /** @type {!HTMLElement} */ (el).offsetTop + dy); }; @@ -35206,8 +32644,8 @@ goog.style.getSizeWithDisplay_ = function(element) { // will still return 0 on Webkit prior to 534.8, see // http://trac.webkit.org/changeset/67252. var clientRect = goog.style.getBoundingClientRect_(element); - return new goog.math.Size(clientRect.right - clientRect.left, - clientRect.bottom - clientRect.top); + return new goog.math.Size( + clientRect.right - clientRect.left, clientRect.bottom - clientRect.top); } return new goog.math.Size(offsetWidth, offsetHeight); }; @@ -35235,8 +32673,8 @@ goog.style.getTransformedSize = function(element) { var clientRect = goog.style.evaluateWithTemporaryDisplay_( goog.style.getBoundingClientRect_, element); - return new goog.math.Size(clientRect.right - clientRect.left, - clientRect.bottom - clientRect.top); + return new goog.math.Size( + clientRect.right - clientRect.left, clientRect.bottom - clientRect.top); }; @@ -35283,6 +32721,7 @@ goog.style.toSelectorCase = function(selector) { * if the opacity is not set. */ goog.style.getOpacity = function(el) { + goog.asserts.assert(el); var style = el.style; var result = ''; if ('opacity' in style) { @@ -35306,6 +32745,7 @@ goog.style.getOpacity = function(el) { * {@code ''} to clear the opacity. */ goog.style.setOpacity = function(el, alpha) { + goog.asserts.assert(el); var style = el.style; if ('opacity' in style) { style.opacity = alpha; @@ -35316,7 +32756,7 @@ goog.style.setOpacity = function(el, alpha) { if (alpha === '') { style.filter = ''; } else { - style.filter = 'alpha(opacity=' + alpha * 100 + ')'; + style.filter = 'alpha(opacity=' + (Number(alpha) * 100) + ')'; } } }; @@ -35439,14 +32879,30 @@ goog.style.isElementShown = function(el) { /** - * Installs the styles string into the window that contains opt_element. If - * opt_element is null, the main window is used. + * Installs the styles string into the window that contains opt_node. If + * opt_node is null, the main window is used. * @param {string} stylesString The style string to install. * @param {Node=} opt_node Node whose parent document should have the * styles installed. - * @return {Element|StyleSheet} The style element created. + * @return {!Element|!StyleSheet} The style element created. + * @deprecated Use {@link #installSafeStyleSheet} instead. */ goog.style.installStyles = function(stylesString, opt_node) { + return goog.style.installSafeStyleSheet( + goog.html.legacyconversions.safeStyleSheetFromString(stylesString), + opt_node); +}; + + +/** + * Installs the style sheet into the window that contains opt_node. If + * opt_node is null, the main window is used. + * @param {!goog.html.SafeStyleSheet} safeStyleSheet The style sheet to install. + * @param {?Node=} opt_node Node whose parent document should have the + * styles installed. + * @return {!Element|!StyleSheet} The style element created. + */ +goog.style.installSafeStyleSheet = function(safeStyleSheet, opt_node) { var dh = goog.dom.getDomHelper(opt_node); var styleSheet = null; @@ -35455,7 +32911,7 @@ goog.style.installStyles = function(stylesString, opt_node) { var doc = dh.getDocument(); if (goog.userAgent.IE && doc.createStyleSheet) { styleSheet = doc.createStyleSheet(); - goog.style.setStyles(styleSheet, stylesString); + goog.style.setSafeStyleSheet(styleSheet, safeStyleSheet); } else { var head = dh.getElementsByTagNameAndClass(goog.dom.TagName.HEAD)[0]; @@ -35471,7 +32927,7 @@ goog.style.installStyles = function(stylesString, opt_node) { // to the head results in a nasty Webkit bug in certain scenarios. Please // refer to https://bugs.webkit.org/show_bug.cgi?id=26307 for additional // details. - goog.style.setStyles(styleSheet, stylesString); + goog.style.setSafeStyleSheet(styleSheet, safeStyleSheet); dh.appendChild(head, styleSheet); } return styleSheet; @@ -35493,21 +32949,39 @@ goog.style.uninstallStyles = function(styleSheet) { /** * Sets the content of a style element. The style element can be any valid * style element. This element will have its content completely replaced by - * the new stylesString. + * the stylesString. * @param {Element|StyleSheet} element A stylesheet element as returned by * installStyles. * @param {string} stylesString The new content of the stylesheet. + * @deprecated Use {@link #setSafeStyleSheet} instead. */ goog.style.setStyles = function(element, stylesString) { + goog.style.setSafeStyleSheet(/** @type {!Element|!StyleSheet} */ (element), + goog.html.legacyconversions.safeStyleSheetFromString(stylesString)); +}; + + +/** + * Sets the content of a style element. The style element can be any valid + * style element. This element will have its content completely replaced by + * the safeStyleSheet. + * @param {!Element|!StyleSheet} element A stylesheet element as returned by + * installStyles. + * @param {!goog.html.SafeStyleSheet} safeStyleSheet The new content of the + * stylesheet. + */ +goog.style.setSafeStyleSheet = function(element, safeStyleSheet) { + var stylesString = goog.html.SafeStyleSheet.unwrap(safeStyleSheet); if (goog.userAgent.IE && goog.isDef(element.cssText)) { // Adding the selectors individually caused the browser to hang if the // selector was invalid or there were CSS comments. Setting the cssText of // the style node works fine and ignores CSS that IE doesn't understand. // However IE >= 11 doesn't support cssText any more, so we make sure that - // cssText is a defined property and otherwise fall back to innerHTML. + // cssText is a defined property and otherwise fall back to setTextContent. element.cssText = stylesString; } else { - element.innerHTML = stylesString; + // NOTE: We could also set textContent directly here. + goog.dom.setTextContent(/** @type {!Element} */ (element), stylesString); } }; @@ -35575,14 +33049,14 @@ goog.style.isRightToLeft = function(el) { /** * The CSS style property corresponding to an element being * unselectable on the current browser platform (null if none). - * Opera and IE instead use a DOM attribute 'unselectable'. + * Opera and IE instead use a DOM attribute 'unselectable'. MS Edge uses + * the Webkit prefix. * @type {?string} * @private */ -goog.style.unselectableStyle_ = - goog.userAgent.GECKO ? 'MozUserSelect' : - goog.userAgent.WEBKIT ? 'WebkitUserSelect' : - null; +goog.style.unselectableStyle_ = goog.userAgent.GECKO ? + 'MozUserSelect' : + goog.userAgent.WEBKIT || goog.userAgent.EDGE ? 'WebkitUserSelect' : null; /** @@ -35668,17 +33142,16 @@ goog.style.setBorderBoxSize = function(element, size) { var doc = goog.dom.getOwnerDocument(element); var isCss1CompatMode = goog.dom.getDomHelper(doc).isCss1CompatMode(); - if (goog.userAgent.IE && - !goog.userAgent.isVersionOrHigher('10') && + if (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('10') && (!isCss1CompatMode || !goog.userAgent.isVersionOrHigher('8'))) { var style = element.style; if (isCss1CompatMode) { var paddingBox = goog.style.getPaddingBox(element); var borderBox = goog.style.getBorderBox(element); style.pixelWidth = size.width - borderBox.left - paddingBox.left - - paddingBox.right - borderBox.right; + paddingBox.right - borderBox.right; style.pixelHeight = size.height - borderBox.top - paddingBox.top - - paddingBox.bottom - borderBox.bottom; + paddingBox.bottom - borderBox.bottom; } else { style.pixelWidth = size.width; style.pixelHeight = size.height; @@ -35698,27 +33171,25 @@ goog.style.setBorderBoxSize = function(element, size) { goog.style.getContentBoxSize = function(element) { var doc = goog.dom.getOwnerDocument(element); var ieCurrentStyle = goog.userAgent.IE && element.currentStyle; - if (ieCurrentStyle && - goog.dom.getDomHelper(doc).isCss1CompatMode() && + if (ieCurrentStyle && goog.dom.getDomHelper(doc).isCss1CompatMode() && ieCurrentStyle.width != 'auto' && ieCurrentStyle.height != 'auto' && !ieCurrentStyle.boxSizing) { // If IE in CSS1Compat mode than just use the width and height. // If we have a boxSizing then fall back on measuring the borders etc. - var width = goog.style.getIePixelValue_(element, ieCurrentStyle.width, - 'width', 'pixelWidth'); - var height = goog.style.getIePixelValue_(element, ieCurrentStyle.height, - 'height', 'pixelHeight'); + var width = goog.style.getIePixelValue_( + element, ieCurrentStyle.width, 'width', 'pixelWidth'); + var height = goog.style.getIePixelValue_( + element, ieCurrentStyle.height, 'height', 'pixelHeight'); return new goog.math.Size(width, height); } else { var borderBoxSize = goog.style.getBorderBoxSize(element); var paddingBox = goog.style.getPaddingBox(element); var borderBox = goog.style.getBorderBox(element); - return new goog.math.Size(borderBoxSize.width - - borderBox.left - paddingBox.left - - paddingBox.right - borderBox.right, - borderBoxSize.height - - borderBox.top - paddingBox.top - - paddingBox.bottom - borderBox.bottom); + return new goog.math.Size( + borderBoxSize.width - borderBox.left - paddingBox.left - + paddingBox.right - borderBox.right, + borderBoxSize.height - borderBox.top - paddingBox.top - + paddingBox.bottom - borderBox.bottom); } }; @@ -35732,8 +33203,7 @@ goog.style.getContentBoxSize = function(element) { goog.style.setContentBoxSize = function(element, size) { var doc = goog.dom.getOwnerDocument(element); var isCss1CompatMode = goog.dom.getDomHelper(doc).isCss1CompatMode(); - if (goog.userAgent.IE && - !goog.userAgent.isVersionOrHigher('10') && + if (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('10') && (!isCss1CompatMode || !goog.userAgent.isVersionOrHigher('8'))) { var style = element.style; if (isCss1CompatMode) { @@ -35743,9 +33213,9 @@ goog.style.setContentBoxSize = function(element, size) { var paddingBox = goog.style.getPaddingBox(element); var borderBox = goog.style.getBorderBox(element); style.pixelWidth = size.width + borderBox.left + paddingBox.left + - paddingBox.right + borderBox.right; + paddingBox.right + borderBox.right; style.pixelHeight = size.height + borderBox.top + paddingBox.top + - paddingBox.bottom + borderBox.bottom; + paddingBox.bottom + borderBox.bottom; } } else { goog.style.setBoxSizingSize_(element, size, 'content-box'); @@ -35820,7 +33290,8 @@ goog.style.getIePixelValue_ = function(element, value, name, pixelName) { goog.style.getIePixelDistance_ = function(element, propName) { var value = goog.style.getCascadedStyle(element, propName); return value ? - goog.style.getIePixelValue_(element, value, 'left', 'pixelLeft') : 0; + goog.style.getIePixelValue_(element, value, 'left', 'pixelLeft') : + 0; }; @@ -35837,8 +33308,8 @@ goog.style.getBox_ = function(element, stylePrefix) { var left = goog.style.getIePixelDistance_(element, stylePrefix + 'Left'); var right = goog.style.getIePixelDistance_(element, stylePrefix + 'Right'); var top = goog.style.getIePixelDistance_(element, stylePrefix + 'Top'); - var bottom = goog.style.getIePixelDistance_( - element, stylePrefix + 'Bottom'); + var bottom = + goog.style.getIePixelDistance_(element, stylePrefix + 'Bottom'); return new goog.math.Box(top, right, bottom, left); } else { // On non-IE browsers, getComputedStyle is always non-null. @@ -35849,10 +33320,9 @@ goog.style.getBox_ = function(element, stylePrefix) { // NOTE(arv): Gecko can return floating point numbers for the computed // style values. - return new goog.math.Box(parseFloat(top), - parseFloat(right), - parseFloat(bottom), - parseFloat(left)); + return new goog.math.Box( + parseFloat(top), parseFloat(right), parseFloat(bottom), + parseFloat(left)); } }; @@ -35879,7 +33349,7 @@ goog.style.getMarginBox = function(element) { /** * A map used to map the border width keywords to a pixel width. - * @type {Object} + * @type {!Object} * @private */ goog.style.ieBorderWidthKeywords_ = { @@ -35927,10 +33397,9 @@ goog.style.getBorderBox = function(element) { var top = goog.style.getComputedStyle(element, 'borderTopWidth'); var bottom = goog.style.getComputedStyle(element, 'borderBottomWidth'); - return new goog.math.Box(parseFloat(top), - parseFloat(right), - parseFloat(bottom), - parseFloat(left)); + return new goog.math.Box( + parseFloat(top), parseFloat(right), parseFloat(bottom), + parseFloat(left)); } }; @@ -36002,15 +33471,15 @@ goog.style.getLengthUnits = function(value) { /** * Map of absolute CSS length units - * @type {Object} + * @type {!Object} * @private */ goog.style.ABSOLUTE_CSS_LENGTH_UNITS_ = { - 'cm' : 1, - 'in' : 1, - 'mm' : 1, - 'pc' : 1, - 'pt' : 1 + 'cm': 1, + 'in': 1, + 'mm': 1, + 'pc': 1, + 'pt': 1 }; @@ -36018,12 +33487,12 @@ goog.style.ABSOLUTE_CSS_LENGTH_UNITS_ = { * Map of relative CSS length units that can be accurately converted to px * font-size values using getIePixelValue_. Only units that are defined in * relation to a font size are convertible (%, small, etc. are not). - * @type {Object} + * @type {!Object} * @private */ goog.style.CONVERTIBLE_RELATIVE_CSS_UNITS_ = { - 'em' : 1, - 'ex' : 1 + 'em': 1, + 'ex': 1 }; @@ -36049,25 +33518,20 @@ goog.style.getFontSize = function(el) { // (em, ex) are applied relative to the element's parentNode and can also // be converted. if (goog.userAgent.IE) { - if (sizeUnits in goog.style.ABSOLUTE_CSS_LENGTH_UNITS_) { - return goog.style.getIePixelValue_(el, - fontSize, - 'left', - 'pixelLeft'); - } else if (el.parentNode && - el.parentNode.nodeType == goog.dom.NodeType.ELEMENT && - sizeUnits in goog.style.CONVERTIBLE_RELATIVE_CSS_UNITS_) { + if (String(sizeUnits) in goog.style.ABSOLUTE_CSS_LENGTH_UNITS_) { + return goog.style.getIePixelValue_(el, fontSize, 'left', 'pixelLeft'); + } else if ( + el.parentNode && el.parentNode.nodeType == goog.dom.NodeType.ELEMENT && + String(sizeUnits) in goog.style.CONVERTIBLE_RELATIVE_CSS_UNITS_) { // Check the parent size - if it is the same it means the relative size // value is inherited and we therefore don't want to count it twice. If // it is different, this element either has explicit style or has a CSS // rule applying to it. var parentElement = /** @type {!Element} */ (el.parentNode); var parentSize = goog.style.getStyle_(parentElement, 'fontSize'); - return goog.style.getIePixelValue_(parentElement, - fontSize == parentSize ? - '1em' : fontSize, - 'left', - 'pixelLeft'); + return goog.style.getIePixelValue_( + parentElement, fontSize == parentSize ? '1em' : fontSize, 'left', + 'pixelLeft'); } } @@ -36076,10 +33540,10 @@ goog.style.getFontSize = function(el) { // an invisible, absolutely-positioned span sized to be the height of an 'M' // rendered in its parent's (i.e., our target element's) font size. This is // the definition of CSS's font size attribute. - var sizeElement = goog.dom.createDom( - goog.dom.TagName.SPAN, - {'style': 'visibility:hidden;position:absolute;' + - 'line-height:0;padding:0;margin:0;border:0;height:1em;'}); + var sizeElement = goog.dom.createDom(goog.dom.TagName.SPAN, { + 'style': 'visibility:hidden;position:absolute;' + + 'line-height:0;padding:0;margin:0;border:0;height:1em;' + }); goog.dom.appendChild(el, sizeElement); fontSize = sizeElement.offsetHeight; goog.dom.removeNode(sizeElement); @@ -36182,10 +33646,10 @@ goog.style.getScrollbarWidth = function(opt_className) { * @const * @private */ -goog.style.MATRIX_TRANSLATION_REGEX_ = - new RegExp('matrix\\([0-9\\.\\-]+, [0-9\\.\\-]+, ' + - '[0-9\\.\\-]+, [0-9\\.\\-]+, ' + - '([0-9\\.\\-]+)p?x?, ([0-9\\.\\-]+)p?x?\\)'); +goog.style.MATRIX_TRANSLATION_REGEX_ = new RegExp( + 'matrix\\([0-9\\.\\-]+, [0-9\\.\\-]+, ' + + '[0-9\\.\\-]+, [0-9\\.\\-]+, ' + + '([0-9\\.\\-]+)p?x?, ([0-9\\.\\-]+)p?x?\\)'); /** @@ -36204,14 +33668,14 @@ goog.style.getCssTranslation = function(element) { if (!matches) { return new goog.math.Coordinate(0, 0); } - return new goog.math.Coordinate(parseFloat(matches[1]), - parseFloat(matches[2])); + return new goog.math.Coordinate( + parseFloat(matches[1]), parseFloat(matches[2])); }; goog.provide('ol.MapEvent'); goog.provide('ol.MapEventType'); -goog.require('goog.events.Event'); +goog.require('ol.events.Event'); /** @@ -36236,14 +33700,13 @@ ol.MapEventType = { }; - /** * @classdesc * Events emitted as map events are instances of this type. * See {@link ol.Map} for which events trigger a map event. * * @constructor - * @extends {goog.events.Event} + * @extends {ol.events.Event} * @implements {oli.MapEvent} * @param {string} type Event type. * @param {ol.Map} map Map. @@ -36268,18 +33731,17 @@ ol.MapEvent = function(type, map, opt_frameState) { this.frameState = opt_frameState !== undefined ? opt_frameState : null; }; -goog.inherits(ol.MapEvent, goog.events.Event); +goog.inherits(ol.MapEvent, ol.events.Event); goog.provide('ol.control.Control'); goog.require('goog.dom'); -goog.require('goog.events'); +goog.require('ol.events'); goog.require('ol'); goog.require('ol.MapEventType'); goog.require('ol.Object'); - /** * @classdesc * A control is a visible widget with a DOM element in a fixed position on the @@ -36333,7 +33795,7 @@ ol.control.Control = function(options) { /** * @protected - * @type {!Array.<?number>} + * @type {!Array.<ol.events.Key>} */ this.listenerKeys = []; @@ -36380,18 +33842,18 @@ ol.control.Control.prototype.setMap = function(map) { if (this.map_) { goog.dom.removeNode(this.element); } - if (this.listenerKeys.length > 0) { - this.listenerKeys.forEach(goog.events.unlistenByKey); - this.listenerKeys.length = 0; + for (var i = 0, ii = this.listenerKeys.length; i < ii; ++i) { + ol.events.unlistenByKey(this.listenerKeys[i]); } + this.listenerKeys.length = 0; this.map_ = map; if (this.map_) { var target = this.target_ ? this.target_ : map.getOverlayContainerStopEvent(); target.appendChild(this.element); if (this.render !== ol.nullFunction) { - this.listenerKeys.push(goog.events.listen(map, - ol.MapEventType.POSTRENDER, this.render, false, this)); + this.listenerKeys.push(ol.events.listen(map, + ol.MapEventType.POSTRENDER, this.render, this)); } map.render(); } @@ -36452,8 +33914,7 @@ ol.css.CLASS_CONTROL = 'ol-control'; goog.provide('ol.structs.LRUCache'); goog.require('goog.asserts'); -goog.require('goog.object'); - +goog.require('ol.object'); /** @@ -36474,19 +33935,19 @@ ol.structs.LRUCache = function() { /** * @private - * @type {Object.<string, ol.structs.LRUCacheEntry>} + * @type {!Object.<string, ol.LRUCacheEntry>} */ this.entries_ = {}; /** * @private - * @type {?ol.structs.LRUCacheEntry} + * @type {?ol.LRUCacheEntry} */ this.oldest_ = null; /** * @private - * @type {?ol.structs.LRUCacheEntry} + * @type {?ol.LRUCacheEntry} */ this.newest_ = null; @@ -36498,14 +33959,14 @@ ol.structs.LRUCache = function() { */ ol.structs.LRUCache.prototype.assertValid = function() { if (this.count_ === 0) { - goog.asserts.assert(goog.object.isEmpty(this.entries_), + goog.asserts.assert(ol.object.isEmpty(this.entries_), 'entries must be an empty object (count = 0)'); goog.asserts.assert(!this.oldest_, 'oldest must be null (count = 0)'); goog.asserts.assert(!this.newest_, 'newest must be null (count = 0)'); } else { - goog.asserts.assert(goog.object.getCount(this.entries_) == this.count_, + goog.asserts.assert(Object.keys(this.entries_).length == this.count_, 'number of entries matches count'); goog.asserts.assert(this.oldest_, 'we have an oldest entry'); @@ -36712,24 +34173,156 @@ ol.structs.LRUCache.prototype.set = function(key, value) { ++this.count_; }; +goog.provide('ol.tilecoord'); + +goog.require('goog.asserts'); +goog.require('ol.extent'); + /** - * @typedef {{key_: string, - * newer: ol.structs.LRUCacheEntry, - * older: ol.structs.LRUCacheEntry, - * value_: *}} + * @enum {number} */ -ol.structs.LRUCacheEntry; +ol.QuadKeyCharCode = { + ZERO: '0'.charCodeAt(0), + ONE: '1'.charCodeAt(0), + TWO: '2'.charCodeAt(0), + THREE: '3'.charCodeAt(0) +}; + + +/** + * @param {string} str String that follows pattern “z/x/y” where x, y and z are + * numbers. + * @return {ol.TileCoord} Tile coord. + */ +ol.tilecoord.createFromString = function(str) { + var v = str.split('/'); + goog.asserts.assert(v.length === 3, + 'must provide a string in "z/x/y" format, got "%s"', str); + return v.map(function(e) { + return parseInt(e, 10); + }); +}; + + +/** + * @param {number} z Z. + * @param {number} x X. + * @param {number} y Y. + * @param {ol.TileCoord=} opt_tileCoord Tile coordinate. + * @return {ol.TileCoord} Tile coordinate. + */ +ol.tilecoord.createOrUpdate = function(z, x, y, opt_tileCoord) { + if (opt_tileCoord !== undefined) { + opt_tileCoord[0] = z; + opt_tileCoord[1] = x; + opt_tileCoord[2] = y; + return opt_tileCoord; + } else { + return [z, x, y]; + } +}; + + +/** + * @param {number} z Z. + * @param {number} x X. + * @param {number} y Y. + * @return {string} Key. + */ +ol.tilecoord.getKeyZXY = function(z, x, y) { + return z + '/' + x + '/' + y; +}; + + +/** + * @param {ol.TileCoord} tileCoord Tile coord. + * @return {number} Hash. + */ +ol.tilecoord.hash = function(tileCoord) { + return (tileCoord[1] << tileCoord[0]) + tileCoord[2]; +}; + + +/** + * @param {ol.TileCoord} tileCoord Tile coord. + * @return {string} Quad key. + */ +ol.tilecoord.quadKey = function(tileCoord) { + var z = tileCoord[0]; + var digits = new Array(z); + var mask = 1 << (z - 1); + var i, charCode; + for (i = 0; i < z; ++i) { + charCode = ol.QuadKeyCharCode.ZERO; + if (tileCoord[1] & mask) { + charCode += 1; + } + if (tileCoord[2] & mask) { + charCode += 2; + } + digits[i] = String.fromCharCode(charCode); + mask >>= 1; + } + return digits.join(''); +}; + + +/** + * @param {ol.TileCoord} tileCoord Tile coordinate. + * @param {ol.tilegrid.TileGrid} tileGrid Tile grid. + * @param {ol.proj.Projection} projection Projection. + * @return {ol.TileCoord} Tile coordinate. + */ +ol.tilecoord.wrapX = function(tileCoord, tileGrid, projection) { + var z = tileCoord[0]; + var center = tileGrid.getTileCoordCenter(tileCoord); + var projectionExtent = ol.tilegrid.extentFromProjection(projection); + if (!ol.extent.containsCoordinate(projectionExtent, center)) { + var worldWidth = ol.extent.getWidth(projectionExtent); + var worldsAway = Math.ceil((projectionExtent[0] - center[0]) / worldWidth); + center[0] += worldWidth * worldsAway; + return tileGrid.getTileCoordForCoordAndZ(center, z); + } else { + return tileCoord; + } +}; + + +/** + * @param {ol.TileCoord} tileCoord Tile coordinate. + * @param {!ol.tilegrid.TileGrid} tileGrid Tile grid. + * @return {boolean} Tile coordinate is within extent and zoom level range. + */ +ol.tilecoord.withinExtentAndZ = function(tileCoord, tileGrid) { + var z = tileCoord[0]; + var x = tileCoord[1]; + var y = tileCoord[2]; + + if (tileGrid.getMinZoom() > z || z > tileGrid.getMaxZoom()) { + return false; + } + var extent = tileGrid.getExtent(); + var tileRange; + if (!extent) { + tileRange = tileGrid.getFullTileRange(z); + } else { + tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z); + } + if (!tileRange) { + return true; + } else { + return tileRange.containsXY(x, y); + } +}; goog.provide('ol.TileCache'); -goog.require('ol'); goog.require('ol.TileRange'); goog.require('ol.structs.LRUCache'); goog.require('ol.tilecoord'); - /** * @constructor * @extends {ol.structs.LRUCache.<ol.Tile>} @@ -36744,8 +34337,7 @@ ol.TileCache = function(opt_highWaterMark) { * @private * @type {number} */ - this.highWaterMark_ = opt_highWaterMark !== undefined ? - opt_highWaterMark : ol.DEFAULT_TILE_CACHE_HIGH_WATER_MARK; + this.highWaterMark_ = opt_highWaterMark !== undefined ? opt_highWaterMark : 2048; }; goog.inherits(ol.TileCache, ol.structs.LRUCache); @@ -36796,10 +34388,9 @@ ol.TileCache.prototype.pruneTileRange = function(tileRange) { goog.provide('ol.Tile'); goog.provide('ol.TileState'); -goog.require('goog.events'); -goog.require('goog.events.EventTarget'); -goog.require('goog.events.EventType'); -goog.require('ol.TileCoord'); +goog.require('ol.events'); +goog.require('ol.events.EventTarget'); +goog.require('ol.events.EventType'); /** @@ -36810,17 +34401,17 @@ ol.TileState = { LOADING: 1, LOADED: 2, ERROR: 3, - EMPTY: 4 + EMPTY: 4, + ABORT: 5 }; - /** * @classdesc * Base class for tiles. * * @constructor - * @extends {goog.events.EventTarget} + * @extends {ol.events.EventTarget} * @param {ol.TileCoord} tileCoord Tile coordinate. * @param {ol.TileState} state State. */ @@ -36856,14 +34447,14 @@ ol.Tile = function(tileCoord, state) { this.key = ''; }; -goog.inherits(ol.Tile, goog.events.EventTarget); +goog.inherits(ol.Tile, ol.events.EventTarget); /** * @protected */ ol.Tile.prototype.changed = function() { - this.dispatchEvent(goog.events.EventType.CHANGE); + this.dispatchEvent(ol.events.EventType.CHANGE); }; @@ -36886,7 +34477,7 @@ ol.Tile.prototype.getKey = function() { /** * Get the tile coordinate for this tile. - * @return {ol.TileCoord} + * @return {ol.TileCoord} The tile coordinate. * @api */ ol.Tile.prototype.getTileCoord = function() { @@ -36907,6 +34498,91 @@ ol.Tile.prototype.getState = function() { */ ol.Tile.prototype.load = goog.abstractMethod; +goog.provide('ol.size'); + + +goog.require('goog.asserts'); + + +/** + * Returns a buffered size. + * @param {ol.Size} size Size. + * @param {number} buffer Buffer. + * @param {ol.Size=} opt_size Optional reusable size array. + * @return {ol.Size} The buffered size. + */ +ol.size.buffer = function(size, buffer, opt_size) { + if (opt_size === undefined) { + opt_size = [0, 0]; + } + opt_size[0] = size[0] + 2 * buffer; + opt_size[1] = size[1] + 2 * buffer; + return opt_size; +}; + + +/** + * Compares sizes for equality. + * @param {ol.Size} a Size. + * @param {ol.Size} b Size. + * @return {boolean} Equals. + */ +ol.size.equals = function(a, b) { + return a[0] == b[0] && a[1] == b[1]; +}; + + +/** + * Determines if a size has a positive area. + * @param {ol.Size} size The size to test. + * @return {boolean} The size has a positive area. + */ +ol.size.hasArea = function(size) { + return size[0] > 0 && size[1] > 0; +}; + + +/** + * Returns a size scaled by a ratio. The result will be an array of integers. + * @param {ol.Size} size Size. + * @param {number} ratio Ratio. + * @param {ol.Size=} opt_size Optional reusable size array. + * @return {ol.Size} The scaled size. + */ +ol.size.scale = function(size, ratio, opt_size) { + if (opt_size === undefined) { + opt_size = [0, 0]; + } + opt_size[0] = (size[0] * ratio + 0.5) | 0; + opt_size[1] = (size[1] * ratio + 0.5) | 0; + return opt_size; +}; + + +/** + * Returns an `ol.Size` array for the passed in number (meaning: square) or + * `ol.Size` array. + * (meaning: non-square), + * @param {number|ol.Size} size Width and height. + * @param {ol.Size=} opt_size Optional reusable size array. + * @return {ol.Size} Size. + * @api stable + */ +ol.size.toSize = function(size, opt_size) { + if (Array.isArray(size)) { + return size; + } else { + goog.asserts.assert(goog.isNumber(size)); + if (opt_size === undefined) { + opt_size = [size, size]; + } else { + opt_size[0] = size; + opt_size[1] = size; + } + return opt_size; + } +}; + goog.provide('ol.source.Source'); goog.provide('ol.source.State'); @@ -36930,17 +34606,6 @@ ol.source.State = { /** - * @typedef {{attributions: (Array.<ol.Attribution>|undefined), - * logo: (string|olx.LogoOptions|undefined), - * projection: ol.proj.ProjectionLike, - * state: (ol.source.State|undefined), - * wrapX: (boolean|undefined)}} - */ -ol.source.SourceOptions; - - - -/** * @classdesc * Abstract base class; normally only used for creating subclasses and not * instantiated in apps. @@ -36950,7 +34615,7 @@ ol.source.SourceOptions; * * @constructor * @extends {ol.Object} - * @param {ol.source.SourceOptions} options Source options. + * @param {ol.SourceSourceOptions} options Source options. * @api stable */ ol.source.Source = function(options) { @@ -36967,8 +34632,7 @@ ol.source.Source = function(options) { * @private * @type {Array.<ol.Attribution>} */ - this.attributions_ = options.attributions !== undefined ? - options.attributions : null; + this.attributions_ = ol.source.Source.toAttributionsArray_(options.attributions); /** * @private @@ -36992,6 +34656,37 @@ ol.source.Source = function(options) { }; goog.inherits(ol.source.Source, ol.Object); +/** + * Turns various ways of defining an attribution to an array of `ol.Attributions`. + * + * @param {ol.AttributionLike|undefined} + * attributionLike The attributions as string, array of strings, + * `ol.Attribution`, array of `ol.Attribution` or undefined. + * @return {Array.<ol.Attribution>} The array of `ol.Attribution` or null if + * `undefined` was given. + */ +ol.source.Source.toAttributionsArray_ = function(attributionLike) { + if (typeof attributionLike === 'string') { + return [new ol.Attribution({html: attributionLike})]; + } else if (attributionLike instanceof ol.Attribution) { + return [attributionLike]; + } else if (Array.isArray(attributionLike)) { + var len = attributionLike.length; + var attributions = new Array(len); + for (var i = 0; i < len; i++) { + var item = attributionLike[i]; + if (typeof item === 'string') { + attributions[i] = new ol.Attribution({html: item}); + } else { + attributions[i] = item; + } + } + return attributions; + } else { + return null; + } +} + /** * @param {ol.Coordinate} coordinate Coordinate. @@ -37061,12 +34756,23 @@ ol.source.Source.prototype.getWrapX = function() { /** + * Refreshes the source and finally dispatches a 'change' event. + * @api + */ +ol.source.Source.prototype.refresh = function() { + this.changed(); +}; + + +/** * Set the attributions of the source. - * @param {Array.<ol.Attribution>} attributions Attributions. + * @param {ol.AttributionLike|undefined} attributions Attributions. + * Can be passed as `string`, `Array<string>`, `{@link ol.Attribution}`, + * `Array<{@link ol.Attribution}>` or `undefined`. * @api */ ol.source.Source.prototype.setAttributions = function(attributions) { - this.attributions_ = attributions; + this.attributions_ = ol.source.Source.toAttributionsArray_(attributions); this.changed(); }; @@ -37090,28 +34796,16 @@ ol.source.Source.prototype.setState = function(state) { this.changed(); }; - -/** - * Set the projection of the source. - * @param {ol.proj.Projection} projection Projection. - */ -ol.source.Source.prototype.setProjection = function(projection) { - this.projection_ = projection; -}; - goog.provide('ol.tilegrid.TileGrid'); -goog.require('goog.array'); goog.require('goog.asserts'); -goog.require('goog.object'); goog.require('ol'); -goog.require('ol.Coordinate'); -goog.require('ol.TileCoord'); goog.require('ol.TileRange'); goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.extent.Corner'); goog.require('ol.math'); +goog.require('ol.object'); goog.require('ol.proj'); goog.require('ol.proj.METERS_PER_UNIT'); goog.require('ol.proj.Projection'); @@ -37120,7 +34814,6 @@ goog.require('ol.size'); goog.require('ol.tilecoord'); - /** * @classdesc * Base class for setting the grid pattern for sources accessing tiled-image @@ -37144,7 +34837,7 @@ ol.tilegrid.TileGrid = function(options) { * @type {!Array.<number>} */ this.resolutions_ = options.resolutions; - goog.asserts.assert(goog.array.isSorted(this.resolutions_, function(a, b) { + goog.asserts.assert(ol.array.isSorted(this.resolutions_, function(a, b) { return b - a; }, true), 'resolutions must be sorted in descending order'); @@ -37219,6 +34912,12 @@ ol.tilegrid.TileGrid = function(options) { */ this.fullTileRanges_ = null; + /** + * @private + * @type {ol.Size} + */ + this.tmpSize_ = [0, 0]; + if (options.sizes !== undefined) { goog.asserts.assert(options.sizes.length == this.resolutions_.length, 'number of sizes and resolutions must be equal'); @@ -37239,12 +34938,6 @@ ol.tilegrid.TileGrid = function(options) { this.calculateTileRanges_(extent); } - /** - * @private - * @type {ol.Size} - */ - this.tmpSize_ = [0, 0]; - }; @@ -37264,8 +34957,7 @@ ol.tilegrid.TileGrid.tmpTileCoord_ = [0, 0, 0]; * @return {boolean} Callback succeeded. * @template T */ -ol.tilegrid.TileGrid.prototype.forEachTileCoordParentTileRange = - function(tileCoord, callback, opt_this, opt_tileRange, opt_extent) { +ol.tilegrid.TileGrid.prototype.forEachTileCoordParentTileRange = function(tileCoord, callback, opt_this, opt_tileRange, opt_extent) { var tileCoordExtent = this.getTileCoordExtent(tileCoord, opt_extent); var z = tileCoord[0] - 1; while (z >= this.minZoom) { @@ -37358,8 +35050,7 @@ ol.tilegrid.TileGrid.prototype.getResolutions = function() { * @param {ol.Extent=} opt_extent Temporary ol.Extent object. * @return {ol.TileRange} Tile range. */ -ol.tilegrid.TileGrid.prototype.getTileCoordChildTileRange = - function(tileCoord, opt_tileRange, opt_extent) { +ol.tilegrid.TileGrid.prototype.getTileCoordChildTileRange = function(tileCoord, opt_tileRange, opt_extent) { if (tileCoord[0] < this.maxZoom) { var tileCoordExtent = this.getTileCoordExtent(tileCoord, opt_extent); return this.getTileRangeForExtentAndZ( @@ -37376,8 +35067,7 @@ ol.tilegrid.TileGrid.prototype.getTileCoordChildTileRange = * @param {ol.Extent=} opt_extent Temporary ol.Extent object. * @return {ol.Extent} Extent. */ -ol.tilegrid.TileGrid.prototype.getTileRangeExtent = - function(z, tileRange, opt_extent) { +ol.tilegrid.TileGrid.prototype.getTileRangeExtent = function(z, tileRange, opt_extent) { var origin = this.getOrigin(z); var resolution = this.getResolution(z); var tileSize = ol.size.toSize(this.getTileSize(z), this.tmpSize_); @@ -37395,8 +35085,7 @@ ol.tilegrid.TileGrid.prototype.getTileRangeExtent = * @param {ol.TileRange=} opt_tileRange Temporary tile range object. * @return {ol.TileRange} Tile range. */ -ol.tilegrid.TileGrid.prototype.getTileRangeForExtentAndResolution = - function(extent, resolution, opt_tileRange) { +ol.tilegrid.TileGrid.prototype.getTileRangeForExtentAndResolution = function(extent, resolution, opt_tileRange) { var tileCoord = ol.tilegrid.TileGrid.tmpTileCoord_; this.getTileCoordForXYAndResolution_( extent[0], extent[1], resolution, false, tileCoord); @@ -37415,8 +35104,7 @@ ol.tilegrid.TileGrid.prototype.getTileRangeForExtentAndResolution = * @param {ol.TileRange=} opt_tileRange Temporary tile range object. * @return {ol.TileRange} Tile range. */ -ol.tilegrid.TileGrid.prototype.getTileRangeForExtentAndZ = - function(extent, z, opt_tileRange) { +ol.tilegrid.TileGrid.prototype.getTileRangeForExtentAndZ = function(extent, z, opt_tileRange) { var resolution = this.getResolution(z); return this.getTileRangeForExtentAndResolution( extent, resolution, opt_tileRange); @@ -37446,8 +35134,7 @@ ol.tilegrid.TileGrid.prototype.getTileCoordCenter = function(tileCoord) { * @return {ol.Extent} Extent. * @api */ -ol.tilegrid.TileGrid.prototype.getTileCoordExtent = - function(tileCoord, opt_extent) { +ol.tilegrid.TileGrid.prototype.getTileCoordExtent = function(tileCoord, opt_extent) { var origin = this.getOrigin(tileCoord[0]); var resolution = this.getResolution(tileCoord[0]); var tileSize = ol.size.toSize(this.getTileSize(tileCoord[0]), this.tmpSize_); @@ -37470,8 +35157,7 @@ ol.tilegrid.TileGrid.prototype.getTileCoordExtent = * @return {ol.TileCoord} Tile coordinate. * @api */ -ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndResolution = - function(coordinate, resolution, opt_tileCoord) { +ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndResolution = function(coordinate, resolution, opt_tileCoord) { return this.getTileCoordForXYAndResolution_( coordinate[0], coordinate[1], resolution, false, opt_tileCoord); }; @@ -37522,8 +35208,7 @@ ol.tilegrid.TileGrid.prototype.getTileCoordForXYAndResolution_ = function( * @return {ol.TileCoord} Tile coordinate. * @api */ -ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndZ = - function(coordinate, z, opt_tileCoord) { +ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndZ = function(coordinate, z, opt_tileCoord) { var resolution = this.getResolution(z); return this.getTileCoordForXYAndResolution_( coordinate[0], coordinate[1], resolution, false, opt_tileCoord); @@ -37583,10 +35268,15 @@ ol.tilegrid.TileGrid.prototype.getFullTileRange = function(z) { /** * @param {number} resolution Resolution. + * @param {number=} opt_direction If 0, the nearest resolution will be used. + * If 1, the nearest lower resolution will be used. If -1, the nearest + * higher resolution will be used. Default is 0. * @return {number} Z. */ -ol.tilegrid.TileGrid.prototype.getZForResolution = function(resolution) { - var z = ol.array.linearFindNearest(this.resolutions_, resolution, 0); +ol.tilegrid.TileGrid.prototype.getZForResolution = function( + resolution, opt_direction) { + var z = ol.array.linearFindNearest(this.resolutions_, resolution, + opt_direction || 0); return ol.math.clamp(z, this.minZoom, this.maxZoom); }; @@ -37629,8 +35319,7 @@ ol.tilegrid.getForProjection = function(projection) { * ol.extent.Corner.TOP_LEFT). * @return {ol.tilegrid.TileGrid} TileGrid instance. */ -ol.tilegrid.createForExtent = - function(extent, opt_maxZoom, opt_tileSize, opt_corner) { +ol.tilegrid.createForExtent = function(extent, opt_maxZoom, opt_tileSize, opt_corner) { var corner = opt_corner !== undefined ? opt_corner : ol.extent.Corner.TOP_LEFT; @@ -37654,7 +35343,7 @@ ol.tilegrid.createForExtent = */ ol.tilegrid.createXYZ = function(opt_options) { var options = /** @type {olx.tilegrid.TileGridOptions} */ ({}); - goog.object.extend(options, opt_options !== undefined ? + ol.object.assign(options, opt_options !== undefined ? opt_options : /** @type {olx.tilegrid.XYZOptions} */ ({})); if (options.extent === undefined) { options.extent = ol.proj.get('EPSG:3857').getExtent(); @@ -37676,8 +35365,7 @@ ol.tilegrid.createXYZ = function(opt_options) { * ol.DEFAULT_TILE_SIZE). * @return {!Array.<number>} Resolutions array. */ -ol.tilegrid.resolutionsFromExtent = - function(extent, opt_maxZoom, opt_tileSize) { +ol.tilegrid.resolutionsFromExtent = function(extent, opt_maxZoom, opt_tileSize) { var maxZoom = opt_maxZoom !== undefined ? opt_maxZoom : ol.DEFAULT_MAX_ZOOM; @@ -37707,8 +35395,7 @@ ol.tilegrid.resolutionsFromExtent = * ol.extent.Corner.BOTTOM_LEFT). * @return {ol.tilegrid.TileGrid} TileGrid instance. */ -ol.tilegrid.createForProjection = - function(projection, opt_maxZoom, opt_tileSize, opt_corner) { +ol.tilegrid.createForProjection = function(projection, opt_maxZoom, opt_tileSize, opt_corner) { var extent = ol.tilegrid.extentFromProjection(projection); return ol.tilegrid.createForExtent( extent, opt_maxZoom, opt_tileSize, opt_corner); @@ -37734,13 +35421,10 @@ ol.tilegrid.extentFromProjection = function(projection) { goog.provide('ol.source.Tile'); goog.provide('ol.source.TileEvent'); -goog.provide('ol.source.TileOptions'); goog.require('goog.asserts'); -goog.require('goog.events.Event'); +goog.require('ol.events.Event'); goog.require('ol'); -goog.require('ol.Attribution'); -goog.require('ol.Extent'); goog.require('ol.TileCache'); goog.require('ol.TileRange'); goog.require('ol.TileState'); @@ -37752,22 +35436,6 @@ goog.require('ol.tilegrid.TileGrid'); /** - * @typedef {{attributions: (Array.<ol.Attribution>|undefined), - * cacheSize: (number|undefined), - * extent: (ol.Extent|undefined), - * logo: (string|olx.LogoOptions|undefined), - * opaque: (boolean|undefined), - * tilePixelRatio: (number|undefined), - * projection: ol.proj.ProjectionLike, - * state: (ol.source.State|undefined), - * tileGrid: (ol.tilegrid.TileGrid|undefined), - * wrapX: (boolean|undefined)}} - */ -ol.source.TileOptions; - - - -/** * @classdesc * Abstract base class; normally only used for creating subclasses and not * instantiated in apps. @@ -37775,7 +35443,7 @@ ol.source.TileOptions; * * @constructor * @extends {ol.source.Source} - * @param {ol.source.TileOptions} options Tile source options. + * @param {ol.SourceTileOptions} options Tile source options. * @api */ ol.source.Tile = function(options) { @@ -37820,6 +35488,12 @@ ol.source.Tile = function(options) { */ this.tmpSize = [0, 0]; + /** + * @private + * @type {string} + */ + this.key_ = ''; + }; goog.inherits(ol.source.Tile, ol.source.Source); @@ -37853,8 +35527,7 @@ ol.source.Tile.prototype.expireCache = function(projection, usedTiles) { * considered loaded. * @return {boolean} The tile range is fully covered with loaded tiles. */ -ol.source.Tile.prototype.forEachLoadedTile = - function(projection, z, tileRange, callback) { +ol.source.Tile.prototype.forEachLoadedTile = function(projection, z, tileRange, callback) { var tileCache = this.getTileCacheForProjection(projection); if (!tileCache) { return false; @@ -37883,21 +35556,34 @@ ol.source.Tile.prototype.forEachLoadedTile = /** + * @param {ol.proj.Projection} projection Projection. * @return {number} Gutter. */ -ol.source.Tile.prototype.getGutter = function() { +ol.source.Tile.prototype.getGutter = function(projection) { return 0; }; /** - * Return the "parameters" key, a string composed of the source's - * parameters/dimensions. - * @return {string} The parameters key. + * Return the key to be used for all tiles in the source. + * @return {string} The key for all tiles. * @protected */ -ol.source.Tile.prototype.getKeyParams = function() { - return ''; +ol.source.Tile.prototype.getKey = function() { + return this.key_; +}; + + +/** + * Set the value to be used as the key for all tiles in the source. + * @param {string} key The key for tiles. + * @protected + */ +ol.source.Tile.prototype.setKey = function(key) { + if (this.key_ !== key) { + this.key_ = key; + this.changed(); + } }; @@ -37912,9 +35598,10 @@ ol.source.Tile.prototype.getKeyZXY = ol.tilecoord.getKeyZXY; /** + * @param {ol.proj.Projection} projection Projection. * @return {boolean} Opaque. */ -ol.source.Tile.prototype.getOpaque = function() { +ol.source.Tile.prototype.getOpaque = function(projection) { return this.opaque_; }; @@ -37977,9 +35664,10 @@ ol.source.Tile.prototype.getTileCacheForProjection = function(projection) { /** + * @param {number} pixelRatio Pixel ratio. * @return {number} Tile pixel ratio. */ -ol.source.Tile.prototype.getTilePixelRatio = function() { +ol.source.Tile.prototype.getTilePixelRatio = function(pixelRatio) { return this.tilePixelRatio_; }; @@ -37990,11 +35678,15 @@ ol.source.Tile.prototype.getTilePixelRatio = function() { * @param {ol.proj.Projection} projection Projection. * @return {ol.Size} Tile size. */ -ol.source.Tile.prototype.getTilePixelSize = - function(z, pixelRatio, projection) { +ol.source.Tile.prototype.getTilePixelSize = function(z, pixelRatio, projection) { var tileGrid = this.getTileGridForProjection(projection); - return ol.size.scale(ol.size.toSize(tileGrid.getTileSize(z), this.tmpSize), - this.tilePixelRatio_, this.tmpSize); + var tilePixelRatio = this.getTilePixelRatio(pixelRatio); + var tileSize = ol.size.toSize(tileGrid.getTileSize(z), this.tmpSize); + if (tilePixelRatio == 1) { + return tileSize; + } else { + return ol.size.scale(tileSize, tilePixelRatio, this.tmpSize); + } }; @@ -38007,8 +35699,7 @@ ol.source.Tile.prototype.getTilePixelSize = * @return {ol.TileCoord} Tile coordinate to be passed to the tileUrlFunction or * null if no tile URL should be created for the passed `tileCoord`. */ -ol.source.Tile.prototype.getTileCoordForTileUrlFunction = - function(tileCoord, opt_projection) { +ol.source.Tile.prototype.getTileCoordForTileUrlFunction = function(tileCoord, opt_projection) { var projection = opt_projection !== undefined ? opt_projection : this.getProjection(); var tileGrid = this.getTileGridForProjection(projection); @@ -38021,6 +35712,15 @@ ol.source.Tile.prototype.getTileCoordForTileUrlFunction = /** + * @inheritDoc + */ +ol.source.Tile.prototype.refresh = function() { + this.tileCache.clear(); + this.changed(); +}; + + +/** * Marks a tile coord as being used, without triggering a load. * @param {number} z Tile coordinate z. * @param {number} x Tile coordinate x. @@ -38030,14 +35730,13 @@ ol.source.Tile.prototype.getTileCoordForTileUrlFunction = ol.source.Tile.prototype.useTile = ol.nullFunction; - /** * @classdesc * Events emitted by {@link ol.source.Tile} instances are instances of this * type. * * @constructor - * @extends {goog.events.Event} + * @extends {ol.events.Event} * @implements {oli.source.TileEvent} * @param {string} type Type. * @param {ol.Tile} tile The tile. @@ -38054,7 +35753,7 @@ ol.source.TileEvent = function(type, tile) { this.tile = tile; }; -goog.inherits(ol.source.TileEvent, goog.events.Event); +goog.inherits(ol.source.TileEvent, ol.events.Event); /** @@ -38091,19 +35790,17 @@ goog.provide('ol.control.Attribution'); goog.require('goog.asserts'); goog.require('goog.dom'); -goog.require('goog.dom.classlist'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.object'); goog.require('goog.style'); goog.require('ol'); goog.require('ol.Attribution'); goog.require('ol.control.Control'); goog.require('ol.css'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); +goog.require('ol.object'); goog.require('ol.source.Tile'); - /** * @classdesc * Control to show all the attributions associated with the layer sources @@ -38152,27 +35849,27 @@ ol.control.Attribution = function(opt_options) { this.collapsed_ = false; } - var className = options.className ? options.className : 'ol-attribution'; + var className = options.className !== undefined ? options.className : 'ol-attribution'; - var tipLabel = options.tipLabel ? options.tipLabel : 'Attributions'; + var tipLabel = options.tipLabel !== undefined ? options.tipLabel : 'Attributions'; - var collapseLabel = options.collapseLabel ? options.collapseLabel : '\u00BB'; + var collapseLabel = options.collapseLabel !== undefined ? options.collapseLabel : '\u00BB'; /** * @private * @type {Node} */ - this.collapseLabel_ = goog.isString(collapseLabel) ? + this.collapseLabel_ = typeof collapseLabel === 'string' ? goog.dom.createDom('SPAN', {}, collapseLabel) : collapseLabel; - var label = options.label ? options.label : 'i'; + var label = options.label !== undefined ? options.label : 'i'; /** * @private * @type {Node} */ - this.label_ = goog.isString(label) ? + this.label_ = typeof label === 'string' ? goog.dom.createDom('SPAN', {}, label) : label; @@ -38183,8 +35880,7 @@ ol.control.Attribution = function(opt_options) { 'title': tipLabel }, activeLabel); - goog.events.listen(button, goog.events.EventType.CLICK, - this.handleClick_, false, this); + ol.events.listen(button, ol.events.EventType.CLICK, this.handleClick_, this); var cssClasses = className + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' + ol.css.CLASS_CONTROL + @@ -38239,7 +35935,7 @@ ol.control.Attribution.prototype.getSourceAttributions = function(frameState) { var intersectsTileRange; var layerStatesArray = frameState.layerStatesArray; /** @type {Object.<string, ol.Attribution>} */ - var attributions = goog.object.clone(frameState.attributions); + var attributions = ol.object.assign({}, frameState.attributions); /** @type {Object.<string, ol.Attribution>} */ var hiddenAttributions = {}; var projection = frameState.viewState.projection; @@ -38325,16 +36021,14 @@ ol.control.Attribution.prototype.updateElement_ = function(frameState) { this.attributionElementRenderedVisible_[attributionKey] = true; } delete visibleAttributions[attributionKey]; - } - else if (attributionKey in hiddenAttributions) { + } else if (attributionKey in hiddenAttributions) { if (this.attributionElementRenderedVisible_[attributionKey]) { goog.style.setElementShown( this.attributionElements_[attributionKey], false); delete this.attributionElementRenderedVisible_[attributionKey]; } delete hiddenAttributions[attributionKey]; - } - else { + } else { goog.dom.removeNode(this.attributionElements_[attributionKey]); delete this.attributionElements_[attributionKey]; delete this.attributionElementRenderedVisible_[attributionKey]; @@ -38358,17 +36052,17 @@ ol.control.Attribution.prototype.updateElement_ = function(frameState) { } var renderVisible = - !goog.object.isEmpty(this.attributionElementRenderedVisible_) || - !goog.object.isEmpty(frameState.logos); + !ol.object.isEmpty(this.attributionElementRenderedVisible_) || + !ol.object.isEmpty(frameState.logos); if (this.renderedVisible_ != renderVisible) { goog.style.setElementShown(this.element, renderVisible); this.renderedVisible_ = renderVisible; } if (renderVisible && - goog.object.isEmpty(this.attributionElementRenderedVisible_)) { - goog.dom.classlist.add(this.element, 'ol-logo-only'); + ol.object.isEmpty(this.attributionElementRenderedVisible_)) { + this.element.classList.add('ol-logo-only'); } else { - goog.dom.classlist.remove(this.element, 'ol-logo-only'); + this.element.classList.remove('ol-logo-only'); } this.insertLogos_(frameState); @@ -38395,10 +36089,14 @@ ol.control.Attribution.prototype.insertLogos_ = function(frameState) { var image, logoElement, logoKey; for (logoKey in logos) { + var logoValue = logos[logoKey]; + if (logoValue instanceof HTMLElement) { + this.logoLi_.appendChild(logoValue); + logoElements[logoKey] = logoValue; + } if (!(logoKey in logoElements)) { image = new Image(); image.src = logoKey; - var logoValue = logos[logoKey]; if (logoValue === '') { logoElement = image; } else { @@ -38412,13 +36110,13 @@ ol.control.Attribution.prototype.insertLogos_ = function(frameState) { } } - goog.style.setElementShown(this.logoLi_, !goog.object.isEmpty(logos)); + goog.style.setElementShown(this.logoLi_, !ol.object.isEmpty(logos)); }; /** - * @param {goog.events.BrowserEvent} event The event to handle + * @param {Event} event The event to handle * @private */ ol.control.Attribution.prototype.handleClick_ = function(event) { @@ -38431,7 +36129,7 @@ ol.control.Attribution.prototype.handleClick_ = function(event) { * @private */ ol.control.Attribution.prototype.handleToggle_ = function() { - goog.dom.classlist.toggle(this.element, 'ol-collapsed'); + this.element.classList.toggle('ol-collapsed'); if (this.collapsed_) { goog.dom.replaceNode(this.collapseLabel_, this.label_); } else { @@ -38461,7 +36159,7 @@ ol.control.Attribution.prototype.setCollapsible = function(collapsible) { return; } this.collapsible_ = collapsible; - goog.dom.classlist.toggle(this.element, 'ol-uncollapsible'); + this.element.classList.toggle('ol-uncollapsible'); if (!collapsible && this.collapsed_) { this.handleToggle_(); } @@ -38496,9 +36194,8 @@ ol.control.Attribution.prototype.getCollapsed = function() { goog.provide('ol.control.Rotate'); goog.require('goog.dom'); -goog.require('goog.dom.classlist'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol'); goog.require('ol.animation'); goog.require('ol.control.Control'); @@ -38506,7 +36203,6 @@ goog.require('ol.css'); goog.require('ol.easing'); - /** * @classdesc * A button control to reset rotation to 0. @@ -38522,10 +36218,9 @@ ol.control.Rotate = function(opt_options) { var options = opt_options ? opt_options : {}; - var className = options.className ? - options.className : 'ol-rotate'; + var className = options.className !== undefined ? options.className : 'ol-rotate'; - var label = options.label ? options.label : '\u21E7'; + var label = options.label !== undefined ? options.label : '\u21E7'; /** * @type {Element} @@ -38533,12 +36228,12 @@ ol.control.Rotate = function(opt_options) { */ this.label_ = null; - if (goog.isString(label)) { + if (typeof label === 'string') { this.label_ = goog.dom.createDom('SPAN', 'ol-compass', label); } else { this.label_ = label; - goog.dom.classlist.add(this.label_, 'ol-compass'); + this.label_.classList.add('ol-compass'); } var tipLabel = options.tipLabel ? options.tipLabel : 'Reset rotation'; @@ -38549,8 +36244,8 @@ ol.control.Rotate = function(opt_options) { 'title': tipLabel }, this.label_); - goog.events.listen(button, goog.events.EventType.CLICK, - ol.control.Rotate.prototype.handleClick_, false, this); + ol.events.listen(button, ol.events.EventType.CLICK, + ol.control.Rotate.prototype.handleClick_, this); var cssClasses = className + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' + ol.css.CLASS_CONTROL; @@ -38585,7 +36280,7 @@ ol.control.Rotate = function(opt_options) { this.rotation_ = undefined; if (this.autoHide_) { - goog.dom.classlist.add(this.element, ol.css.CLASS_HIDDEN); + this.element.classList.add(ol.css.CLASS_HIDDEN); } }; @@ -38593,7 +36288,7 @@ goog.inherits(ol.control.Rotate, ol.control.Control); /** - * @param {goog.events.BrowserEvent} event The event to handle + * @param {Event} event The event to handle * @private */ ol.control.Rotate.prototype.handleClick_ = function(event) { @@ -38653,8 +36348,12 @@ ol.control.Rotate.render = function(mapEvent) { if (rotation != this.rotation_) { var transform = 'rotate(' + rotation + 'rad)'; if (this.autoHide_) { - goog.dom.classlist.enable( - this.element, ol.css.CLASS_HIDDEN, rotation === 0); + var contains = this.element.classList.contains(ol.css.CLASS_HIDDEN); + if (!contains && rotation === 0) { + this.element.classList.add(ol.css.CLASS_HIDDEN); + } else if (contains && rotation !== 0) { + this.element.classList.remove(ol.css.CLASS_HIDDEN); + } } this.label_.style.msTransform = transform; this.label_.style.webkitTransform = transform; @@ -38666,15 +36365,14 @@ ol.control.Rotate.render = function(mapEvent) { goog.provide('ol.control.Zoom'); goog.require('goog.dom'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol.animation'); goog.require('ol.control.Control'); goog.require('ol.css'); goog.require('ol.easing'); - /** * @classdesc * A control with 2 buttons, one for zoom in and one for zoom out. @@ -38690,16 +36388,16 @@ ol.control.Zoom = function(opt_options) { var options = opt_options ? opt_options : {}; - var className = options.className ? options.className : 'ol-zoom'; + var className = options.className !== undefined ? options.className : 'ol-zoom'; - var delta = options.delta ? options.delta : 1; + var delta = options.delta !== undefined ? options.delta : 1; - var zoomInLabel = options.zoomInLabel ? options.zoomInLabel : '+'; - var zoomOutLabel = options.zoomOutLabel ? options.zoomOutLabel : '\u2212'; + var zoomInLabel = options.zoomInLabel !== undefined ? options.zoomInLabel : '+'; + var zoomOutLabel = options.zoomOutLabel !== undefined ? options.zoomOutLabel : '\u2212'; - var zoomInTipLabel = options.zoomInTipLabel ? + var zoomInTipLabel = options.zoomInTipLabel !== undefined ? options.zoomInTipLabel : 'Zoom in'; - var zoomOutTipLabel = options.zoomOutTipLabel ? + var zoomOutTipLabel = options.zoomOutTipLabel !== undefined ? options.zoomOutTipLabel : 'Zoom out'; var inElement = goog.dom.createDom('BUTTON', { @@ -38708,9 +36406,8 @@ ol.control.Zoom = function(opt_options) { 'title': zoomInTipLabel }, zoomInLabel); - goog.events.listen(inElement, - goog.events.EventType.CLICK, goog.partial( - ol.control.Zoom.prototype.handleClick_, delta), false, this); + ol.events.listen(inElement, ol.events.EventType.CLICK, + ol.control.Zoom.prototype.handleClick_.bind(this, delta)); var outElement = goog.dom.createDom('BUTTON', { 'class': className + '-out', @@ -38718,14 +36415,12 @@ ol.control.Zoom = function(opt_options) { 'title': zoomOutTipLabel }, zoomOutLabel); - goog.events.listen(outElement, - goog.events.EventType.CLICK, goog.partial( - ol.control.Zoom.prototype.handleClick_, -delta), false, this); + ol.events.listen(outElement, ol.events.EventType.CLICK, + ol.control.Zoom.prototype.handleClick_.bind(this, -delta)); var cssClasses = className + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' + ol.css.CLASS_CONTROL; - var element = goog.dom.createDom('DIV', cssClasses, inElement, - outElement); + var element = goog.dom.createDom('DIV', cssClasses, inElement, outElement); goog.base(this, { element: element, @@ -38744,7 +36439,7 @@ goog.inherits(ol.control.Zoom, ol.control.Control); /** * @param {number} delta Zoom delta. - * @param {goog.events.BrowserEvent} event The event to handle + * @param {Event} event The event to handle * @private */ ol.control.Zoom.prototype.handleClick_ = function(delta, event) { @@ -38884,7 +36579,8 @@ goog.dom.fullscreen.EventType = { goog.dom.fullscreen.isSupported = function(opt_domHelper) { var doc = goog.dom.fullscreen.getDocument_(opt_domHelper); var body = doc.body; - return !!(body.webkitRequestFullscreen || + return !!( + body.webkitRequestFullscreen || (body.mozRequestFullScreen && doc.mozFullScreenEnabled) || (body.msRequestFullscreen && doc.msFullscreenEnabled) || (body.requestFullscreen && doc.fullscreenEnabled)); @@ -38912,8 +36608,7 @@ goog.dom.fullscreen.requestFullScreen = function(element) { * Requests putting the element in full screen with full keyboard access. * @param {!Element} element The element to put full screen. */ -goog.dom.fullscreen.requestFullScreenWithKeys = function( - element) { +goog.dom.fullscreen.requestFullScreenWithKeys = function(element) { if (element.mozRequestFullScreenWithKeys) { element.mozRequestFullScreenWithKeys(); } else if (element.webkitRequestFullscreen) { @@ -38953,8 +36648,9 @@ goog.dom.fullscreen.isFullScreen = function(opt_domHelper) { var doc = goog.dom.fullscreen.getDocument_(opt_domHelper); // IE 11 doesn't have similar boolean property, so check whether // document.msFullscreenElement is null instead. - return !!(doc.webkitIsFullScreen || doc.mozFullScreen || - doc.msFullscreenElement || doc.fullscreenElement); + return !!( + doc.webkitIsFullScreen || doc.mozFullScreen || doc.msFullscreenElement || + doc.fullscreenElement); }; @@ -38967,10 +36663,8 @@ goog.dom.fullscreen.isFullScreen = function(opt_domHelper) { goog.dom.fullscreen.getFullScreenElement = function(opt_domHelper) { var doc = goog.dom.fullscreen.getDocument_(opt_domHelper); var element_list = [ - doc.webkitFullscreenElement, - doc.mozFullScreenElement, - doc.msFullscreenElement, - doc.fullscreenElement + doc.webkitFullscreenElement, doc.mozFullScreenElement, + doc.msFullscreenElement, doc.fullscreenElement ]; for (var i = 0; i < element_list.length; i++) { if (element_list[i] != null) { @@ -38989,29 +36683,30 @@ goog.dom.fullscreen.getFullScreenElement = function(opt_domHelper) { * @private */ goog.dom.fullscreen.getDocument_ = function(opt_domHelper) { - return opt_domHelper ? - opt_domHelper.getDocument() : - goog.dom.getDomHelper().getDocument(); + return opt_domHelper ? opt_domHelper.getDocument() : + goog.dom.getDomHelper().getDocument(); }; goog.provide('ol.control.FullScreen'); goog.require('goog.asserts'); goog.require('goog.dom'); -goog.require('goog.dom.classlist'); goog.require('goog.dom.fullscreen'); goog.require('goog.dom.fullscreen.EventType'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol'); goog.require('ol.control.Control'); goog.require('ol.css'); - /** * @classdesc * Provides a button that when clicked fills up the full screen with the map. + * The full screen source element is by default the element containing the map viewport unless + * overriden by providing the `source` option. In which case, the dom + * element introduced using this parameter will be displayed in full screen. + * * When in full screen mode, a close button is shown to exit full screen mode. * The [Fullscreen API](http://www.w3.org/TR/fullscreen/) is used to * toggle the map in full screen mode. @@ -39030,24 +36725,25 @@ ol.control.FullScreen = function(opt_options) { * @private * @type {string} */ - this.cssClassName_ = options.className ? options.className : 'ol-full-screen'; + this.cssClassName_ = options.className !== undefined ? options.className : + 'ol-full-screen'; - var label = options.label ? options.label : '\u2922'; + var label = options.label !== undefined ? options.label : '\u2922'; /** * @private * @type {Node} */ - this.labelNode_ = goog.isString(label) ? + this.labelNode_ = typeof label === 'string' ? document.createTextNode(label) : label; - var labelActive = options.labelActive ? options.labelActive : '\u00d7'; + var labelActive = options.labelActive !== undefined ? options.labelActive : '\u00d7'; /** * @private * @type {Node} */ - this.labelActiveNode_ = goog.isString(labelActive) ? + this.labelActiveNode_ = typeof labelActive === 'string' ? document.createTextNode(labelActive) : labelActive; var tipLabel = options.tipLabel ? options.tipLabel : 'Toggle full-screen'; @@ -39057,12 +36753,8 @@ ol.control.FullScreen = function(opt_options) { 'title': tipLabel }, this.labelNode_); - goog.events.listen(button, goog.events.EventType.CLICK, - this.handleClick_, false, this); - - goog.events.listen(goog.global.document, - goog.dom.fullscreen.EventType.CHANGE, - this.handleFullScreenChange_, false, this); + ol.events.listen(button, ol.events.EventType.CLICK, + this.handleClick_, this); var cssClasses = this.cssClassName_ + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' + ol.css.CLASS_CONTROL + ' ' + @@ -39080,12 +36772,18 @@ ol.control.FullScreen = function(opt_options) { */ this.keys_ = options.keys !== undefined ? options.keys : false; + /** + * @private + * @type {Element|string|undefined} + */ + this.source_ = options.source; + }; goog.inherits(ol.control.FullScreen, ol.control.Control); /** - * @param {goog.events.BrowserEvent} event The event to handle + * @param {Event} event The event to handle * @private */ ol.control.FullScreen.prototype.handleClick_ = function(event) { @@ -39108,9 +36806,8 @@ ol.control.FullScreen.prototype.handleFullScreen_ = function() { if (goog.dom.fullscreen.isFullScreen()) { goog.dom.fullscreen.exitFullScreen(); } else { - var target = map.getTarget(); - goog.asserts.assert(target, 'target should be defined'); - var element = goog.dom.getElement(target); + var element = this.source_ ? + goog.dom.getElement(this.source_) : map.getTargetElement(); goog.asserts.assert(element, 'element should be defined'); if (this.keys_) { goog.dom.fullscreen.requestFullScreenWithKeys(element); @@ -39125,15 +36822,13 @@ ol.control.FullScreen.prototype.handleFullScreen_ = function() { * @private */ ol.control.FullScreen.prototype.handleFullScreenChange_ = function() { - var opened = this.cssClassName_ + '-true'; - var closed = this.cssClassName_ + '-false'; - var button = goog.dom.getFirstElementChild(this.element); + var button = this.element.firstElementChild; var map = this.getMap(); if (goog.dom.fullscreen.isFullScreen()) { - goog.dom.classlist.swap(button, closed, opened); + button.className = this.cssClassName_ + '-true'; goog.dom.replaceNode(this.labelActiveNode_, this.labelNode_); } else { - goog.dom.classlist.swap(button, opened, closed); + button.className = this.cssClassName_ + '-false'; goog.dom.replaceNode(this.labelNode_, this.labelActiveNode_); } if (map) { @@ -39141,28 +36836,28 @@ ol.control.FullScreen.prototype.handleFullScreenChange_ = function() { } }; -goog.provide('ol.Pixel'); - /** - * An array with two elements, representing a pixel. The first element is the - * x-coordinate, the second the y-coordinate of the pixel. - * @typedef {Array.<number>} + * @inheritDoc * @api stable */ -ol.Pixel; +ol.control.FullScreen.prototype.setMap = function(map) { + goog.base(this, 'setMap', map); + if (map) { + this.listenerKeys.push( + ol.events.listen(ol.global.document, goog.dom.fullscreen.EventType.CHANGE, + this.handleFullScreenChange_, this) + ); + } +}; // FIXME should listen on appropriate pane, once it is defined goog.provide('ol.control.MousePosition'); -goog.require('goog.dom'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('ol.CoordinateFormatType'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol.Object'); -goog.require('ol.Pixel'); -goog.require('ol.TransformFunction'); goog.require('ol.control.Control'); goog.require('ol.proj'); goog.require('ol.proj.Projection'); @@ -39177,7 +36872,6 @@ ol.control.MousePositionProperty = { }; - /** * @classdesc * A control to show the 2D coordinates of the mouse cursor. By default, these @@ -39195,9 +36889,8 @@ ol.control.MousePosition = function(opt_options) { var options = opt_options ? opt_options : {}; - var className = options.className ? options.className : 'ol-mouse-position'; - - var element = goog.dom.createDom('DIV', className); + var element = document.createElement('DIV'); + element.className = options.className !== undefined ? options.className : 'ol-mouse-position' var render = options.render ? options.render : ol.control.MousePosition.render; @@ -39208,9 +36901,9 @@ ol.control.MousePosition = function(opt_options) { target: options.target }); - goog.events.listen(this, + ol.events.listen(this, ol.Object.getChangeEventType(ol.control.MousePositionProperty.PROJECTION), - this.handleProjectionChanged_, false, this); + this.handleProjectionChanged_, this); if (options.coordinateFormat) { this.setCoordinateFormat(options.coordinateFormat); @@ -39223,7 +36916,7 @@ ol.control.MousePosition = function(opt_options) { * @private * @type {string} */ - this.undefinedHTML_ = options.undefinedHTML ? options.undefinedHTML : ''; + this.undefinedHTML_ = options.undefinedHTML !== undefined ? options.undefinedHTML : ''; /** * @private @@ -39309,21 +37002,21 @@ ol.control.MousePosition.prototype.getProjection = function() { /** - * @param {goog.events.BrowserEvent} browserEvent Browser event. + * @param {Event} event Browser event. * @protected */ -ol.control.MousePosition.prototype.handleMouseMove = function(browserEvent) { +ol.control.MousePosition.prototype.handleMouseMove = function(event) { var map = this.getMap(); - this.lastMouseMovePixel_ = map.getEventPixel(browserEvent.getBrowserEvent()); + this.lastMouseMovePixel_ = map.getEventPixel(event); this.updateHTML_(this.lastMouseMovePixel_); }; /** - * @param {goog.events.BrowserEvent} browserEvent Browser event. + * @param {Event} event Browser event. * @protected */ -ol.control.MousePosition.prototype.handleMouseOut = function(browserEvent) { +ol.control.MousePosition.prototype.handleMouseOut = function(event) { this.updateHTML_(null); this.lastMouseMovePixel_ = null; }; @@ -39338,10 +37031,10 @@ ol.control.MousePosition.prototype.setMap = function(map) { if (map) { var viewport = map.getViewport(); this.listenerKeys.push( - goog.events.listen(viewport, goog.events.EventType.MOUSEMOVE, - this.handleMouseMove, false, this), - goog.events.listen(viewport, goog.events.EventType.MOUSEOUT, - this.handleMouseOut, false, this) + ol.events.listen(viewport, ol.events.EventType.MOUSEMOVE, + this.handleMouseMove, this), + ol.events.listen(viewport, ol.events.EventType.MOUSEOUT, + this.handleMouseOut, this) ); } }; @@ -39405,7 +37098,7 @@ ol.control.MousePosition.prototype.updateHTML_ = function(pixel) { } }; -// Copyright 2012 The Closure Library Authors. All Rights Reserved. +// Copyright 2010 The Closure Library Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -39420,1324 +37113,152 @@ ol.control.MousePosition.prototype.updateHTML_ = function(pixel) { // limitations under the License. /** - * @fileoverview A delayed callback that pegs to the next animation frame - * instead of a user-configurable timeout. - * - * @author nicksantos@google.com (Nick Santos) - */ - -goog.provide('goog.async.AnimationDelay'); - -goog.require('goog.Disposable'); -goog.require('goog.events'); -goog.require('goog.functions'); - - - -// TODO(nicksantos): Should we factor out the common code between this and -// goog.async.Delay? I'm not sure if there's enough code for this to really -// make sense. Subclassing seems like the wrong approach for a variety of -// reasons. Maybe there should be a common interface? - - - -/** - * A delayed callback that pegs to the next animation frame - * instead of a user configurable timeout. By design, this should have - * the same interface as goog.async.Delay. - * - * Uses requestAnimationFrame and friends when available, but falls - * back to a timeout of goog.async.AnimationDelay.TIMEOUT. + * @fileoverview A global registry for entry points into a program, + * so that they can be instrumented. Each module should register their + * entry points with this registry. Designed to be compiled out + * if no instrumentation is requested. * - * For more on requestAnimationFrame and how you can use it to create smoother - * animations, see: - * @see http://paulirish.com/2011/requestanimationframe-for-smart-animating/ + * Entry points may be registered before or after a call to + * goog.debug.entryPointRegistry.monitorAll. If an entry point is registered + * later, the existing monitor will instrument the new entry point. * - * @param {function(number)} listener Function to call when the delay completes. - * Will be passed the timestamp when it's called, in unix ms. - * @param {Window=} opt_window The window object to execute the delay in. - * Defaults to the global object. - * @param {Object=} opt_handler The object scope to invoke the function in. - * @constructor - * @struct - * @extends {goog.Disposable} - * @final + * @author nicksantos@google.com (Nick Santos) */ -goog.async.AnimationDelay = function(listener, opt_window, opt_handler) { - goog.async.AnimationDelay.base(this, 'constructor'); - - /** - * Identifier of the active delay timeout, or event listener, - * or null when inactive. - * @private {goog.events.Key|number} - */ - this.id_ = null; - /** - * If we're using dom listeners. - * @private {?boolean} - */ - this.usingListeners_ = false; - - /** - * The function that will be invoked after a delay. - * @private {function(number)} - */ - this.listener_ = listener; - - /** - * The object context to invoke the callback in. - * @private {Object|undefined} - */ - this.handler_ = opt_handler; +goog.provide('goog.debug.EntryPointMonitor'); +goog.provide('goog.debug.entryPointRegistry'); - /** - * @private {Window} - */ - this.win_ = opt_window || window; +goog.require('goog.asserts'); - /** - * Cached callback function invoked when the delay finishes. - * @private {function()} - */ - this.callback_ = goog.bind(this.doAction_, this); -}; -goog.inherits(goog.async.AnimationDelay, goog.Disposable); /** - * Default wait timeout for animations (in milliseconds). Only used for timed - * animation, which uses a timer (setTimeout) to schedule animation. - * - * @type {number} - * @const + * @interface */ -goog.async.AnimationDelay.TIMEOUT = 20; +goog.debug.EntryPointMonitor = function() {}; /** - * Name of event received from the requestAnimationFrame in Firefox. + * Instruments a function. * - * @type {string} - * @const - * @private - */ -goog.async.AnimationDelay.MOZ_BEFORE_PAINT_EVENT_ = 'MozBeforePaint'; - - -/** - * Starts the delay timer. The provided listener function will be called - * before the next animation frame. - */ -goog.async.AnimationDelay.prototype.start = function() { - this.stop(); - this.usingListeners_ = false; - - var raf = this.getRaf_(); - var cancelRaf = this.getCancelRaf_(); - if (raf && !cancelRaf && this.win_.mozRequestAnimationFrame) { - // Because Firefox (Gecko) runs animation in separate threads, it also saves - // time by running the requestAnimationFrame callbacks in that same thread. - // Sadly this breaks the assumption of implicit thread-safety in JS, and can - // thus create thread-based inconsistencies on counters etc. - // - // Calling cycleAnimations_ using the MozBeforePaint event instead of as - // callback fixes this. - // - // Trigger this condition only if the mozRequestAnimationFrame is available, - // but not the W3C requestAnimationFrame function (as in draft) or the - // equivalent cancel functions. - this.id_ = goog.events.listen( - this.win_, - goog.async.AnimationDelay.MOZ_BEFORE_PAINT_EVENT_, - this.callback_); - this.win_.mozRequestAnimationFrame(null); - this.usingListeners_ = true; - } else if (raf && cancelRaf) { - this.id_ = raf.call(this.win_, this.callback_); - } else { - this.id_ = this.win_.setTimeout( - // Prior to Firefox 13, Gecko passed a non-standard parameter - // to the callback that we want to ignore. - goog.functions.lock(this.callback_), - goog.async.AnimationDelay.TIMEOUT); - } -}; - - -/** - * Stops the delay timer if it is active. No action is taken if the timer is not - * in use. - */ -goog.async.AnimationDelay.prototype.stop = function() { - if (this.isActive()) { - var raf = this.getRaf_(); - var cancelRaf = this.getCancelRaf_(); - if (raf && !cancelRaf && this.win_.mozRequestAnimationFrame) { - goog.events.unlistenByKey(this.id_); - } else if (raf && cancelRaf) { - cancelRaf.call(this.win_, /** @type {number} */ (this.id_)); - } else { - this.win_.clearTimeout(/** @type {number} */ (this.id_)); - } - } - this.id_ = null; -}; - - -/** - * Fires delay's action even if timer has already gone off or has not been - * started yet; guarantees action firing. Stops the delay timer. - */ -goog.async.AnimationDelay.prototype.fire = function() { - this.stop(); - this.doAction_(); -}; - - -/** - * Fires delay's action only if timer is currently active. Stops the delay - * timer. - */ -goog.async.AnimationDelay.prototype.fireIfActive = function() { - if (this.isActive()) { - this.fire(); - } -}; - - -/** - * @return {boolean} True if the delay is currently active, false otherwise. - */ -goog.async.AnimationDelay.prototype.isActive = function() { - return this.id_ != null; -}; - - -/** - * Invokes the callback function after the delay successfully completes. - * @private - */ -goog.async.AnimationDelay.prototype.doAction_ = function() { - if (this.usingListeners_ && this.id_) { - goog.events.unlistenByKey(this.id_); - } - this.id_ = null; - - // We are not using the timestamp returned by requestAnimationFrame - // because it may be either a Date.now-style time or a - // high-resolution time (depending on browser implementation). Using - // goog.now() will ensure that the timestamp used is consistent and - // compatible with goog.fx.Animation. - this.listener_.call(this.handler_, goog.now()); -}; - - -/** @override */ -goog.async.AnimationDelay.prototype.disposeInternal = function() { - this.stop(); - goog.async.AnimationDelay.base(this, 'disposeInternal'); -}; - - -/** - * @return {?function(function(number)): number} The requestAnimationFrame - * function, or null if not available on this browser. - * @private - */ -goog.async.AnimationDelay.prototype.getRaf_ = function() { - var win = this.win_; - return win.requestAnimationFrame || - win.webkitRequestAnimationFrame || - win.mozRequestAnimationFrame || - win.oRequestAnimationFrame || - win.msRequestAnimationFrame || - null; -}; - - -/** - * @return {?function(number): number} The cancelAnimationFrame function, - * or null if not available on this browser. - * @private + * @param {!Function} fn A function to instrument. + * @return {!Function} The instrumented function. */ -goog.async.AnimationDelay.prototype.getCancelRaf_ = function() { - var win = this.win_; - return win.cancelAnimationFrame || - win.cancelRequestAnimationFrame || - win.webkitCancelRequestAnimationFrame || - win.mozCancelRequestAnimationFrame || - win.oCancelRequestAnimationFrame || - win.msCancelRequestAnimationFrame || - null; -}; +goog.debug.EntryPointMonitor.prototype.wrap; -// Copyright 2013 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. /** - * @fileoverview Provides a function to schedule running a function as soon - * as possible after the current JS execution stops and yields to the event - * loop. + * Try to remove an instrumentation wrapper created by this monitor. + * If the function passed to unwrap is not a wrapper created by this + * monitor, then we will do nothing. * - */ - -goog.provide('goog.async.nextTick'); -goog.provide('goog.async.throwException'); - -goog.require('goog.debug.entryPointRegistry'); -goog.require('goog.dom.TagName'); -goog.require('goog.functions'); -goog.require('goog.labs.userAgent.browser'); -goog.require('goog.labs.userAgent.engine'); - - -/** - * Throw an item without interrupting the current execution context. For - * example, if processing a group of items in a loop, sometimes it is useful - * to report an error while still allowing the rest of the batch to be - * processed. - * @param {*} exception - */ -goog.async.throwException = function(exception) { - // Each throw needs to be in its own context. - goog.global.setTimeout(function() { throw exception; }, 0); -}; - - -/** - * Fires the provided callbacks as soon as possible after the current JS - * execution context. setTimeout(…, 0) takes at least 4ms when called from - * within another setTimeout(…, 0) for legacy reasons. + * Notice that some wrappers may not be unwrappable. For example, if other + * monitors have applied their own wrappers, then it will be impossible to + * unwrap them because their wrappers will have captured our wrapper. * - * This will not schedule the callback as a microtask (i.e. a task that can - * preempt user input or networking callbacks). It is meant to emulate what - * setTimeout(_, 0) would do if it were not throttled. If you desire microtask - * behavior, use {@see goog.Promise} instead. + * So it is important that entry points are unwrapped in the reverse + * order that they were wrapped. * - * @param {function(this:SCOPE)} callback Callback function to fire as soon as - * possible. - * @param {SCOPE=} opt_context Object in whose scope to call the listener. - * @param {boolean=} opt_useSetImmediate Avoid the IE workaround that - * ensures correctness at the cost of speed. See comments for details. - * @template SCOPE - */ -goog.async.nextTick = function(callback, opt_context, opt_useSetImmediate) { - var cb = callback; - if (opt_context) { - cb = goog.bind(callback, opt_context); - } - cb = goog.async.nextTick.wrapCallback_(cb); - // window.setImmediate was introduced and currently only supported by IE10+, - // but due to a bug in the implementation it is not guaranteed that - // setImmediate is faster than setTimeout nor that setImmediate N is before - // setImmediate N+1. That is why we do not use the native version if - // available. We do, however, call setImmediate if it is a normal function - // because that indicates that it has been replaced by goog.testing.MockClock - // which we do want to support. - // See - // http://connect.microsoft.com/IE/feedback/details/801823/setimmediate-and-messagechannel-are-broken-in-ie10 - // - // Note we do allow callers to also request setImmediate if they are willing - // to accept the possible tradeoffs of incorrectness in exchange for speed. - // The IE fallback of readystate change is much slower. - if (goog.isFunction(goog.global.setImmediate) && - // Opt in. - (opt_useSetImmediate || - // or it isn't a browser or the environment is weird - !goog.global.Window || !goog.global.Window.prototype || - // or something redefined setImmediate in which case we (YOLO) decide - // to use it (This is so that we use the mockClock setImmediate. sigh). - goog.global.Window.prototype.setImmediate != goog.global.setImmediate)) { - goog.global.setImmediate(cb); - return; - } - - // Look for and cache the custom fallback version of setImmediate. - if (!goog.async.nextTick.setImmediate_) { - goog.async.nextTick.setImmediate_ = - goog.async.nextTick.getSetImmediateEmulator_(); - } - goog.async.nextTick.setImmediate_(cb); -}; - - -/** - * Cache for the setImmediate implementation. - * @type {function(function())} - * @private - */ -goog.async.nextTick.setImmediate_; - - -/** - * Determines the best possible implementation to run a function as soon as - * the JS event loop is idle. - * @return {function(function())} The "setImmediate" implementation. - * @private + * @param {!Function} fn A function to unwrap. + * @return {!Function} The unwrapped function, or {@code fn} if it was not + * a wrapped function created by this monitor. */ -goog.async.nextTick.getSetImmediateEmulator_ = function() { - // Create a private message channel and use it to postMessage empty messages - // to ourselves. - var Channel = goog.global['MessageChannel']; - // If MessageChannel is not available and we are in a browser, implement - // an iframe based polyfill in browsers that have postMessage and - // document.addEventListener. The latter excludes IE8 because it has a - // synchronous postMessage implementation. - if (typeof Channel === 'undefined' && typeof window !== 'undefined' && - window.postMessage && window.addEventListener && - // Presto (The old pre-blink Opera engine) has problems with iframes - // and contentWindow. - !goog.labs.userAgent.engine.isPresto()) { - /** @constructor */ - Channel = function() { - // Make an empty, invisible iframe. - var iframe = document.createElement(goog.dom.TagName.IFRAME); - iframe.style.display = 'none'; - iframe.src = ''; - document.documentElement.appendChild(iframe); - var win = iframe.contentWindow; - var doc = win.document; - doc.open(); - doc.write(''); - doc.close(); - // Do not post anything sensitive over this channel, as the workaround for - // pages with file: origin could allow that information to be modified or - // intercepted. - var message = 'callImmediate' + Math.random(); - // The same origin policy rejects attempts to postMessage from file: urls - // unless the origin is '*'. - // TODO(b/16335441): Use '*' origin for data: and other similar protocols. - var origin = win.location.protocol == 'file:' ? - '*' : win.location.protocol + '//' + win.location.host; - var onmessage = goog.bind(function(e) { - // Validate origin and message to make sure that this message was - // intended for us. If the origin is set to '*' (see above) only the - // message needs to match since, for example, '*' != 'file://'. Allowing - // the wildcard is ok, as we are not concerned with security here. - if ((origin != '*' && e.origin != origin) || e.data != message) { - return; - } - this['port1'].onmessage(); - }, this); - win.addEventListener('message', onmessage, false); - this['port1'] = {}; - this['port2'] = { - postMessage: function() { - win.postMessage(message, origin); - } - }; - }; - } - if (typeof Channel !== 'undefined' && - (!goog.labs.userAgent.browser.isIE())) { - // Exclude all of IE due to - // http://codeforhire.com/2013/09/21/setimmediate-and-messagechannel-broken-on-internet-explorer-10/ - // which allows starving postMessage with a busy setTimeout loop. - // This currently affects IE10 and IE11 which would otherwise be able - // to use the postMessage based fallbacks. - var channel = new Channel(); - // Use a fifo linked list to call callbacks in the right order. - var head = {}; - var tail = head; - channel['port1'].onmessage = function() { - if (goog.isDef(head.next)) { - head = head.next; - var cb = head.cb; - head.cb = null; - cb(); - } - }; - return function(cb) { - tail.next = { - cb: cb - }; - tail = tail.next; - channel['port2'].postMessage(0); - }; - } - // Implementation for IE6+: Script elements fire an asynchronous - // onreadystatechange event when inserted into the DOM. - if (typeof document !== 'undefined' && 'onreadystatechange' in - document.createElement(goog.dom.TagName.SCRIPT)) { - return function(cb) { - var script = document.createElement(goog.dom.TagName.SCRIPT); - script.onreadystatechange = function() { - // Clean up and call the callback. - script.onreadystatechange = null; - script.parentNode.removeChild(script); - script = null; - cb(); - cb = null; - }; - document.documentElement.appendChild(script); - }; - } - // Fall back to setTimeout with 0. In browsers this creates a delay of 5ms - // or more. - return function(cb) { - goog.global.setTimeout(cb, 0); - }; -}; +goog.debug.EntryPointMonitor.prototype.unwrap; /** - * Helper function that is overrided to protect callbacks with entry point - * monitor if the application monitors entry points. - * @param {function()} callback Callback function to fire as soon as possible. - * @return {function()} The wrapped callback. + * An array of entry point callbacks. + * @type {!Array<function(!Function)>} * @private */ -goog.async.nextTick.wrapCallback_ = goog.functions.identity; - - -// Register the callback function as an entry point, so that it can be -// monitored for exception handling, etc. This has to be done in this file -// since it requires special code to handle all browsers. -goog.debug.entryPointRegistry.register( - /** - * @param {function(!Function): !Function} transformer The transforming - * function. - */ - function(transformer) { - goog.async.nextTick.wrapCallback_ = transformer; - }); - -// Copyright 2014 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview The SafeScript type and its builders. - * - * TODO(xtof): Link to document stating type contract. - */ - -goog.provide('goog.html.SafeScript'); - -goog.require('goog.asserts'); -goog.require('goog.string.Const'); -goog.require('goog.string.TypedString'); - - - -/** - * A string-like object which represents JavaScript code and that carries the - * security type contract that its value, as a string, will not cause execution - * of unconstrained attacker controlled code (XSS) when evaluated as JavaScript - * in a browser. - * - * Instances of this type must be created via the factory method - * {@code goog.html.SafeScript.fromConstant} and not by invoking its - * constructor. The constructor intentionally takes no parameters and the type - * is immutable; hence only a default instance corresponding to the empty string - * can be obtained via constructor invocation. - * - * A SafeScript's string representation can safely be interpolated as the - * content of a script element within HTML. The SafeScript string should not be - * escaped before interpolation. - * - * Note that the SafeScript might contain text that is attacker-controlled but - * that text should have been interpolated with appropriate escaping, - * sanitization and/or validation into the right location in the script, such - * that it is highly constrained in its effect (for example, it had to match a - * set of whitelisted words). - * - * A SafeScript can be constructed via security-reviewed unchecked - * conversions. In this case producers of SafeScript must ensure themselves that - * the SafeScript does not contain unsafe script. Note in particular that - * {@code <} is dangerous, even when inside JavaScript strings, and so should - * always be forbidden or JavaScript escaped in user controlled input. For - * example, if {@code </script><script>evil</script>"} were - * interpolated inside a JavaScript string, it would break out of the context - * of the original script element and {@code evil} would execute. Also note - * that within an HTML script (raw text) element, HTML character references, - * such as "<" are not allowed. See - * http://www.w3.org/TR/html5/scripting-1.html#restrictions-for-contents-of-script-elements. - * - * @see goog.html.SafeScript#fromConstant - * @constructor - * @final - * @struct - * @implements {goog.string.TypedString} - */ -goog.html.SafeScript = function() { - /** - * The contained value of this SafeScript. The field has a purposely - * ugly name to make (non-compiled) code that attempts to directly access this - * field stand out. - * @private {string} - */ - this.privateDoNotAccessOrElseSafeScriptWrappedValue_ = ''; - - /** - * A type marker used to implement additional run-time type checking. - * @see goog.html.SafeScript#unwrap - * @const - * @private - */ - this.SAFE_SCRIPT_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = - goog.html.SafeScript.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_; -}; - - -/** - * @override - * @const - */ -goog.html.SafeScript.prototype.implementsGoogStringTypedString = true; +goog.debug.entryPointRegistry.refList_ = []; /** - * Type marker for the SafeScript type, used to implement additional - * run-time type checking. - * @const {!Object} + * Monitors that should wrap all the entry points. + * @type {!Array<!goog.debug.EntryPointMonitor>} * @private */ -goog.html.SafeScript.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {}; - - -/** - * Creates a SafeScript object from a compile-time constant string. - * - * @param {!goog.string.Const} script A compile-time-constant string from which - * to create a SafeScript. - * @return {!goog.html.SafeScript} A SafeScript object initialized to - * {@code script}. - */ -goog.html.SafeScript.fromConstant = function(script) { - var scriptString = goog.string.Const.unwrap(script); - if (scriptString.length === 0) { - return goog.html.SafeScript.EMPTY; - } - return goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse( - scriptString); -}; - - -/** - * Returns this SafeScript's value as a string. - * - * IMPORTANT: In code where it is security relevant that an object's type is - * indeed {@code SafeScript}, use {@code goog.html.SafeScript.unwrap} instead of - * this method. If in doubt, assume that it's security relevant. In particular, - * note that goog.html functions which return a goog.html type do not guarantee - * the returned instance is of the right type. For example: - * - * <pre> - * var fakeSafeHtml = new String('fake'); - * fakeSafeHtml.__proto__ = goog.html.SafeHtml.prototype; - * var newSafeHtml = goog.html.SafeHtml.htmlEscape(fakeSafeHtml); - * // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by - * // goog.html.SafeHtml.htmlEscape() as fakeSafeHtml - * // instanceof goog.html.SafeHtml. - * </pre> - * - * @see goog.html.SafeScript#unwrap - * @override - */ -goog.html.SafeScript.prototype.getTypedStringValue = function() { - return this.privateDoNotAccessOrElseSafeScriptWrappedValue_; -}; - - -if (goog.DEBUG) { - /** - * Returns a debug string-representation of this value. - * - * To obtain the actual string value wrapped in a SafeScript, use - * {@code goog.html.SafeScript.unwrap}. - * - * @see goog.html.SafeScript#unwrap - * @override - */ - goog.html.SafeScript.prototype.toString = function() { - return 'SafeScript{' + - this.privateDoNotAccessOrElseSafeScriptWrappedValue_ + '}'; - }; -} - - -/** - * Performs a runtime check that the provided object is indeed a - * SafeScript object, and returns its value. - * - * @param {!goog.html.SafeScript} safeScript The object to extract from. - * @return {string} The safeScript object's contained string, unless - * the run-time type check fails. In that case, {@code unwrap} returns an - * innocuous string, or, if assertions are enabled, throws - * {@code goog.asserts.AssertionError}. - */ -goog.html.SafeScript.unwrap = function(safeScript) { - // Perform additional Run-time type-checking to ensure that - // safeScript is indeed an instance of the expected type. This - // provides some additional protection against security bugs due to - // application code that disables type checks. - // Specifically, the following checks are performed: - // 1. The object is an instance of the expected type. - // 2. The object is not an instance of a subclass. - // 3. The object carries a type marker for the expected type. "Faking" an - // object requires a reference to the type marker, which has names intended - // to stand out in code reviews. - if (safeScript instanceof goog.html.SafeScript && - safeScript.constructor === goog.html.SafeScript && - safeScript.SAFE_SCRIPT_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ === - goog.html.SafeScript.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) { - return safeScript.privateDoNotAccessOrElseSafeScriptWrappedValue_; - } else { - goog.asserts.fail( - 'expected object of type SafeScript, got \'' + safeScript + '\''); - return 'type_error:SafeScript'; - } -}; - - -/** - * Package-internal utility method to create SafeScript instances. - * - * @param {string} script The string to initialize the SafeScript object with. - * @return {!goog.html.SafeScript} The initialized SafeScript object. - * @package - */ -goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse = - function(script) { - return new goog.html.SafeScript().initSecurityPrivateDoNotAccessOrElse_( - script); -}; +goog.debug.entryPointRegistry.monitors_ = []; /** - * Called from createSafeScriptSecurityPrivateDoNotAccessOrElse(). This - * method exists only so that the compiler can dead code eliminate static - * fields (like EMPTY) when they're not accessed. - * @param {string} script - * @return {!goog.html.SafeScript} + * Whether goog.debug.entryPointRegistry.monitorAll has ever been called. + * Checking this allows the compiler to optimize out the registrations. + * @type {boolean} * @private */ -goog.html.SafeScript.prototype.initSecurityPrivateDoNotAccessOrElse_ = function( - script) { - this.privateDoNotAccessOrElseSafeScriptWrappedValue_ = script; - return this; -}; - - -/** - * A SafeScript instance corresponding to the empty string. - * @const {!goog.html.SafeScript} - */ -goog.html.SafeScript.EMPTY = - goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse(''); - -// Copyright 2013 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Unchecked conversions to create values of goog.html types from - * plain strings. Use of these functions could potentially result in instances - * of goog.html types that violate their type contracts, and hence result in - * security vulnerabilties. - * - * Therefore, all uses of the methods herein must be carefully security - * reviewed. Avoid use of the methods in this file whenever possible; instead - * prefer to create instances of goog.html types using inherently safe builders - * or template systems. - * - * - * - * @visibility {//closure/goog/html:approved_for_unchecked_conversion} - * @visibility {//closure/goog/bin/sizetests:__pkg__} - */ - - -goog.provide('goog.html.uncheckedconversions'); - -goog.require('goog.asserts'); -goog.require('goog.html.SafeHtml'); -goog.require('goog.html.SafeScript'); -goog.require('goog.html.SafeStyle'); -goog.require('goog.html.SafeStyleSheet'); -goog.require('goog.html.SafeUrl'); -goog.require('goog.html.TrustedResourceUrl'); -goog.require('goog.string'); -goog.require('goog.string.Const'); - - -/** - * Performs an "unchecked conversion" to SafeHtml from a plain string that is - * known to satisfy the SafeHtml type contract. - * - * IMPORTANT: Uses of this method must be carefully security-reviewed to ensure - * that the value of {@code html} satisfies the SafeHtml type contract in all - * possible program states. - * - * - * @param {!goog.string.Const} justification A constant string explaining why - * this use of this method is safe. May include a security review ticket - * number. - * @param {string} html A string that is claimed to adhere to the SafeHtml - * contract. - * @param {?goog.i18n.bidi.Dir=} opt_dir The optional directionality of the - * SafeHtml to be constructed. A null or undefined value signifies an - * unknown directionality. - * @return {!goog.html.SafeHtml} The value of html, wrapped in a SafeHtml - * object. - * @suppress {visibility} For access to SafeHtml.create... Note that this - * use is appropriate since this method is intended to be "package private" - * withing goog.html. DO NOT call SafeHtml.create... from outside this - * package; use appropriate wrappers instead. - */ -goog.html.uncheckedconversions.safeHtmlFromStringKnownToSatisfyTypeContract = - function(justification, html, opt_dir) { - // unwrap() called inside an assert so that justification can be optimized - // away in production code. - goog.asserts.assertString(goog.string.Const.unwrap(justification), - 'must provide justification'); - goog.asserts.assert( - !goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)), - 'must provide non-empty justification'); - return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse( - html, opt_dir || null); -}; - - -/** - * Performs an "unchecked conversion" to SafeScript from a plain string that is - * known to satisfy the SafeScript type contract. - * - * IMPORTANT: Uses of this method must be carefully security-reviewed to ensure - * that the value of {@code script} satisfies the SafeScript type contract in - * all possible program states. - * - * - * @param {!goog.string.Const} justification A constant string explaining why - * this use of this method is safe. May include a security review ticket - * number. - * @param {string} script The string to wrap as a SafeScript. - * @return {!goog.html.SafeScript} The value of {@code script}, wrapped in a - * SafeScript object. - */ -goog.html.uncheckedconversions.safeScriptFromStringKnownToSatisfyTypeContract = - function(justification, script) { - // unwrap() called inside an assert so that justification can be optimized - // away in production code. - goog.asserts.assertString(goog.string.Const.unwrap(justification), - 'must provide justification'); - goog.asserts.assert( - !goog.string.isEmpty(goog.string.Const.unwrap(justification)), - 'must provide non-empty justification'); - return goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse( - script); -}; - - -/** - * Performs an "unchecked conversion" to SafeStyle from a plain string that is - * known to satisfy the SafeStyle type contract. - * - * IMPORTANT: Uses of this method must be carefully security-reviewed to ensure - * that the value of {@code style} satisfies the SafeUrl type contract in all - * possible program states. - * - * - * @param {!goog.string.Const} justification A constant string explaining why - * this use of this method is safe. May include a security review ticket - * number. - * @param {string} style The string to wrap as a SafeStyle. - * @return {!goog.html.SafeStyle} The value of {@code style}, wrapped in a - * SafeStyle object. - */ -goog.html.uncheckedconversions.safeStyleFromStringKnownToSatisfyTypeContract = - function(justification, style) { - // unwrap() called inside an assert so that justification can be optimized - // away in production code. - goog.asserts.assertString(goog.string.Const.unwrap(justification), - 'must provide justification'); - goog.asserts.assert( - !goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)), - 'must provide non-empty justification'); - return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse( - style); -}; - - -/** - * Performs an "unchecked conversion" to SafeStyleSheet from a plain string - * that is known to satisfy the SafeStyleSheet type contract. - * - * IMPORTANT: Uses of this method must be carefully security-reviewed to ensure - * that the value of {@code styleSheet} satisfies the SafeUrl type contract in - * all possible program states. - * - * - * @param {!goog.string.Const} justification A constant string explaining why - * this use of this method is safe. May include a security review ticket - * number. - * @param {string} styleSheet The string to wrap as a SafeStyleSheet. - * @return {!goog.html.SafeStyleSheet} The value of {@code styleSheet}, wrapped - * in a SafeStyleSheet object. - */ -goog.html.uncheckedconversions. - safeStyleSheetFromStringKnownToSatisfyTypeContract = - function(justification, styleSheet) { - // unwrap() called inside an assert so that justification can be optimized - // away in production code. - goog.asserts.assertString(goog.string.Const.unwrap(justification), - 'must provide justification'); - goog.asserts.assert( - !goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)), - 'must provide non-empty justification'); - return goog.html.SafeStyleSheet. - createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(styleSheet); -}; - - -/** - * Performs an "unchecked conversion" to SafeUrl from a plain string that is - * known to satisfy the SafeUrl type contract. - * - * IMPORTANT: Uses of this method must be carefully security-reviewed to ensure - * that the value of {@code url} satisfies the SafeUrl type contract in all - * possible program states. - * - * - * @param {!goog.string.Const} justification A constant string explaining why - * this use of this method is safe. May include a security review ticket - * number. - * @param {string} url The string to wrap as a SafeUrl. - * @return {!goog.html.SafeUrl} The value of {@code url}, wrapped in a SafeUrl - * object. - */ -goog.html.uncheckedconversions.safeUrlFromStringKnownToSatisfyTypeContract = - function(justification, url) { - // unwrap() called inside an assert so that justification can be optimized - // away in production code. - goog.asserts.assertString(goog.string.Const.unwrap(justification), - 'must provide justification'); - goog.asserts.assert( - !goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)), - 'must provide non-empty justification'); - return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url); -}; - - -/** - * Performs an "unchecked conversion" to TrustedResourceUrl from a plain string - * that is known to satisfy the TrustedResourceUrl type contract. - * - * IMPORTANT: Uses of this method must be carefully security-reviewed to ensure - * that the value of {@code url} satisfies the TrustedResourceUrl type contract - * in all possible program states. - * - * - * @param {!goog.string.Const} justification A constant string explaining why - * this use of this method is safe. May include a security review ticket - * number. - * @param {string} url The string to wrap as a TrustedResourceUrl. - * @return {!goog.html.TrustedResourceUrl} The value of {@code url}, wrapped in - * a TrustedResourceUrl object. - */ -goog.html.uncheckedconversions. - trustedResourceUrlFromStringKnownToSatisfyTypeContract = - function(justification, url) { - // unwrap() called inside an assert so that justification can be optimized - // away in production code. - goog.asserts.assertString(goog.string.Const.unwrap(justification), - 'must provide justification'); - goog.asserts.assert( - !goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)), - 'must provide non-empty justification'); - return goog.html.TrustedResourceUrl. - createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(url); -}; - -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Generics method for collection-like classes and objects. - * - * @author arv@google.com (Erik Arvidsson) - * - * This file contains functions to work with collections. It supports using - * Map, Set, Array and Object and other classes that implement collection-like - * methods. - */ - - -goog.provide('goog.structs'); - -goog.require('goog.array'); -goog.require('goog.object'); - - -// We treat an object as a dictionary if it has getKeys or it is an object that -// isn't arrayLike. - - -/** - * Returns the number of values in the collection-like object. - * @param {Object} col The collection-like object. - * @return {number} The number of values in the collection-like object. - */ -goog.structs.getCount = function(col) { - if (typeof col.getCount == 'function') { - return col.getCount(); - } - if (goog.isArrayLike(col) || goog.isString(col)) { - return col.length; - } - return goog.object.getCount(col); -}; - - -/** - * Returns the values of the collection-like object. - * @param {Object} col The collection-like object. - * @return {!Array<?>} The values in the collection-like object. - */ -goog.structs.getValues = function(col) { - if (typeof col.getValues == 'function') { - return col.getValues(); - } - if (goog.isString(col)) { - return col.split(''); - } - if (goog.isArrayLike(col)) { - var rv = []; - var l = col.length; - for (var i = 0; i < l; i++) { - rv.push(col[i]); - } - return rv; - } - return goog.object.getValues(col); -}; - - -/** - * Returns the keys of the collection. Some collections have no notion of - * keys/indexes and this function will return undefined in those cases. - * @param {Object} col The collection-like object. - * @return {!Array|undefined} The keys in the collection. - */ -goog.structs.getKeys = function(col) { - if (typeof col.getKeys == 'function') { - return col.getKeys(); - } - // if we have getValues but no getKeys we know this is a key-less collection - if (typeof col.getValues == 'function') { - return undefined; - } - if (goog.isArrayLike(col) || goog.isString(col)) { - var rv = []; - var l = col.length; - for (var i = 0; i < l; i++) { - rv.push(i); - } - return rv; - } - - return goog.object.getKeys(col); -}; - - -/** - * Whether the collection contains the given value. This is O(n) and uses - * equals (==) to test the existence. - * @param {Object} col The collection-like object. - * @param {*} val The value to check for. - * @return {boolean} True if the map contains the value. - */ -goog.structs.contains = function(col, val) { - if (typeof col.contains == 'function') { - return col.contains(val); - } - if (typeof col.containsValue == 'function') { - return col.containsValue(val); - } - if (goog.isArrayLike(col) || goog.isString(col)) { - return goog.array.contains(/** @type {!Array<?>} */ (col), val); - } - return goog.object.containsValue(col, val); -}; - - -/** - * Whether the collection is empty. - * @param {Object} col The collection-like object. - * @return {boolean} True if empty. - */ -goog.structs.isEmpty = function(col) { - if (typeof col.isEmpty == 'function') { - return col.isEmpty(); - } - - // We do not use goog.string.isEmptyOrWhitespace because here we treat the string as - // collection and as such even whitespace matters - - if (goog.isArrayLike(col) || goog.isString(col)) { - return goog.array.isEmpty(/** @type {!Array<?>} */ (col)); - } - return goog.object.isEmpty(col); -}; - - -/** - * Removes all the elements from the collection. - * @param {Object} col The collection-like object. - */ -goog.structs.clear = function(col) { - // NOTE(arv): This should not contain strings because strings are immutable - if (typeof col.clear == 'function') { - col.clear(); - } else if (goog.isArrayLike(col)) { - goog.array.clear(/** @type {goog.array.ArrayLike} */ (col)); - } else { - goog.object.clear(col); - } -}; +goog.debug.entryPointRegistry.monitorsMayExist_ = false; /** - * Calls a function for each value in a collection. The function takes - * three arguments; the value, the key and the collection. - * - * NOTE: This will be deprecated soon! Please use a more specific method if - * possible, e.g. goog.array.forEach, goog.object.forEach, etc. + * Register an entry point with this module. * - * @param {S} col The collection-like object. - * @param {function(this:T,?,?,S):?} f The function to call for every value. - * This function takes - * 3 arguments (the value, the key or undefined if the collection has no - * notion of keys, and the collection) and the return value is irrelevant. - * @param {T=} opt_obj The object to be used as the value of 'this' - * within {@code f}. - * @template T,S - */ -goog.structs.forEach = function(col, f, opt_obj) { - if (typeof col.forEach == 'function') { - col.forEach(f, opt_obj); - } else if (goog.isArrayLike(col) || goog.isString(col)) { - goog.array.forEach(/** @type {!Array<?>} */ (col), f, opt_obj); - } else { - var keys = goog.structs.getKeys(col); - var values = goog.structs.getValues(col); - var l = values.length; - for (var i = 0; i < l; i++) { - f.call(opt_obj, values[i], keys && keys[i], col); - } - } -}; - - -/** - * Calls a function for every value in the collection. When a call returns true, - * adds the value to a new collection (Array is returned by default). + * The entry point will be instrumented when a monitor is passed to + * goog.debug.entryPointRegistry.monitorAll. If this has already occurred, the + * entry point is instrumented immediately. * - * @param {S} col The collection-like object. - * @param {function(this:T,?,?,S):boolean} f The function to call for every - * value. This function takes - * 3 arguments (the value, the key or undefined if the collection has no - * notion of keys, and the collection) and should return a Boolean. If the - * return value is true the value is added to the result collection. If it - * is false the value is not included. - * @param {T=} opt_obj The object to be used as the value of 'this' - * within {@code f}. - * @return {!Object|!Array<?>} A new collection where the passed values are - * present. If col is a key-less collection an array is returned. If col - * has keys and values a plain old JS object is returned. - * @template T,S + * @param {function(!Function)} callback A callback function which is called + * with a transforming function to instrument the entry point. The callback + * is responsible for wrapping the relevant entry point with the + * transforming function. */ -goog.structs.filter = function(col, f, opt_obj) { - if (typeof col.filter == 'function') { - return col.filter(f, opt_obj); - } - if (goog.isArrayLike(col) || goog.isString(col)) { - return goog.array.filter(/** @type {!Array<?>} */ (col), f, opt_obj); - } - - var rv; - var keys = goog.structs.getKeys(col); - var values = goog.structs.getValues(col); - var l = values.length; - if (keys) { - rv = {}; - for (var i = 0; i < l; i++) { - if (f.call(opt_obj, values[i], keys[i], col)) { - rv[keys[i]] = values[i]; - } - } - } else { - // We should not use goog.array.filter here since we want to make sure that - // the index is undefined as well as make sure that col is passed to the - // function. - rv = []; - for (var i = 0; i < l; i++) { - if (f.call(opt_obj, values[i], undefined, col)) { - rv.push(values[i]); - } +goog.debug.entryPointRegistry.register = function(callback) { + // Don't use push(), so that this can be compiled out. + goog.debug.entryPointRegistry + .refList_[goog.debug.entryPointRegistry.refList_.length] = callback; + // If no one calls monitorAll, this can be compiled out. + if (goog.debug.entryPointRegistry.monitorsMayExist_) { + var monitors = goog.debug.entryPointRegistry.monitors_; + for (var i = 0; i < monitors.length; i++) { + callback(goog.bind(monitors[i].wrap, monitors[i])); } } - return rv; }; /** - * Calls a function for every value in the collection and adds the result into a - * new collection (defaults to creating a new Array). + * Configures a monitor to wrap all entry points. * - * @param {S} col The collection-like object. - * @param {function(this:T,?,?,S):V} f The function to call for every value. - * This function takes 3 arguments (the value, the key or undefined if the - * collection has no notion of keys, and the collection) and should return - * something. The result will be used as the value in the new collection. - * @param {T=} opt_obj The object to be used as the value of 'this' - * within {@code f}. - * @return {!Object<V>|!Array<V>} A new collection with the new values. If - * col is a key-less collection an array is returned. If col has keys and - * values a plain old JS object is returned. - * @template T,S,V - */ -goog.structs.map = function(col, f, opt_obj) { - if (typeof col.map == 'function') { - return col.map(f, opt_obj); - } - if (goog.isArrayLike(col) || goog.isString(col)) { - return goog.array.map(/** @type {!Array<?>} */ (col), f, opt_obj); - } - - var rv; - var keys = goog.structs.getKeys(col); - var values = goog.structs.getValues(col); - var l = values.length; - if (keys) { - rv = {}; - for (var i = 0; i < l; i++) { - rv[keys[i]] = f.call(opt_obj, values[i], keys[i], col); - } - } else { - // We should not use goog.array.map here since we want to make sure that - // the index is undefined as well as make sure that col is passed to the - // function. - rv = []; - for (var i = 0; i < l; i++) { - rv[i] = f.call(opt_obj, values[i], undefined, col); - } - } - return rv; -}; - - -/** - * Calls f for each value in a collection. If any call returns true this returns - * true (without checking the rest). If all returns false this returns false. + * Entry points that have already been registered are immediately wrapped by + * the monitor. When an entry point is registered in the future, it will also + * be wrapped by the monitor when it is registered. * - * @param {S} col The collection-like object. - * @param {function(this:T,?,?,S):boolean} f The function to call for every - * value. This function takes 3 arguments (the value, the key or undefined - * if the collection has no notion of keys, and the collection) and should - * return a boolean. - * @param {T=} opt_obj The object to be used as the value of 'this' - * within {@code f}. - * @return {boolean} True if any value passes the test. - * @template T,S + * @param {!goog.debug.EntryPointMonitor} monitor An entry point monitor. */ -goog.structs.some = function(col, f, opt_obj) { - if (typeof col.some == 'function') { - return col.some(f, opt_obj); - } - if (goog.isArrayLike(col) || goog.isString(col)) { - return goog.array.some(/** @type {!Array<?>} */ (col), f, opt_obj); - } - var keys = goog.structs.getKeys(col); - var values = goog.structs.getValues(col); - var l = values.length; - for (var i = 0; i < l; i++) { - if (f.call(opt_obj, values[i], keys && keys[i], col)) { - return true; - } +goog.debug.entryPointRegistry.monitorAll = function(monitor) { + goog.debug.entryPointRegistry.monitorsMayExist_ = true; + var transformer = goog.bind(monitor.wrap, monitor); + for (var i = 0; i < goog.debug.entryPointRegistry.refList_.length; i++) { + goog.debug.entryPointRegistry.refList_[i](transformer); } - return false; + goog.debug.entryPointRegistry.monitors_.push(monitor); }; /** - * Calls f for each value in a collection. If all calls return true this return - * true this returns true. If any returns false this returns false at this point - * and does not continue to check the remaining values. + * Try to unmonitor all the entry points that have already been registered. If + * an entry point is registered in the future, it will not be wrapped by the + * monitor when it is registered. Note that this may fail if the entry points + * have additional wrapping. * - * @param {S} col The collection-like object. - * @param {function(this:T,?,?,S):boolean} f The function to call for every - * value. This function takes 3 arguments (the value, the key or - * undefined if the collection has no notion of keys, and the collection) - * and should return a boolean. - * @param {T=} opt_obj The object to be used as the value of 'this' - * within {@code f}. - * @return {boolean} True if all key-value pairs pass the test. - * @template T,S + * @param {!goog.debug.EntryPointMonitor} monitor The last monitor to wrap + * the entry points. + * @throws {Error} If the monitor is not the most recently configured monitor. */ -goog.structs.every = function(col, f, opt_obj) { - if (typeof col.every == 'function') { - return col.every(f, opt_obj); - } - if (goog.isArrayLike(col) || goog.isString(col)) { - return goog.array.every(/** @type {!Array<?>} */ (col), f, opt_obj); - } - var keys = goog.structs.getKeys(col); - var values = goog.structs.getValues(col); - var l = values.length; - for (var i = 0; i < l; i++) { - if (!f.call(opt_obj, values[i], keys && keys[i], col)) { - return false; - } +goog.debug.entryPointRegistry.unmonitorAllIfPossible = function(monitor) { + var monitors = goog.debug.entryPointRegistry.monitors_; + goog.asserts.assert( + monitor == monitors[monitors.length - 1], + 'Only the most recent monitor can be unwrapped.'); + var transformer = goog.bind(monitor.unwrap, monitor); + for (var i = 0; i < goog.debug.entryPointRegistry.refList_.length; i++) { + goog.debug.entryPointRegistry.refList_[i](transformer); } - return true; + monitors.length--; }; -// Copyright 2011 The Closure Library Authors. All Rights Reserved. +// Copyright 2008 The Closure Library Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -40752,4093 +37273,449 @@ goog.structs.every = function(col, f, opt_obj) { // limitations under the License. /** - * @fileoverview Defines the collection interface. + * @fileoverview Utilities for creating functions. Loosely inspired by the + * java classes: http://goo.gl/GM0Hmu and http://goo.gl/6k7nI8. * - * @author nnaze@google.com (Nathan Naze) + * @author nicksantos@google.com (Nick Santos) */ -goog.provide('goog.structs.Collection'); +goog.provide('goog.functions'); /** - * An interface for a collection of values. - * @interface + * Creates a function that always returns the same value. + * @param {T} retValue The value to return. + * @return {function():T} The new function. * @template T */ -goog.structs.Collection = function() {}; - - -/** - * @param {T} value Value to add to the collection. - */ -goog.structs.Collection.prototype.add; - - -/** - * @param {T} value Value to remove from the collection. - */ -goog.structs.Collection.prototype.remove; - - -/** - * @param {T} value Value to find in the collection. - * @return {boolean} Whether the collection contains the specified value. - */ -goog.structs.Collection.prototype.contains; - - -/** - * @return {number} The number of values stored in the collection. - */ -goog.structs.Collection.prototype.getCount; - - -// Copyright 2007 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Python style iteration utilities. - * @author arv@google.com (Erik Arvidsson) - */ - - -goog.provide('goog.iter'); -goog.provide('goog.iter.Iterable'); -goog.provide('goog.iter.Iterator'); -goog.provide('goog.iter.StopIteration'); - -goog.require('goog.array'); -goog.require('goog.asserts'); -goog.require('goog.functions'); -goog.require('goog.math'); - - -/** - * @typedef {goog.iter.Iterator|{length:number}|{__iterator__}} - */ -goog.iter.Iterable; +goog.functions.constant = function(retValue) { + return function() { return retValue; }; +}; /** - * Singleton Error object that is used to terminate iterations. - * @const {!Error} + * Always returns false. + * @type {function(...): boolean} */ -goog.iter.StopIteration = ('StopIteration' in goog.global) ? - // For script engines that support legacy iterators. - goog.global['StopIteration'] : - { message: 'StopIteration', stack: ''}; - +goog.functions.FALSE = goog.functions.constant(false); /** - * Class/interface for iterators. An iterator needs to implement a {@code next} - * method and it needs to throw a {@code goog.iter.StopIteration} when the - * iteration passes beyond the end. Iterators have no {@code hasNext} method. - * It is recommended to always use the helper functions to iterate over the - * iterator or in case you are only targeting JavaScript 1.7 for in loops. - * @constructor - * @template VALUE + * Always returns true. + * @type {function(...): boolean} */ -goog.iter.Iterator = function() {}; +goog.functions.TRUE = goog.functions.constant(true); /** - * Returns the next value of the iteration. This will throw the object - * {@see goog.iter#StopIteration} when the iteration passes the end. - * @return {VALUE} Any object or value. + * Always returns NULL. + * @type {function(...): null} */ -goog.iter.Iterator.prototype.next = function() { - throw goog.iter.StopIteration; -}; +goog.functions.NULL = goog.functions.constant(null); /** - * Returns the {@code Iterator} object itself. This is used to implement - * the iterator protocol in JavaScript 1.7 - * @param {boolean=} opt_keys Whether to return the keys or values. Default is - * to only return the values. This is being used by the for-in loop (true) - * and the for-each-in loop (false). Even though the param gives a hint - * about what the iterator will return there is no guarantee that it will - * return the keys when true is passed. - * @return {!goog.iter.Iterator<VALUE>} The object itself. + * A simple function that returns the first argument of whatever is passed + * into it. + * @param {T=} opt_returnValue The single value that will be returned. + * @param {...*} var_args Optional trailing arguments. These are ignored. + * @return {T} The first argument passed in, or undefined if nothing was passed. + * @template T */ -goog.iter.Iterator.prototype.__iterator__ = function(opt_keys) { - return this; +goog.functions.identity = function(opt_returnValue, var_args) { + return opt_returnValue; }; /** - * Returns an iterator that knows how to iterate over the values in the object. - * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable If the - * object is an iterator it will be returned as is. If the object has an - * {@code __iterator__} method that will be called to get the value - * iterator. If the object is an array-like object we create an iterator - * for that. - * @return {!goog.iter.Iterator<VALUE>} An iterator that knows how to iterate - * over the values in {@code iterable}. - * @template VALUE + * Creates a function that always throws an error with the given message. + * @param {string} message The error message. + * @return {!Function} The error-throwing function. */ -goog.iter.toIterator = function(iterable) { - if (iterable instanceof goog.iter.Iterator) { - return iterable; - } - if (typeof iterable.__iterator__ == 'function') { - return iterable.__iterator__(false); - } - if (goog.isArrayLike(iterable)) { - var i = 0; - var newIter = new goog.iter.Iterator; - newIter.next = function() { - while (true) { - if (i >= iterable.length) { - throw goog.iter.StopIteration; - } - // Don't include deleted elements. - if (!(i in iterable)) { - i++; - continue; - } - return iterable[i++]; - } - }; - return newIter; - } - - - // TODO(arv): Should we fall back on goog.structs.getValues()? - throw Error('Not implemented'); +goog.functions.error = function(message) { + return function() { throw Error(message); }; }; /** - * Calls a function for each element in the iterator with the element of the - * iterator passed as argument. - * - * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterator - * to iterate over. If the iterable is an object {@code toIterator} will be - * called on it. - * @param {function(this:THIS,VALUE,?,!goog.iter.Iterator<VALUE>)} f - * The function to call for every element. This function takes 3 arguments - * (the element, undefined, and the iterator) and the return value is - * irrelevant. The reason for passing undefined as the second argument is - * so that the same function can be used in {@see goog.array#forEach} as - * well as others. The third parameter is of type "number" for - * arraylike objects, undefined, otherwise. - * @param {THIS=} opt_obj The object to be used as the value of 'this' within - * {@code f}. - * @template THIS, VALUE + * Creates a function that throws the given object. + * @param {*} err An object to be thrown. + * @return {!Function} The error-throwing function. */ -goog.iter.forEach = function(iterable, f, opt_obj) { - if (goog.isArrayLike(iterable)) { - /** @preserveTry */ - try { - // NOTES: this passes the index number to the second parameter - // of the callback contrary to the documentation above. - goog.array.forEach(/** @type {goog.array.ArrayLike} */(iterable), f, - opt_obj); - } catch (ex) { - if (ex !== goog.iter.StopIteration) { - throw ex; - } - } - } else { - iterable = goog.iter.toIterator(iterable); - /** @preserveTry */ - try { - while (true) { - f.call(opt_obj, iterable.next(), undefined, iterable); - } - } catch (ex) { - if (ex !== goog.iter.StopIteration) { - throw ex; - } - } - } +goog.functions.fail = function(err) { + return function() { throw err; } }; /** - * Calls a function for every element in the iterator, and if the function - * returns true adds the element to a new iterator. - * - * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterator - * to iterate over. - * @param { - * function(this:THIS,VALUE,undefined,!goog.iter.Iterator<VALUE>):boolean} f - * The function to call for every element. This function takes 3 arguments - * (the element, undefined, and the iterator) and should return a boolean. - * If the return value is true the element will be included in the returned - * iterator. If it is false the element is not included. - * @param {THIS=} opt_obj The object to be used as the value of 'this' within - * {@code f}. - * @return {!goog.iter.Iterator<VALUE>} A new iterator in which only elements - * that passed the test are present. - * @template THIS, VALUE + * Given a function, create a function that keeps opt_numArgs arguments and + * silently discards all additional arguments. + * @param {Function} f The original function. + * @param {number=} opt_numArgs The number of arguments to keep. Defaults to 0. + * @return {!Function} A version of f that only keeps the first opt_numArgs + * arguments. */ -goog.iter.filter = function(iterable, f, opt_obj) { - var iterator = goog.iter.toIterator(iterable); - var newIter = new goog.iter.Iterator; - newIter.next = function() { - while (true) { - var val = iterator.next(); - if (f.call(opt_obj, val, undefined, iterator)) { - return val; - } - } +goog.functions.lock = function(f, opt_numArgs) { + opt_numArgs = opt_numArgs || 0; + return function() { + return f.apply(this, Array.prototype.slice.call(arguments, 0, opt_numArgs)); }; - return newIter; }; /** - * Calls a function for every element in the iterator, and if the function - * returns false adds the element to a new iterator. - * - * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterator - * to iterate over. - * @param { - * function(this:THIS,VALUE,undefined,!goog.iter.Iterator<VALUE>):boolean} f - * The function to call for every element. This function takes 3 arguments - * (the element, undefined, and the iterator) and should return a boolean. - * If the return value is false the element will be included in the returned - * iterator. If it is true the element is not included. - * @param {THIS=} opt_obj The object to be used as the value of 'this' within - * {@code f}. - * @return {!goog.iter.Iterator<VALUE>} A new iterator in which only elements - * that did not pass the test are present. - * @template THIS, VALUE + * Creates a function that returns its nth argument. + * @param {number} n The position of the return argument. + * @return {!Function} A new function. */ -goog.iter.filterFalse = function(iterable, f, opt_obj) { - return goog.iter.filter(iterable, goog.functions.not(f), opt_obj); +goog.functions.nth = function(n) { + return function() { return arguments[n]; }; }; /** - * Creates a new iterator that returns the values in a range. This function - * can take 1, 2 or 3 arguments: - * <pre> - * range(5) same as range(0, 5, 1) - * range(2, 5) same as range(2, 5, 1) - * </pre> + * Like goog.partial(), except that arguments are added after arguments to the + * returned function. * - * @param {number} startOrStop The stop value if only one argument is provided. - * The start value if 2 or more arguments are provided. If only one - * argument is used the start value is 0. - * @param {number=} opt_stop The stop value. If left out then the first - * argument is used as the stop value. - * @param {number=} opt_step The number to increment with between each call to - * next. This can be negative. - * @return {!goog.iter.Iterator<number>} A new iterator that returns the values - * in the range. - */ -goog.iter.range = function(startOrStop, opt_stop, opt_step) { - var start = 0; - var stop = startOrStop; - var step = opt_step || 1; - if (arguments.length > 1) { - start = startOrStop; - stop = opt_stop; - } - if (step == 0) { - throw Error('Range step argument must not be zero'); - } - - var newIter = new goog.iter.Iterator; - newIter.next = function() { - if (step > 0 && start >= stop || step < 0 && start <= stop) { - throw goog.iter.StopIteration; - } - var rv = start; - start += step; - return rv; - }; - return newIter; -}; - - -/** - * Joins the values in a iterator with a delimiter. - * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterator - * to get the values from. - * @param {string} deliminator The text to put between the values. - * @return {string} The joined value string. - * @template VALUE - */ -goog.iter.join = function(iterable, deliminator) { - return goog.iter.toArray(iterable).join(deliminator); -}; - - -/** - * For every element in the iterator call a function and return a new iterator - * with that value. + * Usage: + * function f(arg1, arg2, arg3, arg4) { ... } + * var g = goog.functions.partialRight(f, arg3, arg4); + * g(arg1, arg2); * - * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The - * iterator to iterate over. - * @param { - * function(this:THIS,VALUE,undefined,!goog.iter.Iterator<VALUE>):RESULT} f - * The function to call for every element. This function takes 3 arguments - * (the element, undefined, and the iterator) and should return a new value. - * @param {THIS=} opt_obj The object to be used as the value of 'this' within - * {@code f}. - * @return {!goog.iter.Iterator<RESULT>} A new iterator that returns the - * results of applying the function to each element in the original - * iterator. - * @template THIS, VALUE, RESULT + * @param {!Function} fn A function to partially apply. + * @param {...*} var_args Additional arguments that are partially applied to fn + * at the end. + * @return {!Function} A partially-applied form of the function goog.partial() + * was invoked as a method of. */ -goog.iter.map = function(iterable, f, opt_obj) { - var iterator = goog.iter.toIterator(iterable); - var newIter = new goog.iter.Iterator; - newIter.next = function() { - var val = iterator.next(); - return f.call(opt_obj, val, undefined, iterator); +goog.functions.partialRight = function(fn, var_args) { + var rightArgs = Array.prototype.slice.call(arguments, 1); + return function() { + var newArgs = Array.prototype.slice.call(arguments); + newArgs.push.apply(newArgs, rightArgs); + return fn.apply(this, newArgs); }; - return newIter; }; /** - * Passes every element of an iterator into a function and accumulates the - * result. - * - * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterator - * to iterate over. - * @param {function(this:THIS,VALUE,VALUE):VALUE} f The function to call for - * every element. This function takes 2 arguments (the function's previous - * result or the initial value, and the value of the current element). - * function(previousValue, currentElement) : newValue. - * @param {VALUE} val The initial value to pass into the function on the first - * call. - * @param {THIS=} opt_obj The object to be used as the value of 'this' within - * f. - * @return {VALUE} Result of evaluating f repeatedly across the values of - * the iterator. - * @template THIS, VALUE + * Given a function, create a new function that swallows its return value + * and replaces it with a new one. + * @param {Function} f A function. + * @param {T} retValue A new return value. + * @return {function(...?):T} A new function. + * @template T */ -goog.iter.reduce = function(iterable, f, val, opt_obj) { - var rval = val; - goog.iter.forEach(iterable, function(val) { - rval = f.call(opt_obj, rval, val); - }); - return rval; +goog.functions.withReturnValue = function(f, retValue) { + return goog.functions.sequence(f, goog.functions.constant(retValue)); }; /** - * Goes through the values in the iterator. Calls f for each of these, and if - * any of them returns true, this returns true (without checking the rest). If - * all return false this will return false. + * Creates a function that returns whether its arguement equals the given value. * - * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterator - * object. - * @param { - * function(this:THIS,VALUE,undefined,!goog.iter.Iterator<VALUE>):boolean} f - * The function to call for every value. This function takes 3 arguments - * (the value, undefined, and the iterator) and should return a boolean. - * @param {THIS=} opt_obj The object to be used as the value of 'this' within - * {@code f}. - * @return {boolean} true if any value passes the test. - * @template THIS, VALUE - */ -goog.iter.some = function(iterable, f, opt_obj) { - iterable = goog.iter.toIterator(iterable); - /** @preserveTry */ - try { - while (true) { - if (f.call(opt_obj, iterable.next(), undefined, iterable)) { - return true; - } - } - } catch (ex) { - if (ex !== goog.iter.StopIteration) { - throw ex; - } - } - return false; -}; - - -/** - * Goes through the values in the iterator. Calls f for each of these and if any - * of them returns false this returns false (without checking the rest). If all - * return true this will return true. + * Example: + * var key = goog.object.findKey(obj, goog.functions.equalTo('needle')); * - * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterator - * object. - * @param { - * function(this:THIS,VALUE,undefined,!goog.iter.Iterator<VALUE>):boolean} f - * The function to call for every value. This function takes 3 arguments - * (the value, undefined, and the iterator) and should return a boolean. - * @param {THIS=} opt_obj The object to be used as the value of 'this' within - * {@code f}. - * @return {boolean} true if every value passes the test. - * @template THIS, VALUE - */ -goog.iter.every = function(iterable, f, opt_obj) { - iterable = goog.iter.toIterator(iterable); - /** @preserveTry */ - try { - while (true) { - if (!f.call(opt_obj, iterable.next(), undefined, iterable)) { - return false; - } - } - } catch (ex) { - if (ex !== goog.iter.StopIteration) { - throw ex; - } - } - return true; -}; - - -/** - * Takes zero or more iterables and returns one iterator that will iterate over - * them in the order chained. - * @param {...!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} var_args Any - * number of iterable objects. - * @return {!goog.iter.Iterator<VALUE>} Returns a new iterator that will - * iterate over all the given iterables' contents. - * @template VALUE - */ -goog.iter.chain = function(var_args) { - return goog.iter.chainFromIterable(arguments); -}; - - -/** - * Takes a single iterable containing zero or more iterables and returns one - * iterator that will iterate over each one in the order given. - * @see http://docs.python.org/2/library/itertools.html#itertools.chain.from_iterable - * @param {goog.iter.Iterable} iterable The iterable of iterables to chain. - * @return {!goog.iter.Iterator<VALUE>} Returns a new iterator that will - * iterate over all the contents of the iterables contained within - * {@code iterable}. - * @template VALUE - */ -goog.iter.chainFromIterable = function(iterable) { - var iterator = goog.iter.toIterator(iterable); - var iter = new goog.iter.Iterator(); - var current = null; - - iter.next = function() { - while (true) { - if (current == null) { - var it = iterator.next(); - current = goog.iter.toIterator(it); - } - try { - return current.next(); - } catch (ex) { - if (ex !== goog.iter.StopIteration) { - throw ex; - } - current = null; - } - } - }; - - return iter; -}; - - -/** - * Builds a new iterator that iterates over the original, but skips elements as - * long as a supplied function returns true. - * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterator - * object. - * @param { - * function(this:THIS,VALUE,undefined,!goog.iter.Iterator<VALUE>):boolean} f - * The function to call for every value. This function takes 3 arguments - * (the value, undefined, and the iterator) and should return a boolean. - * @param {THIS=} opt_obj The object to be used as the value of 'this' within - * {@code f}. - * @return {!goog.iter.Iterator<VALUE>} A new iterator that drops elements from - * the original iterator as long as {@code f} is true. - * @template THIS, VALUE - */ -goog.iter.dropWhile = function(iterable, f, opt_obj) { - var iterator = goog.iter.toIterator(iterable); - var newIter = new goog.iter.Iterator; - var dropping = true; - newIter.next = function() { - while (true) { - var val = iterator.next(); - if (dropping && f.call(opt_obj, val, undefined, iterator)) { - continue; - } else { - dropping = false; - } - return val; - } - }; - return newIter; -}; - - -/** - * Builds a new iterator that iterates over the original, but only as long as a - * supplied function returns true. - * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterator - * object. - * @param { - * function(this:THIS,VALUE,undefined,!goog.iter.Iterator<VALUE>):boolean} f - * The function to call for every value. This function takes 3 arguments - * (the value, undefined, and the iterator) and should return a boolean. - * @param {THIS=} opt_obj This is used as the 'this' object in f when called. - * @return {!goog.iter.Iterator<VALUE>} A new iterator that keeps elements in - * the original iterator as long as the function is true. - * @template THIS, VALUE + * @param {*} value The value to compare to. + * @param {boolean=} opt_useLooseComparison Whether to use a loose (==) + * comparison rather than a strict (===) one. Defaults to false. + * @return {function(*):boolean} The new function. */ -goog.iter.takeWhile = function(iterable, f, opt_obj) { - var iterator = goog.iter.toIterator(iterable); - var iter = new goog.iter.Iterator(); - iter.next = function() { - var val = iterator.next(); - if (f.call(opt_obj, val, undefined, iterator)) { - return val; - } - throw goog.iter.StopIteration; +goog.functions.equalTo = function(value, opt_useLooseComparison) { + return function(other) { + return opt_useLooseComparison ? (value == other) : (value === other); }; - return iter; -}; - - -/** - * Converts the iterator to an array - * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterator - * to convert to an array. - * @return {!Array<VALUE>} An array of the elements the iterator iterates over. - * @template VALUE - */ -goog.iter.toArray = function(iterable) { - // Fast path for array-like. - if (goog.isArrayLike(iterable)) { - return goog.array.toArray(/** @type {!goog.array.ArrayLike} */(iterable)); - } - iterable = goog.iter.toIterator(iterable); - var array = []; - goog.iter.forEach(iterable, function(val) { - array.push(val); - }); - return array; -}; - - -/** - * Iterates over two iterables and returns true if they contain the same - * sequence of elements and have the same length. - * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable1 The first - * iterable object. - * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable2 The second - * iterable object. - * @param {function(VALUE,VALUE):boolean=} opt_equalsFn Optional comparison - * function. - * Should take two arguments to compare, and return true if the arguments - * are equal. Defaults to {@link goog.array.defaultCompareEquality} which - * compares the elements using the built-in '===' operator. - * @return {boolean} true if the iterables contain the same sequence of elements - * and have the same length. - * @template VALUE - */ -goog.iter.equals = function(iterable1, iterable2, opt_equalsFn) { - var fillValue = {}; - var pairs = goog.iter.zipLongest(fillValue, iterable1, iterable2); - var equalsFn = opt_equalsFn || goog.array.defaultCompareEquality; - return goog.iter.every(pairs, function(pair) { - return equalsFn(pair[0], pair[1]); - }); }; /** - * Advances the iterator to the next position, returning the given default value - * instead of throwing an exception if the iterator has no more entries. - * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterable - * object. - * @param {VALUE} defaultValue The value to return if the iterator is empty. - * @return {VALUE} The next item in the iteration, or defaultValue if the - * iterator was empty. - * @template VALUE + * Creates the composition of the functions passed in. + * For example, (goog.functions.compose(f, g))(a) is equivalent to f(g(a)). + * @param {function(...?):T} fn The final function. + * @param {...Function} var_args A list of functions. + * @return {function(...?):T} The composition of all inputs. + * @template T */ -goog.iter.nextOrValue = function(iterable, defaultValue) { - try { - return goog.iter.toIterator(iterable).next(); - } catch (e) { - if (e != goog.iter.StopIteration) { - throw e; +goog.functions.compose = function(fn, var_args) { + var functions = arguments; + var length = functions.length; + return function() { + var result; + if (length) { + result = functions[length - 1].apply(this, arguments); } - return defaultValue; - } -}; - - -/** - * Cartesian product of zero or more sets. Gives an iterator that gives every - * combination of one element chosen from each set. For example, - * ([1, 2], [3, 4]) gives ([1, 3], [1, 4], [2, 3], [2, 4]). - * @see http://docs.python.org/library/itertools.html#itertools.product - * @param {...!goog.array.ArrayLike<VALUE>} var_args Zero or more sets, as - * arrays. - * @return {!goog.iter.Iterator<!Array<VALUE>>} An iterator that gives each - * n-tuple (as an array). - * @template VALUE - */ -goog.iter.product = function(var_args) { - var someArrayEmpty = goog.array.some(arguments, function(arr) { - return !arr.length; - }); - - // An empty set in a cartesian product gives an empty set. - if (someArrayEmpty || !arguments.length) { - return new goog.iter.Iterator(); - } - - var iter = new goog.iter.Iterator(); - var arrays = arguments; - - // The first indices are [0, 0, ...] - var indicies = goog.array.repeat(0, arrays.length); - - iter.next = function() { - - if (indicies) { - var retVal = goog.array.map(indicies, function(valueIndex, arrayIndex) { - return arrays[arrayIndex][valueIndex]; - }); - // Generate the next-largest indices for the next call. - // Increase the rightmost index. If it goes over, increase the next - // rightmost (like carry-over addition). - for (var i = indicies.length - 1; i >= 0; i--) { - // Assertion prevents compiler warning below. - goog.asserts.assert(indicies); - if (indicies[i] < arrays[i].length - 1) { - indicies[i]++; - break; - } - - // We're at the last indices (the last element of every array), so - // the iteration is over on the next call. - if (i == 0) { - indicies = null; - break; - } - // Reset the index in this column and loop back to increment the - // next one. - indicies[i] = 0; - } - return retVal; + for (var i = length - 2; i >= 0; i--) { + result = functions[i].call(this, result); } - - throw goog.iter.StopIteration; + return result; }; - - return iter; }; /** - * Create an iterator to cycle over the iterable's elements indefinitely. - * For example, ([1, 2, 3]) would return : 1, 2, 3, 1, 2, 3, ... - * @see: http://docs.python.org/library/itertools.html#itertools.cycle. - * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The - * iterable object. - * @return {!goog.iter.Iterator<VALUE>} An iterator that iterates indefinitely - * over the values in {@code iterable}. - * @template VALUE + * Creates a function that calls the functions passed in in sequence, and + * returns the value of the last function. For example, + * (goog.functions.sequence(f, g))(x) is equivalent to f(x),g(x). + * @param {...Function} var_args A list of functions. + * @return {!Function} A function that calls all inputs in sequence. */ -goog.iter.cycle = function(iterable) { - var baseIterator = goog.iter.toIterator(iterable); - - // We maintain a cache to store the iterable elements as we iterate - // over them. The cache is used to return elements once we have - // iterated over the iterable once. - var cache = []; - var cacheIndex = 0; - - var iter = new goog.iter.Iterator(); - - // This flag is set after the iterable is iterated over once - var useCache = false; - - iter.next = function() { - var returnElement = null; - - // Pull elements off the original iterator if not using cache - if (!useCache) { - try { - // Return the element from the iterable - returnElement = baseIterator.next(); - cache.push(returnElement); - return returnElement; - } catch (e) { - // If an exception other than StopIteration is thrown - // or if there are no elements to iterate over (the iterable was empty) - // throw an exception - if (e != goog.iter.StopIteration || goog.array.isEmpty(cache)) { - throw e; - } - // set useCache to true after we know that a 'StopIteration' exception - // was thrown and the cache is not empty (to handle the 'empty iterable' - // use case) - useCache = true; - } +goog.functions.sequence = function(var_args) { + var functions = arguments; + var length = functions.length; + return function() { + var result; + for (var i = 0; i < length; i++) { + result = functions[i].apply(this, arguments); } - - returnElement = cache[cacheIndex]; - cacheIndex = (cacheIndex + 1) % cache.length; - - return returnElement; - }; - - return iter; -}; - - -/** - * Creates an iterator that counts indefinitely from a starting value. - * @see http://docs.python.org/2/library/itertools.html#itertools.count - * @param {number=} opt_start The starting value. Default is 0. - * @param {number=} opt_step The number to increment with between each call to - * next. Negative and floating point numbers are allowed. Default is 1. - * @return {!goog.iter.Iterator<number>} A new iterator that returns the values - * in the series. - */ -goog.iter.count = function(opt_start, opt_step) { - var counter = opt_start || 0; - var step = goog.isDef(opt_step) ? opt_step : 1; - var iter = new goog.iter.Iterator(); - - iter.next = function() { - var returnValue = counter; - counter += step; - return returnValue; - }; - - return iter; -}; - - -/** - * Creates an iterator that returns the same object or value repeatedly. - * @param {VALUE} value Any object or value to repeat. - * @return {!goog.iter.Iterator<VALUE>} A new iterator that returns the - * repeated value. - * @template VALUE - */ -goog.iter.repeat = function(value) { - var iter = new goog.iter.Iterator(); - - iter.next = goog.functions.constant(value); - - return iter; -}; - - -/** - * Creates an iterator that returns running totals from the numbers in - * {@code iterable}. For example, the array {@code [1, 2, 3, 4, 5]} yields - * {@code 1 -> 3 -> 6 -> 10 -> 15}. - * @see http://docs.python.org/3.2/library/itertools.html#itertools.accumulate - * @param {!goog.iter.Iterable<number>} iterable The iterable of numbers to - * accumulate. - * @return {!goog.iter.Iterator<number>} A new iterator that returns the - * numbers in the series. - */ -goog.iter.accumulate = function(iterable) { - var iterator = goog.iter.toIterator(iterable); - var total = 0; - var iter = new goog.iter.Iterator(); - - iter.next = function() { - total += iterator.next(); - return total; + return result; }; - - return iter; -}; - - -/** - * Creates an iterator that returns arrays containing the ith elements from the - * provided iterables. The returned arrays will be the same size as the number - * of iterables given in {@code var_args}. Once the shortest iterable is - * exhausted, subsequent calls to {@code next()} will throw - * {@code goog.iter.StopIteration}. - * @see http://docs.python.org/2/library/itertools.html#itertools.izip - * @param {...!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} var_args Any - * number of iterable objects. - * @return {!goog.iter.Iterator<!Array<VALUE>>} A new iterator that returns - * arrays of elements from the provided iterables. - * @template VALUE - */ -goog.iter.zip = function(var_args) { - var args = arguments; - var iter = new goog.iter.Iterator(); - - if (args.length > 0) { - var iterators = goog.array.map(args, goog.iter.toIterator); - iter.next = function() { - var arr = goog.array.map(iterators, function(it) { - return it.next(); - }); - return arr; - }; - } - - return iter; -}; - - -/** - * Creates an iterator that returns arrays containing the ith elements from the - * provided iterables. The returned arrays will be the same size as the number - * of iterables given in {@code var_args}. Shorter iterables will be extended - * with {@code fillValue}. Once the longest iterable is exhausted, subsequent - * calls to {@code next()} will throw {@code goog.iter.StopIteration}. - * @see http://docs.python.org/2/library/itertools.html#itertools.izip_longest - * @param {VALUE} fillValue The object or value used to fill shorter iterables. - * @param {...!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} var_args Any - * number of iterable objects. - * @return {!goog.iter.Iterator<!Array<VALUE>>} A new iterator that returns - * arrays of elements from the provided iterables. - * @template VALUE - */ -goog.iter.zipLongest = function(fillValue, var_args) { - var args = goog.array.slice(arguments, 1); - var iter = new goog.iter.Iterator(); - - if (args.length > 0) { - var iterators = goog.array.map(args, goog.iter.toIterator); - - iter.next = function() { - var iteratorsHaveValues = false; // false when all iterators are empty. - var arr = goog.array.map(iterators, function(it) { - var returnValue; - try { - returnValue = it.next(); - // Iterator had a value, so we've not exhausted the iterators. - // Set flag accordingly. - iteratorsHaveValues = true; - } catch (ex) { - if (ex !== goog.iter.StopIteration) { - throw ex; - } - returnValue = fillValue; - } - return returnValue; - }); - - if (!iteratorsHaveValues) { - throw goog.iter.StopIteration; - } - return arr; - }; - } - - return iter; }; /** - * Creates an iterator that filters {@code iterable} based on a series of - * {@code selectors}. On each call to {@code next()}, one item is taken from - * both the {@code iterable} and {@code selectors} iterators. If the item from - * {@code selectors} evaluates to true, the item from {@code iterable} is given. - * Otherwise, it is skipped. Once either {@code iterable} or {@code selectors} - * is exhausted, subsequent calls to {@code next()} will throw - * {@code goog.iter.StopIteration}. - * @see http://docs.python.org/2/library/itertools.html#itertools.compress - * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The - * iterable to filter. - * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} selectors An - * iterable of items to be evaluated in a boolean context to determine if - * the corresponding element in {@code iterable} should be included in the - * result. - * @return {!goog.iter.Iterator<VALUE>} A new iterator that returns the - * filtered values. - * @template VALUE - */ -goog.iter.compress = function(iterable, selectors) { - var selectorIterator = goog.iter.toIterator(selectors); - - return goog.iter.filter(iterable, function() { - return !!selectorIterator.next(); - }); -}; - - - -/** - * Implements the {@code goog.iter.groupBy} iterator. - * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The - * iterable to group. - * @param {function(...VALUE): KEY=} opt_keyFunc Optional function for - * determining the key value for each group in the {@code iterable}. Default - * is the identity function. - * @constructor - * @extends {goog.iter.Iterator<!Array<?>>} - * @template KEY, VALUE - * @private - */ -goog.iter.GroupByIterator_ = function(iterable, opt_keyFunc) { - - /** - * The iterable to group, coerced to an iterator. - * @type {!goog.iter.Iterator} - */ - this.iterator = goog.iter.toIterator(iterable); - - /** - * A function for determining the key value for each element in the iterable. - * If no function is provided, the identity function is used and returns the - * element unchanged. - * @type {function(...VALUE): KEY} - */ - this.keyFunc = opt_keyFunc || goog.functions.identity; - - /** - * The target key for determining the start of a group. - * @type {KEY} - */ - this.targetKey; - - /** - * The current key visited during iteration. - * @type {KEY} - */ - this.currentKey; - - /** - * The current value being added to the group. - * @type {VALUE} - */ - this.currentValue; -}; -goog.inherits(goog.iter.GroupByIterator_, goog.iter.Iterator); - - -/** @override */ -goog.iter.GroupByIterator_.prototype.next = function() { - while (this.currentKey == this.targetKey) { - this.currentValue = this.iterator.next(); // Exits on StopIteration - this.currentKey = this.keyFunc(this.currentValue); - } - this.targetKey = this.currentKey; - return [this.currentKey, this.groupItems_(this.targetKey)]; -}; - - -/** - * Performs the grouping of objects using the given key. - * @param {KEY} targetKey The target key object for the group. - * @return {!Array<VALUE>} An array of grouped objects. - * @private + * Creates a function that returns true if each of its components evaluates + * to true. The components are evaluated in order, and the evaluation will be + * short-circuited as soon as a function returns false. + * For example, (goog.functions.and(f, g))(x) is equivalent to f(x) && g(x). + * @param {...Function} var_args A list of functions. + * @return {function(...?):boolean} A function that ANDs its component + * functions. */ -goog.iter.GroupByIterator_.prototype.groupItems_ = function(targetKey) { - var arr = []; - while (this.currentKey == targetKey) { - arr.push(this.currentValue); - try { - this.currentValue = this.iterator.next(); - } catch (ex) { - if (ex !== goog.iter.StopIteration) { - throw ex; +goog.functions.and = function(var_args) { + var functions = arguments; + var length = functions.length; + return function() { + for (var i = 0; i < length; i++) { + if (!functions[i].apply(this, arguments)) { + return false; } - break; } - this.currentKey = this.keyFunc(this.currentValue); - } - return arr; -}; - - -/** - * Creates an iterator that returns arrays containing elements from the - * {@code iterable} grouped by a key value. For iterables with repeated - * elements (i.e. sorted according to a particular key function), this function - * has a {@code uniq}-like effect. For example, grouping the array: - * {@code [A, B, B, C, C, A]} produces - * {@code [A, [A]], [B, [B, B]], [C, [C, C]], [A, [A]]}. - * @see http://docs.python.org/2/library/itertools.html#itertools.groupby - * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The - * iterable to group. - * @param {function(...VALUE): KEY=} opt_keyFunc Optional function for - * determining the key value for each group in the {@code iterable}. Default - * is the identity function. - * @return {!goog.iter.Iterator<!Array<?>>} A new iterator that returns - * arrays of consecutive key and groups. - * @template KEY, VALUE - */ -goog.iter.groupBy = function(iterable, opt_keyFunc) { - return new goog.iter.GroupByIterator_(iterable, opt_keyFunc); -}; - - -/** - * Gives an iterator that gives the result of calling the given function - * <code>f</code> with the arguments taken from the next element from - * <code>iterable</code> (the elements are expected to also be iterables). - * - * Similar to {@see goog.iter#map} but allows the function to accept multiple - * arguments from the iterable. - * - * @param {!goog.iter.Iterable<!goog.iter.Iterable>} iterable The iterable of - * iterables to iterate over. - * @param {function(this:THIS,...*):RESULT} f The function to call for every - * element. This function takes N+2 arguments, where N represents the - * number of items from the next element of the iterable. The two - * additional arguments passed to the function are undefined and the - * iterator itself. The function should return a new value. - * @param {THIS=} opt_obj The object to be used as the value of 'this' within - * {@code f}. - * @return {!goog.iter.Iterator<RESULT>} A new iterator that returns the - * results of applying the function to each element in the original - * iterator. - * @template THIS, RESULT - */ -goog.iter.starMap = function(iterable, f, opt_obj) { - var iterator = goog.iter.toIterator(iterable); - var iter = new goog.iter.Iterator(); - - iter.next = function() { - var args = goog.iter.toArray(iterator.next()); - return f.apply(opt_obj, goog.array.concat(args, undefined, iterator)); + return true; }; - - return iter; }; /** - * Returns an array of iterators each of which can iterate over the values in - * {@code iterable} without advancing the others. - * @see http://docs.python.org/2/library/itertools.html#itertools.tee - * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The - * iterable to tee. - * @param {number=} opt_num The number of iterators to create. Default is 2. - * @return {!Array<goog.iter.Iterator<VALUE>>} An array of iterators. - * @template VALUE + * Creates a function that returns true if any of its components evaluates + * to true. The components are evaluated in order, and the evaluation will be + * short-circuited as soon as a function returns true. + * For example, (goog.functions.or(f, g))(x) is equivalent to f(x) || g(x). + * @param {...Function} var_args A list of functions. + * @return {function(...?):boolean} A function that ORs its component + * functions. */ -goog.iter.tee = function(iterable, opt_num) { - var iterator = goog.iter.toIterator(iterable); - var num = goog.isNumber(opt_num) ? opt_num : 2; - var buffers = goog.array.map(goog.array.range(num), function() { - return []; - }); - - var addNextIteratorValueToBuffers = function() { - var val = iterator.next(); - goog.array.forEach(buffers, function(buffer) { - buffer.push(val); - }); - }; - - var createIterator = function(buffer) { - // Each tee'd iterator has an associated buffer (initially empty). When a - // tee'd iterator's buffer is empty, it calls - // addNextIteratorValueToBuffers(), adding the next value to all tee'd - // iterators' buffers, and then returns that value. This allows each - // iterator to be advanced independently. - var iter = new goog.iter.Iterator(); - - iter.next = function() { - if (goog.array.isEmpty(buffer)) { - addNextIteratorValueToBuffers(); +goog.functions.or = function(var_args) { + var functions = arguments; + var length = functions.length; + return function() { + for (var i = 0; i < length; i++) { + if (functions[i].apply(this, arguments)) { + return true; } - goog.asserts.assert(!goog.array.isEmpty(buffer)); - return buffer.shift(); - }; - - return iter; - }; - - return goog.array.map(buffers, createIterator); -}; - - -/** - * Creates an iterator that returns arrays containing a count and an element - * obtained from the given {@code iterable}. - * @see http://docs.python.org/2/library/functions.html#enumerate - * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The - * iterable to enumerate. - * @param {number=} opt_start Optional starting value. Default is 0. - * @return {!goog.iter.Iterator<!Array<?>>} A new iterator containing - * count/item pairs. - * @template VALUE - */ -goog.iter.enumerate = function(iterable, opt_start) { - return goog.iter.zip(goog.iter.count(opt_start), iterable); -}; - - -/** - * Creates an iterator that returns the first {@code limitSize} elements from an - * iterable. If this number is greater than the number of elements in the - * iterable, all the elements are returned. - * @see http://goo.gl/V0sihp Inspired by the limit iterator in Guava. - * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The - * iterable to limit. - * @param {number} limitSize The maximum number of elements to return. - * @return {!goog.iter.Iterator<VALUE>} A new iterator containing - * {@code limitSize} elements. - * @template VALUE - */ -goog.iter.limit = function(iterable, limitSize) { - goog.asserts.assert(goog.math.isInt(limitSize) && limitSize >= 0); - - var iterator = goog.iter.toIterator(iterable); - - var iter = new goog.iter.Iterator(); - var remaining = limitSize; - - iter.next = function() { - if (remaining-- > 0) { - return iterator.next(); } - throw goog.iter.StopIteration; + return false; }; - - return iter; -}; - - -/** - * Creates an iterator that is advanced {@code count} steps ahead. Consumed - * values are silently discarded. If {@code count} is greater than the number - * of elements in {@code iterable}, an empty iterator is returned. Subsequent - * calls to {@code next()} will throw {@code goog.iter.StopIteration}. - * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The - * iterable to consume. - * @param {number} count The number of elements to consume from the iterator. - * @return {!goog.iter.Iterator<VALUE>} An iterator advanced zero or more steps - * ahead. - * @template VALUE - */ -goog.iter.consume = function(iterable, count) { - goog.asserts.assert(goog.math.isInt(count) && count >= 0); - - var iterator = goog.iter.toIterator(iterable); - - while (count-- > 0) { - goog.iter.nextOrValue(iterator, null); - } - - return iterator; -}; - - -/** - * Creates an iterator that returns a range of elements from an iterable. - * Similar to {@see goog.array#slice} but does not support negative indexes. - * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The - * iterable to slice. - * @param {number} start The index of the first element to return. - * @param {number=} opt_end The index after the last element to return. If - * defined, must be greater than or equal to {@code start}. - * @return {!goog.iter.Iterator<VALUE>} A new iterator containing a slice of - * the original. - * @template VALUE - */ -goog.iter.slice = function(iterable, start, opt_end) { - goog.asserts.assert(goog.math.isInt(start) && start >= 0); - - var iterator = goog.iter.consume(iterable, start); - - if (goog.isNumber(opt_end)) { - goog.asserts.assert(goog.math.isInt(opt_end) && opt_end >= start); - iterator = goog.iter.limit(iterator, opt_end - start /* limitSize */); - } - - return iterator; -}; - - -/** - * Checks an array for duplicate elements. - * @param {Array<VALUE>|goog.array.ArrayLike} arr The array to check for - * duplicates. - * @return {boolean} True, if the array contains duplicates, false otherwise. - * @private - * @template VALUE - */ -// TODO(user): Consider moving this into goog.array as a public function. -goog.iter.hasDuplicates_ = function(arr) { - var deduped = []; - goog.array.removeDuplicates(arr, deduped); - return arr.length != deduped.length; -}; - - -/** - * Creates an iterator that returns permutations of elements in - * {@code iterable}. - * - * Permutations are obtained by taking the Cartesian product of - * {@code opt_length} iterables and filtering out those with repeated - * elements. For example, the permutations of {@code [1,2,3]} are - * {@code [[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]]}. - * @see http://docs.python.org/2/library/itertools.html#itertools.permutations - * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The - * iterable from which to generate permutations. - * @param {number=} opt_length Length of each permutation. If omitted, defaults - * to the length of {@code iterable}. - * @return {!goog.iter.Iterator<!Array<VALUE>>} A new iterator containing the - * permutations of {@code iterable}. - * @template VALUE - */ -goog.iter.permutations = function(iterable, opt_length) { - var elements = goog.iter.toArray(iterable); - var length = goog.isNumber(opt_length) ? opt_length : elements.length; - - var sets = goog.array.repeat(elements, length); - var product = goog.iter.product.apply(undefined, sets); - - return goog.iter.filter(product, function(arr) { - return !goog.iter.hasDuplicates_(arr); - }); }; /** - * Creates an iterator that returns combinations of elements from - * {@code iterable}. - * - * Combinations are obtained by taking the {@see goog.iter#permutations} of - * {@code iterable} and filtering those whose elements appear in the order they - * are encountered in {@code iterable}. For example, the 3-length combinations - * of {@code [0,1,2,3]} are {@code [[0,1,2], [0,1,3], [0,2,3], [1,2,3]]}. - * @see http://docs.python.org/2/library/itertools.html#itertools.combinations - * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The - * iterable from which to generate combinations. - * @param {number} length The length of each combination. - * @return {!goog.iter.Iterator<!Array<VALUE>>} A new iterator containing - * combinations from the {@code iterable}. - * @template VALUE + * Creates a function that returns the Boolean opposite of a provided function. + * For example, (goog.functions.not(f))(x) is equivalent to !f(x). + * @param {!Function} f The original function. + * @return {function(...?):boolean} A function that delegates to f and returns + * opposite. */ -goog.iter.combinations = function(iterable, length) { - var elements = goog.iter.toArray(iterable); - var indexes = goog.iter.range(elements.length); - var indexIterator = goog.iter.permutations(indexes, length); - // sortedIndexIterator will now give arrays of with the given length that - // indicate what indexes into "elements" should be returned on each iteration. - var sortedIndexIterator = goog.iter.filter(indexIterator, function(arr) { - return goog.array.isSorted(arr); - }); - - var iter = new goog.iter.Iterator(); - - function getIndexFromElements(index) { - return elements[index]; - } - - iter.next = function() { - return goog.array.map(sortedIndexIterator.next(), getIndexFromElements); - }; - - return iter; +goog.functions.not = function(f) { + return function() { return !f.apply(this, arguments); }; }; /** - * Creates an iterator that returns combinations of elements from - * {@code iterable}, with repeated elements possible. + * Generic factory function to construct an object given the constructor + * and the arguments. Intended to be bound to create object factories. * - * Combinations are obtained by taking the Cartesian product of {@code length} - * iterables and filtering those whose elements appear in the order they are - * encountered in {@code iterable}. For example, the 2-length combinations of - * {@code [1,2,3]} are {@code [[1,1], [1,2], [1,3], [2,2], [2,3], [3,3]]}. - * @see http://docs.python.org/2/library/itertools.html#itertools.combinations_with_replacement - * @see http://en.wikipedia.org/wiki/Combination#Number_of_combinations_with_repetition - * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The - * iterable to combine. - * @param {number} length The length of each combination. - * @return {!goog.iter.Iterator<!Array<VALUE>>} A new iterator containing - * combinations from the {@code iterable}. - * @template VALUE - */ -goog.iter.combinationsWithReplacement = function(iterable, length) { - var elements = goog.iter.toArray(iterable); - var indexes = goog.array.range(elements.length); - var sets = goog.array.repeat(indexes, length); - var indexIterator = goog.iter.product.apply(undefined, sets); - // sortedIndexIterator will now give arrays of with the given length that - // indicate what indexes into "elements" should be returned on each iteration. - var sortedIndexIterator = goog.iter.filter(indexIterator, function(arr) { - return goog.array.isSorted(arr); - }); - - var iter = new goog.iter.Iterator(); - - function getIndexFromElements(index) { - return elements[index]; - } - - iter.next = function() { - return goog.array.map( - /** @type {!Array<number>} */ - (sortedIndexIterator.next()), getIndexFromElements); - }; - - return iter; -}; - -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Datastructure: Hash Map. + * Example: * - * @author arv@google.com (Erik Arvidsson) + * var factory = goog.partial(goog.functions.create, Class); * - * This file contains an implementation of a Map structure. It implements a lot - * of the methods used in goog.structs so those functions work on hashes. This - * is best suited for complex key types. For simple keys such as numbers and - * strings consider using the lighter-weight utilities in goog.object. - */ - - -goog.provide('goog.structs.Map'); - -goog.require('goog.iter.Iterator'); -goog.require('goog.iter.StopIteration'); -goog.require('goog.object'); - - - -/** - * Class for Hash Map datastructure. - * @param {*=} opt_map Map or Object to initialize the map with. - * @param {...*} var_args If 2 or more arguments are present then they - * will be used as key-value pairs. - * @constructor - * @template K, V + * @param {function(new:T, ...)} constructor The constructor for the Object. + * @param {...*} var_args The arguments to be passed to the constructor. + * @return {T} A new instance of the class given in {@code constructor}. + * @template T */ -goog.structs.Map = function(opt_map, var_args) { - - /** - * Underlying JS object used to implement the map. - * @private {!Object} - */ - this.map_ = {}; - - /** - * An array of keys. This is necessary for two reasons: - * 1. Iterating the keys using for (var key in this.map_) allocates an - * object for every key in IE which is really bad for IE6 GC perf. - * 2. Without a side data structure, we would need to escape all the keys - * as that would be the only way we could tell during iteration if the - * key was an internal key or a property of the object. - * - * This array can contain deleted keys so it's necessary to check the map - * as well to see if the key is still in the map (this doesn't require a - * memory allocation in IE). - * @private {!Array<string>} - */ - this.keys_ = []; - - /** - * The number of key value pairs in the map. - * @private {number} - */ - this.count_ = 0; - +goog.functions.create = function(constructor, var_args) { /** - * Version used to detect changes while iterating. - * @private {number} + * @constructor + * @final */ - this.version_ = 0; - - var argLength = arguments.length; - - if (argLength > 1) { - if (argLength % 2) { - throw Error('Uneven number of arguments'); - } - for (var i = 0; i < argLength; i += 2) { - this.set(arguments[i], arguments[i + 1]); - } - } else if (opt_map) { - this.addAll(/** @type {Object} */ (opt_map)); - } -}; - - -/** - * @return {number} The number of key-value pairs in the map. - */ -goog.structs.Map.prototype.getCount = function() { - return this.count_; -}; - - -/** - * Returns the values of the map. - * @return {!Array<V>} The values in the map. - */ -goog.structs.Map.prototype.getValues = function() { - this.cleanupKeysArray_(); - - var rv = []; - for (var i = 0; i < this.keys_.length; i++) { - var key = this.keys_[i]; - rv.push(this.map_[key]); - } - return rv; -}; - - -/** - * Returns the keys of the map. - * @return {!Array<string>} Array of string values. - */ -goog.structs.Map.prototype.getKeys = function() { - this.cleanupKeysArray_(); - return /** @type {!Array<string>} */ (this.keys_.concat()); -}; - - -/** - * Whether the map contains the given key. - * @param {*} key The key to check for. - * @return {boolean} Whether the map contains the key. - */ -goog.structs.Map.prototype.containsKey = function(key) { - return goog.structs.Map.hasKey_(this.map_, key); -}; - - -/** - * Whether the map contains the given value. This is O(n). - * @param {V} val The value to check for. - * @return {boolean} Whether the map contains the value. - */ -goog.structs.Map.prototype.containsValue = function(val) { - for (var i = 0; i < this.keys_.length; i++) { - var key = this.keys_[i]; - if (goog.structs.Map.hasKey_(this.map_, key) && this.map_[key] == val) { - return true; - } - } - return false; -}; - - -/** - * Whether this map is equal to the argument map. - * @param {goog.structs.Map} otherMap The map against which to test equality. - * @param {function(V, V): boolean=} opt_equalityFn Optional equality function - * to test equality of values. If not specified, this will test whether - * the values contained in each map are identical objects. - * @return {boolean} Whether the maps are equal. - */ -goog.structs.Map.prototype.equals = function(otherMap, opt_equalityFn) { - if (this === otherMap) { - return true; - } - - if (this.count_ != otherMap.getCount()) { - return false; - } - - var equalityFn = opt_equalityFn || goog.structs.Map.defaultEquals; - - this.cleanupKeysArray_(); - for (var key, i = 0; key = this.keys_[i]; i++) { - if (!equalityFn(this.get(key), otherMap.get(key))) { - return false; - } - } - - return true; -}; - - -/** - * Default equality test for values. - * @param {*} a The first value. - * @param {*} b The second value. - * @return {boolean} Whether a and b reference the same object. - */ -goog.structs.Map.defaultEquals = function(a, b) { - return a === b; -}; - - -/** - * @return {boolean} Whether the map is empty. - */ -goog.structs.Map.prototype.isEmpty = function() { - return this.count_ == 0; -}; - - -/** - * Removes all key-value pairs from the map. - */ -goog.structs.Map.prototype.clear = function() { - this.map_ = {}; - this.keys_.length = 0; - this.count_ = 0; - this.version_ = 0; -}; - - -/** - * Removes a key-value pair based on the key. This is O(logN) amortized due to - * updating the keys array whenever the count becomes half the size of the keys - * in the keys array. - * @param {*} key The key to remove. - * @return {boolean} Whether object was removed. - */ -goog.structs.Map.prototype.remove = function(key) { - if (goog.structs.Map.hasKey_(this.map_, key)) { - delete this.map_[key]; - this.count_--; - this.version_++; - - // clean up the keys array if the threshhold is hit - if (this.keys_.length > 2 * this.count_) { - this.cleanupKeysArray_(); - } - - return true; - } - return false; -}; - - -/** - * Cleans up the temp keys array by removing entries that are no longer in the - * map. - * @private - */ -goog.structs.Map.prototype.cleanupKeysArray_ = function() { - if (this.count_ != this.keys_.length) { - // First remove keys that are no longer in the map. - var srcIndex = 0; - var destIndex = 0; - while (srcIndex < this.keys_.length) { - var key = this.keys_[srcIndex]; - if (goog.structs.Map.hasKey_(this.map_, key)) { - this.keys_[destIndex++] = key; - } - srcIndex++; - } - this.keys_.length = destIndex; - } - - if (this.count_ != this.keys_.length) { - // If the count still isn't correct, that means we have duplicates. This can - // happen when the same key is added and removed multiple times. Now we have - // to allocate one extra Object to remove the duplicates. This could have - // been done in the first pass, but in the common case, we can avoid - // allocating an extra object by only doing this when necessary. - var seen = {}; - var srcIndex = 0; - var destIndex = 0; - while (srcIndex < this.keys_.length) { - var key = this.keys_[srcIndex]; - if (!(goog.structs.Map.hasKey_(seen, key))) { - this.keys_[destIndex++] = key; - seen[key] = 1; - } - srcIndex++; - } - this.keys_.length = destIndex; - } -}; - - -/** - * Returns the value for the given key. If the key is not found and the default - * value is not given this will return {@code undefined}. - * @param {*} key The key to get the value for. - * @param {DEFAULT=} opt_val The value to return if no item is found for the - * given key, defaults to undefined. - * @return {V|DEFAULT} The value for the given key. - * @template DEFAULT - */ -goog.structs.Map.prototype.get = function(key, opt_val) { - if (goog.structs.Map.hasKey_(this.map_, key)) { - return this.map_[key]; - } - return opt_val; -}; - - -/** - * Adds a key-value pair to the map. - * @param {*} key The key. - * @param {V} value The value to add. - * @return {*} Some subclasses return a value. - */ -goog.structs.Map.prototype.set = function(key, value) { - if (!(goog.structs.Map.hasKey_(this.map_, key))) { - this.count_++; - this.keys_.push(key); - // Only change the version if we add a new key. - this.version_++; - } - this.map_[key] = value; -}; - - -/** - * Adds multiple key-value pairs from another goog.structs.Map or Object. - * @param {Object} map Object containing the data to add. - */ -goog.structs.Map.prototype.addAll = function(map) { - var keys, values; - if (map instanceof goog.structs.Map) { - keys = map.getKeys(); - values = map.getValues(); - } else { - keys = goog.object.getKeys(map); - values = goog.object.getValues(map); - } - // we could use goog.array.forEach here but I don't want to introduce that - // dependency just for this. - for (var i = 0; i < keys.length; i++) { - this.set(keys[i], values[i]); - } -}; - - -/** - * Calls the given function on each entry in the map. - * @param {function(this:T, V, K, goog.structs.Map<K,V>)} f - * @param {T=} opt_obj The value of "this" inside f. - * @template T - */ -goog.structs.Map.prototype.forEach = function(f, opt_obj) { - var keys = this.getKeys(); - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - var value = this.get(key); - f.call(opt_obj, value, key, this); - } -}; - - -/** - * Clones a map and returns a new map. - * @return {!goog.structs.Map} A new map with the same key-value pairs. - */ -goog.structs.Map.prototype.clone = function() { - return new goog.structs.Map(this); -}; - - -/** - * Returns a new map in which all the keys and values are interchanged - * (keys become values and values become keys). If multiple keys map to the - * same value, the chosen transposed value is implementation-dependent. - * - * It acts very similarly to {goog.object.transpose(Object)}. - * - * @return {!goog.structs.Map} The transposed map. - */ -goog.structs.Map.prototype.transpose = function() { - var transposed = new goog.structs.Map(); - for (var i = 0; i < this.keys_.length; i++) { - var key = this.keys_[i]; - var value = this.map_[key]; - transposed.set(value, key); - } - - return transposed; -}; + var temp = function() {}; + temp.prototype = constructor.prototype; + // obj will have constructor's prototype in its chain and + // 'obj instanceof constructor' will be true. + var obj = new temp(); -/** - * @return {!Object} Object representation of the map. - */ -goog.structs.Map.prototype.toObject = function() { - this.cleanupKeysArray_(); - var obj = {}; - for (var i = 0; i < this.keys_.length; i++) { - var key = this.keys_[i]; - obj[key] = this.map_[key]; - } + // obj is initialized by constructor. + // arguments is only array-like so lacks shift(), but can be used with + // the Array prototype function. + constructor.apply(obj, Array.prototype.slice.call(arguments, 1)); return obj; }; /** - * Returns an iterator that iterates over the keys in the map. Removal of keys - * while iterating might have undesired side effects. - * @return {!goog.iter.Iterator} An iterator over the keys in the map. - */ -goog.structs.Map.prototype.getKeyIterator = function() { - return this.__iterator__(true); -}; - - -/** - * Returns an iterator that iterates over the values in the map. Removal of - * keys while iterating might have undesired side effects. - * @return {!goog.iter.Iterator} An iterator over the values in the map. - */ -goog.structs.Map.prototype.getValueIterator = function() { - return this.__iterator__(false); -}; - - -/** - * Returns an iterator that iterates over the values or the keys in the map. - * This throws an exception if the map was mutated since the iterator was - * created. - * @param {boolean=} opt_keys True to iterate over the keys. False to iterate - * over the values. The default value is false. - * @return {!goog.iter.Iterator} An iterator over the values or keys in the map. - */ -goog.structs.Map.prototype.__iterator__ = function(opt_keys) { - // Clean up keys to minimize the risk of iterating over dead keys. - this.cleanupKeysArray_(); - - var i = 0; - var version = this.version_; - var selfObj = this; - - var newIter = new goog.iter.Iterator; - newIter.next = function() { - if (version != selfObj.version_) { - throw Error('The map has changed since the iterator was created'); - } - if (i >= selfObj.keys_.length) { - throw goog.iter.StopIteration; - } - var key = selfObj.keys_[i++]; - return opt_keys ? key : selfObj.map_[key]; - }; - return newIter; -}; - - -/** - * Safe way to test for hasOwnProperty. It even allows testing for - * 'hasOwnProperty'. - * @param {Object} obj The object to test for presence of the given key. - * @param {*} key The key to check for. - * @return {boolean} Whether the object has the key. - * @private + * @define {boolean} Whether the return value cache should be used. + * This should only be used to disable caches when testing. */ -goog.structs.Map.hasKey_ = function(obj, key) { - return Object.prototype.hasOwnProperty.call(obj, key); -}; +goog.define('goog.functions.CACHE_RETURN_VALUE', true); -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. /** - * @fileoverview Datastructure: Set. + * Gives a wrapper function that caches the return value of a parameterless + * function when first called. * - * @author arv@google.com (Erik Arvidsson) + * When called for the first time, the given function is called and its + * return value is cached (thus this is only appropriate for idempotent + * functions). Subsequent calls will return the cached return value. This + * allows the evaluation of expensive functions to be delayed until first used. * - * This class implements a set data structure. Adding and removing is O(1). It - * supports both object and primitive values. Be careful because you can add - * both 1 and new Number(1), because these are not the same. You can even add - * multiple new Number(1) because these are not equal. - */ - - -goog.provide('goog.structs.Set'); - -goog.require('goog.structs'); -goog.require('goog.structs.Collection'); -goog.require('goog.structs.Map'); - - - -/** - * A set that can contain both primitives and objects. Adding and removing - * elements is O(1). Primitives are treated as identical if they have the same - * type and convert to the same string. Objects are treated as identical only - * if they are references to the same object. WARNING: A goog.structs.Set can - * contain both 1 and (new Number(1)), because they are not the same. WARNING: - * Adding (new Number(1)) twice will yield two distinct elements, because they - * are two different objects. WARNING: Any object that is added to a - * goog.structs.Set will be modified! Because goog.getUid() is used to - * identify objects, every object in the set will be mutated. - * @param {Array<T>|Object<?,T>=} opt_values Initial values to start with. - * @constructor - * @implements {goog.structs.Collection<T>} - * @final - * @template T - */ -goog.structs.Set = function(opt_values) { - this.map_ = new goog.structs.Map; - if (opt_values) { - this.addAll(opt_values); - } -}; - - -/** - * Obtains a unique key for an element of the set. Primitives will yield the - * same key if they have the same type and convert to the same string. Object - * references will yield the same key only if they refer to the same object. - * @param {*} val Object or primitive value to get a key for. - * @return {string} A unique key for this value/object. - * @private - */ -goog.structs.Set.getKey_ = function(val) { - var type = typeof val; - if (type == 'object' && val || type == 'function') { - return 'o' + goog.getUid(/** @type {Object} */ (val)); - } else { - return type.substr(0, 1) + val; - } -}; - - -/** - * @return {number} The number of elements in the set. - * @override - */ -goog.structs.Set.prototype.getCount = function() { - return this.map_.getCount(); -}; - - -/** - * Add a primitive or an object to the set. - * @param {T} element The primitive or object to add. - * @override - */ -goog.structs.Set.prototype.add = function(element) { - this.map_.set(goog.structs.Set.getKey_(element), element); -}; - - -/** - * Adds all the values in the given collection to this set. - * @param {Array<T>|goog.structs.Collection<T>|Object<?,T>} col A collection - * containing the elements to add. - */ -goog.structs.Set.prototype.addAll = function(col) { - var values = goog.structs.getValues(col); - var l = values.length; - for (var i = 0; i < l; i++) { - this.add(values[i]); - } -}; - - -/** - * Removes all values in the given collection from this set. - * @param {Array<T>|goog.structs.Collection<T>|Object<?,T>} col A collection - * containing the elements to remove. - */ -goog.structs.Set.prototype.removeAll = function(col) { - var values = goog.structs.getValues(col); - var l = values.length; - for (var i = 0; i < l; i++) { - this.remove(values[i]); - } -}; - - -/** - * Removes the given element from this set. - * @param {T} element The primitive or object to remove. - * @return {boolean} Whether the element was found and removed. - * @override - */ -goog.structs.Set.prototype.remove = function(element) { - return this.map_.remove(goog.structs.Set.getKey_(element)); -}; - - -/** - * Removes all elements from this set. - */ -goog.structs.Set.prototype.clear = function() { - this.map_.clear(); -}; - - -/** - * Tests whether this set is empty. - * @return {boolean} True if there are no elements in this set. - */ -goog.structs.Set.prototype.isEmpty = function() { - return this.map_.isEmpty(); -}; - - -/** - * Tests whether this set contains the given element. - * @param {T} element The primitive or object to test for. - * @return {boolean} True if this set contains the given element. - * @override - */ -goog.structs.Set.prototype.contains = function(element) { - return this.map_.containsKey(goog.structs.Set.getKey_(element)); -}; - - -/** - * Tests whether this set contains all the values in a given collection. - * Repeated elements in the collection are ignored, e.g. (new - * goog.structs.Set([1, 2])).containsAll([1, 1]) is True. - * @param {goog.structs.Collection<T>|Object} col A collection-like object. - * @return {boolean} True if the set contains all elements. - */ -goog.structs.Set.prototype.containsAll = function(col) { - return goog.structs.every(col, this.contains, this); -}; - - -/** - * Finds all values that are present in both this set and the given collection. - * @param {Array<S>|Object<?,S>} col A collection. - * @return {!goog.structs.Set<T|S>} A new set containing all the values - * (primitives or objects) present in both this set and the given - * collection. - * @template S - */ -goog.structs.Set.prototype.intersection = function(col) { - var result = new goog.structs.Set(); - - var values = goog.structs.getValues(col); - for (var i = 0; i < values.length; i++) { - var value = values[i]; - if (this.contains(value)) { - result.add(value); - } - } - - return result; -}; - - -/** - * Finds all values that are present in this set and not in the given - * collection. - * @param {Array<T>|goog.structs.Collection<T>|Object<?,T>} col A collection. - * @return {!goog.structs.Set} A new set containing all the values - * (primitives or objects) present in this set but not in the given - * collection. - */ -goog.structs.Set.prototype.difference = function(col) { - var result = this.clone(); - result.removeAll(col); - return result; -}; - - -/** - * Returns an array containing all the elements in this set. - * @return {!Array<T>} An array containing all the elements in this set. - */ -goog.structs.Set.prototype.getValues = function() { - return this.map_.getValues(); -}; - - -/** - * Creates a shallow clone of this set. - * @return {!goog.structs.Set<T>} A new set containing all the same elements as - * this set. - */ -goog.structs.Set.prototype.clone = function() { - return new goog.structs.Set(this); -}; - - -/** - * Tests whether the given collection consists of the same elements as this set, - * regardless of order, without repetition. Primitives are treated as equal if - * they have the same type and convert to the same string; objects are treated - * as equal if they are references to the same object. This operation is O(n). - * @param {goog.structs.Collection<T>|Object} col A collection. - * @return {boolean} True if the given collection consists of the same elements - * as this set, regardless of order, without repetition. - */ -goog.structs.Set.prototype.equals = function(col) { - return this.getCount() == goog.structs.getCount(col) && this.isSubsetOf(col); -}; - - -/** - * Tests whether the given collection contains all the elements in this set. - * Primitives are treated as equal if they have the same type and convert to the - * same string; objects are treated as equal if they are references to the same - * object. This operation is O(n). - * @param {goog.structs.Collection<T>|Object} col A collection. - * @return {boolean} True if this set is a subset of the given collection. - */ -goog.structs.Set.prototype.isSubsetOf = function(col) { - var colCount = goog.structs.getCount(col); - if (this.getCount() > colCount) { - return false; - } - // TODO(user) Find the minimal collection size where the conversion makes - // the contains() method faster. - if (!(col instanceof goog.structs.Set) && colCount > 5) { - // Convert to a goog.structs.Set so that goog.structs.contains runs in - // O(1) time instead of O(n) time. - col = new goog.structs.Set(col); - } - return goog.structs.every(this, function(value) { - return goog.structs.contains(col, value); - }); -}; - - -/** - * Returns an iterator that iterates over the elements in this set. - * @param {boolean=} opt_keys This argument is ignored. - * @return {!goog.iter.Iterator} An iterator over the elements in this set. - */ -goog.structs.Set.prototype.__iterator__ = function(opt_keys) { - return this.map_.__iterator__(false); -}; - -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Logging and debugging utilities. + * To cache the return values of functions with parameters, see goog.memoize. * - * @see ../demos/debug.html - */ - -goog.provide('goog.debug'); - -goog.require('goog.array'); -goog.require('goog.html.SafeHtml'); -goog.require('goog.html.SafeUrl'); -goog.require('goog.html.uncheckedconversions'); -goog.require('goog.string.Const'); -goog.require('goog.structs.Set'); -goog.require('goog.userAgent'); - - -/** @define {boolean} Whether logging should be enabled. */ -goog.define('goog.debug.LOGGING_ENABLED', goog.DEBUG); - - -/** - * Catches onerror events fired by windows and similar objects. - * @param {function(Object)} logFunc The function to call with the error - * information. - * @param {boolean=} opt_cancel Whether to stop the error from reaching the - * browser. - * @param {Object=} opt_target Object that fires onerror events. - */ -goog.debug.catchErrors = function(logFunc, opt_cancel, opt_target) { - var target = opt_target || goog.global; - var oldErrorHandler = target.onerror; - var retVal = !!opt_cancel; - - // Chrome interprets onerror return value backwards (http://crbug.com/92062) - // until it was fixed in webkit revision r94061 (Webkit 535.3). This - // workaround still needs to be skipped in Safari after the webkit change - // gets pushed out in Safari. - // See https://bugs.webkit.org/show_bug.cgi?id=67119 - if (goog.userAgent.WEBKIT && - !goog.userAgent.isVersionOrHigher('535.3')) { - retVal = !retVal; - } - - /** - * New onerror handler for this target. This onerror handler follows the spec - * according to - * http://www.whatwg.org/specs/web-apps/current-work/#runtime-script-errors - * The spec was changed in August 2013 to support receiving column information - * and an error object for all scripts on the same origin or cross origin - * scripts with the proper headers. See - * https://mikewest.org/2013/08/debugging-runtime-errors-with-window-onerror - * - * @param {string} message The error message. For cross-origin errors, this - * will be scrubbed to just "Script error.". For new browsers that have - * updated to follow the latest spec, errors that come from origins that - * have proper cross origin headers will not be scrubbed. - * @param {string} url The URL of the script that caused the error. The URL - * will be scrubbed to "" for cross origin scripts unless the script has - * proper cross origin headers and the browser has updated to the latest - * spec. - * @param {number} line The line number in the script that the error - * occurred on. - * @param {number=} opt_col The optional column number that the error - * occurred on. Only browsers that have updated to the latest spec will - * include this. - * @param {Error=} opt_error The optional actual error object for this - * error that should include the stack. Only browsers that have updated - * to the latest spec will inlude this parameter. - * @return {boolean} Whether to prevent the error from reaching the browser. - */ - target.onerror = function(message, url, line, opt_col, opt_error) { - if (oldErrorHandler) { - oldErrorHandler(message, url, line, opt_col, opt_error); - } - logFunc({ - message: message, - fileName: url, - line: line, - col: opt_col, - error: opt_error - }); - return retVal; - }; -}; - - -/** - * Creates a string representing an object and all its properties. - * @param {Object|null|undefined} obj Object to expose. - * @param {boolean=} opt_showFn Show the functions as well as the properties, - * default is false. - * @return {string} The string representation of {@code obj}. - */ -goog.debug.expose = function(obj, opt_showFn) { - if (typeof obj == 'undefined') { - return 'undefined'; - } - if (obj == null) { - return 'NULL'; - } - var str = []; - - for (var x in obj) { - if (!opt_showFn && goog.isFunction(obj[x])) { - continue; - } - var s = x + ' = '; - /** @preserveTry */ - try { - s += obj[x]; - } catch (e) { - s += '*** ' + e + ' ***'; - } - str.push(s); - } - return str.join('\n'); -}; - - -/** - * Creates a string representing a given primitive or object, and for an - * object, all its properties and nested objects. WARNING: If an object is - * given, it and all its nested objects will be modified. To detect reference - * cycles, this method identifies objects using goog.getUid() which mutates the - * object. - * @param {*} obj Object to expose. - * @param {boolean=} opt_showFn Also show properties that are functions (by - * default, functions are omitted). - * @return {string} A string representation of {@code obj}. - */ -goog.debug.deepExpose = function(obj, opt_showFn) { - var str = []; - - var helper = function(obj, space, parentSeen) { - var nestspace = space + ' '; - var seen = new goog.structs.Set(parentSeen); - - var indentMultiline = function(str) { - return str.replace(/\n/g, '\n' + space); - }; - - /** @preserveTry */ - try { - if (!goog.isDef(obj)) { - str.push('undefined'); - } else if (goog.isNull(obj)) { - str.push('NULL'); - } else if (goog.isString(obj)) { - str.push('"' + indentMultiline(obj) + '"'); - } else if (goog.isFunction(obj)) { - str.push(indentMultiline(String(obj))); - } else if (goog.isObject(obj)) { - if (seen.contains(obj)) { - str.push('*** reference loop detected ***'); - } else { - seen.add(obj); - str.push('{'); - for (var x in obj) { - if (!opt_showFn && goog.isFunction(obj[x])) { - continue; - } - str.push('\n'); - str.push(nestspace); - str.push(x + ' = '); - helper(obj[x], nestspace, seen); - } - str.push('\n' + space + '}'); - } - } else { - str.push(obj); - } - } catch (e) { - str.push('*** ' + e + ' ***'); - } - }; - - helper(obj, '', new goog.structs.Set()); - return str.join(''); -}; - - -/** - * Recursively outputs a nested array as a string. - * @param {Array<?>} arr The array. - * @return {string} String representing nested array. - */ -goog.debug.exposeArray = function(arr) { - var str = []; - for (var i = 0; i < arr.length; i++) { - if (goog.isArray(arr[i])) { - str.push(goog.debug.exposeArray(arr[i])); - } else { - str.push(arr[i]); - } - } - return '[ ' + str.join(', ') + ' ]'; -}; - - -/** - * Exposes an exception that has been caught by a try...catch and outputs the - * error as HTML with a stack trace. - * @param {Object} err Error object or string. - * @param {Function=} opt_fn Optional function to start stack trace from. - * @return {string} Details of exception, as HTML. - */ -goog.debug.exposeException = function(err, opt_fn) { - var html = goog.debug.exposeExceptionAsHtml(err, opt_fn); - return goog.html.SafeHtml.unwrap(html); -}; - - -/** - * Exposes an exception that has been caught by a try...catch and outputs the - * error with a stack trace. - * @param {Object} err Error object or string. - * @param {Function=} opt_fn Optional function to start stack trace from. - * @return {!goog.html.SafeHtml} Details of exception. - */ -goog.debug.exposeExceptionAsHtml = function(err, opt_fn) { - /** @preserveTry */ - try { - var e = goog.debug.normalizeErrorObject(err); - // Create the error message - var viewSourceUrl = goog.debug.createViewSourceUrl_(e.fileName); - var error = goog.html.SafeHtml.concat( - goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces( - 'Message: ' + e.message + '\nUrl: '), - goog.html.SafeHtml.create('a', - {href: viewSourceUrl, target: '_new'}, e.fileName), - goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces( - '\nLine: ' + e.lineNumber + '\n\nBrowser stack:\n' + - e.stack + '-> ' + '[end]\n\nJS stack traversal:\n' + - goog.debug.getStacktrace(opt_fn) + '-> ')); - return error; - } catch (e2) { - return goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces( - 'Exception trying to expose exception! You win, we lose. ' + e2); - } -}; - - -/** - * @param {?string=} opt_fileName - * @return {!goog.html.SafeUrl} SafeUrl with view-source scheme, pointing at - * fileName. - * @private - */ -goog.debug.createViewSourceUrl_ = function(opt_fileName) { - if (!goog.isDefAndNotNull(opt_fileName)) { - opt_fileName = ''; - } - if (!/^https?:\/\//i.test(opt_fileName)) { - return goog.html.SafeUrl.fromConstant( - goog.string.Const.from('sanitizedviewsrc')); - } - var sanitizedFileName = goog.html.SafeUrl.sanitize(opt_fileName); - return goog.html.uncheckedconversions. - safeUrlFromStringKnownToSatisfyTypeContract( - goog.string.Const.from('view-source scheme plus HTTP/HTTPS URL'), - 'view-source:' + goog.html.SafeUrl.unwrap(sanitizedFileName)); -}; - - -/** - * Normalizes the error/exception object between browsers. - * @param {Object} err Raw error object. - * @return {!Object} Normalized error object. - */ -goog.debug.normalizeErrorObject = function(err) { - var href = goog.getObjectByName('window.location.href'); - if (goog.isString(err)) { - return { - 'message': err, - 'name': 'Unknown error', - 'lineNumber': 'Not available', - 'fileName': href, - 'stack': 'Not available' - }; - } - - var lineNumber, fileName; - var threwError = false; - - try { - lineNumber = err.lineNumber || err.line || 'Not available'; - } catch (e) { - // Firefox 2 sometimes throws an error when accessing 'lineNumber': - // Message: Permission denied to get property UnnamedClass.lineNumber - lineNumber = 'Not available'; - threwError = true; - } - - try { - fileName = err.fileName || err.filename || err.sourceURL || - // $googDebugFname may be set before a call to eval to set the filename - // that the eval is supposed to present. - goog.global['$googDebugFname'] || href; - } catch (e) { - // Firefox 2 may also throw an error when accessing 'filename'. - fileName = 'Not available'; - threwError = true; - } - - // The IE Error object contains only the name and the message. - // The Safari Error object uses the line and sourceURL fields. - if (threwError || !err.lineNumber || !err.fileName || !err.stack || - !err.message || !err.name) { - return { - 'message': err.message || 'Not available', - 'name': err.name || 'UnknownError', - 'lineNumber': lineNumber, - 'fileName': fileName, - 'stack': err.stack || 'Not available' - }; - } - - // Standards error object - return err; -}; - - -/** - * Converts an object to an Error if it's a String, - * adds a stacktrace if there isn't one, - * and optionally adds an extra message. - * @param {Error|string} err the original thrown object or string. - * @param {string=} opt_message optional additional message to add to the - * error. - * @return {!Error} If err is a string, it is used to create a new Error, - * which is enhanced and returned. Otherwise err itself is enhanced - * and returned. - */ -goog.debug.enhanceError = function(err, opt_message) { - var error; - if (typeof err == 'string') { - error = Error(err); - if (Error.captureStackTrace) { - // Trim this function off the call stack, if we can. - Error.captureStackTrace(error, goog.debug.enhanceError); - } - } else { - error = err; - } - - if (!error.stack) { - error.stack = goog.debug.getStacktrace(goog.debug.enhanceError); - } - if (opt_message) { - // find the first unoccupied 'messageX' property - var x = 0; - while (error['message' + x]) { - ++x; - } - error['message' + x] = String(opt_message); - } - return error; -}; - - -/** - * Gets the current stack trace. Simple and iterative - doesn't worry about - * catching circular references or getting the args. - * @param {number=} opt_depth Optional maximum depth to trace back to. - * @return {string} A string with the function names of all functions in the - * stack, separated by \n. - * @suppress {es5Strict} - */ -goog.debug.getStacktraceSimple = function(opt_depth) { - if (goog.STRICT_MODE_COMPATIBLE) { - var stack = goog.debug.getNativeStackTrace_(goog.debug.getStacktraceSimple); - if (stack) { - return stack; - } - // NOTE: browsers that have strict mode support also have native "stack" - // properties. Fall-through for legacy browser support. - } - - var sb = []; - var fn = arguments.callee.caller; - var depth = 0; - - while (fn && (!opt_depth || depth < opt_depth)) { - sb.push(goog.debug.getFunctionName(fn)); - sb.push('()\n'); - /** @preserveTry */ - try { - fn = fn.caller; - } catch (e) { - sb.push('[exception trying to get caller]\n'); - break; - } - depth++; - if (depth >= goog.debug.MAX_STACK_DEPTH) { - sb.push('[...long stack...]'); - break; - } - } - if (opt_depth && depth >= opt_depth) { - sb.push('[...reached max depth limit...]'); - } else { - sb.push('[end]'); - } - - return sb.join(''); -}; - - -/** - * Max length of stack to try and output - * @type {number} - */ -goog.debug.MAX_STACK_DEPTH = 50; - - -/** - * @param {Function} fn The function to start getting the trace from. - * @return {?string} - * @private - */ -goog.debug.getNativeStackTrace_ = function(fn) { - var tempErr = new Error(); - if (Error.captureStackTrace) { - Error.captureStackTrace(tempErr, fn); - return String(tempErr.stack); - } else { - // IE10, only adds stack traces when an exception is thrown. - try { - throw tempErr; - } catch (e) { - tempErr = e; - } - var stack = tempErr.stack; - if (stack) { - return String(stack); - } - } - return null; -}; - - -/** - * Gets the current stack trace, either starting from the caller or starting - * from a specified function that's currently on the call stack. - * @param {Function=} opt_fn Optional function to start getting the trace from. - * If not provided, defaults to the function that called this. - * @return {string} Stack trace. - * @suppress {es5Strict} - */ -goog.debug.getStacktrace = function(opt_fn) { - var stack; - if (goog.STRICT_MODE_COMPATIBLE) { - // Try to get the stack trace from the environment if it is available. - var contextFn = opt_fn || goog.debug.getStacktrace; - stack = goog.debug.getNativeStackTrace_(contextFn); - } - if (!stack) { - // NOTE: browsers that have strict mode support also have native "stack" - // properties. This function will throw in strict mode. - stack = goog.debug.getStacktraceHelper_( - opt_fn || arguments.callee.caller, []); - } - return stack; -}; - - -/** - * Private helper for getStacktrace(). - * @param {Function} fn Function to start getting the trace from. - * @param {Array<!Function>} visited List of functions visited so far. - * @return {string} Stack trace starting from function fn. - * @suppress {es5Strict} - * @private - */ -goog.debug.getStacktraceHelper_ = function(fn, visited) { - var sb = []; - - // Circular reference, certain functions like bind seem to cause a recursive - // loop so we need to catch circular references - if (goog.array.contains(visited, fn)) { - sb.push('[...circular reference...]'); - - // Traverse the call stack until function not found or max depth is reached - } else if (fn && visited.length < goog.debug.MAX_STACK_DEPTH) { - sb.push(goog.debug.getFunctionName(fn) + '('); - var args = fn.arguments; - // Args may be null for some special functions such as host objects or eval. - for (var i = 0; args && i < args.length; i++) { - if (i > 0) { - sb.push(', '); - } - var argDesc; - var arg = args[i]; - switch (typeof arg) { - case 'object': - argDesc = arg ? 'object' : 'null'; - break; - - case 'string': - argDesc = arg; - break; - - case 'number': - argDesc = String(arg); - break; - - case 'boolean': - argDesc = arg ? 'true' : 'false'; - break; - - case 'function': - argDesc = goog.debug.getFunctionName(arg); - argDesc = argDesc ? argDesc : '[fn]'; - break; - - case 'undefined': - default: - argDesc = typeof arg; - break; - } - - if (argDesc.length > 40) { - argDesc = argDesc.substr(0, 40) + '...'; - } - sb.push(argDesc); - } - visited.push(fn); - sb.push(')\n'); - /** @preserveTry */ - try { - sb.push(goog.debug.getStacktraceHelper_(fn.caller, visited)); - } catch (e) { - sb.push('[exception trying to get caller]\n'); - } - - } else if (fn) { - sb.push('[...long stack...]'); - } else { - sb.push('[end]'); - } - return sb.join(''); -}; - - -/** - * Set a custom function name resolver. - * @param {function(Function): string} resolver Resolves functions to their - * names. + * @param {!function():T} fn A function to lazily evaluate. + * @return {!function():T} A wrapped version the function. + * @template T */ -goog.debug.setFunctionResolver = function(resolver) { - goog.debug.fnNameResolver_ = resolver; -}; - +goog.functions.cacheReturnValue = function(fn) { + var called = false; + var value; -/** - * Gets a function name - * @param {Function} fn Function to get name of. - * @return {string} Function's name. - */ -goog.debug.getFunctionName = function(fn) { - if (goog.debug.fnNameCache_[fn]) { - return goog.debug.fnNameCache_[fn]; - } - if (goog.debug.fnNameResolver_) { - var name = goog.debug.fnNameResolver_(fn); - if (name) { - goog.debug.fnNameCache_[fn] = name; - return name; + return function() { + if (!goog.functions.CACHE_RETURN_VALUE) { + return fn(); } - } - // Heuristically determine function name based on code. - var functionSource = String(fn); - if (!goog.debug.fnNameCache_[functionSource]) { - var matches = /function ([^\(]+)/.exec(functionSource); - if (matches) { - var method = matches[1]; - goog.debug.fnNameCache_[functionSource] = method; - } else { - goog.debug.fnNameCache_[functionSource] = '[Anonymous]'; + if (!called) { + value = fn(); + called = true; } - } - - return goog.debug.fnNameCache_[functionSource]; -}; - - -/** - * Makes whitespace visible by replacing it with printable characters. - * This is useful in finding diffrences between the expected and the actual - * output strings of a testcase. - * @param {string} string whose whitespace needs to be made visible. - * @return {string} string whose whitespace is made visible. - */ -goog.debug.makeWhitespaceVisible = function(string) { - return string.replace(/ /g, '[_]') - .replace(/\f/g, '[f]') - .replace(/\n/g, '[n]\n') - .replace(/\r/g, '[r]') - .replace(/\t/g, '[t]'); -}; - - -/** - * Returns the type of a value. If a constructor is passed, and a suitable - * string cannot be found, 'unknown type name' will be returned. - * - * <p>Forked rather than moved from {@link goog.asserts.getType_} - * to avoid adding a dependency to goog.asserts. - * @param {*} value A constructor, object, or primitive. - * @return {string} The best display name for the value, or 'unknown type name'. - */ -goog.debug.runtimeType = function(value) { - if (value instanceof Function) { - return value.displayName || value.name || 'unknown type name'; - } else if (value instanceof Object) { - return value.constructor.displayName || value.constructor.name || - Object.prototype.toString.call(value); - } else { - return value === null ? 'null' : typeof value; - } -}; - -/** - * Hash map for storing function names that have already been looked up. - * @type {Object} - * @private - */ -goog.debug.fnNameCache_ = {}; - - -/** - * Resolves functions to their names. Resolved function names will be cached. - * @type {function(Function):string} - * @private - */ -goog.debug.fnNameResolver_; - -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Definition of the LogRecord class. Please minimize - * dependencies this file has on other closure classes as any dependency it - * takes won't be able to use the logging infrastructure. - * - */ - -goog.provide('goog.debug.LogRecord'); - - - -/** - * LogRecord objects are used to pass logging requests between - * the logging framework and individual log Handlers. - * @constructor - * @param {goog.debug.Logger.Level} level One of the level identifiers. - * @param {string} msg The string message. - * @param {string} loggerName The name of the source logger. - * @param {number=} opt_time Time this log record was created if other than now. - * If 0, we use #goog.now. - * @param {number=} opt_sequenceNumber Sequence number of this log record. This - * should only be passed in when restoring a log record from persistence. - */ -goog.debug.LogRecord = function(level, msg, loggerName, - opt_time, opt_sequenceNumber) { - this.reset(level, msg, loggerName, opt_time, opt_sequenceNumber); -}; - - -/** - * Time the LogRecord was created. - * @type {number} - * @private - */ -goog.debug.LogRecord.prototype.time_; - - -/** - * Level of the LogRecord - * @type {goog.debug.Logger.Level} - * @private - */ -goog.debug.LogRecord.prototype.level_; - - -/** - * Message associated with the record - * @type {string} - * @private - */ -goog.debug.LogRecord.prototype.msg_; - - -/** - * Name of the logger that created the record. - * @type {string} - * @private - */ -goog.debug.LogRecord.prototype.loggerName_; - - -/** - * Sequence number for the LogRecord. Each record has a unique sequence number - * that is greater than all log records created before it. - * @type {number} - * @private - */ -goog.debug.LogRecord.prototype.sequenceNumber_ = 0; - - -/** - * Exception associated with the record - * @type {Object} - * @private - */ -goog.debug.LogRecord.prototype.exception_ = null; - - -/** - * @define {boolean} Whether to enable log sequence numbers. - */ -goog.define('goog.debug.LogRecord.ENABLE_SEQUENCE_NUMBERS', true); - - -/** - * A sequence counter for assigning increasing sequence numbers to LogRecord - * objects. - * @type {number} - * @private - */ -goog.debug.LogRecord.nextSequenceNumber_ = 0; - - -/** - * Sets all fields of the log record. - * @param {goog.debug.Logger.Level} level One of the level identifiers. - * @param {string} msg The string message. - * @param {string} loggerName The name of the source logger. - * @param {number=} opt_time Time this log record was created if other than now. - * If 0, we use #goog.now. - * @param {number=} opt_sequenceNumber Sequence number of this log record. This - * should only be passed in when restoring a log record from persistence. - */ -goog.debug.LogRecord.prototype.reset = function(level, msg, loggerName, - opt_time, opt_sequenceNumber) { - if (goog.debug.LogRecord.ENABLE_SEQUENCE_NUMBERS) { - this.sequenceNumber_ = typeof opt_sequenceNumber == 'number' ? - opt_sequenceNumber : goog.debug.LogRecord.nextSequenceNumber_++; + return value; } - - this.time_ = opt_time || goog.now(); - this.level_ = level; - this.msg_ = msg; - this.loggerName_ = loggerName; - delete this.exception_; -}; - - -/** - * Get the source Logger's name. - * - * @return {string} source logger name (may be null). - */ -goog.debug.LogRecord.prototype.getLoggerName = function() { - return this.loggerName_; -}; - - -/** - * Get the exception that is part of the log record. - * - * @return {Object} the exception. - */ -goog.debug.LogRecord.prototype.getException = function() { - return this.exception_; -}; - - -/** - * Set the exception that is part of the log record. - * - * @param {Object} exception the exception. - */ -goog.debug.LogRecord.prototype.setException = function(exception) { - this.exception_ = exception; -}; - - -/** - * Get the source Logger's name. - * - * @param {string} loggerName source logger name (may be null). - */ -goog.debug.LogRecord.prototype.setLoggerName = function(loggerName) { - this.loggerName_ = loggerName; -}; - - -/** - * Get the logging message level, for example Level.SEVERE. - * @return {goog.debug.Logger.Level} the logging message level. - */ -goog.debug.LogRecord.prototype.getLevel = function() { - return this.level_; -}; - - -/** - * Set the logging message level, for example Level.SEVERE. - * @param {goog.debug.Logger.Level} level the logging message level. - */ -goog.debug.LogRecord.prototype.setLevel = function(level) { - this.level_ = level; }; /** - * Get the "raw" log message, before localization or formatting. - * - * @return {string} the raw message string. - */ -goog.debug.LogRecord.prototype.getMessage = function() { - return this.msg_; -}; - - -/** - * Set the "raw" log message, before localization or formatting. + * Wraps a function to allow it to be called, at most, once. All + * additional calls are no-ops. * - * @param {string} msg the raw message string. - */ -goog.debug.LogRecord.prototype.setMessage = function(msg) { - this.msg_ = msg; -}; - - -/** - * Get event time in milliseconds since 1970. + * This is particularly useful for initialization functions + * that should be called, at most, once. * - * @return {number} event time in millis since 1970. + * @param {function():*} f Function to call. + * @return {function():undefined} Wrapped function. */ -goog.debug.LogRecord.prototype.getMillis = function() { - return this.time_; +goog.functions.once = function(f) { + // Keep a reference to the function that we null out when we're done with + // it -- that way, the function can be GC'd when we're done with it. + var inner = f; + return function() { + if (inner) { + var tmp = inner; + inner = null; + tmp(); + } + }; }; /** - * Set event time in milliseconds since 1970. + * Wraps a function to allow it to be called, at most, once for each sequence of + * calls fired repeatedly so long as they are fired less than a specified + * interval apart (in milliseconds). Whether it receives one signal or multiple, + * it will always wait until a full interval has elapsed since the last signal + * before performing the action, passing the arguments from the last call of the + * debouncing decorator into the decorated function. * - * @param {number} time event time in millis since 1970. - */ -goog.debug.LogRecord.prototype.setMillis = function(time) { - this.time_ = time; -}; - - -/** - * Get the sequence number. - * <p> - * Sequence numbers are normally assigned in the LogRecord - * constructor, which assigns unique sequence numbers to - * each new LogRecord in increasing order. - * @return {number} the sequence number. - */ -goog.debug.LogRecord.prototype.getSequenceNumber = function() { - return this.sequenceNumber_; -}; - - -// Copyright 2010 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview A buffer for log records. The purpose of this is to improve - * logging performance by re-using old objects when the buffer becomes full and - * to eliminate the need for each app to implement their own log buffer. The - * disadvantage to doing this is that log handlers cannot maintain references to - * log records and expect that they are not overwriten at a later point. + * This is particularly useful for bulking up repeated user actions (e.g. only + * refreshing a view once a user finishes typing rather than updating with every + * keystroke). For more stateful debouncing with support for pausing, resuming, + * and canceling debounced actions, use {@code goog.async.Debouncer}. * - * @author agrieve@google.com (Andrew Grieve) - */ - -goog.provide('goog.debug.LogBuffer'); - -goog.require('goog.asserts'); -goog.require('goog.debug.LogRecord'); - - - -/** - * Creates the log buffer. - * @constructor - * @final - */ -goog.debug.LogBuffer = function() { - goog.asserts.assert(goog.debug.LogBuffer.isBufferingEnabled(), - 'Cannot use goog.debug.LogBuffer without defining ' + - 'goog.debug.LogBuffer.CAPACITY.'); - this.clear(); -}; - - -/** - * A static method that always returns the same instance of LogBuffer. - * @return {!goog.debug.LogBuffer} The LogBuffer singleton instance. - */ -goog.debug.LogBuffer.getInstance = function() { - if (!goog.debug.LogBuffer.instance_) { - // This function is written with the return statement after the assignment - // to avoid the jscompiler StripCode bug described in http://b/2608064. - // After that bug is fixed this can be refactored. - goog.debug.LogBuffer.instance_ = new goog.debug.LogBuffer(); - } - return goog.debug.LogBuffer.instance_; -}; - - -/** - * @define {number} The number of log records to buffer. 0 means disable - * buffering. - */ -goog.define('goog.debug.LogBuffer.CAPACITY', 0); - - -/** - * The array to store the records. - * @type {!Array<!goog.debug.LogRecord|undefined>} - * @private - */ -goog.debug.LogBuffer.prototype.buffer_; - - -/** - * The index of the most recently added record or -1 if there are no records. - * @type {number} - * @private - */ -goog.debug.LogBuffer.prototype.curIndex_; - - -/** - * Whether the buffer is at capacity. - * @type {boolean} - * @private - */ -goog.debug.LogBuffer.prototype.isFull_; - - -/** - * Adds a log record to the buffer, possibly overwriting the oldest record. - * @param {goog.debug.Logger.Level} level One of the level identifiers. - * @param {string} msg The string message. - * @param {string} loggerName The name of the source logger. - * @return {!goog.debug.LogRecord} The log record. - */ -goog.debug.LogBuffer.prototype.addRecord = function(level, msg, loggerName) { - var curIndex = (this.curIndex_ + 1) % goog.debug.LogBuffer.CAPACITY; - this.curIndex_ = curIndex; - if (this.isFull_) { - var ret = this.buffer_[curIndex]; - ret.reset(level, msg, loggerName); - return ret; - } - this.isFull_ = curIndex == goog.debug.LogBuffer.CAPACITY - 1; - return this.buffer_[curIndex] = - new goog.debug.LogRecord(level, msg, loggerName); -}; - - -/** - * @return {boolean} Whether the log buffer is enabled. - */ -goog.debug.LogBuffer.isBufferingEnabled = function() { - return goog.debug.LogBuffer.CAPACITY > 0; -}; - - -/** - * Removes all buffered log records. - */ -goog.debug.LogBuffer.prototype.clear = function() { - this.buffer_ = new Array(goog.debug.LogBuffer.CAPACITY); - this.curIndex_ = -1; - this.isFull_ = false; -}; - - -/** - * Calls the given function for each buffered log record, starting with the - * oldest one. - * @param {function(!goog.debug.LogRecord)} func The function to call. + * @param {function(this:SCOPE, ...?)} f Function to call. + * @param {number} interval Interval over which to debounce. The function will + * only be called after the full interval has elapsed since the last call. + * @param {SCOPE=} opt_scope Object in whose scope to call the function. + * @return {function(...?): undefined} Wrapped function. + * @template SCOPE */ -goog.debug.LogBuffer.prototype.forEachRecord = function(func) { - var buffer = this.buffer_; - // Corner case: no records. - if (!buffer[0]) { - return; +goog.functions.debounce = function(f, interval, opt_scope) { + if (opt_scope) { + f = goog.bind(f, opt_scope); } - var curIndex = this.curIndex_; - var i = this.isFull_ ? curIndex : -1; - do { - i = (i + 1) % goog.debug.LogBuffer.CAPACITY; - func(/** @type {!goog.debug.LogRecord} */ (buffer[i])); - } while (i != curIndex); -}; - - -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Definition of the Logger class. Please minimize dependencies - * this file has on other closure classes as any dependency it takes won't be - * able to use the logging infrastructure. - * - * @see ../demos/debug.html - */ - -goog.provide('goog.debug.LogManager'); -goog.provide('goog.debug.Loggable'); -goog.provide('goog.debug.Logger'); -goog.provide('goog.debug.Logger.Level'); - -goog.require('goog.array'); -goog.require('goog.asserts'); -goog.require('goog.debug'); -goog.require('goog.debug.LogBuffer'); -goog.require('goog.debug.LogRecord'); - - -/** - * A message value that can be handled by a Logger. - * - * Functions are treated like callbacks, but are only called when the event's - * log level is enabled. This is useful for logging messages that are expensive - * to construct. - * - * @typedef {string|function(): string} - */ -goog.debug.Loggable; - - - -/** - * The Logger is an object used for logging debug messages. Loggers are - * normally named, using a hierarchical dot-separated namespace. Logger names - * can be arbitrary strings, but they should normally be based on the package - * name or class name of the logged component, such as goog.net.BrowserChannel. - * - * The Logger object is loosely based on the java class - * java.util.logging.Logger. It supports different levels of filtering for - * different loggers. - * - * The logger object should never be instantiated by application code. It - * should always use the goog.debug.Logger.getLogger function. - * - * @constructor - * @param {string} name The name of the Logger. - * @final - */ -goog.debug.Logger = function(name) { - /** - * Name of the Logger. Generally a dot-separated namespace - * @private {string} - */ - this.name_ = name; - - /** - * Parent Logger. - * @private {goog.debug.Logger} - */ - this.parent_ = null; - - /** - * Level that this logger only filters above. Null indicates it should - * inherit from the parent. - * @private {goog.debug.Logger.Level} - */ - this.level_ = null; - - /** - * Map of children loggers. The keys are the leaf names of the children and - * the values are the child loggers. - * @private {Object} - */ - this.children_ = null; - - /** - * Handlers that are listening to this logger. - * @private {Array<Function>} - */ - this.handlers_ = null; + var timeout = null; + return /** @type {function(...?)} */ (function(var_args) { + goog.global.clearTimeout(timeout); + var args = arguments; + timeout = + goog.global.setTimeout(function() { f.apply(null, args); }, interval); + }); }; -/** @const */ -goog.debug.Logger.ROOT_LOGGER_NAME = ''; - - -/** - * @define {boolean} Toggles whether loggers other than the root logger can have - * log handlers attached to them and whether they can have their log level - * set. Logging is a bit faster when this is set to false. - */ -goog.define('goog.debug.Logger.ENABLE_HIERARCHY', true); - - -if (!goog.debug.Logger.ENABLE_HIERARCHY) { - /** - * @type {!Array<Function>} - * @private - */ - goog.debug.Logger.rootHandlers_ = []; - - - /** - * @type {goog.debug.Logger.Level} - * @private - */ - goog.debug.Logger.rootLevel_; -} - - - /** - * The Level class defines a set of standard logging levels that - * can be used to control logging output. The logging Level objects - * are ordered and are specified by ordered integers. Enabling logging - * at a given level also enables logging at all higher levels. - * <p> - * Clients should normally use the predefined Level constants such - * as Level.SEVERE. - * <p> - * The levels in descending order are: - * <ul> - * <li>SEVERE (highest value) - * <li>WARNING - * <li>INFO - * <li>CONFIG - * <li>FINE - * <li>FINER - * <li>FINEST (lowest value) - * </ul> - * In addition there is a level OFF that can be used to turn - * off logging, and a level ALL that can be used to enable - * logging of all messages. + * Wraps a function to allow it to be called, at most, once per interval + * (specified in milliseconds). If it is called multiple times while it is + * waiting, it will only perform the action once at the end of the interval, + * passing the arguments from the last call of the throttling decorator into the + * decorated function. * - * @param {string} name The name of the level. - * @param {number} value The numeric value of the level. - * @constructor - * @final - */ -goog.debug.Logger.Level = function(name, value) { - /** - * The name of the level - * @type {string} - */ - this.name = name; - - /** - * The numeric value of the level - * @type {number} - */ - this.value = value; -}; - - -/** - * @return {string} String representation of the logger level. - * @override - */ -goog.debug.Logger.Level.prototype.toString = function() { - return this.name; -}; - - -/** - * OFF is a special level that can be used to turn off logging. - * This level is initialized to <CODE>Infinity</CODE>. - * @type {!goog.debug.Logger.Level} - */ -goog.debug.Logger.Level.OFF = - new goog.debug.Logger.Level('OFF', Infinity); - - -/** - * SHOUT is a message level for extra debugging loudness. - * This level is initialized to <CODE>1200</CODE>. - * @type {!goog.debug.Logger.Level} - */ -goog.debug.Logger.Level.SHOUT = new goog.debug.Logger.Level('SHOUT', 1200); - - -/** - * SEVERE is a message level indicating a serious failure. - * This level is initialized to <CODE>1000</CODE>. - * @type {!goog.debug.Logger.Level} - */ -goog.debug.Logger.Level.SEVERE = new goog.debug.Logger.Level('SEVERE', 1000); - - -/** - * WARNING is a message level indicating a potential problem. - * This level is initialized to <CODE>900</CODE>. - * @type {!goog.debug.Logger.Level} - */ -goog.debug.Logger.Level.WARNING = new goog.debug.Logger.Level('WARNING', 900); - - -/** - * INFO is a message level for informational messages. - * This level is initialized to <CODE>800</CODE>. - * @type {!goog.debug.Logger.Level} - */ -goog.debug.Logger.Level.INFO = new goog.debug.Logger.Level('INFO', 800); - - -/** - * CONFIG is a message level for static configuration messages. - * This level is initialized to <CODE>700</CODE>. - * @type {!goog.debug.Logger.Level} - */ -goog.debug.Logger.Level.CONFIG = new goog.debug.Logger.Level('CONFIG', 700); - - -/** - * FINE is a message level providing tracing information. - * This level is initialized to <CODE>500</CODE>. - * @type {!goog.debug.Logger.Level} - */ -goog.debug.Logger.Level.FINE = new goog.debug.Logger.Level('FINE', 500); - - -/** - * FINER indicates a fairly detailed tracing message. - * This level is initialized to <CODE>400</CODE>. - * @type {!goog.debug.Logger.Level} - */ -goog.debug.Logger.Level.FINER = new goog.debug.Logger.Level('FINER', 400); - -/** - * FINEST indicates a highly detailed tracing message. - * This level is initialized to <CODE>300</CODE>. - * @type {!goog.debug.Logger.Level} - */ - -goog.debug.Logger.Level.FINEST = new goog.debug.Logger.Level('FINEST', 300); - - -/** - * ALL indicates that all messages should be logged. - * This level is initialized to <CODE>0</CODE>. - * @type {!goog.debug.Logger.Level} - */ -goog.debug.Logger.Level.ALL = new goog.debug.Logger.Level('ALL', 0); - - -/** - * The predefined levels. - * @type {!Array<!goog.debug.Logger.Level>} - * @final - */ -goog.debug.Logger.Level.PREDEFINED_LEVELS = [ - goog.debug.Logger.Level.OFF, - goog.debug.Logger.Level.SHOUT, - goog.debug.Logger.Level.SEVERE, - goog.debug.Logger.Level.WARNING, - goog.debug.Logger.Level.INFO, - goog.debug.Logger.Level.CONFIG, - goog.debug.Logger.Level.FINE, - goog.debug.Logger.Level.FINER, - goog.debug.Logger.Level.FINEST, - goog.debug.Logger.Level.ALL]; - - -/** - * A lookup map used to find the level object based on the name or value of - * the level object. - * @type {Object} - * @private - */ -goog.debug.Logger.Level.predefinedLevelsCache_ = null; - - -/** - * Creates the predefined levels cache and populates it. - * @private - */ -goog.debug.Logger.Level.createPredefinedLevelsCache_ = function() { - goog.debug.Logger.Level.predefinedLevelsCache_ = {}; - for (var i = 0, level; level = goog.debug.Logger.Level.PREDEFINED_LEVELS[i]; - i++) { - goog.debug.Logger.Level.predefinedLevelsCache_[level.value] = level; - goog.debug.Logger.Level.predefinedLevelsCache_[level.name] = level; - } -}; - - -/** - * Gets the predefined level with the given name. - * @param {string} name The name of the level. - * @return {goog.debug.Logger.Level} The level, or null if none found. - */ -goog.debug.Logger.Level.getPredefinedLevel = function(name) { - if (!goog.debug.Logger.Level.predefinedLevelsCache_) { - goog.debug.Logger.Level.createPredefinedLevelsCache_(); - } - - return goog.debug.Logger.Level.predefinedLevelsCache_[name] || null; -}; - - -/** - * Gets the highest predefined level <= #value. - * @param {number} value Level value. - * @return {goog.debug.Logger.Level} The level, or null if none found. - */ -goog.debug.Logger.Level.getPredefinedLevelByValue = function(value) { - if (!goog.debug.Logger.Level.predefinedLevelsCache_) { - goog.debug.Logger.Level.createPredefinedLevelsCache_(); - } - - if (value in goog.debug.Logger.Level.predefinedLevelsCache_) { - return goog.debug.Logger.Level.predefinedLevelsCache_[value]; - } - - for (var i = 0; i < goog.debug.Logger.Level.PREDEFINED_LEVELS.length; ++i) { - var level = goog.debug.Logger.Level.PREDEFINED_LEVELS[i]; - if (level.value <= value) { - return level; - } - } - return null; -}; - - -/** - * Finds or creates a logger for a named subsystem. If a logger has already been - * created with the given name it is returned. Otherwise a new logger is - * created. If a new logger is created its log level will be configured based - * on the LogManager configuration and it will configured to also send logging - * output to its parent's handlers. It will be registered in the LogManager - * global namespace. + * This is particularly useful for limiting repeated user requests (e.g. + * preventing a user from spamming a server with frequent view refreshes). For + * more stateful throttling with support for pausing, resuming, and canceling + * throttled actions, use {@code goog.async.Throttle}. * - * @param {string} name A name for the logger. This should be a dot-separated - * name and should normally be based on the package name or class name of the - * subsystem, such as goog.net.BrowserChannel. - * @return {!goog.debug.Logger} The named logger. - * @deprecated use goog.log instead. http://go/goog-debug-logger-deprecated - */ -goog.debug.Logger.getLogger = function(name) { - return goog.debug.LogManager.getLogger(name); -}; - - -/** - * Logs a message to profiling tools, if available. - * {@see https://developers.google.com/web-toolkit/speedtracer/logging-api} - * {@see http://msdn.microsoft.com/en-us/library/dd433074(VS.85).aspx} - * @param {string} msg The message to log. + * @param {function(this:SCOPE, ...?)} f Function to call. + * @param {number} interval Interval over which to throttle. The function can + * only be called once per interval. + * @param {SCOPE=} opt_scope Object in whose scope to call the function. + * @return {function(...?): undefined} Wrapped function. + * @template SCOPE */ -goog.debug.Logger.logToProfilers = function(msg) { - // Using goog.global, as loggers might be used in window-less contexts. - if (goog.global['console']) { - if (goog.global['console']['timeStamp']) { - // Logs a message to Firebug, Web Inspector, SpeedTracer, etc. - goog.global['console']['timeStamp'](msg); - } else if (goog.global['console']['markTimeline']) { - // TODO(user): markTimeline is deprecated. Drop this else clause entirely - // after Chrome M14 hits stable. - goog.global['console']['markTimeline'](msg); - } - } - - if (goog.global['msWriteProfilerMark']) { - // Logs a message to the Microsoft profiler - goog.global['msWriteProfilerMark'](msg); +goog.functions.throttle = function(f, interval, opt_scope) { + if (opt_scope) { + f = goog.bind(f, opt_scope); } -}; - - -/** - * Gets the name of this logger. - * @return {string} The name of this logger. - */ -goog.debug.Logger.prototype.getName = function() { - return this.name_; -}; - + var timeout = null; + var shouldFire = false; + var args = []; -/** - * Adds a handler to the logger. This doesn't use the event system because - * we want to be able to add logging to the event system. - * @param {Function} handler Handler function to add. - */ -goog.debug.Logger.prototype.addHandler = function(handler) { - if (goog.debug.LOGGING_ENABLED) { - if (goog.debug.Logger.ENABLE_HIERARCHY) { - if (!this.handlers_) { - this.handlers_ = []; - } - this.handlers_.push(handler); - } else { - goog.asserts.assert(!this.name_, - 'Cannot call addHandler on a non-root logger when ' + - 'goog.debug.Logger.ENABLE_HIERARCHY is false.'); - goog.debug.Logger.rootHandlers_.push(handler); + var handleTimeout = function() { + timeout = null; + if (shouldFire) { + shouldFire = false; + fire(); } - } -}; - - -/** - * Removes a handler from the logger. This doesn't use the event system because - * we want to be able to add logging to the event system. - * @param {Function} handler Handler function to remove. - * @return {boolean} Whether the handler was removed. - */ -goog.debug.Logger.prototype.removeHandler = function(handler) { - if (goog.debug.LOGGING_ENABLED) { - var handlers = goog.debug.Logger.ENABLE_HIERARCHY ? this.handlers_ : - goog.debug.Logger.rootHandlers_; - return !!handlers && goog.array.remove(handlers, handler); - } else { - return false; - } -}; - - -/** - * Returns the parent of this logger. - * @return {goog.debug.Logger} The parent logger or null if this is the root. - */ -goog.debug.Logger.prototype.getParent = function() { - return this.parent_; -}; - - -/** - * Returns the children of this logger as a map of the child name to the logger. - * @return {!Object} The map where the keys are the child leaf names and the - * values are the Logger objects. - */ -goog.debug.Logger.prototype.getChildren = function() { - if (!this.children_) { - this.children_ = {}; - } - return this.children_; -}; + }; + var fire = function() { + timeout = goog.global.setTimeout(handleTimeout, interval); + f.apply(null, args); + }; -/** - * Set the log level specifying which message levels will be logged by this - * logger. Message levels lower than this value will be discarded. - * The level value Level.OFF can be used to turn off logging. If the new level - * is null, it means that this node should inherit its level from its nearest - * ancestor with a specific (non-null) level value. - * - * @param {goog.debug.Logger.Level} level The new level. - */ -goog.debug.Logger.prototype.setLevel = function(level) { - if (goog.debug.LOGGING_ENABLED) { - if (goog.debug.Logger.ENABLE_HIERARCHY) { - this.level_ = level; + return /** @type {function(...?)} */ (function(var_args) { + args = arguments; + if (!timeout) { + fire(); } else { - goog.asserts.assert(!this.name_, - 'Cannot call setLevel() on a non-root logger when ' + - 'goog.debug.Logger.ENABLE_HIERARCHY is false.'); - goog.debug.Logger.rootLevel_ = level; - } - } -}; - - -/** - * Gets the log level specifying which message levels will be logged by this - * logger. Message levels lower than this value will be discarded. - * The level value Level.OFF can be used to turn off logging. If the level - * is null, it means that this node should inherit its level from its nearest - * ancestor with a specific (non-null) level value. - * - * @return {goog.debug.Logger.Level} The level. - */ -goog.debug.Logger.prototype.getLevel = function() { - return goog.debug.LOGGING_ENABLED ? - this.level_ : goog.debug.Logger.Level.OFF; -}; - - -/** - * Returns the effective level of the logger based on its ancestors' levels. - * @return {goog.debug.Logger.Level} The level. - */ -goog.debug.Logger.prototype.getEffectiveLevel = function() { - if (!goog.debug.LOGGING_ENABLED) { - return goog.debug.Logger.Level.OFF; - } - - if (!goog.debug.Logger.ENABLE_HIERARCHY) { - return goog.debug.Logger.rootLevel_; - } - if (this.level_) { - return this.level_; - } - if (this.parent_) { - return this.parent_.getEffectiveLevel(); - } - goog.asserts.fail('Root logger has no level set.'); - return null; -}; - - -/** - * Checks if a message of the given level would actually be logged by this - * logger. This check is based on the Loggers effective level, which may be - * inherited from its parent. - * @param {goog.debug.Logger.Level} level The level to check. - * @return {boolean} Whether the message would be logged. - */ -goog.debug.Logger.prototype.isLoggable = function(level) { - return goog.debug.LOGGING_ENABLED && - level.value >= this.getEffectiveLevel().value; -}; - - -/** - * Logs a message. If the logger is currently enabled for the - * given message level then the given message is forwarded to all the - * registered output Handler objects. - * @param {goog.debug.Logger.Level} level One of the level identifiers. - * @param {goog.debug.Loggable} msg The message to log. - * @param {Error|Object=} opt_exception An exception associated with the - * message. - */ -goog.debug.Logger.prototype.log = function(level, msg, opt_exception) { - // java caches the effective level, not sure it's necessary here - if (goog.debug.LOGGING_ENABLED && this.isLoggable(level)) { - // Message callbacks can be useful when a log message is expensive to build. - if (goog.isFunction(msg)) { - msg = msg(); - } - - this.doLogRecord_(this.getLogRecord(level, msg, opt_exception)); - } -}; - - -/** - * Creates a new log record and adds the exception (if present) to it. - * @param {goog.debug.Logger.Level} level One of the level identifiers. - * @param {string} msg The string message. - * @param {Error|Object=} opt_exception An exception associated with the - * message. - * @return {!goog.debug.LogRecord} A log record. - * @suppress {es5Strict} - */ -goog.debug.Logger.prototype.getLogRecord = function( - level, msg, opt_exception) { - if (goog.debug.LogBuffer.isBufferingEnabled()) { - var logRecord = - goog.debug.LogBuffer.getInstance().addRecord(level, msg, this.name_); - } else { - logRecord = new goog.debug.LogRecord(level, String(msg), this.name_); - } - if (opt_exception) { - logRecord.setException(opt_exception); - } - return logRecord; -}; - - -/** - * Logs a message at the Logger.Level.SHOUT level. - * If the logger is currently enabled for the given message level then the - * given message is forwarded to all the registered output Handler objects. - * @param {goog.debug.Loggable} msg The message to log. - * @param {Error=} opt_exception An exception associated with the message. - */ -goog.debug.Logger.prototype.shout = function(msg, opt_exception) { - if (goog.debug.LOGGING_ENABLED) { - this.log(goog.debug.Logger.Level.SHOUT, msg, opt_exception); - } -}; - - -/** - * Logs a message at the Logger.Level.SEVERE level. - * If the logger is currently enabled for the given message level then the - * given message is forwarded to all the registered output Handler objects. - * @param {goog.debug.Loggable} msg The message to log. - * @param {Error=} opt_exception An exception associated with the message. - */ -goog.debug.Logger.prototype.severe = function(msg, opt_exception) { - if (goog.debug.LOGGING_ENABLED) { - this.log(goog.debug.Logger.Level.SEVERE, msg, opt_exception); - } -}; - - -/** - * Logs a message at the Logger.Level.WARNING level. - * If the logger is currently enabled for the given message level then the - * given message is forwarded to all the registered output Handler objects. - * @param {goog.debug.Loggable} msg The message to log. - * @param {Error=} opt_exception An exception associated with the message. - */ -goog.debug.Logger.prototype.warning = function(msg, opt_exception) { - if (goog.debug.LOGGING_ENABLED) { - this.log(goog.debug.Logger.Level.WARNING, msg, opt_exception); - } -}; - - -/** - * Logs a message at the Logger.Level.INFO level. - * If the logger is currently enabled for the given message level then the - * given message is forwarded to all the registered output Handler objects. - * @param {goog.debug.Loggable} msg The message to log. - * @param {Error=} opt_exception An exception associated with the message. - */ -goog.debug.Logger.prototype.info = function(msg, opt_exception) { - if (goog.debug.LOGGING_ENABLED) { - this.log(goog.debug.Logger.Level.INFO, msg, opt_exception); - } -}; - - -/** - * Logs a message at the Logger.Level.CONFIG level. - * If the logger is currently enabled for the given message level then the - * given message is forwarded to all the registered output Handler objects. - * @param {goog.debug.Loggable} msg The message to log. - * @param {Error=} opt_exception An exception associated with the message. - */ -goog.debug.Logger.prototype.config = function(msg, opt_exception) { - if (goog.debug.LOGGING_ENABLED) { - this.log(goog.debug.Logger.Level.CONFIG, msg, opt_exception); - } -}; - - -/** - * Logs a message at the Logger.Level.FINE level. - * If the logger is currently enabled for the given message level then the - * given message is forwarded to all the registered output Handler objects. - * @param {goog.debug.Loggable} msg The message to log. - * @param {Error=} opt_exception An exception associated with the message. - */ -goog.debug.Logger.prototype.fine = function(msg, opt_exception) { - if (goog.debug.LOGGING_ENABLED) { - this.log(goog.debug.Logger.Level.FINE, msg, opt_exception); - } -}; - - -/** - * Logs a message at the Logger.Level.FINER level. - * If the logger is currently enabled for the given message level then the - * given message is forwarded to all the registered output Handler objects. - * @param {goog.debug.Loggable} msg The message to log. - * @param {Error=} opt_exception An exception associated with the message. - */ -goog.debug.Logger.prototype.finer = function(msg, opt_exception) { - if (goog.debug.LOGGING_ENABLED) { - this.log(goog.debug.Logger.Level.FINER, msg, opt_exception); - } -}; - - -/** - * Logs a message at the Logger.Level.FINEST level. - * If the logger is currently enabled for the given message level then the - * given message is forwarded to all the registered output Handler objects. - * @param {goog.debug.Loggable} msg The message to log. - * @param {Error=} opt_exception An exception associated with the message. - */ -goog.debug.Logger.prototype.finest = function(msg, opt_exception) { - if (goog.debug.LOGGING_ENABLED) { - this.log(goog.debug.Logger.Level.FINEST, msg, opt_exception); - } -}; - - -/** - * Logs a LogRecord. If the logger is currently enabled for the - * given message level then the given message is forwarded to all the - * registered output Handler objects. - * @param {goog.debug.LogRecord} logRecord A log record to log. - */ -goog.debug.Logger.prototype.logRecord = function(logRecord) { - if (goog.debug.LOGGING_ENABLED && this.isLoggable(logRecord.getLevel())) { - this.doLogRecord_(logRecord); - } -}; - - -/** - * Logs a LogRecord. - * @param {goog.debug.LogRecord} logRecord A log record to log. - * @private - */ -goog.debug.Logger.prototype.doLogRecord_ = function(logRecord) { - goog.debug.Logger.logToProfilers('log:' + logRecord.getMessage()); - if (goog.debug.Logger.ENABLE_HIERARCHY) { - var target = this; - while (target) { - target.callPublish_(logRecord); - target = target.getParent(); - } - } else { - for (var i = 0, handler; handler = goog.debug.Logger.rootHandlers_[i++]; ) { - handler(logRecord); - } - } -}; - - -/** - * Calls the handlers for publish. - * @param {goog.debug.LogRecord} logRecord The log record to publish. - * @private - */ -goog.debug.Logger.prototype.callPublish_ = function(logRecord) { - if (this.handlers_) { - for (var i = 0, handler; handler = this.handlers_[i]; i++) { - handler(logRecord); + shouldFire = true; } - } -}; - - -/** - * Sets the parent of this logger. This is used for setting up the logger tree. - * @param {goog.debug.Logger} parent The parent logger. - * @private - */ -goog.debug.Logger.prototype.setParent_ = function(parent) { - this.parent_ = parent; -}; - - -/** - * Adds a child to this logger. This is used for setting up the logger tree. - * @param {string} name The leaf name of the child. - * @param {goog.debug.Logger} logger The child logger. - * @private - */ -goog.debug.Logger.prototype.addChild_ = function(name, logger) { - this.getChildren()[name] = logger; -}; - - -/** - * There is a single global LogManager object that is used to maintain a set of - * shared state about Loggers and log services. This is loosely based on the - * java class java.util.logging.LogManager. - * @const - */ -goog.debug.LogManager = {}; - - -/** - * Map of logger names to logger objects. - * - * @type {!Object<string, !goog.debug.Logger>} - * @private - */ -goog.debug.LogManager.loggers_ = {}; - - -/** - * The root logger which is the root of the logger tree. - * @type {goog.debug.Logger} - * @private - */ -goog.debug.LogManager.rootLogger_ = null; - - -/** - * Initializes the LogManager if not already initialized. - */ -goog.debug.LogManager.initialize = function() { - if (!goog.debug.LogManager.rootLogger_) { - goog.debug.LogManager.rootLogger_ = new goog.debug.Logger( - goog.debug.Logger.ROOT_LOGGER_NAME); - goog.debug.LogManager.loggers_[goog.debug.Logger.ROOT_LOGGER_NAME] = - goog.debug.LogManager.rootLogger_; - goog.debug.LogManager.rootLogger_.setLevel(goog.debug.Logger.Level.CONFIG); - } -}; - - -/** - * Returns all the loggers. - * @return {!Object<string, !goog.debug.Logger>} Map of logger names to logger - * objects. - */ -goog.debug.LogManager.getLoggers = function() { - return goog.debug.LogManager.loggers_; -}; - - -/** - * Returns the root of the logger tree namespace, the logger with the empty - * string as its name. - * - * @return {!goog.debug.Logger} The root logger. - */ -goog.debug.LogManager.getRoot = function() { - goog.debug.LogManager.initialize(); - return /** @type {!goog.debug.Logger} */ (goog.debug.LogManager.rootLogger_); -}; - - -/** - * Finds a named logger. - * - * @param {string} name A name for the logger. This should be a dot-separated - * name and should normally be based on the package name or class name of the - * subsystem, such as goog.net.BrowserChannel. - * @return {!goog.debug.Logger} The named logger. - */ -goog.debug.LogManager.getLogger = function(name) { - goog.debug.LogManager.initialize(); - var ret = goog.debug.LogManager.loggers_[name]; - return ret || goog.debug.LogManager.createLogger_(name); -}; - - -/** - * Creates a function that can be passed to goog.debug.catchErrors. The function - * will log all reported errors using the given logger. - * @param {goog.debug.Logger=} opt_logger The logger to log the errors to. - * Defaults to the root logger. - * @return {function(Object)} The created function. - */ -goog.debug.LogManager.createFunctionForCatchErrors = function(opt_logger) { - return function(info) { - var logger = opt_logger || goog.debug.LogManager.getRoot(); - logger.severe('Error: ' + info.message + ' (' + info.fileName + - ' @ Line: ' + info.line + ')'); - }; -}; - - -/** - * Creates the named logger. Will also create the parents of the named logger - * if they don't yet exist. - * @param {string} name The name of the logger. - * @return {!goog.debug.Logger} The named logger. - * @private - */ -goog.debug.LogManager.createLogger_ = function(name) { - // find parent logger - var logger = new goog.debug.Logger(name); - if (goog.debug.Logger.ENABLE_HIERARCHY) { - var lastDotIndex = name.lastIndexOf('.'); - var parentName = name.substr(0, lastDotIndex); - var leafName = name.substr(lastDotIndex + 1); - var parentLogger = goog.debug.LogManager.getLogger(parentName); - - // tell the parent about the child and the child about the parent - parentLogger.addChild_(leafName, logger); - logger.setParent_(parentLogger); - } - - goog.debug.LogManager.loggers_[name] = logger; - return logger; -}; - -// Copyright 2007 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Definition the goog.debug.RelativeTimeProvider class. - * - */ - -goog.provide('goog.debug.RelativeTimeProvider'); - - - -/** - * A simple object to keep track of a timestamp considered the start of - * something. The main use is for the logger system to maintain a start time - * that is occasionally reset. For example, in Gmail, we reset this relative - * time at the start of a user action so that timings are offset from the - * beginning of the action. This class also provides a singleton as the default - * behavior for most use cases is to share the same start time. - * - * @constructor - * @final - */ -goog.debug.RelativeTimeProvider = function() { - /** - * The start time. - * @type {number} - * @private - */ - this.relativeTimeStart_ = goog.now(); -}; - - -/** - * Default instance. - * @type {goog.debug.RelativeTimeProvider} - * @private - */ -goog.debug.RelativeTimeProvider.defaultInstance_ = - new goog.debug.RelativeTimeProvider(); - - -/** - * Sets the start time to the specified time. - * @param {number} timeStamp The start time. - */ -goog.debug.RelativeTimeProvider.prototype.set = function(timeStamp) { - this.relativeTimeStart_ = timeStamp; -}; - - -/** - * Resets the start time to now. - */ -goog.debug.RelativeTimeProvider.prototype.reset = function() { - this.set(goog.now()); -}; - - -/** - * @return {number} The start time. - */ -goog.debug.RelativeTimeProvider.prototype.get = function() { - return this.relativeTimeStart_; -}; - - -/** - * @return {goog.debug.RelativeTimeProvider} The default instance. - */ -goog.debug.RelativeTimeProvider.getDefaultInstance = function() { - return goog.debug.RelativeTimeProvider.defaultInstance_; + }); }; -// Copyright 2006 The Closure Library Authors. All Rights Reserved. +// Copyright 2013 The Closure Library Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -44853,2232 +37730,253 @@ goog.debug.RelativeTimeProvider.getDefaultInstance = function() { // limitations under the License. /** - * @fileoverview Definition of various formatters for logging. Please minimize - * dependencies this file has on other closure classes as any dependency it - * takes won't be able to use the logging infrastructure. - * - */ - -goog.provide('goog.debug.Formatter'); -goog.provide('goog.debug.HtmlFormatter'); -goog.provide('goog.debug.TextFormatter'); - -goog.require('goog.debug'); -goog.require('goog.debug.Logger'); -goog.require('goog.debug.RelativeTimeProvider'); -goog.require('goog.html.SafeHtml'); - - - -/** - * Base class for Formatters. A Formatter is used to format a LogRecord into - * something that can be displayed to the user. - * - * @param {string=} opt_prefix The prefix to place before text records. - * @constructor - */ -goog.debug.Formatter = function(opt_prefix) { - this.prefix_ = opt_prefix || ''; - - /** - * A provider that returns the relative start time. - * @type {goog.debug.RelativeTimeProvider} - * @private - */ - this.startTimeProvider_ = - goog.debug.RelativeTimeProvider.getDefaultInstance(); -}; - - -/** - * Whether to append newlines to the end of formatted log records. - * @type {boolean} - */ -goog.debug.Formatter.prototype.appendNewline = true; - - -/** - * Whether to show absolute time in the DebugWindow. - * @type {boolean} - */ -goog.debug.Formatter.prototype.showAbsoluteTime = true; - - -/** - * Whether to show relative time in the DebugWindow. - * @type {boolean} - */ -goog.debug.Formatter.prototype.showRelativeTime = true; - - -/** - * Whether to show the logger name in the DebugWindow. - * @type {boolean} - */ -goog.debug.Formatter.prototype.showLoggerName = true; - - -/** - * Whether to show the logger exception text. - * @type {boolean} - */ -goog.debug.Formatter.prototype.showExceptionText = false; - - -/** - * Whether to show the severity level. - * @type {boolean} - */ -goog.debug.Formatter.prototype.showSeverityLevel = false; - - -/** - * Formats a record. - * @param {goog.debug.LogRecord} logRecord the logRecord to format. - * @return {string} The formatted string. - */ -goog.debug.Formatter.prototype.formatRecord = goog.abstractMethod; - - -/** - * Formats a record as SafeHtml. - * @param {goog.debug.LogRecord} logRecord the logRecord to format. - * @return {!goog.html.SafeHtml} The formatted string as SafeHtml. - */ -goog.debug.Formatter.prototype.formatRecordAsHtml = goog.abstractMethod; - - -/** - * Sets the start time provider. By default, this is the default instance - * but can be changed. - * @param {goog.debug.RelativeTimeProvider} provider The provider to use. - */ -goog.debug.Formatter.prototype.setStartTimeProvider = function(provider) { - this.startTimeProvider_ = provider; -}; - - -/** - * Returns the start time provider. By default, this is the default instance - * but can be changed. - * @return {goog.debug.RelativeTimeProvider} The start time provider. - */ -goog.debug.Formatter.prototype.getStartTimeProvider = function() { - return this.startTimeProvider_; -}; - - -/** - * Resets the start relative time. - */ -goog.debug.Formatter.prototype.resetRelativeTimeStart = function() { - this.startTimeProvider_.reset(); -}; - - -/** - * Returns a string for the time/date of the LogRecord. - * @param {goog.debug.LogRecord} logRecord The record to get a time stamp for. - * @return {string} A string representation of the time/date of the LogRecord. - * @private - */ -goog.debug.Formatter.getDateTimeStamp_ = function(logRecord) { - var time = new Date(logRecord.getMillis()); - return goog.debug.Formatter.getTwoDigitString_((time.getFullYear() - 2000)) + - goog.debug.Formatter.getTwoDigitString_((time.getMonth() + 1)) + - goog.debug.Formatter.getTwoDigitString_(time.getDate()) + ' ' + - goog.debug.Formatter.getTwoDigitString_(time.getHours()) + ':' + - goog.debug.Formatter.getTwoDigitString_(time.getMinutes()) + ':' + - goog.debug.Formatter.getTwoDigitString_(time.getSeconds()) + '.' + - goog.debug.Formatter.getTwoDigitString_( - Math.floor(time.getMilliseconds() / 10)); -}; - - -/** - * Returns the number as a two-digit string, meaning it prepends a 0 if the - * number if less than 10. - * @param {number} n The number to format. - * @return {string} A two-digit string representation of {@code n}. - * @private - */ -goog.debug.Formatter.getTwoDigitString_ = function(n) { - if (n < 10) { - return '0' + n; - } - return String(n); -}; - - -/** - * Returns a string for the number of seconds relative to the start time. - * Prepads with spaces so that anything less than 1000 seconds takes up the - * same number of characters for better formatting. - * @param {goog.debug.LogRecord} logRecord The log to compare time to. - * @param {number} relativeTimeStart The start time to compare to. - * @return {string} The number of seconds of the LogRecord relative to the - * start time. - * @private - */ -goog.debug.Formatter.getRelativeTime_ = function(logRecord, - relativeTimeStart) { - var ms = logRecord.getMillis() - relativeTimeStart; - var sec = ms / 1000; - var str = sec.toFixed(3); - - var spacesToPrepend = 0; - if (sec < 1) { - spacesToPrepend = 2; - } else { - while (sec < 100) { - spacesToPrepend++; - sec *= 10; - } - } - while (spacesToPrepend-- > 0) { - str = ' ' + str; - } - return str; -}; - - - -/** - * Formatter that returns formatted html. See formatRecord for the classes - * it uses for various types of formatted output. - * - * @param {string=} opt_prefix The prefix to place before text records. - * @constructor - * @extends {goog.debug.Formatter} - */ -goog.debug.HtmlFormatter = function(opt_prefix) { - goog.debug.Formatter.call(this, opt_prefix); -}; -goog.inherits(goog.debug.HtmlFormatter, goog.debug.Formatter); - - -/** - * Whether to show the logger exception text - * @type {boolean} - * @override - */ -goog.debug.HtmlFormatter.prototype.showExceptionText = true; - - -/** - * Formats a record - * @param {goog.debug.LogRecord} logRecord the logRecord to format. - * @return {string} The formatted string as html. - * @override - */ -goog.debug.HtmlFormatter.prototype.formatRecord = function(logRecord) { - if (!logRecord) { - return ''; - } - // OK not to use goog.html.SafeHtml.unwrap() here. - return this.formatRecordAsHtml(logRecord).getTypedStringValue(); -}; - - -/** - * Formats a record. - * @param {goog.debug.LogRecord} logRecord the logRecord to format. - * @return {!goog.html.SafeHtml} The formatted string as SafeHtml. - * @override - */ -goog.debug.HtmlFormatter.prototype.formatRecordAsHtml = function(logRecord) { - if (!logRecord) { - return goog.html.SafeHtml.EMPTY; - } - - var className; - switch (logRecord.getLevel().value) { - case goog.debug.Logger.Level.SHOUT.value: - className = 'dbg-sh'; - break; - case goog.debug.Logger.Level.SEVERE.value: - className = 'dbg-sev'; - break; - case goog.debug.Logger.Level.WARNING.value: - className = 'dbg-w'; - break; - case goog.debug.Logger.Level.INFO.value: - className = 'dbg-i'; - break; - case goog.debug.Logger.Level.FINE.value: - default: - className = 'dbg-f'; - break; - } - - // HTML for user defined prefix, time, logger name, and severity. - var sb = []; - sb.push(this.prefix_, ' '); - if (this.showAbsoluteTime) { - sb.push('[', goog.debug.Formatter.getDateTimeStamp_(logRecord), '] '); - } - if (this.showRelativeTime) { - sb.push('[', - goog.debug.Formatter.getRelativeTime_( - logRecord, this.startTimeProvider_.get()), - 's] '); - } - if (this.showLoggerName) { - sb.push('[', logRecord.getLoggerName(), '] '); - } - if (this.showSeverityLevel) { - sb.push('[', logRecord.getLevel().name, '] '); - } - var fullPrefixHtml = - goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces(sb.join('')); - - // HTML for exception text and log record. - var exceptionHtml = goog.html.SafeHtml.EMPTY; - if (this.showExceptionText && logRecord.getException()) { - exceptionHtml = goog.html.SafeHtml.concat( - goog.html.SafeHtml.create('br'), - goog.debug.exposeExceptionAsHtml(logRecord.getException())); - } - var logRecordHtml = goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces( - logRecord.getMessage()); - var recordAndExceptionHtml = goog.html.SafeHtml.create( - 'span', - {'class': className}, - goog.html.SafeHtml.concat(logRecordHtml, exceptionHtml)); - - - // Combine both pieces of HTML and, if needed, append a final newline. - var html; - if (this.appendNewline) { - html = goog.html.SafeHtml.concat(fullPrefixHtml, recordAndExceptionHtml, - goog.html.SafeHtml.create('br')); - } else { - html = goog.html.SafeHtml.concat(fullPrefixHtml, recordAndExceptionHtml); - } - return html; -}; - - - -/** - * Formatter that returns formatted plain text + * @fileoverview Provides a function to schedule running a function as soon + * as possible after the current JS execution stops and yields to the event + * loop. * - * @param {string=} opt_prefix The prefix to place before text records. - * @constructor - * @extends {goog.debug.Formatter} - * @final */ -goog.debug.TextFormatter = function(opt_prefix) { - goog.debug.Formatter.call(this, opt_prefix); -}; -goog.inherits(goog.debug.TextFormatter, goog.debug.Formatter); +goog.provide('goog.async.nextTick'); +goog.provide('goog.async.throwException'); -/** - * Formats a record as text - * @param {goog.debug.LogRecord} logRecord the logRecord to format. - * @return {string} The formatted string. - * @override - */ -goog.debug.TextFormatter.prototype.formatRecord = function(logRecord) { - var sb = []; - sb.push(this.prefix_, ' '); - if (this.showAbsoluteTime) { - sb.push('[', goog.debug.Formatter.getDateTimeStamp_(logRecord), '] '); - } - if (this.showRelativeTime) { - sb.push('[', goog.debug.Formatter.getRelativeTime_(logRecord, - this.startTimeProvider_.get()), 's] '); - } - - if (this.showLoggerName) { - sb.push('[', logRecord.getLoggerName(), '] '); - } - if (this.showSeverityLevel) { - sb.push('[', logRecord.getLevel().name, '] '); - } - sb.push(logRecord.getMessage()); - if (this.showExceptionText) { - var exception = logRecord.getException(); - if (exception) { - var exceptionText = exception instanceof Error ? - exception.message : - exception.toString(); - sb.push('\n', exceptionText); - } - } - if (this.appendNewline) { - sb.push('\n'); - } - return sb.join(''); -}; +goog.require('goog.debug.entryPointRegistry'); +goog.require('goog.dom.TagName'); +goog.require('goog.functions'); +goog.require('goog.labs.userAgent.browser'); +goog.require('goog.labs.userAgent.engine'); /** - * Formats a record as text - * @param {goog.debug.LogRecord} logRecord the logRecord to format. - * @return {!goog.html.SafeHtml} The formatted string as SafeHtml. This is - * just an HTML-escaped version of the text obtained from formatRecord(). - * @override + * Throw an item without interrupting the current execution context. For + * example, if processing a group of items in a loop, sometimes it is useful + * to report an error while still allowing the rest of the batch to be + * processed. + * @param {*} exception */ -goog.debug.TextFormatter.prototype.formatRecordAsHtml = function(logRecord) { - return goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces( - goog.debug.TextFormatter.prototype.formatRecord(logRecord)); +goog.async.throwException = function(exception) { + // Each throw needs to be in its own context. + goog.global.setTimeout(function() { throw exception; }, 0); }; -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. /** - * @fileoverview Simple logger that logs to the window console if available. + * Fires the provided callbacks as soon as possible after the current JS + * execution context. setTimeout(…, 0) takes at least 4ms when called from + * within another setTimeout(…, 0) for legacy reasons. * - * Has an autoInstall option which can be put into initialization code, which - * will start logging if "Debug=true" is in document.location.href + * This will not schedule the callback as a microtask (i.e. a task that can + * preempt user input or networking callbacks). It is meant to emulate what + * setTimeout(_, 0) would do if it were not throttled. If you desire microtask + * behavior, use {@see goog.Promise} instead. * + * @param {function(this:SCOPE)} callback Callback function to fire as soon as + * possible. + * @param {SCOPE=} opt_context Object in whose scope to call the listener. + * @param {boolean=} opt_useSetImmediate Avoid the IE workaround that + * ensures correctness at the cost of speed. See comments for details. + * @template SCOPE */ - -goog.provide('goog.debug.Console'); - -goog.require('goog.debug.LogManager'); -goog.require('goog.debug.Logger'); -goog.require('goog.debug.TextFormatter'); - - - -/** - * Create and install a log handler that logs to window.console if available - * @constructor - */ -goog.debug.Console = function() { - this.publishHandler_ = goog.bind(this.addLogRecord, this); - - /** - * Formatter for formatted output. - * @type {!goog.debug.TextFormatter} - * @private - */ - this.formatter_ = new goog.debug.TextFormatter(); - this.formatter_.showAbsoluteTime = false; - this.formatter_.showExceptionText = false; - // The console logging methods automatically append a newline. - this.formatter_.appendNewline = false; - - this.isCapturing_ = false; - this.logBuffer_ = ''; - - /** - * Loggers that we shouldn't output. - * @type {!Object<boolean>} - * @private - */ - this.filteredLoggers_ = {}; -}; - - -/** - * Returns the text formatter used by this console - * @return {!goog.debug.TextFormatter} The text formatter. - */ -goog.debug.Console.prototype.getFormatter = function() { - return this.formatter_; -}; - - -/** - * Sets whether we are currently capturing logger output. - * @param {boolean} capturing Whether to capture logger output. - */ -goog.debug.Console.prototype.setCapturing = function(capturing) { - if (capturing == this.isCapturing_) { - return; - } - - // attach or detach handler from the root logger - var rootLogger = goog.debug.LogManager.getRoot(); - if (capturing) { - rootLogger.addHandler(this.publishHandler_); - } else { - rootLogger.removeHandler(this.publishHandler_); - this.logBuffer = ''; +goog.async.nextTick = function(callback, opt_context, opt_useSetImmediate) { + var cb = callback; + if (opt_context) { + cb = goog.bind(callback, opt_context); } - this.isCapturing_ = capturing; -}; - - -/** - * Adds a log record. - * @param {goog.debug.LogRecord} logRecord The log entry. - */ -goog.debug.Console.prototype.addLogRecord = function(logRecord) { - - // Check to see if the log record is filtered or not. - if (this.filteredLoggers_[logRecord.getLoggerName()]) { + cb = goog.async.nextTick.wrapCallback_(cb); + // Note we do allow callers to also request setImmediate if they are willing + // to accept the possible tradeoffs of incorrectness in exchange for speed. + // The IE fallback of readystate change is much slower. See useSetImmediate_ + // for details. + if (goog.isFunction(goog.global.setImmediate) && + (opt_useSetImmediate || goog.async.nextTick.useSetImmediate_())) { + goog.global.setImmediate(cb); return; } - var record = this.formatter_.formatRecord(logRecord); - var console = goog.debug.Console.console_; - if (console) { - switch (logRecord.getLevel()) { - case goog.debug.Logger.Level.SHOUT: - goog.debug.Console.logToConsole_(console, 'info', record); - break; - case goog.debug.Logger.Level.SEVERE: - goog.debug.Console.logToConsole_(console, 'error', record); - break; - case goog.debug.Logger.Level.WARNING: - goog.debug.Console.logToConsole_(console, 'warn', record); - break; - default: - goog.debug.Console.logToConsole_(console, 'debug', record); - break; - } - } else { - this.logBuffer_ += record; - } -}; - - -/** - * Adds a logger name to be filtered. - * @param {string} loggerName the logger name to add. - */ -goog.debug.Console.prototype.addFilter = function(loggerName) { - this.filteredLoggers_[loggerName] = true; -}; - - -/** - * Removes a logger name to be filtered. - * @param {string} loggerName the logger name to remove. - */ -goog.debug.Console.prototype.removeFilter = function(loggerName) { - delete this.filteredLoggers_[loggerName]; -}; - - -/** - * Global console logger instance - * @type {goog.debug.Console} - */ -goog.debug.Console.instance = null; - - -/** - * The console to which to log. This is a property so it can be mocked out in - * this unit test for goog.debug.Console. Using goog.global, as console might be - * used in window-less contexts. - * @type {Object} - * @private - */ -goog.debug.Console.console_ = goog.global['console']; - - -/** - * Sets the console to which to log. - * @param {!Object} console The console to which to log. - */ -goog.debug.Console.setConsole = function(console) { - goog.debug.Console.console_ = console; -}; - - -/** - * Install the console and start capturing if "Debug=true" is in the page URL - */ -goog.debug.Console.autoInstall = function() { - if (!goog.debug.Console.instance) { - goog.debug.Console.instance = new goog.debug.Console(); - } - - if (goog.global.location && - goog.global.location.href.indexOf('Debug=true') != -1) { - goog.debug.Console.instance.setCapturing(true); - } -}; - - -/** - * Show an alert with all of the captured debug information. - * Information is only captured if console is not available - */ -goog.debug.Console.show = function() { - alert(goog.debug.Console.instance.logBuffer_); -}; - - -/** - * Logs the record to the console using the given function. If the function is - * not available on the console object, the log function is used instead. - * @param {!Object} console The console object. - * @param {string} fnName The name of the function to use. - * @param {string} record The record to log. - * @private - */ -goog.debug.Console.logToConsole_ = function(console, fnName, record) { - if (console[fnName]) { - console[fnName](record); - } else { - console.log(record); + // Look for and cache the custom fallback version of setImmediate. + if (!goog.async.nextTick.setImmediate_) { + goog.async.nextTick.setImmediate_ = + goog.async.nextTick.getSetImmediateEmulator_(); } + goog.async.nextTick.setImmediate_(cb); }; -// Copyright 2007 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Utility class that monitors viewport size changes. - * - * @author attila@google.com (Attila Bodis) - * @see ../demos/viewportsizemonitor.html - */ - -goog.provide('goog.dom.ViewportSizeMonitor'); - -goog.require('goog.dom'); -goog.require('goog.events'); -goog.require('goog.events.EventTarget'); -goog.require('goog.events.EventType'); -goog.require('goog.math.Size'); - - /** - * This class can be used to monitor changes in the viewport size. Instances - * dispatch a {@link goog.events.EventType.RESIZE} event when the viewport size - * changes. Handlers can call {@link goog.dom.ViewportSizeMonitor#getSize} to - * get the new viewport size. - * - * Use this class if you want to execute resize/reflow logic each time the - * user resizes the browser window. This class is guaranteed to only dispatch - * {@code RESIZE} events when the pixel dimensions of the viewport change. - * (Internet Explorer fires resize events if any element on the page is resized, - * even if the viewport dimensions are unchanged, which can lead to infinite - * resize loops.) + * Returns whether should use setImmediate implementation currently on window. * - * Example usage: - * <pre> - * var vsm = new goog.dom.ViewportSizeMonitor(); - * goog.events.listen(vsm, goog.events.EventType.RESIZE, function(e) { - * alert('Viewport size changed to ' + vsm.getSize()); - * }); - * </pre> - * - * Manually verified on IE6, IE7, FF2, Opera 11, Safari 4 and Chrome. + * window.setImmediate was introduced and currently only supported by IE10+, + * but due to a bug in the implementation it is not guaranteed that + * setImmediate is faster than setTimeout nor that setImmediate N is before + * setImmediate N+1. That is why we do not use the native version if + * available. We do, however, call setImmediate if it is a non-native function + * because that indicates that it has been replaced by goog.testing.MockClock + * which we do want to support. + * See + * http://connect.microsoft.com/IE/feedback/details/801823/setimmediate-and-messagechannel-are-broken-in-ie10 * - * @param {Window=} opt_window The window to monitor; defaults to the window in - * which this code is executing. - * @constructor - * @extends {goog.events.EventTarget} - */ -goog.dom.ViewportSizeMonitor = function(opt_window) { - goog.dom.ViewportSizeMonitor.base(this, 'constructor'); - - /** - * The window to monitor. Defaults to the window in which the code is running. - * @private {Window} - */ - this.window_ = opt_window || window; - - /** - * Event listener key for window the window resize handler, as returned by - * {@link goog.events.listen}. - * @private {goog.events.Key} - */ - this.listenerKey_ = goog.events.listen(this.window_, - goog.events.EventType.RESIZE, this.handleResize_, false, this); - - /** - * The most recently recorded size of the viewport, in pixels. - * @private {goog.math.Size} - */ - this.size_ = goog.dom.getViewportSize(this.window_); -}; -goog.inherits(goog.dom.ViewportSizeMonitor, goog.events.EventTarget); - - -/** - * Returns a viewport size monitor for the given window. A new one is created - * if it doesn't exist already. This prevents the unnecessary creation of - * multiple spooling monitors for a window. - * @param {Window=} opt_window The window to monitor; defaults to the window in - * which this code is executing. - * @return {!goog.dom.ViewportSizeMonitor} Monitor for the given window. - */ -goog.dom.ViewportSizeMonitor.getInstanceForWindow = function(opt_window) { - var currentWindow = opt_window || window; - var uid = goog.getUid(currentWindow); - - return goog.dom.ViewportSizeMonitor.windowInstanceMap_[uid] = - goog.dom.ViewportSizeMonitor.windowInstanceMap_[uid] || - new goog.dom.ViewportSizeMonitor(currentWindow); -}; - - -/** - * Removes and disposes a viewport size monitor for the given window if one - * exists. - * @param {Window=} opt_window The window whose monitor should be removed; - * defaults to the window in which this code is executing. - */ -goog.dom.ViewportSizeMonitor.removeInstanceForWindow = function(opt_window) { - var uid = goog.getUid(opt_window || window); - - goog.dispose(goog.dom.ViewportSizeMonitor.windowInstanceMap_[uid]); - delete goog.dom.ViewportSizeMonitor.windowInstanceMap_[uid]; -}; - - -/** - * Map of window hash code to viewport size monitor for that window, if - * created. - * @type {Object<number,goog.dom.ViewportSizeMonitor>} + * @return {boolean} Whether to use the implementation of setImmediate defined + * on Window. * @private */ -goog.dom.ViewportSizeMonitor.windowInstanceMap_ = {}; - - -/** - * Returns the most recently recorded size of the viewport, in pixels. May - * return null if no window resize event has been handled yet. - * @return {goog.math.Size} The viewport dimensions, in pixels. - */ -goog.dom.ViewportSizeMonitor.prototype.getSize = function() { - // Return a clone instead of the original to preserve encapsulation. - return this.size_ ? this.size_.clone() : null; -}; - - -/** @override */ -goog.dom.ViewportSizeMonitor.prototype.disposeInternal = function() { - goog.dom.ViewportSizeMonitor.superClass_.disposeInternal.call(this); - - if (this.listenerKey_) { - goog.events.unlistenByKey(this.listenerKey_); - this.listenerKey_ = null; - } - - this.window_ = null; - this.size_ = null; -}; - - -/** - * Handles window resize events by measuring the dimensions of the - * viewport and dispatching a {@link goog.events.EventType.RESIZE} event if the - * current dimensions are different from the previous ones. - * @param {goog.events.Event} event The window resize event to handle. - * @private - */ -goog.dom.ViewportSizeMonitor.prototype.handleResize_ = function(event) { - var size = goog.dom.getViewportSize(this.window_); - if (!goog.math.Size.equals(size, this.size_)) { - this.size_ = size; - this.dispatchEvent(goog.events.EventType.RESIZE); - } -}; - -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Constant declarations for common key codes. - * - * @author eae@google.com (Emil A Eklund) - * @see ../demos/keyhandler.html - */ - -goog.provide('goog.events.KeyCodes'); - -goog.require('goog.userAgent'); - -goog.forwardDeclare('goog.events.BrowserEvent'); - - -/** - * Key codes for common characters. - * - * This list is not localized and therefore some of the key codes are not - * correct for non US keyboard layouts. See comments below. - * - * @enum {number} - */ -goog.events.KeyCodes = { - WIN_KEY_FF_LINUX: 0, - MAC_ENTER: 3, - BACKSPACE: 8, - TAB: 9, - NUM_CENTER: 12, // NUMLOCK on FF/Safari Mac - ENTER: 13, - SHIFT: 16, - CTRL: 17, - ALT: 18, - PAUSE: 19, - CAPS_LOCK: 20, - ESC: 27, - SPACE: 32, - PAGE_UP: 33, // also NUM_NORTH_EAST - PAGE_DOWN: 34, // also NUM_SOUTH_EAST - END: 35, // also NUM_SOUTH_WEST - HOME: 36, // also NUM_NORTH_WEST - LEFT: 37, // also NUM_WEST - UP: 38, // also NUM_NORTH - RIGHT: 39, // also NUM_EAST - DOWN: 40, // also NUM_SOUTH - PLUS_SIGN: 43, // NOT numpad plus - PRINT_SCREEN: 44, - INSERT: 45, // also NUM_INSERT - DELETE: 46, // also NUM_DELETE - ZERO: 48, - ONE: 49, - TWO: 50, - THREE: 51, - FOUR: 52, - FIVE: 53, - SIX: 54, - SEVEN: 55, - EIGHT: 56, - NINE: 57, - FF_SEMICOLON: 59, // Firefox (Gecko) fires this for semicolon instead of 186 - FF_EQUALS: 61, // Firefox (Gecko) fires this for equals instead of 187 - FF_DASH: 173, // Firefox (Gecko) fires this for dash instead of 189 - QUESTION_MARK: 63, // needs localization - AT_SIGN: 64, - A: 65, - B: 66, - C: 67, - D: 68, - E: 69, - F: 70, - G: 71, - H: 72, - I: 73, - J: 74, - K: 75, - L: 76, - M: 77, - N: 78, - O: 79, - P: 80, - Q: 81, - R: 82, - S: 83, - T: 84, - U: 85, - V: 86, - W: 87, - X: 88, - Y: 89, - Z: 90, - META: 91, // WIN_KEY_LEFT - WIN_KEY_RIGHT: 92, - CONTEXT_MENU: 93, - NUM_ZERO: 96, - NUM_ONE: 97, - NUM_TWO: 98, - NUM_THREE: 99, - NUM_FOUR: 100, - NUM_FIVE: 101, - NUM_SIX: 102, - NUM_SEVEN: 103, - NUM_EIGHT: 104, - NUM_NINE: 105, - NUM_MULTIPLY: 106, - NUM_PLUS: 107, - NUM_MINUS: 109, - NUM_PERIOD: 110, - NUM_DIVISION: 111, - F1: 112, - F2: 113, - F3: 114, - F4: 115, - F5: 116, - F6: 117, - F7: 118, - F8: 119, - F9: 120, - F10: 121, - F11: 122, - F12: 123, - NUMLOCK: 144, - SCROLL_LOCK: 145, - - // OS-specific media keys like volume controls and browser controls. - FIRST_MEDIA_KEY: 166, - LAST_MEDIA_KEY: 183, - - SEMICOLON: 186, // needs localization - DASH: 189, // needs localization - EQUALS: 187, // needs localization - COMMA: 188, // needs localization - PERIOD: 190, // needs localization - SLASH: 191, // needs localization - APOSTROPHE: 192, // needs localization - TILDE: 192, // needs localization - SINGLE_QUOTE: 222, // needs localization - OPEN_SQUARE_BRACKET: 219, // needs localization - BACKSLASH: 220, // needs localization - CLOSE_SQUARE_BRACKET: 221, // needs localization - WIN_KEY: 224, - MAC_FF_META: 224, // Firefox (Gecko) fires this for the meta key instead of 91 - MAC_WK_CMD_LEFT: 91, // WebKit Left Command key fired, same as META - MAC_WK_CMD_RIGHT: 93, // WebKit Right Command key fired, different from META - WIN_IME: 229, - - // "Reserved for future use". Some programs (e.g. the SlingPlayer 2.4 ActiveX - // control) fire this as a hacky way to disable screensavers. - VK_NONAME: 252, - - // We've seen users whose machines fire this keycode at regular one - // second intervals. The common thread among these users is that - // they're all using Dell Inspiron laptops, so we suspect that this - // indicates a hardware/bios problem. - // http://en.community.dell.com/support-forums/laptop/f/3518/p/19285957/19523128.aspx - PHANTOM: 255 -}; - - -/** - * Returns true if the event contains a text modifying key. - * @param {goog.events.BrowserEvent} e A key event. - * @return {boolean} Whether it's a text modifying key. - */ -goog.events.KeyCodes.isTextModifyingKeyEvent = function(e) { - if (e.altKey && !e.ctrlKey || - e.metaKey || - // Function keys don't generate text - e.keyCode >= goog.events.KeyCodes.F1 && - e.keyCode <= goog.events.KeyCodes.F12) { - return false; - } - - // The following keys are quite harmless, even in combination with - // CTRL, ALT or SHIFT. - switch (e.keyCode) { - case goog.events.KeyCodes.ALT: - case goog.events.KeyCodes.CAPS_LOCK: - case goog.events.KeyCodes.CONTEXT_MENU: - case goog.events.KeyCodes.CTRL: - case goog.events.KeyCodes.DOWN: - case goog.events.KeyCodes.END: - case goog.events.KeyCodes.ESC: - case goog.events.KeyCodes.HOME: - case goog.events.KeyCodes.INSERT: - case goog.events.KeyCodes.LEFT: - case goog.events.KeyCodes.MAC_FF_META: - case goog.events.KeyCodes.META: - case goog.events.KeyCodes.NUMLOCK: - case goog.events.KeyCodes.NUM_CENTER: - case goog.events.KeyCodes.PAGE_DOWN: - case goog.events.KeyCodes.PAGE_UP: - case goog.events.KeyCodes.PAUSE: - case goog.events.KeyCodes.PHANTOM: - case goog.events.KeyCodes.PRINT_SCREEN: - case goog.events.KeyCodes.RIGHT: - case goog.events.KeyCodes.SCROLL_LOCK: - case goog.events.KeyCodes.SHIFT: - case goog.events.KeyCodes.UP: - case goog.events.KeyCodes.VK_NONAME: - case goog.events.KeyCodes.WIN_KEY: - case goog.events.KeyCodes.WIN_KEY_RIGHT: - return false; - case goog.events.KeyCodes.WIN_KEY_FF_LINUX: - return !goog.userAgent.GECKO; - default: - return e.keyCode < goog.events.KeyCodes.FIRST_MEDIA_KEY || - e.keyCode > goog.events.KeyCodes.LAST_MEDIA_KEY; - } -}; - - -/** - * Returns true if the key fires a keypress event in the current browser. - * - * Accoridng to MSDN [1] IE only fires keypress events for the following keys: - * - Letters: A - Z (uppercase and lowercase) - * - Numerals: 0 - 9 - * - Symbols: ! @ # $ % ^ & * ( ) _ - + = < [ ] { } , . / ? \ | ' ` " ~ - * - System: ESC, SPACEBAR, ENTER - * - * That's not entirely correct though, for instance there's no distinction - * between upper and lower case letters. - * - * [1] http://msdn2.microsoft.com/en-us/library/ms536939(VS.85).aspx) - * - * Safari is similar to IE, but does not fire keypress for ESC. - * - * Additionally, IE6 does not fire keydown or keypress events for letters when - * the control or alt keys are held down and the shift key is not. IE7 does - * fire keydown in these cases, though, but not keypress. - * - * @param {number} keyCode A key code. - * @param {number=} opt_heldKeyCode Key code of a currently-held key. - * @param {boolean=} opt_shiftKey Whether the shift key is held down. - * @param {boolean=} opt_ctrlKey Whether the control key is held down. - * @param {boolean=} opt_altKey Whether the alt key is held down. - * @return {boolean} Whether it's a key that fires a keypress event. - */ -goog.events.KeyCodes.firesKeyPressEvent = function(keyCode, opt_heldKeyCode, - opt_shiftKey, opt_ctrlKey, opt_altKey) { - if (!goog.userAgent.IE && !goog.userAgent.EDGE && - !(goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher('525'))) { - return true; - } - - if (goog.userAgent.MAC && opt_altKey) { - return goog.events.KeyCodes.isCharacterKey(keyCode); - } - - // Alt but not AltGr which is represented as Alt+Ctrl. - if (opt_altKey && !opt_ctrlKey) { - return false; - } - - // Saves Ctrl or Alt + key for IE and WebKit 525+, which won't fire keypress. - // Non-IE browsers and WebKit prior to 525 won't get this far so no need to - // check the user agent. - if (goog.isNumber(opt_heldKeyCode)) { - opt_heldKeyCode = goog.events.KeyCodes.normalizeKeyCode(opt_heldKeyCode); - } - if (!opt_shiftKey && - (opt_heldKeyCode == goog.events.KeyCodes.CTRL || - opt_heldKeyCode == goog.events.KeyCodes.ALT || - goog.userAgent.MAC && - opt_heldKeyCode == goog.events.KeyCodes.META)) { - return false; - } - - // Some keys with Ctrl/Shift do not issue keypress in WEBKIT. - if ((goog.userAgent.WEBKIT || goog.userAgent.EDGE) && - opt_ctrlKey && opt_shiftKey) { - switch (keyCode) { - case goog.events.KeyCodes.BACKSLASH: - case goog.events.KeyCodes.OPEN_SQUARE_BRACKET: - case goog.events.KeyCodes.CLOSE_SQUARE_BRACKET: - case goog.events.KeyCodes.TILDE: - case goog.events.KeyCodes.SEMICOLON: - case goog.events.KeyCodes.DASH: - case goog.events.KeyCodes.EQUALS: - case goog.events.KeyCodes.COMMA: - case goog.events.KeyCodes.PERIOD: - case goog.events.KeyCodes.SLASH: - case goog.events.KeyCodes.APOSTROPHE: - case goog.events.KeyCodes.SINGLE_QUOTE: - return false; - } - } - - // When Ctrl+<somekey> is held in IE, it only fires a keypress once, but it - // continues to fire keydown events as the event repeats. - if (goog.userAgent.IE && opt_ctrlKey && opt_heldKeyCode == keyCode) { - return false; - } - - switch (keyCode) { - case goog.events.KeyCodes.ENTER: - return true; - case goog.events.KeyCodes.ESC: - return !(goog.userAgent.WEBKIT || goog.userAgent.EDGE); - } - - return goog.events.KeyCodes.isCharacterKey(keyCode); -}; - - -/** - * Returns true if the key produces a character. - * This does not cover characters on non-US keyboards (Russian, Hebrew, etc.). - * - * @param {number} keyCode A key code. - * @return {boolean} Whether it's a character key. - */ -goog.events.KeyCodes.isCharacterKey = function(keyCode) { - if (keyCode >= goog.events.KeyCodes.ZERO && - keyCode <= goog.events.KeyCodes.NINE) { - return true; - } - - if (keyCode >= goog.events.KeyCodes.NUM_ZERO && - keyCode <= goog.events.KeyCodes.NUM_MULTIPLY) { - return true; - } - - if (keyCode >= goog.events.KeyCodes.A && - keyCode <= goog.events.KeyCodes.Z) { +goog.async.nextTick.useSetImmediate_ = function() { + // Not a browser environment. + if (!goog.global.Window || !goog.global.Window.prototype) { return true; } - // Safari sends zero key code for non-latin characters. - if ((goog.userAgent.WEBKIT || goog.userAgent.EDGE) && keyCode == 0) { + // MS Edge has window.setImmediate natively, but it's not on Window.prototype. + // Also, there's no clean way to detect if the goog.global.setImmediate has + // been replaced by mockClock as its replacement also shows up as "[native + // code]" when using toString. Therefore, just always use + // goog.global.setImmediate for Edge. It's unclear if it suffers the same + // issues as IE10/11, but based on + // https://dev.modern.ie/testdrive/demos/setimmediatesorting/ + // it seems they've been working to ensure it's WAI. + if (goog.labs.userAgent.browser.isEdge() || + goog.global.Window.prototype.setImmediate != goog.global.setImmediate) { + // Something redefined setImmediate in which case we decide to use it (This + // is so that we use the mockClock setImmediate). return true; } - switch (keyCode) { - case goog.events.KeyCodes.SPACE: - case goog.events.KeyCodes.PLUS_SIGN: - case goog.events.KeyCodes.QUESTION_MARK: - case goog.events.KeyCodes.AT_SIGN: - case goog.events.KeyCodes.NUM_PLUS: - case goog.events.KeyCodes.NUM_MINUS: - case goog.events.KeyCodes.NUM_PERIOD: - case goog.events.KeyCodes.NUM_DIVISION: - case goog.events.KeyCodes.SEMICOLON: - case goog.events.KeyCodes.FF_SEMICOLON: - case goog.events.KeyCodes.DASH: - case goog.events.KeyCodes.EQUALS: - case goog.events.KeyCodes.FF_EQUALS: - case goog.events.KeyCodes.COMMA: - case goog.events.KeyCodes.PERIOD: - case goog.events.KeyCodes.SLASH: - case goog.events.KeyCodes.APOSTROPHE: - case goog.events.KeyCodes.SINGLE_QUOTE: - case goog.events.KeyCodes.OPEN_SQUARE_BRACKET: - case goog.events.KeyCodes.BACKSLASH: - case goog.events.KeyCodes.CLOSE_SQUARE_BRACKET: - return true; - default: - return false; - } -}; - - -/** - * Normalizes key codes from OS/Browser-specific value to the general one. - * @param {number} keyCode The native key code. - * @return {number} The normalized key code. - */ -goog.events.KeyCodes.normalizeKeyCode = function(keyCode) { - if (goog.userAgent.GECKO) { - return goog.events.KeyCodes.normalizeGeckoKeyCode(keyCode); - } else if (goog.userAgent.MAC && goog.userAgent.WEBKIT) { - return goog.events.KeyCodes.normalizeMacWebKitKeyCode(keyCode); - } else { - return keyCode; - } -}; - - -/** - * Normalizes key codes from their Gecko-specific value to the general one. - * @param {number} keyCode The native key code. - * @return {number} The normalized key code. - */ -goog.events.KeyCodes.normalizeGeckoKeyCode = function(keyCode) { - switch (keyCode) { - case goog.events.KeyCodes.FF_EQUALS: - return goog.events.KeyCodes.EQUALS; - case goog.events.KeyCodes.FF_SEMICOLON: - return goog.events.KeyCodes.SEMICOLON; - case goog.events.KeyCodes.FF_DASH: - return goog.events.KeyCodes.DASH; - case goog.events.KeyCodes.MAC_FF_META: - return goog.events.KeyCodes.META; - case goog.events.KeyCodes.WIN_KEY_FF_LINUX: - return goog.events.KeyCodes.WIN_KEY; - default: - return keyCode; - } -}; - - -/** - * Normalizes key codes from their Mac WebKit-specific value to the general one. - * @param {number} keyCode The native key code. - * @return {number} The normalized key code. - */ -goog.events.KeyCodes.normalizeMacWebKitKeyCode = function(keyCode) { - switch (keyCode) { - case goog.events.KeyCodes.MAC_WK_CMD_RIGHT: // 93 - return goog.events.KeyCodes.META; // 91 - default: - return keyCode; - } -}; - -// Copyright 2007 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview This file contains a class for working with keyboard events - * that repeat consistently across browsers and platforms. It also unifies the - * key code so that it is the same in all browsers and platforms. - * - * Different web browsers have very different keyboard event handling. Most - * importantly is that only certain browsers repeat keydown events: - * IE, Opera, FF/Win32, and Safari 3 repeat keydown events. - * FF/Mac and Safari 2 do not. - * - * For the purposes of this code, "Safari 3" means WebKit 525+, when WebKit - * decided that they should try to match IE's key handling behavior. - * Safari 3.0.4, which shipped with Leopard (WebKit 523), has the - * Safari 2 behavior. - * - * Firefox, Safari, Opera prevent on keypress - * - * IE prevents on keydown - * - * Firefox does not fire keypress for shift, ctrl, alt - * Firefox does fire keydown for shift, ctrl, alt, meta - * Firefox does not repeat keydown for shift, ctrl, alt, meta - * - * Firefox does not fire keypress for up and down in an input - * - * Opera fires keypress for shift, ctrl, alt, meta - * Opera does not repeat keypress for shift, ctrl, alt, meta - * - * Safari 2 and 3 do not fire keypress for shift, ctrl, alt - * Safari 2 does not fire keydown for shift, ctrl, alt - * Safari 3 *does* fire keydown for shift, ctrl, alt - * - * IE provides the keycode for keyup/down events and the charcode (in the - * keycode field) for keypress. - * - * Mozilla provides the keycode for keyup/down and the charcode for keypress - * unless it's a non text modifying key in which case the keycode is provided. - * - * Safari 3 provides the keycode and charcode for all events. - * - * Opera provides the keycode for keyup/down event and either the charcode or - * the keycode (in the keycode field) for keypress events. - * - * Firefox x11 doesn't fire keydown events if a another key is already held down - * until the first key is released. This can cause a key event to be fired with - * a keyCode for the first key and a charCode for the second key. - * - * Safari in keypress - * - * charCode keyCode which - * ENTER: 13 13 13 - * F1: 63236 63236 63236 - * F8: 63243 63243 63243 - * ... - * p: 112 112 112 - * P: 80 80 80 - * - * Firefox, keypress: - * - * charCode keyCode which - * ENTER: 0 13 13 - * F1: 0 112 0 - * F8: 0 119 0 - * ... - * p: 112 0 112 - * P: 80 0 80 - * - * Opera, Mac+Win32, keypress: - * - * charCode keyCode which - * ENTER: undefined 13 13 - * F1: undefined 112 0 - * F8: undefined 119 0 - * ... - * p: undefined 112 112 - * P: undefined 80 80 - * - * IE7, keydown - * - * charCode keyCode which - * ENTER: undefined 13 undefined - * F1: undefined 112 undefined - * F8: undefined 119 undefined - * ... - * p: undefined 80 undefined - * P: undefined 80 undefined - * - * @author arv@google.com (Erik Arvidsson) - * @author eae@google.com (Emil A Eklund) - * @see ../demos/keyhandler.html - */ - -goog.provide('goog.events.KeyEvent'); -goog.provide('goog.events.KeyHandler'); -goog.provide('goog.events.KeyHandler.EventType'); - -goog.require('goog.events'); -goog.require('goog.events.BrowserEvent'); -goog.require('goog.events.EventTarget'); -goog.require('goog.events.EventType'); -goog.require('goog.events.KeyCodes'); -goog.require('goog.userAgent'); - - - -/** - * A wrapper around an element that you want to listen to keyboard events on. - * @param {Element|Document=} opt_element The element or document to listen on. - * @param {boolean=} opt_capture Whether to listen for browser events in - * capture phase (defaults to false). - * @constructor - * @extends {goog.events.EventTarget} - * @final - */ -goog.events.KeyHandler = function(opt_element, opt_capture) { - goog.events.EventTarget.call(this); - - if (opt_element) { - this.attach(opt_element, opt_capture); - } + return false; }; -goog.inherits(goog.events.KeyHandler, goog.events.EventTarget); - - -/** - * This is the element that we will listen to the real keyboard events on. - * @type {Element|Document|null} - * @private - */ -goog.events.KeyHandler.prototype.element_ = null; - - -/** - * The key for the key press listener. - * @type {goog.events.Key} - * @private - */ -goog.events.KeyHandler.prototype.keyPressKey_ = null; - - -/** - * The key for the key down listener. - * @type {goog.events.Key} - * @private - */ -goog.events.KeyHandler.prototype.keyDownKey_ = null; - - -/** - * The key for the key up listener. - * @type {goog.events.Key} - * @private - */ -goog.events.KeyHandler.prototype.keyUpKey_ = null; - - -/** - * Used to detect keyboard repeat events. - * @private - * @type {number} - */ -goog.events.KeyHandler.prototype.lastKey_ = -1; - - -/** - * Keycode recorded for key down events. As most browsers don't report the - * keycode in the key press event we need to record it in the key down phase. - * @private - * @type {number} - */ -goog.events.KeyHandler.prototype.keyCode_ = -1; - - -/** - * Alt key recorded for key down events. FF on Mac does not report the alt key - * flag in the key press event, we need to record it in the key down phase. - * @type {boolean} - * @private - */ -goog.events.KeyHandler.prototype.altKey_ = false; - - -/** - * Enum type for the events fired by the key handler - * @enum {string} - */ -goog.events.KeyHandler.EventType = { - KEY: 'key' -}; - - -/** - * An enumeration of key codes that Safari 2 does incorrectly - * @type {Object} - * @private - */ -goog.events.KeyHandler.safariKey_ = { - '3': goog.events.KeyCodes.ENTER, // 13 - '12': goog.events.KeyCodes.NUMLOCK, // 144 - '63232': goog.events.KeyCodes.UP, // 38 - '63233': goog.events.KeyCodes.DOWN, // 40 - '63234': goog.events.KeyCodes.LEFT, // 37 - '63235': goog.events.KeyCodes.RIGHT, // 39 - '63236': goog.events.KeyCodes.F1, // 112 - '63237': goog.events.KeyCodes.F2, // 113 - '63238': goog.events.KeyCodes.F3, // 114 - '63239': goog.events.KeyCodes.F4, // 115 - '63240': goog.events.KeyCodes.F5, // 116 - '63241': goog.events.KeyCodes.F6, // 117 - '63242': goog.events.KeyCodes.F7, // 118 - '63243': goog.events.KeyCodes.F8, // 119 - '63244': goog.events.KeyCodes.F9, // 120 - '63245': goog.events.KeyCodes.F10, // 121 - '63246': goog.events.KeyCodes.F11, // 122 - '63247': goog.events.KeyCodes.F12, // 123 - '63248': goog.events.KeyCodes.PRINT_SCREEN, // 44 - '63272': goog.events.KeyCodes.DELETE, // 46 - '63273': goog.events.KeyCodes.HOME, // 36 - '63275': goog.events.KeyCodes.END, // 35 - '63276': goog.events.KeyCodes.PAGE_UP, // 33 - '63277': goog.events.KeyCodes.PAGE_DOWN, // 34 - '63289': goog.events.KeyCodes.NUMLOCK, // 144 - '63302': goog.events.KeyCodes.INSERT // 45 -}; - - -/** - * An enumeration of key identifiers currently part of the W3C draft for DOM3 - * and their mappings to keyCodes. - * http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set - * This is currently supported in Safari and should be platform independent. - * @type {Object} - * @private - */ -goog.events.KeyHandler.keyIdentifier_ = { - 'Up': goog.events.KeyCodes.UP, // 38 - 'Down': goog.events.KeyCodes.DOWN, // 40 - 'Left': goog.events.KeyCodes.LEFT, // 37 - 'Right': goog.events.KeyCodes.RIGHT, // 39 - 'Enter': goog.events.KeyCodes.ENTER, // 13 - 'F1': goog.events.KeyCodes.F1, // 112 - 'F2': goog.events.KeyCodes.F2, // 113 - 'F3': goog.events.KeyCodes.F3, // 114 - 'F4': goog.events.KeyCodes.F4, // 115 - 'F5': goog.events.KeyCodes.F5, // 116 - 'F6': goog.events.KeyCodes.F6, // 117 - 'F7': goog.events.KeyCodes.F7, // 118 - 'F8': goog.events.KeyCodes.F8, // 119 - 'F9': goog.events.KeyCodes.F9, // 120 - 'F10': goog.events.KeyCodes.F10, // 121 - 'F11': goog.events.KeyCodes.F11, // 122 - 'F12': goog.events.KeyCodes.F12, // 123 - 'U+007F': goog.events.KeyCodes.DELETE, // 46 - 'Home': goog.events.KeyCodes.HOME, // 36 - 'End': goog.events.KeyCodes.END, // 35 - 'PageUp': goog.events.KeyCodes.PAGE_UP, // 33 - 'PageDown': goog.events.KeyCodes.PAGE_DOWN, // 34 - 'Insert': goog.events.KeyCodes.INSERT // 45 -}; - - -/** - * If true, the KeyEvent fires on keydown. Otherwise, it fires on keypress. - * - * @type {boolean} - * @private - */ -goog.events.KeyHandler.USES_KEYDOWN_ = goog.userAgent.IE || - goog.userAgent.EDGE || - goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher('525'); /** - * If true, the alt key flag is saved during the key down and reused when - * handling the key press. FF on Mac does not set the alt flag in the key press - * event. - * @type {boolean} + * Cache for the setImmediate implementation. + * @type {function(function())} * @private */ -goog.events.KeyHandler.SAVE_ALT_FOR_KEYPRESS_ = goog.userAgent.MAC && - goog.userAgent.GECKO; +goog.async.nextTick.setImmediate_; /** - * Records the keycode for browsers that only returns the keycode for key up/ - * down events. For browser/key combinations that doesn't trigger a key pressed - * event it also fires the patched key event. - * @param {goog.events.BrowserEvent} e The key down event. + * Determines the best possible implementation to run a function as soon as + * the JS event loop is idle. + * @return {function(function())} The "setImmediate" implementation. * @private */ -goog.events.KeyHandler.prototype.handleKeyDown_ = function(e) { - // Ctrl-Tab and Alt-Tab can cause the focus to be moved to another window - // before we've caught a key-up event. If the last-key was one of these we - // reset the state. - if (goog.userAgent.WEBKIT || goog.userAgent.EDGE) { - if (this.lastKey_ == goog.events.KeyCodes.CTRL && !e.ctrlKey || - this.lastKey_ == goog.events.KeyCodes.ALT && !e.altKey || - goog.userAgent.MAC && - this.lastKey_ == goog.events.KeyCodes.META && !e.metaKey) { - this.resetState(); - } - } - - if (this.lastKey_ == -1) { - if (e.ctrlKey && e.keyCode != goog.events.KeyCodes.CTRL) { - this.lastKey_ = goog.events.KeyCodes.CTRL; - } else if (e.altKey && e.keyCode != goog.events.KeyCodes.ALT) { - this.lastKey_ = goog.events.KeyCodes.ALT; - } else if (e.metaKey && e.keyCode != goog.events.KeyCodes.META) { - this.lastKey_ = goog.events.KeyCodes.META; - } - } - - if (goog.events.KeyHandler.USES_KEYDOWN_ && - !goog.events.KeyCodes.firesKeyPressEvent(e.keyCode, - this.lastKey_, e.shiftKey, e.ctrlKey, e.altKey)) { - this.handleEvent(e); - } else { - this.keyCode_ = goog.events.KeyCodes.normalizeKeyCode(e.keyCode); - if (goog.events.KeyHandler.SAVE_ALT_FOR_KEYPRESS_) { - this.altKey_ = e.altKey; - } +goog.async.nextTick.getSetImmediateEmulator_ = function() { + // Create a private message channel and use it to postMessage empty messages + // to ourselves. + var Channel = goog.global['MessageChannel']; + // If MessageChannel is not available and we are in a browser, implement + // an iframe based polyfill in browsers that have postMessage and + // document.addEventListener. The latter excludes IE8 because it has a + // synchronous postMessage implementation. + if (typeof Channel === 'undefined' && typeof window !== 'undefined' && + window.postMessage && window.addEventListener && + // Presto (The old pre-blink Opera engine) has problems with iframes + // and contentWindow. + !goog.labs.userAgent.engine.isPresto()) { + /** @constructor */ + Channel = function() { + // Make an empty, invisible iframe. + var iframe = /** @type {!HTMLIFrameElement} */ ( + document.createElement(goog.dom.TagName.IFRAME)); + iframe.style.display = 'none'; + iframe.src = ''; + document.documentElement.appendChild(iframe); + var win = iframe.contentWindow; + var doc = win.document; + doc.open(); + doc.write(''); + doc.close(); + // Do not post anything sensitive over this channel, as the workaround for + // pages with file: origin could allow that information to be modified or + // intercepted. + var message = 'callImmediate' + Math.random(); + // The same origin policy rejects attempts to postMessage from file: urls + // unless the origin is '*'. + // TODO(b/16335441): Use '*' origin for data: and other similar protocols. + var origin = win.location.protocol == 'file:' ? + '*' : + win.location.protocol + '//' + win.location.host; + var onmessage = goog.bind(function(e) { + // Validate origin and message to make sure that this message was + // intended for us. If the origin is set to '*' (see above) only the + // message needs to match since, for example, '*' != 'file://'. Allowing + // the wildcard is ok, as we are not concerned with security here. + if ((origin != '*' && e.origin != origin) || e.data != message) { + return; + } + this['port1'].onmessage(); + }, this); + win.addEventListener('message', onmessage, false); + this['port1'] = {}; + this['port2'] = { + postMessage: function() { win.postMessage(message, origin); } + }; + }; } -}; - - -/** - * Resets the stored previous values. Needed to be called for webkit which will - * not generate a key up for meta key operations. This should only be called - * when having finished with repeat key possiblities. - */ -goog.events.KeyHandler.prototype.resetState = function() { - this.lastKey_ = -1; - this.keyCode_ = -1; -}; - - -/** - * Clears the stored previous key value, resetting the key repeat status. Uses - * -1 because the Safari 3 Windows beta reports 0 for certain keys (like Home - * and End.) - * @param {goog.events.BrowserEvent} e The keyup event. - * @private - */ -goog.events.KeyHandler.prototype.handleKeyup_ = function(e) { - this.resetState(); - this.altKey_ = e.altKey; -}; - - -/** - * Handles the events on the element. - * @param {goog.events.BrowserEvent} e The keyboard event sent from the - * browser. - */ -goog.events.KeyHandler.prototype.handleEvent = function(e) { - var be = e.getBrowserEvent(); - var keyCode, charCode; - var altKey = be.altKey; - - // IE reports the character code in the keyCode field for keypress events. - // There are two exceptions however, Enter and Escape. - if (goog.userAgent.IE && e.type == goog.events.EventType.KEYPRESS) { - keyCode = this.keyCode_; - charCode = keyCode != goog.events.KeyCodes.ENTER && - keyCode != goog.events.KeyCodes.ESC ? - be.keyCode : 0; - - // Safari reports the character code in the keyCode field for keypress - // events but also has a charCode field. - } else if ((goog.userAgent.WEBKIT || goog.userAgent.EDGE) && - e.type == goog.events.EventType.KEYPRESS) { - keyCode = this.keyCode_; - charCode = be.charCode >= 0 && be.charCode < 63232 && - goog.events.KeyCodes.isCharacterKey(keyCode) ? - be.charCode : 0; - - // Opera reports the keycode or the character code in the keyCode field. - } else if (goog.userAgent.OPERA && !goog.userAgent.WEBKIT) { - keyCode = this.keyCode_; - charCode = goog.events.KeyCodes.isCharacterKey(keyCode) ? - be.keyCode : 0; - - // Mozilla reports the character code in the charCode field. - } else { - keyCode = be.keyCode || this.keyCode_; - charCode = be.charCode || 0; - if (goog.events.KeyHandler.SAVE_ALT_FOR_KEYPRESS_) { - altKey = this.altKey_; - } - // On the Mac, shift-/ triggers a question mark char code and no key code - // (normalized to WIN_KEY), so we synthesize the latter. - if (goog.userAgent.MAC && - charCode == goog.events.KeyCodes.QUESTION_MARK && - keyCode == goog.events.KeyCodes.WIN_KEY) { - keyCode = goog.events.KeyCodes.SLASH; - } - } - - keyCode = goog.events.KeyCodes.normalizeKeyCode(keyCode); - var key = keyCode; - var keyIdentifier = be.keyIdentifier; - - // Correct the key value for certain browser-specific quirks. - if (keyCode) { - if (keyCode >= 63232 && keyCode in goog.events.KeyHandler.safariKey_) { - // NOTE(nicksantos): Safari 3 has fixed this problem, - // this is only needed for Safari 2. - key = goog.events.KeyHandler.safariKey_[keyCode]; - } else { - - // Safari returns 25 for Shift+Tab instead of 9. - if (keyCode == 25 && e.shiftKey) { - key = 9; + if (typeof Channel !== 'undefined' && (!goog.labs.userAgent.browser.isIE())) { + // Exclude all of IE due to + // http://codeforhire.com/2013/09/21/setimmediate-and-messagechannel-broken-on-internet-explorer-10/ + // which allows starving postMessage with a busy setTimeout loop. + // This currently affects IE10 and IE11 which would otherwise be able + // to use the postMessage based fallbacks. + var channel = new Channel(); + // Use a fifo linked list to call callbacks in the right order. + var head = {}; + var tail = head; + channel['port1'].onmessage = function() { + if (goog.isDef(head.next)) { + head = head.next; + var cb = head.cb; + head.cb = null; + cb(); } - } - } else if (keyIdentifier && - keyIdentifier in goog.events.KeyHandler.keyIdentifier_) { - // This is needed for Safari Windows because it currently doesn't give a - // keyCode/which for non printable keys. - key = goog.events.KeyHandler.keyIdentifier_[keyIdentifier]; - } - - // If we get the same keycode as a keydown/keypress without having seen a - // keyup event, then this event was caused by key repeat. - var repeat = key == this.lastKey_; - this.lastKey_ = key; - - var event = new goog.events.KeyEvent(key, charCode, repeat, be); - event.altKey = altKey; - this.dispatchEvent(event); -}; - - -/** - * Returns the element listened on for the real keyboard events. - * @return {Element|Document|null} The element listened on for the real - * keyboard events. - */ -goog.events.KeyHandler.prototype.getElement = function() { - return this.element_; -}; - - -/** - * Adds the proper key event listeners to the element. - * @param {Element|Document} element The element to listen on. - * @param {boolean=} opt_capture Whether to listen for browser events in - * capture phase (defaults to false). - */ -goog.events.KeyHandler.prototype.attach = function(element, opt_capture) { - if (this.keyUpKey_) { - this.detach(); - } - - this.element_ = element; - - this.keyPressKey_ = goog.events.listen(this.element_, - goog.events.EventType.KEYPRESS, - this, - opt_capture); - - // Most browsers (Safari 2 being the notable exception) doesn't include the - // keyCode in keypress events (IE has the char code in the keyCode field and - // Mozilla only included the keyCode if there's no charCode). Thus we have to - // listen for keydown to capture the keycode. - this.keyDownKey_ = goog.events.listen(this.element_, - goog.events.EventType.KEYDOWN, - this.handleKeyDown_, - opt_capture, - this); - - - this.keyUpKey_ = goog.events.listen(this.element_, - goog.events.EventType.KEYUP, - this.handleKeyup_, - opt_capture, - this); -}; - - -/** - * Removes the listeners that may exist. - */ -goog.events.KeyHandler.prototype.detach = function() { - if (this.keyPressKey_) { - goog.events.unlistenByKey(this.keyPressKey_); - goog.events.unlistenByKey(this.keyDownKey_); - goog.events.unlistenByKey(this.keyUpKey_); - this.keyPressKey_ = null; - this.keyDownKey_ = null; - this.keyUpKey_ = null; - } - this.element_ = null; - this.lastKey_ = -1; - this.keyCode_ = -1; -}; - - -/** @override */ -goog.events.KeyHandler.prototype.disposeInternal = function() { - goog.events.KeyHandler.superClass_.disposeInternal.call(this); - this.detach(); -}; - - - -/** - * This class is used for the goog.events.KeyHandler.EventType.KEY event and - * it overrides the key code with the fixed key code. - * @param {number} keyCode The adjusted key code. - * @param {number} charCode The unicode character code. - * @param {boolean} repeat Whether this event was generated by keyboard repeat. - * @param {Event} browserEvent Browser event object. - * @constructor - * @extends {goog.events.BrowserEvent} - * @final - */ -goog.events.KeyEvent = function(keyCode, charCode, repeat, browserEvent) { - goog.events.BrowserEvent.call(this, browserEvent); - this.type = goog.events.KeyHandler.EventType.KEY; - - /** - * Keycode of key press. - * @type {number} - */ - this.keyCode = keyCode; - - /** - * Unicode character code. - * @type {number} - */ - this.charCode = charCode; - - /** - * True if this event was generated by keyboard auto-repeat (i.e., the user is - * holding the key down.) - * @type {boolean} - */ - this.repeat = repeat; -}; -goog.inherits(goog.events.KeyEvent, goog.events.BrowserEvent); - -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview This event wrapper will dispatch an event when the user uses - * the mouse wheel to scroll an element. You can get the direction by checking - * the deltaX and deltaY properties of the event. - * - * This class aims to smooth out inconsistencies between browser platforms with - * regards to mousewheel events, but we do not cover every possible - * software/hardware combination out there, some of which occasionally produce - * very large deltas in mousewheel events. If your application wants to guard - * against extremely large deltas, use the setMaxDeltaX and setMaxDeltaY APIs - * to set maximum values that make sense for your application. - * - * @author arv@google.com (Erik Arvidsson) - * @see ../demos/mousewheelhandler.html - */ - -goog.provide('goog.events.MouseWheelEvent'); -goog.provide('goog.events.MouseWheelHandler'); -goog.provide('goog.events.MouseWheelHandler.EventType'); - -goog.require('goog.dom'); -goog.require('goog.events'); -goog.require('goog.events.BrowserEvent'); -goog.require('goog.events.EventTarget'); -goog.require('goog.math'); -goog.require('goog.style'); -goog.require('goog.userAgent'); - - - -/** - * This event handler allows you to catch mouse wheel events in a consistent - * manner. - * @param {Element|Document} element The element to listen to the mouse wheel - * event on. - * @param {boolean=} opt_capture Whether to handle the mouse wheel event in - * capture phase. - * @constructor - * @extends {goog.events.EventTarget} - */ -goog.events.MouseWheelHandler = function(element, opt_capture) { - goog.events.EventTarget.call(this); - - /** - * This is the element that we will listen to the real mouse wheel events on. - * @type {Element|Document} - * @private - */ - this.element_ = element; - - var rtlElement = goog.dom.isElement(this.element_) ? - /** @type {Element} */ (this.element_) : - (this.element_ ? /** @type {Document} */ (this.element_).body : null); - - /** - * True if the element exists and is RTL, false otherwise. - * @type {boolean} - * @private - */ - this.isRtl_ = !!rtlElement && goog.style.isRightToLeft(rtlElement); - - var type = goog.userAgent.GECKO ? 'DOMMouseScroll' : 'mousewheel'; - - /** - * The key returned from the goog.events.listen. - * @type {goog.events.Key} - * @private - */ - this.listenKey_ = goog.events.listen(this.element_, type, this, opt_capture); -}; -goog.inherits(goog.events.MouseWheelHandler, goog.events.EventTarget); - - -/** - * Enum type for the events fired by the mouse wheel handler. - * @enum {string} - */ -goog.events.MouseWheelHandler.EventType = { - MOUSEWHEEL: 'mousewheel' -}; - - -/** - * Optional maximum magnitude for x delta on each mousewheel event. - * @type {number|undefined} - * @private - */ -goog.events.MouseWheelHandler.prototype.maxDeltaX_; - - -/** - * Optional maximum magnitude for y delta on each mousewheel event. - * @type {number|undefined} - * @private - */ -goog.events.MouseWheelHandler.prototype.maxDeltaY_; - - -/** - * @param {number} maxDeltaX Maximum magnitude for x delta on each mousewheel - * event. Should be non-negative. - */ -goog.events.MouseWheelHandler.prototype.setMaxDeltaX = function(maxDeltaX) { - this.maxDeltaX_ = maxDeltaX; -}; - - -/** - * @param {number} maxDeltaY Maximum magnitude for y delta on each mousewheel - * event. Should be non-negative. - */ -goog.events.MouseWheelHandler.prototype.setMaxDeltaY = function(maxDeltaY) { - this.maxDeltaY_ = maxDeltaY; -}; - - -/** - * Handles the events on the element. - * @param {goog.events.BrowserEvent} e The underlying browser event. - */ -goog.events.MouseWheelHandler.prototype.handleEvent = function(e) { - var deltaX = 0; - var deltaY = 0; - var detail = 0; - var be = e.getBrowserEvent(); - if (be.type == 'mousewheel') { - var wheelDeltaScaleFactor = 1; - if (goog.userAgent.IE || - goog.userAgent.WEBKIT && - (goog.userAgent.WINDOWS || goog.userAgent.isVersionOrHigher('532.0'))) { - // In IE we get a multiple of 120; we adjust to a multiple of 3 to - // represent number of lines scrolled (like Gecko). - // Newer versions of Webkit match IE behavior, and WebKit on - // Windows also matches IE behavior. - // See bug https://bugs.webkit.org/show_bug.cgi?id=24368 - wheelDeltaScaleFactor = 40; - } - - detail = goog.events.MouseWheelHandler.smartScale_( - -be.wheelDelta, wheelDeltaScaleFactor); - if (goog.isDef(be.wheelDeltaX)) { - // Webkit has two properties to indicate directional scroll, and - // can scroll both directions at once. - deltaX = goog.events.MouseWheelHandler.smartScale_( - -be.wheelDeltaX, wheelDeltaScaleFactor); - deltaY = goog.events.MouseWheelHandler.smartScale_( - -be.wheelDeltaY, wheelDeltaScaleFactor); - } else { - deltaY = detail; - } - - // Historical note: Opera (pre 9.5) used to negate the detail value. - } else { // Gecko - // Gecko returns multiple of 3 (representing the number of lines scrolled) - detail = be.detail; - - // Gecko sometimes returns really big values if the user changes settings to - // scroll a whole page per scroll - if (detail > 100) { - detail = 3; - } else if (detail < -100) { - detail = -3; - } - - // Firefox 3.1 adds an axis field to the event to indicate direction of - // scroll. See https://developer.mozilla.org/en/Gecko-Specific_DOM_Events - if (goog.isDef(be.axis) && be.axis === be.HORIZONTAL_AXIS) { - deltaX = detail; - } else { - deltaY = detail; - } - } - - if (goog.isNumber(this.maxDeltaX_)) { - deltaX = goog.math.clamp(deltaX, -this.maxDeltaX_, this.maxDeltaX_); - } - if (goog.isNumber(this.maxDeltaY_)) { - deltaY = goog.math.clamp(deltaY, -this.maxDeltaY_, this.maxDeltaY_); + }; + return function(cb) { + tail.next = {cb: cb}; + tail = tail.next; + channel['port2'].postMessage(0); + }; } - // Don't clamp 'detail', since it could be ambiguous which axis it refers to - // and because it's informally deprecated anyways. - - // For horizontal scrolling we need to flip the value for RTL grids. - if (this.isRtl_) { - deltaX = -deltaX; + // Implementation for IE6 to IE10: Script elements fire an asynchronous + // onreadystatechange event when inserted into the DOM. + if (typeof document !== 'undefined' && + 'onreadystatechange' in document.createElement(goog.dom.TagName.SCRIPT)) { + return function(cb) { + var script = document.createElement(goog.dom.TagName.SCRIPT); + script.onreadystatechange = function() { + // Clean up and call the callback. + script.onreadystatechange = null; + script.parentNode.removeChild(script); + script = null; + cb(); + cb = null; + }; + document.documentElement.appendChild(script); + }; } - var newEvent = new goog.events.MouseWheelEvent(detail, be, deltaX, deltaY); - this.dispatchEvent(newEvent); + // Fall back to setTimeout with 0. In browsers this creates a delay of 5ms + // or more. + // NOTE(user): This fallback is used for IE11. + return function(cb) { goog.global.setTimeout(cb, 0); }; }; /** - * Helper for scaling down a mousewheel delta by a scale factor, if appropriate. - * @param {number} mouseWheelDelta Delta from a mouse wheel event. Expected to - * be an integer. - * @param {number} scaleFactor Factor to scale the delta down by. Expected to - * be an integer. - * @return {number} Scaled-down delta value, or the original delta if the - * scaleFactor does not appear to be applicable. + * Helper function that is overrided to protect callbacks with entry point + * monitor if the application monitors entry points. + * @param {function()} callback Callback function to fire as soon as possible. + * @return {function()} The wrapped callback. * @private */ -goog.events.MouseWheelHandler.smartScale_ = function(mouseWheelDelta, - scaleFactor) { - // The basic problem here is that in Webkit on Mac and Linux, we can get two - // very different types of mousewheel events: from continuous devices - // (touchpads, Mighty Mouse) or non-continuous devices (normal wheel mice). - // - // Non-continuous devices in Webkit get their wheel deltas scaled up to - // behave like IE. Continuous devices return much smaller unscaled values - // (which most of the time will not be cleanly divisible by the IE scale - // factor), so we should not try to normalize them down. - // - // Detailed discussion: - // https://bugs.webkit.org/show_bug.cgi?id=29601 - // http://trac.webkit.org/browser/trunk/WebKit/chromium/src/mac/WebInputEventFactory.mm#L1063 - if (goog.userAgent.WEBKIT && - (goog.userAgent.MAC || goog.userAgent.LINUX) && - (mouseWheelDelta % scaleFactor) != 0) { - return mouseWheelDelta; - } else { - return mouseWheelDelta / scaleFactor; - } -}; - - -/** @override */ -goog.events.MouseWheelHandler.prototype.disposeInternal = function() { - goog.events.MouseWheelHandler.superClass_.disposeInternal.call(this); - goog.events.unlistenByKey(this.listenKey_); - this.listenKey_ = null; -}; - - - -/** - * A base class for mouse wheel events. This is used with the - * MouseWheelHandler. - * - * @param {number} detail The number of rows the user scrolled. - * @param {Event} browserEvent Browser event object. - * @param {number} deltaX The number of rows the user scrolled in the X - * direction. - * @param {number} deltaY The number of rows the user scrolled in the Y - * direction. - * @constructor - * @extends {goog.events.BrowserEvent} - * @final - */ -goog.events.MouseWheelEvent = function(detail, browserEvent, deltaX, deltaY) { - goog.events.BrowserEvent.call(this, browserEvent); - - this.type = goog.events.MouseWheelHandler.EventType.MOUSEWHEEL; - - /** - * The number of lines the user scrolled - * @type {number} - * NOTE: Informally deprecated. Use deltaX and deltaY instead, they provide - * more information. - */ - this.detail = detail; - - /** - * The number of "lines" scrolled in the X direction. - * - * Note that not all browsers provide enough information to distinguish - * horizontal and vertical scroll events, so for these unsupported browsers, - * we will always have a deltaX of 0, even if the user scrolled their mouse - * wheel or trackpad sideways. - * - * Currently supported browsers are Webkit and Firefox 3.1 or later. - * - * @type {number} - */ - this.deltaX = deltaX; - - /** - * The number of lines scrolled in the Y direction. - * @type {number} - */ - this.deltaY = deltaY; -}; -goog.inherits(goog.events.MouseWheelEvent, goog.events.BrowserEvent); - -// Copyright 2013 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Basic strippable logging definitions. - * @see http://go/closurelogging - * - * @author johnlenz@google.com (John Lenz) - */ - -goog.provide('goog.log'); -goog.provide('goog.log.Level'); -goog.provide('goog.log.LogRecord'); -goog.provide('goog.log.Logger'); - -goog.require('goog.debug'); -goog.require('goog.debug.LogManager'); -goog.require('goog.debug.LogRecord'); -goog.require('goog.debug.Logger'); - - -/** @define {boolean} Whether logging is enabled. */ -goog.define('goog.log.ENABLED', goog.debug.LOGGING_ENABLED); - - -/** @const */ -goog.log.ROOT_LOGGER_NAME = goog.debug.Logger.ROOT_LOGGER_NAME; - - - -/** - * @constructor - * @final - */ -goog.log.Logger = goog.debug.Logger; - - - -/** - * @constructor - * @final - */ -goog.log.Level = goog.debug.Logger.Level; - - - -/** - * @constructor - * @final - */ -goog.log.LogRecord = goog.debug.LogRecord; - - -/** - * Finds or creates a logger for a named subsystem. If a logger has already been - * created with the given name it is returned. Otherwise a new logger is - * created. If a new logger is created its log level will be configured based - * on the goog.debug.LogManager configuration and it will configured to also - * send logging output to its parent's handlers. - * @see goog.debug.LogManager - * - * @param {string} name A name for the logger. This should be a dot-separated - * name and should normally be based on the package name or class name of - * the subsystem, such as goog.net.BrowserChannel. - * @param {goog.log.Level=} opt_level If provided, override the - * default logging level with the provided level. - * @return {goog.log.Logger} The named logger or null if logging is disabled. - */ -goog.log.getLogger = function(name, opt_level) { - if (goog.log.ENABLED) { - var logger = goog.debug.LogManager.getLogger(name); - if (opt_level && logger) { - logger.setLevel(opt_level); - } - return logger; - } else { - return null; - } -}; - - -// TODO(johnlenz): try to tighten the types to these functions. -/** - * Adds a handler to the logger. This doesn't use the event system because - * we want to be able to add logging to the event system. - * @param {goog.log.Logger} logger - * @param {Function} handler Handler function to add. - */ -goog.log.addHandler = function(logger, handler) { - if (goog.log.ENABLED && logger) { - logger.addHandler(handler); - } -}; - - -/** - * Removes a handler from the logger. This doesn't use the event system because - * we want to be able to add logging to the event system. - * @param {goog.log.Logger} logger - * @param {Function} handler Handler function to remove. - * @return {boolean} Whether the handler was removed. - */ -goog.log.removeHandler = function(logger, handler) { - if (goog.log.ENABLED && logger) { - return logger.removeHandler(handler); - } else { - return false; - } -}; - - -/** - * Logs a message. If the logger is currently enabled for the - * given message level then the given message is forwarded to all the - * registered output Handler objects. - * @param {goog.log.Logger} logger - * @param {goog.log.Level} level One of the level identifiers. - * @param {goog.debug.Loggable} msg The message to log. - * @param {Error|Object=} opt_exception An exception associated with the - * message. - */ -goog.log.log = function(logger, level, msg, opt_exception) { - if (goog.log.ENABLED && logger) { - logger.log(level, msg, opt_exception); - } -}; - - -/** - * Logs a message at the Level.SEVERE level. - * If the logger is currently enabled for the given message level then the - * given message is forwarded to all the registered output Handler objects. - * @param {goog.log.Logger} logger - * @param {goog.debug.Loggable} msg The message to log. - * @param {Error=} opt_exception An exception associated with the message. - */ -goog.log.error = function(logger, msg, opt_exception) { - if (goog.log.ENABLED && logger) { - logger.severe(msg, opt_exception); - } -}; - - -/** - * Logs a message at the Level.WARNING level. - * If the logger is currently enabled for the given message level then the - * given message is forwarded to all the registered output Handler objects. - * @param {goog.log.Logger} logger - * @param {goog.debug.Loggable} msg The message to log. - * @param {Error=} opt_exception An exception associated with the message. - */ -goog.log.warning = function(logger, msg, opt_exception) { - if (goog.log.ENABLED && logger) { - logger.warning(msg, opt_exception); - } -}; - - -/** - * Logs a message at the Level.INFO level. - * If the logger is currently enabled for the given message level then the - * given message is forwarded to all the registered output Handler objects. - * @param {goog.log.Logger} logger - * @param {goog.debug.Loggable} msg The message to log. - * @param {Error=} opt_exception An exception associated with the message. - */ -goog.log.info = function(logger, msg, opt_exception) { - if (goog.log.ENABLED && logger) { - logger.info(msg, opt_exception); - } -}; +goog.async.nextTick.wrapCallback_ = goog.functions.identity; -/** - * Logs a message at the Level.Fine level. - * If the logger is currently enabled for the given message level then the - * given message is forwarded to all the registered output Handler objects. - * @param {goog.log.Logger} logger - * @param {goog.debug.Loggable} msg The message to log. - * @param {Error=} opt_exception An exception associated with the message. - */ -goog.log.fine = function(logger, msg, opt_exception) { - if (goog.log.ENABLED && logger) { - logger.fine(msg, opt_exception); - } -}; +// Register the callback function as an entry point, so that it can be +// monitored for exception handling, etc. This has to be done in this file +// since it requires special code to handle all browsers. +goog.debug.entryPointRegistry.register( + /** + * @param {function(!Function): !Function} transformer The transforming + * function. + */ + function(transformer) { goog.async.nextTick.wrapCallback_ = transformer; }); // Based on https://github.com/Polymer/PointerEvents @@ -47113,9 +38011,8 @@ goog.log.fine = function(logger, msg, opt_exception) { goog.provide('ol.pointer.PointerEvent'); -goog.require('goog.events'); -goog.require('goog.events.Event'); - +goog.require('ol.events'); +goog.require('ol.events.Event'); /** @@ -47125,20 +38022,20 @@ goog.require('goog.events.Event'); * touch events and even native pointer events. * * @constructor - * @extends {goog.events.Event} + * @extends {ol.events.Event} * @param {string} type The type of the event to create. - * @param {goog.events.BrowserEvent} browserEvent + * @param {Event} originalEvent The event. * @param {Object.<string, ?>=} opt_eventDict An optional dictionary of * initial event properties. */ -ol.pointer.PointerEvent = function(type, browserEvent, opt_eventDict) { +ol.pointer.PointerEvent = function(type, originalEvent, opt_eventDict) { goog.base(this, type); /** * @const - * @type {goog.events.BrowserEvent} + * @type {Event} */ - this.browserEvent = browserEvent; + this.originalEvent = originalEvent; var eventDict = opt_eventDict ? opt_eventDict : {}; @@ -47269,19 +38166,19 @@ ol.pointer.PointerEvent = function(type, browserEvent, opt_eventDict) { this.isPrimary = 'isPrimary' in eventDict ? eventDict['isPrimary'] : false; // keep the semantics of preventDefault - if (browserEvent.preventDefault) { + if (originalEvent.preventDefault) { this.preventDefault = function() { - browserEvent.preventDefault(); + originalEvent.preventDefault(); }; } }; -goog.inherits(ol.pointer.PointerEvent, goog.events.Event); +goog.inherits(ol.pointer.PointerEvent, ol.events.Event); /** * @private - * @param {Object.<string, ?>} eventDict - * @return {number} + * @param {Object.<string, ?>} eventDict The event dictionary. + * @return {number} Button indicator. */ ol.pointer.PointerEvent.prototype.getButtons_ = function(eventDict) { // According to the w3c spec, @@ -47322,9 +38219,9 @@ ol.pointer.PointerEvent.prototype.getButtons_ = function(eventDict) { /** * @private - * @param {Object.<string, ?>} eventDict - * @param {number} buttons - * @return {number} + * @param {Object.<string, ?>} eventDict The event dictionary. + * @param {number} buttons Button indicator. + * @return {number} The pressure. */ ol.pointer.PointerEvent.prototype.getPressure_ = function(eventDict, buttons) { // Spec requires that pointers without pressure specified use 0.5 for down @@ -47354,16 +38251,13 @@ ol.pointer.PointerEvent.HAS_BUTTONS = false; var ev = new MouseEvent('click', {buttons: 1}); ol.pointer.PointerEvent.HAS_BUTTONS = ev.buttons === 1; } catch (e) { + // pass } })(); -// FIXME add tests for browser features (Modernizr?) - goog.provide('ol.dom'); -goog.provide('ol.dom.BrowserFeature'); goog.require('goog.asserts'); -goog.require('goog.dom'); goog.require('goog.userAgent'); goog.require('goog.vec.Mat4'); goog.require('ol'); @@ -47373,7 +38267,7 @@ goog.require('ol'); * Create an html canvas element and returns its 2d context. * @param {number=} opt_width Canvas width. * @param {number=} opt_height Canvas height. - * @return {CanvasRenderingContext2D} + * @return {CanvasRenderingContext2D} The context. */ ol.dom.createCanvasContext2D = function(opt_width, opt_height) { var canvas = document.createElement('CANVAS'); @@ -47399,31 +38293,29 @@ ol.dom.canUseCssTransform = (function() { if (canUseCssTransform === undefined) { goog.asserts.assert(document.body, 'document.body should not be null'); - if (!goog.global.getComputedStyle) { - // this browser is ancient - canUseCssTransform = false; - } else { - var el = document.createElement('P'), - has2d, - transforms = { - 'webkitTransform': '-webkit-transform', - 'OTransform': '-o-transform', - 'msTransform': '-ms-transform', - 'MozTransform': '-moz-transform', - 'transform': 'transform' - }; - document.body.appendChild(el); - for (var t in transforms) { - if (t in el.style) { - el.style[t] = 'translate(1px,1px)'; - has2d = goog.global.getComputedStyle(el).getPropertyValue( - transforms[t]); - } + goog.asserts.assert(ol.global.getComputedStyle, + 'getComputedStyle is required (unsupported browser?)'); + + var el = document.createElement('P'), + has2d, + transforms = { + 'webkitTransform': '-webkit-transform', + 'OTransform': '-o-transform', + 'msTransform': '-ms-transform', + 'MozTransform': '-moz-transform', + 'transform': 'transform' + }; + document.body.appendChild(el); + for (var t in transforms) { + if (t in el.style) { + el.style[t] = 'translate(1px,1px)'; + has2d = ol.global.getComputedStyle(el).getPropertyValue( + transforms[t]); } - goog.dom.removeNode(el); - - canUseCssTransform = (has2d && has2d !== 'none'); } + document.body.removeChild(el); + + canUseCssTransform = (has2d && has2d !== 'none'); } return canUseCssTransform; }; @@ -47442,31 +38334,29 @@ ol.dom.canUseCssTransform3D = (function() { if (canUseCssTransform3D === undefined) { goog.asserts.assert(document.body, 'document.body should not be null'); - if (!goog.global.getComputedStyle) { - // this browser is ancient - canUseCssTransform3D = false; - } else { - var el = document.createElement('P'), - has3d, - transforms = { - 'webkitTransform': '-webkit-transform', - 'OTransform': '-o-transform', - 'msTransform': '-ms-transform', - 'MozTransform': '-moz-transform', - 'transform': 'transform' - }; - document.body.appendChild(el); - for (var t in transforms) { - if (t in el.style) { - el.style[t] = 'translate3d(1px,1px,1px)'; - has3d = goog.global.getComputedStyle(el).getPropertyValue( - transforms[t]); - } + goog.asserts.assert(ol.global.getComputedStyle, + 'getComputedStyle is required (unsupported browser?)'); + + var el = document.createElement('P'), + has3d, + transforms = { + 'webkitTransform': '-webkit-transform', + 'OTransform': '-o-transform', + 'msTransform': '-ms-transform', + 'MozTransform': '-moz-transform', + 'transform': 'transform' + }; + document.body.appendChild(el); + for (var t in transforms) { + if (t in el.style) { + el.style[t] = 'translate3d(1px,1px,1px)'; + has3d = ol.global.getComputedStyle(el).getPropertyValue( + transforms[t]); } - goog.dom.removeNode(el); - - canUseCssTransform3D = (has3d && has3d !== 'none'); } + document.body.removeChild(el); + + canUseCssTransform3D = (has3d && has3d !== 'none'); } return canUseCssTransform3D; }; @@ -47555,11 +38445,11 @@ ol.dom.transformElement2D = function(element, transform, opt_precision) { * padding and border. * Equivalent to jQuery's `$(el).outerWidth(true)`. * @param {!Element} element Element. - * @return {number} + * @return {number} The width. */ ol.dom.outerWidth = function(element) { var width = element.offsetWidth; - var style = element.currentStyle || window.getComputedStyle(element); + var style = element.currentStyle || ol.global.getComputedStyle(element); width += parseInt(style.marginLeft, 10) + parseInt(style.marginRight, 10); return width; @@ -47571,11 +38461,11 @@ ol.dom.outerWidth = function(element) { * padding and border. * Equivalent to jQuery's `$(el).outerHeight(true)`. * @param {!Element} element Element. - * @return {number} + * @return {number} The height. */ ol.dom.outerHeight = function(element) { var height = element.offsetHeight; - var style = element.currentStyle || window.getComputedStyle(element); + var style = element.currentStyle || ol.global.getComputedStyle(element); height += parseInt(style.marginTop, 10) + parseInt(style.marginBottom, 10); return height; @@ -47621,6 +38511,7 @@ ol.webgl.getContext = function(canvas, opt_attributes) { return /** @type {!WebGLRenderingContext} */ (context); } } catch (e) { + // pass } } return null; @@ -47633,6 +38524,28 @@ goog.require('ol.dom'); goog.require('ol.webgl'); +var ua = typeof navigator !== 'undefined' ? + navigator.userAgent.toLowerCase() : ''; + +/** + * User agent string says we are dealing with Firefox as browser. + * @type {boolean} + */ +ol.has.FIREFOX = ua.indexOf('firefox') !== -1; + +/** + * User agent string says we are dealing with Safari as browser. + * @type {boolean} + */ +ol.has.SAFARI = ua.indexOf('safari') !== -1 && ua.indexOf('chrom') === -1; + +/** + * User agent string says we are dealing with a Mac as platform. + * @type {boolean} + */ +ol.has.MAC = ua.indexOf('macintosh') !== -1; + + /** * The ratio between physical pixels and device-independent pixels * (dips) on the device (`window.devicePixelRatio`). @@ -47640,7 +38553,7 @@ goog.require('ol.webgl'); * @type {number} * @api stable */ -ol.has.DEVICE_PIXEL_RATIO = goog.global.devicePixelRatio || 1; +ol.has.DEVICE_PIXEL_RATIO = ol.global.devicePixelRatio || 1; /** @@ -47662,7 +38575,7 @@ ol.has.CANVAS = ol.ENABLE_CANVAS && ( * @return {boolean} Canvas supported. */ function() { - if (!('HTMLCanvasElement' in goog.global)) { + if (!('HTMLCanvasElement' in ol.global)) { return false; } try { @@ -47687,7 +38600,7 @@ ol.has.CANVAS = ol.ENABLE_CANVAS && ( * @type {boolean} * @api stable */ -ol.has.DEVICE_ORIENTATION = 'DeviceOrientationEvent' in goog.global; +ol.has.DEVICE_ORIENTATION = 'DeviceOrientationEvent' in ol.global; /** @@ -47704,7 +38617,7 @@ ol.has.DOM = ol.ENABLE_DOM; * @type {boolean} * @api stable */ -ol.has.GEOLOCATION = 'geolocation' in goog.global.navigator; +ol.has.GEOLOCATION = 'geolocation' in ol.global.navigator; /** @@ -47713,7 +38626,7 @@ ol.has.GEOLOCATION = 'geolocation' in goog.global.navigator; * @type {boolean} * @api stable */ -ol.has.TOUCH = ol.ASSUME_TOUCH || 'ontouchstart' in goog.global; +ol.has.TOUCH = ol.ASSUME_TOUCH || 'ontouchstart' in ol.global; /** @@ -47721,7 +38634,7 @@ ol.has.TOUCH = ol.ASSUME_TOUCH || 'ontouchstart' in goog.global; * @const * @type {boolean} */ -ol.has.POINTER = 'PointerEvent' in goog.global; +ol.has.POINTER = 'PointerEvent' in ol.global; /** @@ -47729,7 +38642,7 @@ ol.has.POINTER = 'PointerEvent' in goog.global; * @const * @type {boolean} */ -ol.has.MSPOINTER = !!(goog.global.navigator.msPointerEnabled); +ol.has.MSPOINTER = !!(ol.global.navigator.msPointerEnabled); /** @@ -47748,7 +38661,7 @@ ol.has.WEBGL; var textureSize; var /** @type {Array.<string>} */ extensions = []; - if ('WebGLRenderingContext' in goog.global) { + if ('WebGLRenderingContext' in ol.global) { try { var canvas = /** @type {HTMLCanvasElement} */ (document.createElement('CANVAS')); @@ -47761,7 +38674,9 @@ ol.has.WEBGL; (gl.getParameter(gl.MAX_TEXTURE_SIZE)); extensions = gl.getSupportedExtensions(); } - } catch (e) {} + } catch (e) { + // pass + } } ol.has.WEBGL = hasWebGL; ol.WEBGL_EXTENSIONS = extensions; @@ -47771,13 +38686,11 @@ ol.has.WEBGL; goog.provide('ol.pointer.EventSource'); -goog.require('goog.events.BrowserEvent'); - - /** - * @param {ol.pointer.PointerEventHandler} dispatcher - * @param {!Object.<string, function(goog.events.BrowserEvent)>} mapping + * @param {ol.pointer.PointerEventHandler} dispatcher Event handler. + * @param {!Object.<string, function(Event)>} mapping Event + * mapping. * @constructor */ ol.pointer.EventSource = function(dispatcher, mapping) { @@ -47789,7 +38702,7 @@ ol.pointer.EventSource = function(dispatcher, mapping) { /** * @private * @const - * @type {!Object.<string, function(goog.events.BrowserEvent)>} + * @type {!Object.<string, function(Event)>} */ this.mapping_ = mapping; }; @@ -47807,7 +38720,7 @@ ol.pointer.EventSource.prototype.getEvents = function() { /** * Returns a mapping between the supported event types and * the handlers that should handle an event. - * @return {Object.<string, function(goog.events.BrowserEvent)>} + * @return {Object.<string, function(Event)>} * Event/Handler mapping */ ol.pointer.EventSource.prototype.getMapping = function() { @@ -47817,8 +38730,8 @@ ol.pointer.EventSource.prototype.getMapping = function() { /** * Returns the handler that should handle a given event type. - * @param {string} eventType - * @return {function(goog.events.BrowserEvent)} Handler + * @param {string} eventType The event type. + * @return {function(Event)} Handler */ ol.pointer.EventSource.prototype.getHandlerForEvent = function(eventType) { return this.mapping_[eventType]; @@ -47859,9 +38772,8 @@ goog.provide('ol.pointer.MouseSource'); goog.require('ol.pointer.EventSource'); - /** - * @param {ol.pointer.PointerEventHandler} dispatcher + * @param {ol.pointer.PointerEventHandler} dispatcher Event handler. * @constructor * @extends {ol.pointer.EventSource} */ @@ -47877,7 +38789,7 @@ ol.pointer.MouseSource = function(dispatcher) { /** * @const - * @type {!Object.<string, goog.events.BrowserEvent|Object>} + * @type {!Object.<string, Event|Object>} */ this.pointerMap = dispatcher.pointerMap; @@ -47934,11 +38846,10 @@ ol.pointer.MouseSource.DEDUP_DIST = 25; * or detect that the positions are invalid. * * @private - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. * @return {boolean} True, if the event was generated by a touch. */ -ol.pointer.MouseSource.prototype.isEventSimulatedFromTouch_ = - function(inEvent) { +ol.pointer.MouseSource.prototype.isEventSimulatedFromTouch_ = function(inEvent) { var lts = this.lastTouches; var x = inEvent.clientX, y = inEvent.clientY; for (var i = 0, l = lts.length, t; i < l && (t = lts[i]); i++) { @@ -47957,12 +38868,12 @@ ol.pointer.MouseSource.prototype.isEventSimulatedFromTouch_ = * Creates a copy of the original event that will be used * for the fake pointer event. * - * @param {goog.events.BrowserEvent} inEvent - * @param {ol.pointer.PointerEventHandler} dispatcher - * @return {Object} + * @param {Event} inEvent The in event. + * @param {ol.pointer.PointerEventHandler} dispatcher Event handler. + * @return {Object} The copied event. */ ol.pointer.MouseSource.prepareEvent = function(inEvent, dispatcher) { - var e = dispatcher.cloneEvent(inEvent, inEvent.getBrowserEvent()); + var e = dispatcher.cloneEvent(inEvent, inEvent); // forward mouse preventDefault var pd = e.preventDefault; @@ -47982,7 +38893,7 @@ ol.pointer.MouseSource.prepareEvent = function(inEvent, dispatcher) { /** * Handler for `mousedown`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.MouseSource.prototype.mousedown = function(inEvent) { if (!this.isEventSimulatedFromTouch_(inEvent)) { @@ -48001,7 +38912,7 @@ ol.pointer.MouseSource.prototype.mousedown = function(inEvent) { /** * Handler for `mousemove`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.MouseSource.prototype.mousemove = function(inEvent) { if (!this.isEventSimulatedFromTouch_(inEvent)) { @@ -48014,7 +38925,7 @@ ol.pointer.MouseSource.prototype.mousemove = function(inEvent) { /** * Handler for `mouseup`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.MouseSource.prototype.mouseup = function(inEvent) { if (!this.isEventSimulatedFromTouch_(inEvent)) { @@ -48032,7 +38943,7 @@ ol.pointer.MouseSource.prototype.mouseup = function(inEvent) { /** * Handler for `mouseover`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.MouseSource.prototype.mouseover = function(inEvent) { if (!this.isEventSimulatedFromTouch_(inEvent)) { @@ -48045,7 +38956,7 @@ ol.pointer.MouseSource.prototype.mouseover = function(inEvent) { /** * Handler for `mouseout`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.MouseSource.prototype.mouseout = function(inEvent) { if (!this.isEventSimulatedFromTouch_(inEvent)) { @@ -48058,7 +38969,7 @@ ol.pointer.MouseSource.prototype.mouseout = function(inEvent) { /** * Dispatches a `pointercancel` event. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.MouseSource.prototype.cancel = function(inEvent) { var e = ol.pointer.MouseSource.prepareEvent(inEvent, this.dispatcher); @@ -48109,9 +39020,8 @@ goog.provide('ol.pointer.MsSource'); goog.require('ol.pointer.EventSource'); - /** - * @param {ol.pointer.PointerEventHandler} dispatcher + * @param {ol.pointer.PointerEventHandler} dispatcher Event handler. * @constructor * @extends {ol.pointer.EventSource} */ @@ -48130,7 +39040,7 @@ ol.pointer.MsSource = function(dispatcher) { /** * @const - * @type {!Object.<string, goog.events.BrowserEvent|Object>} + * @type {!Object.<string, Event|Object>} */ this.pointerMap = dispatcher.pointerMap; @@ -48154,14 +39064,14 @@ goog.inherits(ol.pointer.MsSource, ol.pointer.EventSource); * for the fake pointer event. * * @private - * @param {goog.events.BrowserEvent} inEvent - * @return {Object} + * @param {Event} inEvent The in event. + * @return {Object} The copied event. */ ol.pointer.MsSource.prototype.prepareEvent_ = function(inEvent) { var e = inEvent; - if (goog.isNumber(inEvent.getBrowserEvent().pointerType)) { - e = this.dispatcher.cloneEvent(inEvent, inEvent.getBrowserEvent()); - e.pointerType = this.POINTER_TYPES[inEvent.getBrowserEvent().pointerType]; + if (goog.isNumber(inEvent.pointerType)) { + e = this.dispatcher.cloneEvent(inEvent, inEvent); + e.pointerType = this.POINTER_TYPES[inEvent.pointerType]; } return e; @@ -48170,7 +39080,7 @@ ol.pointer.MsSource.prototype.prepareEvent_ = function(inEvent) { /** * Remove this pointer from the list of active pointers. - * @param {number} pointerId + * @param {number} pointerId Pointer identifier. */ ol.pointer.MsSource.prototype.cleanup = function(pointerId) { delete this.pointerMap[pointerId.toString()]; @@ -48180,10 +39090,10 @@ ol.pointer.MsSource.prototype.cleanup = function(pointerId) { /** * Handler for `msPointerDown`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.MsSource.prototype.msPointerDown = function(inEvent) { - this.pointerMap[inEvent.getBrowserEvent().pointerId.toString()] = inEvent; + this.pointerMap[inEvent.pointerId.toString()] = inEvent; var e = this.prepareEvent_(inEvent); this.dispatcher.down(e, inEvent); }; @@ -48192,7 +39102,7 @@ ol.pointer.MsSource.prototype.msPointerDown = function(inEvent) { /** * Handler for `msPointerMove`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.MsSource.prototype.msPointerMove = function(inEvent) { var e = this.prepareEvent_(inEvent); @@ -48203,19 +39113,19 @@ ol.pointer.MsSource.prototype.msPointerMove = function(inEvent) { /** * Handler for `msPointerUp`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.MsSource.prototype.msPointerUp = function(inEvent) { var e = this.prepareEvent_(inEvent); this.dispatcher.up(e, inEvent); - this.cleanup(inEvent.getBrowserEvent().pointerId); + this.cleanup(inEvent.pointerId); }; /** * Handler for `msPointerOut`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.MsSource.prototype.msPointerOut = function(inEvent) { var e = this.prepareEvent_(inEvent); @@ -48226,7 +39136,7 @@ ol.pointer.MsSource.prototype.msPointerOut = function(inEvent) { /** * Handler for `msPointerOver`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.MsSource.prototype.msPointerOver = function(inEvent) { var e = this.prepareEvent_(inEvent); @@ -48237,23 +39147,23 @@ ol.pointer.MsSource.prototype.msPointerOver = function(inEvent) { /** * Handler for `msPointerCancel`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.MsSource.prototype.msPointerCancel = function(inEvent) { var e = this.prepareEvent_(inEvent); this.dispatcher.cancel(e, inEvent); - this.cleanup(inEvent.getBrowserEvent().pointerId); + this.cleanup(inEvent.pointerId); }; /** * Handler for `msLostPointerCapture`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.MsSource.prototype.msLostPointerCapture = function(inEvent) { var e = this.dispatcher.makeEvent('lostpointercapture', - inEvent.getBrowserEvent(), inEvent); + inEvent, inEvent); this.dispatcher.dispatchEvent(e); }; @@ -48261,11 +39171,11 @@ ol.pointer.MsSource.prototype.msLostPointerCapture = function(inEvent) { /** * Handler for `msGotPointerCapture`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.MsSource.prototype.msGotPointerCapture = function(inEvent) { var e = this.dispatcher.makeEvent('gotpointercapture', - inEvent.getBrowserEvent(), inEvent); + inEvent, inEvent); this.dispatcher.dispatchEvent(e); }; @@ -48304,9 +39214,8 @@ goog.provide('ol.pointer.NativeSource'); goog.require('ol.pointer.EventSource'); - /** - * @param {ol.pointer.PointerEventHandler} dispatcher + * @param {ol.pointer.PointerEventHandler} dispatcher Event handler. * @constructor * @extends {ol.pointer.EventSource} */ @@ -48329,7 +39238,7 @@ goog.inherits(ol.pointer.NativeSource, ol.pointer.EventSource); /** * Handler for `pointerdown`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.NativeSource.prototype.pointerDown = function(inEvent) { this.dispatcher.fireNativeEvent(inEvent); @@ -48339,7 +39248,7 @@ ol.pointer.NativeSource.prototype.pointerDown = function(inEvent) { /** * Handler for `pointermove`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.NativeSource.prototype.pointerMove = function(inEvent) { this.dispatcher.fireNativeEvent(inEvent); @@ -48349,7 +39258,7 @@ ol.pointer.NativeSource.prototype.pointerMove = function(inEvent) { /** * Handler for `pointerup`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.NativeSource.prototype.pointerUp = function(inEvent) { this.dispatcher.fireNativeEvent(inEvent); @@ -48359,7 +39268,7 @@ ol.pointer.NativeSource.prototype.pointerUp = function(inEvent) { /** * Handler for `pointerout`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.NativeSource.prototype.pointerOut = function(inEvent) { this.dispatcher.fireNativeEvent(inEvent); @@ -48369,7 +39278,7 @@ ol.pointer.NativeSource.prototype.pointerOut = function(inEvent) { /** * Handler for `pointerover`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.NativeSource.prototype.pointerOver = function(inEvent) { this.dispatcher.fireNativeEvent(inEvent); @@ -48379,7 +39288,7 @@ ol.pointer.NativeSource.prototype.pointerOver = function(inEvent) { /** * Handler for `pointercancel`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.NativeSource.prototype.pointerCancel = function(inEvent) { this.dispatcher.fireNativeEvent(inEvent); @@ -48389,7 +39298,7 @@ ol.pointer.NativeSource.prototype.pointerCancel = function(inEvent) { /** * Handler for `lostpointercapture`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.NativeSource.prototype.lostPointerCapture = function(inEvent) { this.dispatcher.fireNativeEvent(inEvent); @@ -48399,7 +39308,7 @@ ol.pointer.NativeSource.prototype.lostPointerCapture = function(inEvent) { /** * Handler for `gotpointercapture`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.NativeSource.prototype.gotPointerCapture = function(inEvent) { this.dispatcher.fireNativeEvent(inEvent); @@ -48437,18 +39346,16 @@ ol.pointer.NativeSource.prototype.gotPointerCapture = function(inEvent) { goog.provide('ol.pointer.TouchSource'); -goog.require('goog.array'); -goog.require('goog.object'); goog.require('ol'); +goog.require('ol.array'); goog.require('ol.pointer.EventSource'); goog.require('ol.pointer.MouseSource'); - /** * @constructor - * @param {ol.pointer.PointerEventHandler} dispatcher - * @param {ol.pointer.MouseSource} mouseSource + * @param {ol.pointer.PointerEventHandler} dispatcher The event handler. + * @param {ol.pointer.MouseSource} mouseSource Mouse source. * @extends {ol.pointer.EventSource} */ ol.pointer.TouchSource = function(dispatcher, mouseSource) { @@ -48462,7 +39369,7 @@ ol.pointer.TouchSource = function(dispatcher, mouseSource) { /** * @const - * @type {!Object.<string, goog.events.BrowserEvent|Object>} + * @type {!Object.<string, Event|Object>} */ this.pointerMap = dispatcher.pointerMap; @@ -48518,7 +39425,7 @@ ol.pointer.TouchSource.POINTER_TYPE = 'touch'; /** * @private - * @param {Touch} inTouch + * @param {Touch} inTouch The in touch. * @return {boolean} True, if this is the primary touch. */ ol.pointer.TouchSource.prototype.isPrimaryTouch_ = function(inTouch) { @@ -48528,11 +39435,11 @@ ol.pointer.TouchSource.prototype.isPrimaryTouch_ = function(inTouch) { /** * Set primary touch if there are no pointers, or the only pointer is the mouse. - * @param {Touch} inTouch + * @param {Touch} inTouch The in touch. * @private */ ol.pointer.TouchSource.prototype.setPrimaryTouch_ = function(inTouch) { - var count = goog.object.getCount(this.pointerMap); + var count = Object.keys(this.pointerMap).length; if (count === 0 || (count === 1 && ol.pointer.MouseSource.POINTER_ID.toString() in this.pointerMap)) { this.firstTouchId_ = inTouch.identifier; @@ -48543,7 +39450,7 @@ ol.pointer.TouchSource.prototype.setPrimaryTouch_ = function(inTouch) { /** * @private - * @param {Object} inPointer + * @param {Object} inPointer The in pointer object. */ ol.pointer.TouchSource.prototype.removePrimaryPointer_ = function(inPointer) { if (inPointer.isPrimary) { @@ -48557,8 +39464,8 @@ ol.pointer.TouchSource.prototype.removePrimaryPointer_ = function(inPointer) { * @private */ ol.pointer.TouchSource.prototype.resetClickCount_ = function() { - this.resetId_ = goog.global.setTimeout( - goog.bind(this.resetClickCountHandler_, this), + this.resetId_ = ol.global.setTimeout( + this.resetClickCountHandler_.bind(this), ol.pointer.TouchSource.CLICK_COUNT_TIMEOUT); }; @@ -48577,19 +39484,18 @@ ol.pointer.TouchSource.prototype.resetClickCountHandler_ = function() { */ ol.pointer.TouchSource.prototype.cancelResetClickCount_ = function() { if (this.resetId_ !== undefined) { - goog.global.clearTimeout(this.resetId_); + ol.global.clearTimeout(this.resetId_); } }; /** * @private - * @param {goog.events.BrowserEvent} browserEvent Browser event + * @param {Event} browserEvent Browser event * @param {Touch} inTouch Touch event - * @return {Object} + * @return {Object} A pointer object. */ -ol.pointer.TouchSource.prototype.touchToPointer_ = - function(browserEvent, inTouch) { +ol.pointer.TouchSource.prototype.touchToPointer_ = function(browserEvent, inTouch) { var e = this.dispatcher.cloneEvent(browserEvent, inTouch); // Spec specifies that pointerId 1 is reserved for Mouse. // Touch identifiers can start at 0. @@ -48621,13 +39527,12 @@ ol.pointer.TouchSource.prototype.touchToPointer_ = /** * @private - * @param {goog.events.BrowserEvent} inEvent Touch event - * @param {function(goog.events.BrowserEvent, Object)} inFunction + * @param {Event} inEvent Touch event + * @param {function(Event, Object)} inFunction In function. */ -ol.pointer.TouchSource.prototype.processTouches_ = - function(inEvent, inFunction) { +ol.pointer.TouchSource.prototype.processTouches_ = function(inEvent, inFunction) { var touches = Array.prototype.slice.call( - inEvent.getBrowserEvent().changedTouches); + inEvent.changedTouches); var count = touches.length; function preventDefault() { inEvent.preventDefault(); @@ -48644,8 +39549,8 @@ ol.pointer.TouchSource.prototype.processTouches_ = /** * @private - * @param {TouchList} touchList - * @param {number} searchId + * @param {TouchList} touchList The touch list. + * @param {number} searchId Search identifier. * @return {boolean} True, if the `Touch` with the given id is in the list. */ ol.pointer.TouchSource.prototype.findTouch_ = function(touchList, searchId) { @@ -48670,10 +39575,10 @@ ol.pointer.TouchSource.prototype.findTouch_ = function(touchList, searchId) { * this "abandoned" touch * * @private - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.TouchSource.prototype.vacuumTouches_ = function(inEvent) { - var touchList = inEvent.getBrowserEvent().touches; + var touchList = inEvent.touches; // pointerMap.getCount() should be < touchList.length here, // as the touchstart has not been processed yet. var keys = Object.keys(this.pointerMap); @@ -48703,11 +39608,11 @@ ol.pointer.TouchSource.prototype.vacuumTouches_ = function(inEvent) { * Handler for `touchstart`, triggers `pointerover`, * `pointerenter` and `pointerdown` events. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.TouchSource.prototype.touchstart = function(inEvent) { this.vacuumTouches_(inEvent); - this.setPrimaryTouch_(inEvent.getBrowserEvent().changedTouches[0]); + this.setPrimaryTouch_(inEvent.changedTouches[0]); this.dedupSynthMouse_(inEvent); this.clickCount_++; this.processTouches_(inEvent, this.overDown_); @@ -48716,8 +39621,8 @@ ol.pointer.TouchSource.prototype.touchstart = function(inEvent) { /** * @private - * @param {goog.events.BrowserEvent} browserEvent - * @param {Object} inPointer + * @param {Event} browserEvent The event. + * @param {Object} inPointer The in pointer object. */ ol.pointer.TouchSource.prototype.overDown_ = function(browserEvent, inPointer) { this.pointerMap[inPointer.pointerId] = { @@ -48734,7 +39639,7 @@ ol.pointer.TouchSource.prototype.overDown_ = function(browserEvent, inPointer) { /** * Handler for `touchmove`. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.TouchSource.prototype.touchmove = function(inEvent) { inEvent.preventDefault(); @@ -48744,11 +39649,10 @@ ol.pointer.TouchSource.prototype.touchmove = function(inEvent) { /** * @private - * @param {goog.events.BrowserEvent} browserEvent - * @param {Object} inPointer + * @param {Event} browserEvent The event. + * @param {Object} inPointer The in pointer. */ -ol.pointer.TouchSource.prototype.moveOverOut_ = - function(browserEvent, inPointer) { +ol.pointer.TouchSource.prototype.moveOverOut_ = function(browserEvent, inPointer) { var event = inPointer; var pointer = this.pointerMap[event.pointerId]; // a finger drifted off the screen, ignore it @@ -48782,7 +39686,7 @@ ol.pointer.TouchSource.prototype.moveOverOut_ = * Handler for `touchend`, triggers `pointerup`, * `pointerout` and `pointerleave` events. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The event. */ ol.pointer.TouchSource.prototype.touchend = function(inEvent) { this.dedupSynthMouse_(inEvent); @@ -48792,8 +39696,8 @@ ol.pointer.TouchSource.prototype.touchend = function(inEvent) { /** * @private - * @param {goog.events.BrowserEvent} browserEvent - * @param {Object} inPointer + * @param {Event} browserEvent An event. + * @param {Object} inPointer The inPointer object. */ ol.pointer.TouchSource.prototype.upOut_ = function(browserEvent, inPointer) { this.dispatcher.up(inPointer, browserEvent); @@ -48807,7 +39711,7 @@ ol.pointer.TouchSource.prototype.upOut_ = function(browserEvent, inPointer) { * Handler for `touchcancel`, triggers `pointercancel`, * `pointerout` and `pointerleave` events. * - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.TouchSource.prototype.touchcancel = function(inEvent) { this.processTouches_(inEvent, this.cancelOut_); @@ -48816,11 +39720,10 @@ ol.pointer.TouchSource.prototype.touchcancel = function(inEvent) { /** * @private - * @param {goog.events.BrowserEvent} browserEvent - * @param {Object} inPointer + * @param {Event} browserEvent The event. + * @param {Object} inPointer The in pointer. */ -ol.pointer.TouchSource.prototype.cancelOut_ = - function(browserEvent, inPointer) { +ol.pointer.TouchSource.prototype.cancelOut_ = function(browserEvent, inPointer) { this.dispatcher.cancel(inPointer, browserEvent); this.dispatcher.out(inPointer, browserEvent); this.dispatcher.leave(inPointer, browserEvent); @@ -48830,7 +39733,7 @@ ol.pointer.TouchSource.prototype.cancelOut_ = /** * @private - * @param {Object} inPointer + * @param {Object} inPointer The inPointer object. */ ol.pointer.TouchSource.prototype.cleanUpPointer_ = function(inPointer) { delete this.pointerMap[inPointer.pointerId]; @@ -48842,20 +39745,20 @@ ol.pointer.TouchSource.prototype.cleanUpPointer_ = function(inPointer) { * Prevent synth mouse events from creating pointer events. * * @private - * @param {goog.events.BrowserEvent} inEvent + * @param {Event} inEvent The in event. */ ol.pointer.TouchSource.prototype.dedupSynthMouse_ = function(inEvent) { var lts = this.mouseSource.lastTouches; - var t = inEvent.getBrowserEvent().changedTouches[0]; + var t = inEvent.changedTouches[0]; // only the primary finger will synth mouse events if (this.isPrimaryTouch_(t)) { // remember x/y of last touch - var lt = /** @type {ol.Pixel} */ ([t.clientX, t.clientY]); + var lt = [t.clientX, t.clientY]; lts.push(lt); - goog.global.setTimeout(function() { + ol.global.setTimeout(function() { // remove touch after timeout - goog.array.remove(lts, lt); + ol.array.remove(lts, lt); }, ol.pointer.TouchSource.DEDUP_TIMEOUT); } }; @@ -48893,9 +39796,8 @@ ol.pointer.TouchSource.prototype.dedupSynthMouse_ = function(inEvent) { goog.provide('ol.pointer.PointerEventHandler'); goog.require('goog.dom'); -goog.require('goog.events'); -goog.require('goog.events.BrowserEvent'); -goog.require('goog.events.EventTarget'); +goog.require('ol.events'); +goog.require('ol.events.EventTarget'); goog.require('ol.has'); goog.require('ol.pointer.MouseSource'); @@ -48905,10 +39807,9 @@ goog.require('ol.pointer.PointerEvent'); goog.require('ol.pointer.TouchSource'); - /** * @constructor - * @extends {goog.events.EventTarget} + * @extends {ol.events.EventTarget} * @param {Element|HTMLDocument} element Viewport element. */ ol.pointer.PointerEventHandler = function(element) { @@ -48923,12 +39824,12 @@ ol.pointer.PointerEventHandler = function(element) { /** * @const - * @type {!Object.<string, goog.events.BrowserEvent|Object>} + * @type {!Object.<string, Event|Object>} */ this.pointerMap = {}; /** - * @type {Object.<string, function(goog.events.BrowserEvent)>} + * @type {Object.<string, function(Event)>} * @private */ this.eventMap_ = {}; @@ -48941,7 +39842,7 @@ ol.pointer.PointerEventHandler = function(element) { this.registerSources(); }; -goog.inherits(ol.pointer.PointerEventHandler, goog.events.EventTarget); +goog.inherits(ol.pointer.PointerEventHandler, ol.events.EventTarget); /** @@ -48972,10 +39873,9 @@ ol.pointer.PointerEventHandler.prototype.registerSources = function() { * Add a new event source that will generate pointer events. * * @param {string} name A name for the event source - * @param {ol.pointer.EventSource} source + * @param {ol.pointer.EventSource} source The source event. */ -ol.pointer.PointerEventHandler.prototype.registerSource = - function(name, source) { +ol.pointer.PointerEventHandler.prototype.registerSource = function(name, source) { var s = source; var newEvents = s.getEvents(); @@ -48984,7 +39884,7 @@ ol.pointer.PointerEventHandler.prototype.registerSource = var handler = s.getHandlerForEvent(e); if (handler) { - this.eventMap_[e] = goog.bind(handler, s); + this.eventMap_[e] = handler.bind(s); } }, this); this.eventSourceList_.push(s); @@ -49023,7 +39923,7 @@ ol.pointer.PointerEventHandler.prototype.unregister_ = function() { /** * Calls the right handler for a new event. * @private - * @param {goog.events.BrowserEvent} inEvent Browser event. + * @param {Event} inEvent Browser event. */ ol.pointer.PointerEventHandler.prototype.eventHandler_ = function(inEvent) { var type = inEvent.type; @@ -49041,8 +39941,7 @@ ol.pointer.PointerEventHandler.prototype.eventHandler_ = function(inEvent) { */ ol.pointer.PointerEventHandler.prototype.addEvents_ = function(events) { events.forEach(function(eventName) { - goog.events.listen(this.element_, eventName, - this.eventHandler_, false, this); + ol.events.listen(this.element_, eventName, this.eventHandler_, this); }, this); }; @@ -49054,8 +39953,7 @@ ol.pointer.PointerEventHandler.prototype.addEvents_ = function(events) { */ ol.pointer.PointerEventHandler.prototype.removeEvents_ = function(events) { events.forEach(function(e) { - goog.events.unlisten(this.element_, e, - this.eventHandler_, false, this); + ol.events.unlisten(this.element_, e, this.eventHandler_, this); }, this); }; @@ -49063,21 +39961,17 @@ ol.pointer.PointerEventHandler.prototype.removeEvents_ = function(events) { /** * Returns a snapshot of inEvent, with writable properties. * - * @param {goog.events.BrowserEvent} browserEvent Browser event. + * @param {Event} event Browser event. * @param {Event|Touch} inEvent An event that contains * properties to copy. * @return {Object} An object containing shallow copies of * `inEvent`'s properties. */ -ol.pointer.PointerEventHandler.prototype.cloneEvent = - function(browserEvent, inEvent) { +ol.pointer.PointerEventHandler.prototype.cloneEvent = function(event, inEvent) { var eventCopy = {}, p; for (var i = 0, ii = ol.pointer.CLONE_PROPS.length; i < ii; i++) { p = ol.pointer.CLONE_PROPS[i][0]; - eventCopy[p] = - browserEvent[p] || - inEvent[p] || - ol.pointer.CLONE_PROPS[i][1]; + eventCopy[p] = event[p] || inEvent[p] || ol.pointer.CLONE_PROPS[i][1]; } return eventCopy; @@ -49089,145 +39983,122 @@ ol.pointer.PointerEventHandler.prototype.cloneEvent = /** * Triggers a 'pointerdown' event. - * @param {Object} pointerEventData - * @param {goog.events.BrowserEvent} browserEvent + * @param {Object} data Pointer event data. + * @param {Event} event The event. */ -ol.pointer.PointerEventHandler.prototype.down = - function(pointerEventData, browserEvent) { - this.fireEvent(ol.pointer.EventType.POINTERDOWN, - pointerEventData, browserEvent); +ol.pointer.PointerEventHandler.prototype.down = function(data, event) { + this.fireEvent(ol.pointer.EventType.POINTERDOWN, data, event); }; /** * Triggers a 'pointermove' event. - * @param {Object} pointerEventData - * @param {goog.events.BrowserEvent} browserEvent + * @param {Object} data Pointer event data. + * @param {Event} event The event. */ -ol.pointer.PointerEventHandler.prototype.move = - function(pointerEventData, browserEvent) { - this.fireEvent(ol.pointer.EventType.POINTERMOVE, - pointerEventData, browserEvent); +ol.pointer.PointerEventHandler.prototype.move = function(data, event) { + this.fireEvent(ol.pointer.EventType.POINTERMOVE, data, event); }; /** * Triggers a 'pointerup' event. - * @param {Object} pointerEventData - * @param {goog.events.BrowserEvent} browserEvent + * @param {Object} data Pointer event data. + * @param {Event} event The event. */ -ol.pointer.PointerEventHandler.prototype.up = - function(pointerEventData, browserEvent) { - this.fireEvent(ol.pointer.EventType.POINTERUP, - pointerEventData, browserEvent); +ol.pointer.PointerEventHandler.prototype.up = function(data, event) { + this.fireEvent(ol.pointer.EventType.POINTERUP, data, event); }; /** * Triggers a 'pointerenter' event. - * @param {Object} pointerEventData - * @param {goog.events.BrowserEvent} browserEvent + * @param {Object} data Pointer event data. + * @param {Event} event The event. */ -ol.pointer.PointerEventHandler.prototype.enter = - function(pointerEventData, browserEvent) { - pointerEventData.bubbles = false; - this.fireEvent(ol.pointer.EventType.POINTERENTER, - pointerEventData, browserEvent); +ol.pointer.PointerEventHandler.prototype.enter = function(data, event) { + data.bubbles = false; + this.fireEvent(ol.pointer.EventType.POINTERENTER, data, event); }; /** * Triggers a 'pointerleave' event. - * @param {Object} pointerEventData - * @param {goog.events.BrowserEvent} browserEvent + * @param {Object} data Pointer event data. + * @param {Event} event The event. */ -ol.pointer.PointerEventHandler.prototype.leave = - function(pointerEventData, browserEvent) { - pointerEventData.bubbles = false; - this.fireEvent(ol.pointer.EventType.POINTERLEAVE, - pointerEventData, browserEvent); +ol.pointer.PointerEventHandler.prototype.leave = function(data, event) { + data.bubbles = false; + this.fireEvent(ol.pointer.EventType.POINTERLEAVE, data, event); }; /** * Triggers a 'pointerover' event. - * @param {Object} pointerEventData - * @param {goog.events.BrowserEvent} browserEvent + * @param {Object} data Pointer event data. + * @param {Event} event The event. */ -ol.pointer.PointerEventHandler.prototype.over = - function(pointerEventData, browserEvent) { - pointerEventData.bubbles = true; - this.fireEvent(ol.pointer.EventType.POINTEROVER, - pointerEventData, browserEvent); +ol.pointer.PointerEventHandler.prototype.over = function(data, event) { + data.bubbles = true; + this.fireEvent(ol.pointer.EventType.POINTEROVER, data, event); }; /** * Triggers a 'pointerout' event. - * @param {Object} pointerEventData - * @param {goog.events.BrowserEvent} browserEvent + * @param {Object} data Pointer event data. + * @param {Event} event The event. */ -ol.pointer.PointerEventHandler.prototype.out = - function(pointerEventData, browserEvent) { - pointerEventData.bubbles = true; - this.fireEvent(ol.pointer.EventType.POINTEROUT, - pointerEventData, browserEvent); +ol.pointer.PointerEventHandler.prototype.out = function(data, event) { + data.bubbles = true; + this.fireEvent(ol.pointer.EventType.POINTEROUT, data, event); }; /** * Triggers a 'pointercancel' event. - * @param {Object} pointerEventData - * @param {goog.events.BrowserEvent} browserEvent + * @param {Object} data Pointer event data. + * @param {Event} event The event. */ -ol.pointer.PointerEventHandler.prototype.cancel = - function(pointerEventData, browserEvent) { - this.fireEvent(ol.pointer.EventType.POINTERCANCEL, - pointerEventData, browserEvent); +ol.pointer.PointerEventHandler.prototype.cancel = function(data, event) { + this.fireEvent(ol.pointer.EventType.POINTERCANCEL, data, event); }; /** * Triggers a combination of 'pointerout' and 'pointerleave' events. - * @param {Object} pointerEventData - * @param {goog.events.BrowserEvent} browserEvent + * @param {Object} data Pointer event data. + * @param {Event} event The event. */ -ol.pointer.PointerEventHandler.prototype.leaveOut = - function(pointerEventData, browserEvent) { - this.out(pointerEventData, browserEvent); - if (!this.contains_( - pointerEventData.target, - pointerEventData.relatedTarget)) { - this.leave(pointerEventData, browserEvent); +ol.pointer.PointerEventHandler.prototype.leaveOut = function(data, event) { + this.out(data, event); + if (!this.contains_(data.target, data.relatedTarget)) { + this.leave(data, event); } }; /** * Triggers a combination of 'pointerover' and 'pointerevents' events. - * @param {Object} pointerEventData - * @param {goog.events.BrowserEvent} browserEvent + * @param {Object} data Pointer event data. + * @param {Event} event The event. */ -ol.pointer.PointerEventHandler.prototype.enterOver = - function(pointerEventData, browserEvent) { - this.over(pointerEventData, browserEvent); - if (!this.contains_( - pointerEventData.target, - pointerEventData.relatedTarget)) { - this.enter(pointerEventData, browserEvent); +ol.pointer.PointerEventHandler.prototype.enterOver = function(data, event) { + this.over(data, event); + if (!this.contains_(data.target, data.relatedTarget)) { + this.enter(data, event); } }; /** * @private - * @param {Element} container - * @param {Element} contained + * @param {Element} container The container element. + * @param {Element} contained The contained element. * @return {boolean} Returns true if the container element * contains the other element. */ -ol.pointer.PointerEventHandler.prototype.contains_ = - function(container, contained) { +ol.pointer.PointerEventHandler.prototype.contains_ = function(container, contained) { if (!contained) { return false; } @@ -49238,28 +40109,26 @@ ol.pointer.PointerEventHandler.prototype.contains_ = // EVENT CREATION AND TRACKING /** * Creates a new Event of type `inType`, based on the information in - * `pointerEventData`. + * `data`. * * @param {string} inType A string representing the type of event to create. - * @param {Object} pointerEventData - * @param {goog.events.BrowserEvent} browserEvent + * @param {Object} data Pointer event data. + * @param {Event} event The event. * @return {ol.pointer.PointerEvent} A PointerEvent of type `inType`. */ -ol.pointer.PointerEventHandler.prototype.makeEvent = - function(inType, pointerEventData, browserEvent) { - return new ol.pointer.PointerEvent(inType, browserEvent, pointerEventData); +ol.pointer.PointerEventHandler.prototype.makeEvent = function(inType, data, event) { + return new ol.pointer.PointerEvent(inType, event, data); }; /** * Make and dispatch an event in one call. * @param {string} inType A string representing the type of event. - * @param {Object} pointerEventData - * @param {goog.events.BrowserEvent} browserEvent + * @param {Object} data Pointer event data. + * @param {Event} event The event. */ -ol.pointer.PointerEventHandler.prototype.fireEvent = - function(inType, pointerEventData, browserEvent) { - var e = this.makeEvent(inType, pointerEventData, browserEvent); +ol.pointer.PointerEventHandler.prototype.fireEvent = function(inType, data, event) { + var e = this.makeEvent(inType, data, event); this.dispatchEvent(e); }; @@ -49267,12 +40136,10 @@ ol.pointer.PointerEventHandler.prototype.fireEvent = /** * Creates a pointer event from a native pointer event * and dispatches this event. - * @param {goog.events.BrowserEvent} nativeEvent A platform event with a target. + * @param {Event} event A platform event with a target. */ -ol.pointer.PointerEventHandler.prototype.fireNativeEvent = - function(nativeEvent) { - var e = this.makeEvent(nativeEvent.type, nativeEvent.getBrowserEvent(), - nativeEvent); +ol.pointer.PointerEventHandler.prototype.fireNativeEvent = function(event) { + var e = this.makeEvent(event.type, event, event); this.dispatchEvent(e); }; @@ -49281,16 +40148,12 @@ ol.pointer.PointerEventHandler.prototype.fireNativeEvent = * Wrap a native mouse event into a pointer event. * This proxy method is required for the legacy IE support. * @param {string} eventType The pointer event type. - * @param {goog.events.BrowserEvent} browserEvent - * @return {ol.pointer.PointerEvent} + * @param {Event} event The event. + * @return {ol.pointer.PointerEvent} The wrapped event. */ -ol.pointer.PointerEventHandler.prototype.wrapMouseEvent = - function(eventType, browserEvent) { +ol.pointer.PointerEventHandler.prototype.wrapMouseEvent = function(eventType, event) { var pointerEvent = this.makeEvent( - eventType, - ol.pointer.MouseSource.prepareEvent(browserEvent, this), - browserEvent - ); + eventType, ol.pointer.MouseSource.prepareEvent(event, this), event); return pointerEvent; }; @@ -49365,20 +40228,15 @@ goog.provide('ol.MapBrowserEventHandler'); goog.provide('ol.MapBrowserPointerEvent'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.BrowserEvent'); -goog.require('goog.events.EventTarget'); -goog.require('goog.events.EventType'); -goog.require('goog.object'); goog.require('ol'); -goog.require('ol.Coordinate'); goog.require('ol.MapEvent'); -goog.require('ol.Pixel'); +goog.require('ol.events'); +goog.require('ol.events.EventTarget'); +goog.require('ol.events.EventType'); goog.require('ol.pointer.PointerEvent'); goog.require('ol.pointer.PointerEventHandler'); - /** * @classdesc * Events emitted as map browser events are instances of this type. @@ -49389,7 +40247,7 @@ goog.require('ol.pointer.PointerEventHandler'); * @implements {oli.MapBrowserEvent} * @param {string} type Event type. * @param {ol.Map} map Map. - * @param {goog.events.BrowserEvent} browserEvent Browser event. + * @param {Event} browserEvent Browser event. * @param {boolean=} opt_dragging Is the map currently being dragged? * @param {?olx.FrameState=} opt_frameState Frame state. */ @@ -49399,25 +40257,19 @@ ol.MapBrowserEvent = function(type, map, browserEvent, opt_dragging, goog.base(this, type, map, opt_frameState); /** - * @const - * @type {goog.events.BrowserEvent} - */ - this.browserEvent = browserEvent; - - /** * The original browser event. * @const * @type {Event} * @api stable */ - this.originalEvent = browserEvent.getBrowserEvent(); + this.originalEvent = browserEvent; /** * The pixel of the original browser event. * @type {ol.Pixel} * @api stable */ - this.pixel = map.getEventPixel(this.originalEvent); + this.pixel = map.getEventPixel(browserEvent); /** * The coordinate of the original browser event. @@ -49447,7 +40299,7 @@ goog.inherits(ol.MapBrowserEvent, ol.MapEvent); */ ol.MapBrowserEvent.prototype.preventDefault = function() { goog.base(this, 'preventDefault'); - this.browserEvent.preventDefault(); + this.originalEvent.preventDefault(); }; @@ -49459,11 +40311,10 @@ ol.MapBrowserEvent.prototype.preventDefault = function() { */ ol.MapBrowserEvent.prototype.stopPropagation = function() { goog.base(this, 'stopPropagation'); - this.browserEvent.stopPropagation(); + this.originalEvent.stopPropagation(); }; - /** * @constructor * @extends {ol.MapBrowserEvent} @@ -49476,7 +40327,7 @@ ol.MapBrowserEvent.prototype.stopPropagation = function() { ol.MapBrowserPointerEvent = function(type, map, pointerEvent, opt_dragging, opt_frameState) { - goog.base(this, type, map, pointerEvent.browserEvent, opt_dragging, + goog.base(this, type, map, pointerEvent.originalEvent, opt_dragging, opt_frameState); /** @@ -49489,11 +40340,10 @@ ol.MapBrowserPointerEvent = function(type, map, pointerEvent, opt_dragging, goog.inherits(ol.MapBrowserPointerEvent, ol.MapBrowserEvent); - /** * @param {ol.Map} map The map with the viewport to listen to events on. * @constructor - * @extends {goog.events.EventTarget} + * @extends {ol.events.EventTarget} */ ol.MapBrowserEventHandler = function(map) { @@ -49519,16 +40369,10 @@ ol.MapBrowserEventHandler = function(map) { this.dragging_ = false; /** - * @type {Array.<goog.events.Key>} - * @private - */ - this.dragListenerKeys_ = null; - - /** - * @type {goog.events.Key} + * @type {!Array.<ol.events.Key>} * @private */ - this.pointerdownListenerKey_ = null; + this.dragListenerKeys_ = []; /** * The most recent "down" type event (or null if none have occurred). @@ -49547,7 +40391,7 @@ ol.MapBrowserEventHandler = function(map) { this.activePointers_ = 0; /** - * @type {Object.<number, boolean>} + * @type {!Object.<number, boolean>} * @private */ this.trackedTouches_ = {}; @@ -49570,16 +40414,24 @@ ol.MapBrowserEventHandler = function(map) { */ this.documentPointerEventHandler_ = null; - this.pointerdownListenerKey_ = goog.events.listen(this.pointerEventHandler_, + /** + * @type {?ol.events.Key} + * @private + */ + this.pointerdownListenerKey_ = ol.events.listen(this.pointerEventHandler_, ol.pointer.EventType.POINTERDOWN, - this.handlePointerDown_, false, this); + this.handlePointerDown_, this); - this.relayedListenerKey_ = goog.events.listen(this.pointerEventHandler_, + /** + * @type {?ol.events.Key} + * @private + */ + this.relayedListenerKey_ = ol.events.listen(this.pointerEventHandler_, ol.pointer.EventType.POINTERMOVE, - this.relayEvent_, false, this); + this.relayEvent_, this); }; -goog.inherits(ol.MapBrowserEventHandler, goog.events.EventTarget); +goog.inherits(ol.MapBrowserEventHandler, ol.events.EventTarget); /** @@ -49593,19 +40445,19 @@ ol.MapBrowserEventHandler.prototype.emulateClick_ = function(pointerEvent) { this.dispatchEvent(newEvent); if (this.clickTimeoutId_ !== 0) { // double-click - goog.global.clearTimeout(this.clickTimeoutId_); + ol.global.clearTimeout(this.clickTimeoutId_); this.clickTimeoutId_ = 0; newEvent = new ol.MapBrowserPointerEvent( ol.MapBrowserEvent.EventType.DBLCLICK, this.map_, pointerEvent); this.dispatchEvent(newEvent); } else { // click - this.clickTimeoutId_ = goog.global.setTimeout(goog.bind(function() { + this.clickTimeoutId_ = ol.global.setTimeout(function() { this.clickTimeoutId_ = 0; var newEvent = new ol.MapBrowserPointerEvent( ol.MapBrowserEvent.EventType.SINGLECLICK, this.map_, pointerEvent); this.dispatchEvent(newEvent); - }, this), 250); + }.bind(this), 250); } }; @@ -49616,8 +40468,7 @@ ol.MapBrowserEventHandler.prototype.emulateClick_ = function(pointerEvent) { * @param {ol.pointer.PointerEvent} pointerEvent Pointer event. * @private */ -ol.MapBrowserEventHandler.prototype.updateActivePointers_ = - function(pointerEvent) { +ol.MapBrowserEventHandler.prototype.updateActivePointers_ = function(pointerEvent) { var event = pointerEvent; if (event.type == ol.MapBrowserEvent.EventType.POINTERUP || @@ -49626,7 +40477,7 @@ ol.MapBrowserEventHandler.prototype.updateActivePointers_ = } else if (event.type == ol.MapBrowserEvent.EventType.POINTERDOWN) { this.trackedTouches_[event.pointerId] = true; } - this.activePointers_ = goog.object.getCount(this.trackedTouches_); + this.activePointers_ = Object.keys(this.trackedTouches_).length; }; @@ -49652,11 +40503,11 @@ ol.MapBrowserEventHandler.prototype.handlePointerUp_ = function(pointerEvent) { goog.asserts.assert(this.activePointers_ >= 0, 'this.activePointers_ should be equal to or larger than 0'); if (this.activePointers_ === 0) { - this.dragListenerKeys_.forEach(goog.events.unlistenByKey); - this.dragListenerKeys_ = null; + this.dragListenerKeys_.forEach(ol.events.unlistenByKey); + this.dragListenerKeys_.length = 0; this.dragging_ = false; this.down_ = null; - goog.dispose(this.documentPointerEventHandler_); + this.documentPointerEventHandler_.dispose(); this.documentPointerEventHandler_ = null; } }; @@ -49667,8 +40518,7 @@ ol.MapBrowserEventHandler.prototype.handlePointerUp_ = function(pointerEvent) { * @return {boolean} If the left mouse button was pressed. * @private */ -ol.MapBrowserEventHandler.prototype.isMouseActionButton_ = - function(pointerEvent) { +ol.MapBrowserEventHandler.prototype.isMouseActionButton_ = function(pointerEvent) { return pointerEvent.button === 0; }; @@ -49677,8 +40527,7 @@ ol.MapBrowserEventHandler.prototype.isMouseActionButton_ = * @param {ol.pointer.PointerEvent} pointerEvent Pointer event. * @private */ -ol.MapBrowserEventHandler.prototype.handlePointerDown_ = - function(pointerEvent) { +ol.MapBrowserEventHandler.prototype.handlePointerDown_ = function(pointerEvent) { this.updateActivePointers_(pointerEvent); var newEvent = new ol.MapBrowserPointerEvent( ol.MapBrowserEvent.EventType.POINTERDOWN, this.map_, pointerEvent); @@ -49686,7 +40535,7 @@ ol.MapBrowserEventHandler.prototype.handlePointerDown_ = this.down_ = pointerEvent; - if (!this.dragListenerKeys_) { + if (this.dragListenerKeys_.length === 0) { /* Set up a pointer event handler on the `document`, * which is required when the pointer is moved outside * the viewport when dragging. @@ -49694,13 +40543,13 @@ ol.MapBrowserEventHandler.prototype.handlePointerDown_ = this.documentPointerEventHandler_ = new ol.pointer.PointerEventHandler(document); - this.dragListenerKeys_ = [ - goog.events.listen(this.documentPointerEventHandler_, + this.dragListenerKeys_.push( + ol.events.listen(this.documentPointerEventHandler_, ol.MapBrowserEvent.EventType.POINTERMOVE, - this.handlePointerMove_, false, this), - goog.events.listen(this.documentPointerEventHandler_, + this.handlePointerMove_, this), + ol.events.listen(this.documentPointerEventHandler_, ol.MapBrowserEvent.EventType.POINTERUP, - this.handlePointerUp_, false, this), + this.handlePointerUp_, this), /* Note that the listener for `pointercancel is set up on * `pointerEventHandler_` and not `documentPointerEventHandler_` like * the `pointerup` and `pointermove` listeners. @@ -49714,10 +40563,10 @@ ol.MapBrowserEventHandler.prototype.handlePointerDown_ = * only receive a `touchcancel` from `pointerEventHandler_`, because it is * only registered there. */ - goog.events.listen(this.pointerEventHandler_, + ol.events.listen(this.pointerEventHandler_, ol.MapBrowserEvent.EventType.POINTERCANCEL, - this.handlePointerUp_, false, this) - ]; + this.handlePointerUp_, this) + ); } }; @@ -49726,8 +40575,7 @@ ol.MapBrowserEventHandler.prototype.handlePointerDown_ = * @param {ol.pointer.PointerEvent} pointerEvent Pointer event. * @private */ -ol.MapBrowserEventHandler.prototype.handlePointerMove_ = - function(pointerEvent) { +ol.MapBrowserEventHandler.prototype.handlePointerMove_ = function(pointerEvent) { // Fix IE10 on windows Surface : When you tap the tablet, it triggers // multiple pointermove events between pointerdown and pointerup with // the exact same coordinates of the pointerdown event. To avoid a @@ -49764,7 +40612,7 @@ ol.MapBrowserEventHandler.prototype.relayEvent_ = function(pointerEvent) { /** * @param {ol.pointer.PointerEvent} pointerEvent Pointer event. - * @return {boolean} + * @return {boolean} Is moving. * @private */ ol.MapBrowserEventHandler.prototype.isMoving_ = function(pointerEvent) { @@ -49778,23 +40626,23 @@ ol.MapBrowserEventHandler.prototype.isMoving_ = function(pointerEvent) { */ ol.MapBrowserEventHandler.prototype.disposeInternal = function() { if (this.relayedListenerKey_) { - goog.events.unlistenByKey(this.relayedListenerKey_); + ol.events.unlistenByKey(this.relayedListenerKey_); this.relayedListenerKey_ = null; } if (this.pointerdownListenerKey_) { - goog.events.unlistenByKey(this.pointerdownListenerKey_); + ol.events.unlistenByKey(this.pointerdownListenerKey_); this.pointerdownListenerKey_ = null; } - if (this.dragListenerKeys_) { - this.dragListenerKeys_.forEach(goog.events.unlistenByKey); - this.dragListenerKeys_ = null; - } + + this.dragListenerKeys_.forEach(ol.events.unlistenByKey); + this.dragListenerKeys_.length = 0; + if (this.documentPointerEventHandler_) { - goog.dispose(this.documentPointerEventHandler_); + this.documentPointerEventHandler_.dispose(); this.documentPointerEventHandler_ = null; } if (this.pointerEventHandler_) { - goog.dispose(this.pointerEventHandler_); + this.pointerEventHandler_.dispose(); this.pointerEventHandler_ = null; } goog.base(this, 'disposeInternal'); @@ -49820,14 +40668,14 @@ ol.MapBrowserEvent.EventType = { * @event ol.MapBrowserEvent#click * @api stable */ - CLICK: goog.events.EventType.CLICK, + CLICK: ol.events.EventType.CLICK, /** * A true double click, with no dragging. * @event ol.MapBrowserEvent#dblclick * @api stable */ - DBLCLICK: goog.events.EventType.DBLCLICK, + DBLCLICK: ol.events.EventType.DBLCLICK, /** * Triggered when a pointer is dragged. @@ -49855,12 +40703,11 @@ ol.MapBrowserEvent.EventType = { goog.provide('ol.layer.Base'); goog.provide('ol.layer.LayerProperty'); -goog.provide('ol.layer.LayerState'); -goog.require('goog.object'); goog.require('ol'); goog.require('ol.Object'); goog.require('ol.math'); +goog.require('ol.object'); goog.require('ol.source.State'); @@ -49879,21 +40726,6 @@ ol.layer.LayerProperty = { /** - * @typedef {{layer: ol.layer.Layer, - * opacity: number, - * sourceState: ol.source.State, - * visible: boolean, - * managed: boolean, - * extent: (ol.Extent|undefined), - * zIndex: number, - * maxResolution: number, - * minResolution: number}} - */ -ol.layer.LayerState; - - - -/** * @classdesc * Abstract base class; normally only used for creating subclasses and not * instantiated in apps. @@ -49913,7 +40745,7 @@ ol.layer.Base = function(options) { /** * @type {Object.<string, *>} */ - var properties = goog.object.clone(options); + var properties = ol.object.assign({}, options); properties[ol.layer.LayerProperty.OPACITY] = options.opacity !== undefined ? options.opacity : 1; properties[ol.layer.LayerProperty.VISIBLE] = @@ -49931,7 +40763,7 @@ goog.inherits(ol.layer.Base, ol.Object); /** - * @return {ol.layer.LayerState} Layer state. + * @return {ol.LayerState} Layer state. */ ol.layer.Base.prototype.getLayerState = function() { var opacity = this.getOpacity(); @@ -49964,9 +40796,9 @@ ol.layer.Base.prototype.getLayersArray = goog.abstractMethod; /** - * @param {Array.<ol.layer.LayerState>=} opt_states Optional list of layer + * @param {Array.<ol.LayerState>=} opt_states Optional list of layer * states (to be modified in place). - * @return {Array.<ol.layer.LayerState>} List of layer states. + * @return {Array.<ol.LayerState>} List of layer states. */ ol.layer.Base.prototype.getLayerStatesArray = goog.abstractMethod; @@ -50118,7 +40950,6 @@ ol.layer.Base.prototype.setZIndex = function(zindex) { goog.provide('ol.render.VectorContext'); - /** * Context for drawing geometries. A vector context is available on render * events and does not need to be constructed directly. @@ -50131,17 +40962,26 @@ ol.render.VectorContext = function() { /** - * @param {number} zIndex Z index. - * @param {function(ol.render.VectorContext)} callback Callback. + * Render a geometry. + * + * @param {ol.geom.Geometry} geometry The geometry to render. + */ +ol.render.VectorContext.prototype.drawGeometry = goog.abstractMethod; + + +/** + * Set the rendering style. + * + * @param {ol.style.Style} style The rendering style. */ -ol.render.VectorContext.prototype.drawAsync = goog.abstractMethod; +ol.render.VectorContext.prototype.setStyle = goog.abstractMethod; /** * @param {ol.geom.Circle} circleGeometry Circle geometry. * @param {ol.Feature} feature Feature, */ -ol.render.VectorContext.prototype.drawCircleGeometry = goog.abstractMethod; +ol.render.VectorContext.prototype.drawCircle = goog.abstractMethod; /** @@ -50156,8 +40996,7 @@ ol.render.VectorContext.prototype.drawFeature = goog.abstractMethod; * collection. * @param {ol.Feature} feature Feature. */ -ol.render.VectorContext.prototype.drawGeometryCollectionGeometry = - goog.abstractMethod; +ol.render.VectorContext.prototype.drawGeometryCollection = goog.abstractMethod; /** @@ -50165,8 +41004,7 @@ ol.render.VectorContext.prototype.drawGeometryCollectionGeometry = * string geometry. * @param {ol.Feature|ol.render.Feature} feature Feature. */ -ol.render.VectorContext.prototype.drawLineStringGeometry = - goog.abstractMethod; +ol.render.VectorContext.prototype.drawLineString = goog.abstractMethod; /** @@ -50174,8 +41012,7 @@ ol.render.VectorContext.prototype.drawLineStringGeometry = * MultiLineString geometry. * @param {ol.Feature|ol.render.Feature} feature Feature. */ -ol.render.VectorContext.prototype.drawMultiLineStringGeometry = - goog.abstractMethod; +ol.render.VectorContext.prototype.drawMultiLineString = goog.abstractMethod; /** @@ -50183,22 +41020,21 @@ ol.render.VectorContext.prototype.drawMultiLineStringGeometry = * geometry. * @param {ol.Feature|ol.render.Feature} feature Feature. */ -ol.render.VectorContext.prototype.drawMultiPointGeometry = goog.abstractMethod; +ol.render.VectorContext.prototype.drawMultiPoint = goog.abstractMethod; /** * @param {ol.geom.MultiPolygon} multiPolygonGeometry MultiPolygon geometry. * @param {ol.Feature} feature Feature. */ -ol.render.VectorContext.prototype.drawMultiPolygonGeometry = - goog.abstractMethod; +ol.render.VectorContext.prototype.drawMultiPolygon = goog.abstractMethod; /** * @param {ol.geom.Point|ol.render.Feature} pointGeometry Point geometry. * @param {ol.Feature|ol.render.Feature} feature Feature. */ -ol.render.VectorContext.prototype.drawPointGeometry = goog.abstractMethod; +ol.render.VectorContext.prototype.drawPoint = goog.abstractMethod; /** @@ -50206,7 +41042,7 @@ ol.render.VectorContext.prototype.drawPointGeometry = goog.abstractMethod; * geometry. * @param {ol.Feature|ol.render.Feature} feature Feature. */ -ol.render.VectorContext.prototype.drawPolygonGeometry = goog.abstractMethod; +ol.render.VectorContext.prototype.drawPolygon = goog.abstractMethod; /** @@ -50241,7 +41077,7 @@ ol.render.VectorContext.prototype.setTextStyle = goog.abstractMethod; goog.provide('ol.render.Event'); goog.provide('ol.render.EventType'); -goog.require('goog.events.Event'); +goog.require('ol.events.Event'); goog.require('ol.render.VectorContext'); @@ -50267,10 +41103,9 @@ ol.render.EventType = { }; - /** * @constructor - * @extends {goog.events.Event} + * @extends {ol.events.Event} * @implements {oli.render.Event} * @param {ol.render.EventType} type Type. * @param {Object=} opt_target Target. @@ -50316,22 +41151,21 @@ ol.render.Event = function( this.glContext = opt_glContext; }; -goog.inherits(ol.render.Event, goog.events.Event); +goog.inherits(ol.render.Event, ol.events.Event); goog.provide('ol.layer.Layer'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.object'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol'); goog.require('ol.Object'); goog.require('ol.layer.Base'); goog.require('ol.layer.LayerProperty'); +goog.require('ol.object'); goog.require('ol.render.EventType'); goog.require('ol.source.State'); - /** * @classdesc * Abstract base class; normally only used for creating subclasses and not @@ -50355,26 +41189,26 @@ goog.require('ol.source.State'); */ ol.layer.Layer = function(options) { - var baseOptions = goog.object.clone(options); + var baseOptions = ol.object.assign({}, options); delete baseOptions.source; - goog.base(this, /** @type {olx.layer.LayerOptions} */ (baseOptions)); + goog.base(this, /** @type {olx.layer.BaseOptions} */ (baseOptions)); /** * @private - * @type {goog.events.Key} + * @type {?ol.events.Key} */ this.mapPrecomposeKey_ = null; /** * @private - * @type {goog.events.Key} + * @type {?ol.events.Key} */ this.mapRenderKey_ = null; /** * @private - * @type {goog.events.Key} + * @type {?ol.events.Key} */ this.sourceChangeKey_ = null; @@ -50382,9 +41216,9 @@ ol.layer.Layer = function(options) { this.setMap(options.map); } - goog.events.listen(this, + ol.events.listen(this, ol.Object.getChangeEventType(ol.layer.LayerProperty.SOURCE), - this.handleSourcePropertyChange_, false, this); + this.handleSourcePropertyChange_, this); var source = options.source ? options.source : null; this.setSource(source); @@ -50396,7 +41230,7 @@ goog.inherits(ol.layer.Layer, ol.layer.Base); * Return `true` if the layer is visible, and if the passed resolution is * between the layer's minResolution and maxResolution. The comparison is * inclusive for `minResolution` and exclusive for `maxResolution`. - * @param {ol.layer.LayerState} layerState Layer state. + * @param {ol.LayerState} layerState Layer state. * @param {number} resolution Resolution. * @return {boolean} The layer is visible at the given resolution. */ @@ -50460,13 +41294,13 @@ ol.layer.Layer.prototype.handleSourceChange_ = function() { */ ol.layer.Layer.prototype.handleSourcePropertyChange_ = function() { if (this.sourceChangeKey_) { - goog.events.unlistenByKey(this.sourceChangeKey_); + ol.events.unlistenByKey(this.sourceChangeKey_); this.sourceChangeKey_ = null; } var source = this.getSource(); if (source) { - this.sourceChangeKey_ = goog.events.listen(source, - goog.events.EventType.CHANGE, this.handleSourceChange_, false, this); + this.sourceChangeKey_ = ol.events.listen(source, + ol.events.EventType.CHANGE, this.handleSourceChange_, this); } this.changed(); }; @@ -50485,24 +41319,28 @@ ol.layer.Layer.prototype.handleSourcePropertyChange_ = function() { * @api */ ol.layer.Layer.prototype.setMap = function(map) { - goog.events.unlistenByKey(this.mapPrecomposeKey_); - this.mapPrecomposeKey_ = null; + if (this.mapPrecomposeKey_) { + ol.events.unlistenByKey(this.mapPrecomposeKey_); + this.mapPrecomposeKey_ = null; + } if (!map) { this.changed(); } - goog.events.unlistenByKey(this.mapRenderKey_); - this.mapRenderKey_ = null; + if (this.mapRenderKey_) { + ol.events.unlistenByKey(this.mapRenderKey_); + this.mapRenderKey_ = null; + } if (map) { - this.mapPrecomposeKey_ = goog.events.listen( + this.mapPrecomposeKey_ = ol.events.listen( map, ol.render.EventType.PRECOMPOSE, function(evt) { var layerState = this.getLayerState(); layerState.managed = false; layerState.zIndex = Infinity; evt.frameState.layerStatesArray.push(layerState); evt.frameState.layerStates[goog.getUid(this)] = layerState; - }, false, this); - this.mapRenderKey_ = goog.events.listen( - this, goog.events.EventType.CHANGE, map.render, false, map); + }, this); + this.mapRenderKey_ = ol.events.listen( + this, ol.events.EventType.CHANGE, map.render, map); this.changed(); } }; @@ -50522,10 +41360,9 @@ goog.provide('ol.ImageBase'); goog.provide('ol.ImageState'); goog.require('goog.asserts'); -goog.require('goog.events.EventTarget'); -goog.require('goog.events.EventType'); +goog.require('ol.events.EventTarget'); +goog.require('ol.events.EventType'); goog.require('ol.Attribution'); -goog.require('ol.Extent'); /** @@ -50539,10 +41376,9 @@ ol.ImageState = { }; - /** * @constructor - * @extends {goog.events.EventTarget} + * @extends {ol.events.EventTarget} * @param {ol.Extent} extent Extent. * @param {number|undefined} resolution Resolution. * @param {number} pixelRatio Pixel ratio. @@ -50584,14 +41420,14 @@ ol.ImageBase = function(extent, resolution, pixelRatio, state, attributions) { this.state = state; }; -goog.inherits(ol.ImageBase, goog.events.EventTarget); +goog.inherits(ol.ImageBase, ol.events.EventTarget); /** * @protected */ ol.ImageBase.prototype.changed = function() { - this.dispatchEvent(goog.events.EventType.CHANGE); + this.dispatchEvent(ol.events.EventType.CHANGE); }; @@ -50742,10 +41578,10 @@ ol.vec.Mat4.multVec2 = function(mat, vec, resultVec) { goog.provide('ol.renderer.Layer'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.functions'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol'); +goog.require('ol.functions'); goog.require('ol.ImageState'); goog.require('ol.Observable'); goog.require('ol.TileRange'); @@ -50754,11 +41590,9 @@ goog.require('ol.layer.Layer'); goog.require('ol.source.Source'); goog.require('ol.source.State'); goog.require('ol.source.Tile'); -goog.require('ol.tilecoord'); goog.require('ol.vec.Mat4'); - /** * @constructor * @extends {ol.Observable} @@ -50800,14 +41634,13 @@ ol.renderer.Layer.prototype.forEachFeatureAtCoordinate = ol.nullFunction; * @return {T|undefined} Callback result. * @template S,T */ -ol.renderer.Layer.prototype.forEachLayerAtPixel = - function(pixel, frameState, callback, thisArg) { +ol.renderer.Layer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) { var coordinate = pixel.slice(); ol.vec.Mat4.multVec2( frameState.pixelToCoordinateMatrix, coordinate, coordinate); var hasFeature = this.forEachFeatureAtCoordinate( - coordinate, frameState, goog.functions.TRUE, this); + coordinate, frameState, ol.functions.TRUE, this); if (hasFeature) { return callback.call(thisArg, this.layer_); @@ -50822,7 +41655,7 @@ ol.renderer.Layer.prototype.forEachLayerAtPixel = * @param {olx.FrameState} frameState Frame state. * @return {boolean} Is there a feature at the given coordinate? */ -ol.renderer.Layer.prototype.hasFeatureAtCoordinate = goog.functions.FALSE; +ol.renderer.Layer.prototype.hasFeatureAtCoordinate = ol.functions.FALSE; /** @@ -50836,8 +41669,7 @@ ol.renderer.Layer.prototype.hasFeatureAtCoordinate = goog.functions.FALSE; * lookup. * @protected */ -ol.renderer.Layer.prototype.createLoadedTileFinder = - function(source, projection, tiles) { +ol.renderer.Layer.prototype.createLoadedTileFinder = function(source, projection, tiles) { return ( /** * @param {number} zoom Zoom level. @@ -50845,13 +41677,13 @@ ol.renderer.Layer.prototype.createLoadedTileFinder = * @return {boolean} The tile range is fully loaded. */ function(zoom, tileRange) { - return source.forEachLoadedTile(projection, zoom, - tileRange, function(tile) { - if (!tiles[zoom]) { - tiles[zoom] = {}; - } - tiles[zoom][tile.tileCoord.toString()] = tile; - }); + function callback(tile) { + if (!tiles[zoom]) { + tiles[zoom] = {}; + } + tiles[zoom][tile.tileCoord.toString()] = tile; + } + return source.forEachLoadedTile(projection, zoom, tileRange, callback); }); }; @@ -50866,7 +41698,7 @@ ol.renderer.Layer.prototype.getLayer = function() { /** * Handle changes in image state. - * @param {goog.events.Event} event Image change event. + * @param {ol.events.Event} event Image change event. * @private */ ol.renderer.Layer.prototype.handleImageChange_ = function(event) { @@ -50894,8 +41726,8 @@ ol.renderer.Layer.prototype.loadImage = function(image) { goog.asserts.assert(imageState == ol.ImageState.IDLE || imageState == ol.ImageState.LOADING, 'imageState is "idle" or "loading"'); - goog.events.listen(image, goog.events.EventType.CHANGE, - this.handleImageChange_, false, this); + ol.events.listen(image, ol.events.EventType.CHANGE, + this.handleImageChange_, this); } if (imageState == ol.ImageState.IDLE) { image.load(); @@ -50924,21 +41756,22 @@ ol.renderer.Layer.prototype.renderIfReadyAndVisible = function() { * @param {ol.source.Tile} tileSource Tile source. * @protected */ -ol.renderer.Layer.prototype.scheduleExpireCache = - function(frameState, tileSource) { +ol.renderer.Layer.prototype.scheduleExpireCache = function(frameState, tileSource) { if (tileSource.canExpireCache()) { + /** + * @param {ol.source.Tile} tileSource Tile source. + * @param {ol.Map} map Map. + * @param {olx.FrameState} frameState Frame state. + */ + var postRenderFunction = function(tileSource, map, frameState) { + var tileSourceKey = goog.getUid(tileSource).toString(); + tileSource.expireCache(frameState.viewState.projection, + frameState.usedTiles[tileSourceKey]); + }.bind(null, tileSource); + frameState.postRenderFunctions.push( - goog.partial( - /** - * @param {ol.source.Tile} tileSource Tile source. - * @param {ol.Map} map Map. - * @param {olx.FrameState} frameState Frame state. - */ - function(tileSource, map, frameState) { - var tileSourceKey = goog.getUid(tileSource).toString(); - tileSource.expireCache(frameState.viewState.projection, - frameState.usedTiles[tileSourceKey]); - }, tileSource)); + /** @type {ol.PostRenderFunction} */ (postRenderFunction) + ); } }; @@ -50949,8 +41782,7 @@ ol.renderer.Layer.prototype.scheduleExpireCache = * @param {Array.<ol.Attribution>} attributions Attributions (source). * @protected */ -ol.renderer.Layer.prototype.updateAttributions = - function(attributionsSet, attributions) { +ol.renderer.Layer.prototype.updateAttributions = function(attributionsSet, attributions) { if (attributions) { var attribution, i, ii; for (i = 0, ii = attributions.length; i < ii; ++i) { @@ -50969,7 +41801,7 @@ ol.renderer.Layer.prototype.updateAttributions = ol.renderer.Layer.prototype.updateLogos = function(frameState, source) { var logo = source.getLogo(); if (logo !== undefined) { - if (goog.isString(logo)) { + if (typeof logo === 'string') { frameState.logos[logo] = ''; } else if (goog.isObject(logo)) { goog.asserts.assertString(logo.href, 'logo.href is a string'); @@ -50987,8 +41819,7 @@ ol.renderer.Layer.prototype.updateLogos = function(frameState, source) { * @param {ol.TileRange} tileRange Tile range. * @protected */ -ol.renderer.Layer.prototype.updateUsedTiles = - function(usedTiles, tileSource, z, tileRange) { +ol.renderer.Layer.prototype.updateUsedTiles = function(usedTiles, tileSource, z, tileRange) { // FIXME should we use tilesToDrawByZ instead? var tileSourceKey = goog.getUid(tileSource).toString(); var zKey = z.toString(); @@ -51012,8 +41843,7 @@ ol.renderer.Layer.prototype.updateUsedTiles = * @protected * @return {ol.Coordinate} Snapped center. */ -ol.renderer.Layer.prototype.snapCenterToPixel = - function(center, resolution, size) { +ol.renderer.Layer.prototype.snapCenterToPixel = function(center, resolution, size) { return [ resolution * (Math.round(center[0] / resolution) + (size[0] % 2) / 2), resolution * (Math.round(center[1] / resolution) + (size[1] % 2) / 2) @@ -51060,7 +41890,7 @@ ol.renderer.Layer.prototype.manageTilePyramid = function( if (currentZ - z <= preload) { tile = tileSource.getTile(z, x, y, pixelRatio, projection); if (tile.getState() == ol.TileState.IDLE) { - wantedTiles[ol.tilecoord.toString(tile.tileCoord)] = true; + wantedTiles[tile.tileCoord.toString()] = true; if (!tileQueue.isKeyQueued(tile.getKey())) { tileQueue.enqueue([tile, tileSourceKey, tileGrid.getTileCoordCenter(tile.tileCoord), tileResolution]); @@ -51093,17 +41923,6 @@ ol.style.ImageState = { /** - * @typedef {{opacity: number, - * rotateWithView: boolean, - * rotation: number, - * scale: number, - * snapToPixel: boolean}} - */ -ol.style.ImageOptions; - - - -/** * @classdesc * A base class used for creating subclasses and not instantiated in * apps. Base class for {@link ol.style.Icon}, {@link ol.style.Circle} and @@ -51311,9 +42130,9 @@ ol.style.Image.prototype.setSnapToPixel = function(snapToPixel) { /** - * @param {function(this: T, goog.events.Event)} listener Listener function. + * @param {function(this: T, ol.events.Event)} listener Listener function. * @param {T} thisArg Value to use as `this` when executing `listener`. - * @return {goog.events.Key|undefined} Listener key. + * @return {ol.events.Key|undefined} Listener key. * @template T */ ol.style.Image.prototype.listenImageChange = goog.abstractMethod; @@ -51326,7 +42145,7 @@ ol.style.Image.prototype.load = goog.abstractMethod; /** - * @param {function(this: T, goog.events.Event)} listener Listener function. + * @param {function(this: T, ol.events.Event)} listener Listener function. * @param {T} thisArg Value to use as `this` when executing `listener`. * @template T */ @@ -51338,9 +42157,10 @@ goog.provide('ol.style.IconImageCache'); goog.provide('ol.style.IconOrigin'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.EventTarget'); -goog.require('goog.events.EventType'); +goog.require('ol.events'); +goog.require('ol.events.EventTarget'); +goog.require('ol.events.EventType'); +goog.require('ol.color'); goog.require('ol.dom'); goog.require('ol.style.Image'); goog.require('ol.style.ImageState'); @@ -51370,7 +42190,6 @@ ol.style.IconOrigin = { }; - /** * @classdesc * Set icon style for vector features. @@ -51441,9 +42260,6 @@ ol.style.Icon = function(opt_options) { goog.asserts.assert(!(src !== undefined && image), 'image and src can not provided at the same time'); goog.asserts.assert( - src === undefined || (src !== undefined && !imgSize), - 'imgSize should not be set when src is provided'); - goog.asserts.assert( !image || (image && imgSize), 'imgSize must be set when image is provided'); @@ -51460,11 +42276,17 @@ ol.style.Icon = function(opt_options) { ol.style.ImageState.IDLE : ol.style.ImageState.LOADED; /** + * @type {ol.Color} + */ + var color = options.color !== undefined ? ol.color.asArray(options.color) : + null; + + /** * @private * @type {ol.style.IconImage_} */ this.iconImage_ = ol.style.IconImage_.get( - image, src, imgSize, crossOrigin, imageState); + image, src, imgSize, crossOrigin, imageState, color); /** * @private @@ -51673,8 +42495,8 @@ ol.style.Icon.prototype.getSize = function() { * @inheritDoc */ ol.style.Icon.prototype.listenImageChange = function(listener, thisArg) { - return goog.events.listen(this.iconImage_, goog.events.EventType.CHANGE, - listener, false, thisArg); + return ol.events.listen(this.iconImage_, ol.events.EventType.CHANGE, + listener, thisArg); }; @@ -51694,12 +42516,11 @@ ol.style.Icon.prototype.load = function() { * @inheritDoc */ ol.style.Icon.prototype.unlistenImageChange = function(listener, thisArg) { - goog.events.unlisten(this.iconImage_, goog.events.EventType.CHANGE, - listener, false, thisArg); + ol.events.unlisten(this.iconImage_, ol.events.EventType.CHANGE, + listener, thisArg); }; - /** * @constructor * @param {Image|HTMLCanvasElement} image Image. @@ -51707,10 +42528,12 @@ ol.style.Icon.prototype.unlistenImageChange = function(listener, thisArg) { * @param {ol.Size} size Size. * @param {?string} crossOrigin Cross origin. * @param {ol.style.ImageState} imageState Image state. - * @extends {goog.events.EventTarget} + * @param {ol.Color} color Color. + * @extends {ol.events.EventTarget} * @private */ -ol.style.IconImage_ = function(image, src, size, crossOrigin, imageState) { +ol.style.IconImage_ = function(image, src, size, crossOrigin, imageState, + color) { goog.base(this); @@ -51732,7 +42555,21 @@ ol.style.IconImage_ = function(image, src, size, crossOrigin, imageState) { /** * @private - * @type {Array.<goog.events.Key>} + * @type {HTMLCanvasElement} + */ + this.canvas_ = color ? + /** @type {HTMLCanvasElement} */ (document.createElement('CANVAS')) : + null; + + /** + * @private + * @type {ol.Color} + */ + this.color_ = color; + + /** + * @private + * @type {Array.<ol.events.Key>} */ this.imageListenerKeys_ = null; @@ -51764,7 +42601,7 @@ ol.style.IconImage_ = function(image, src, size, crossOrigin, imageState) { } }; -goog.inherits(ol.style.IconImage_, goog.events.EventTarget); +goog.inherits(ol.style.IconImage_, ol.events.EventTarget); /** @@ -51773,15 +42610,17 @@ goog.inherits(ol.style.IconImage_, goog.events.EventTarget); * @param {ol.Size} size Size. * @param {?string} crossOrigin Cross origin. * @param {ol.style.ImageState} imageState Image state. + * @param {ol.Color} color Color. * @return {ol.style.IconImage_} Icon image. */ -ol.style.IconImage_.get = function(image, src, size, crossOrigin, imageState) { +ol.style.IconImage_.get = function(image, src, size, crossOrigin, imageState, + color) { var iconImageCache = ol.style.IconImageCache.getInstance(); - var iconImage = iconImageCache.get(src, crossOrigin); + var iconImage = iconImageCache.get(src, crossOrigin, color); if (!iconImage) { iconImage = new ol.style.IconImage_( - image, src, size, crossOrigin, imageState); - iconImageCache.set(src, crossOrigin, iconImage); + image, src, size, crossOrigin, imageState, color); + iconImageCache.set(src, crossOrigin, color, iconImage); } return iconImage; }; @@ -51805,7 +42644,7 @@ ol.style.IconImage_.prototype.determineTainting_ = function() { * @private */ ol.style.IconImage_.prototype.dispatchChangeEvent_ = function() { - this.dispatchEvent(goog.events.EventType.CHANGE); + this.dispatchEvent(ol.events.EventType.CHANGE); }; @@ -51824,9 +42663,14 @@ ol.style.IconImage_.prototype.handleImageError_ = function() { */ ol.style.IconImage_.prototype.handleImageLoad_ = function() { this.imageState_ = ol.style.ImageState.LOADED; + if (this.size_) { + this.image_.width = this.size_[0]; + this.image_.height = this.size_[1]; + } this.size_ = [this.image_.width, this.image_.height]; this.unlistenImage_(); this.determineTainting_(); + this.replaceColor_(); this.dispatchChangeEvent_(); }; @@ -51836,7 +42680,7 @@ ol.style.IconImage_.prototype.handleImageLoad_ = function() { * @return {Image|HTMLCanvasElement} Image or Canvas element. */ ol.style.IconImage_.prototype.getImage = function(pixelRatio) { - return this.image_; + return this.canvas_ ? this.canvas_ : this.image_; }; @@ -51895,10 +42739,10 @@ ol.style.IconImage_.prototype.load = function() { 'no listener keys existing'); this.imageState_ = ol.style.ImageState.LOADING; this.imageListenerKeys_ = [ - goog.events.listenOnce(this.image_, goog.events.EventType.ERROR, - this.handleImageError_, false, this), - goog.events.listenOnce(this.image_, goog.events.EventType.LOAD, - this.handleImageLoad_, false, this) + ol.events.listenOnce(this.image_, ol.events.EventType.ERROR, + this.handleImageError_, this), + ol.events.listenOnce(this.image_, ol.events.EventType.LOAD, + this.handleImageLoad_, this) ]; try { this.image_.src = this.src_; @@ -51910,6 +42754,38 @@ ol.style.IconImage_.prototype.load = function() { /** + * @private + */ +ol.style.IconImage_.prototype.replaceColor_ = function() { + if (this.tainting_ || this.color_ === null) { + return; + } + + goog.asserts.assert(this.canvas_ !== null, + 'this.canvas_ must not be null'); + + this.canvas_.width = this.image_.width; + this.canvas_.height = this.image_.height; + + var ctx = this.canvas_.getContext('2d'); + ctx.drawImage(this.image_, 0, 0); + + var imgData = ctx.getImageData(0, 0, this.image_.width, this.image_.height); + var data = imgData.data; + var r = this.color_[0] / 255.0; + var g = this.color_[1] / 255.0; + var b = this.color_[2] / 255.0; + + for (var i = 0, ii = data.length; i < ii; i += 4) { + data[i] *= r; + data[i + 1] *= g; + data[i + 2] *= b; + } + ctx.putImageData(imgData, 0, 0); +}; + + +/** * Discards event handlers which listen for load completion or errors. * * @private @@ -51917,12 +42793,11 @@ ol.style.IconImage_.prototype.load = function() { ol.style.IconImage_.prototype.unlistenImage_ = function() { goog.asserts.assert(this.imageListenerKeys_, 'we must have listeners registered'); - this.imageListenerKeys_.forEach(goog.events.unlistenByKey); + this.imageListenerKeys_.forEach(ol.events.unlistenByKey); this.imageListenerKeys_ = null; }; - /** * @constructor */ @@ -51953,12 +42828,14 @@ goog.addSingletonGetter(ol.style.IconImageCache); /** * @param {string} src Src. * @param {?string} crossOrigin Cross origin. + * @param {ol.Color} color Color. * @return {string} Cache key. */ -ol.style.IconImageCache.getKey = function(src, crossOrigin) { +ol.style.IconImageCache.getKey = function(src, crossOrigin, color) { goog.asserts.assert(crossOrigin !== undefined, 'argument crossOrigin must be defined'); - return crossOrigin + ':' + src; + var colorString = color ? ol.color.asString(color) : 'null'; + return crossOrigin + ':' + src + ':' + colorString; }; @@ -51980,7 +42857,7 @@ ol.style.IconImageCache.prototype.expire = function() { var key, iconImage; for (key in this.cache_) { iconImage = this.cache_[key]; - if ((i++ & 3) === 0 && !goog.events.hasListener(iconImage)) { + if ((i++ & 3) === 0 && !iconImage.hasListener()) { delete this.cache_[key]; --this.cacheSize_; } @@ -51992,10 +42869,11 @@ ol.style.IconImageCache.prototype.expire = function() { /** * @param {string} src Src. * @param {?string} crossOrigin Cross origin. + * @param {ol.Color} color Color. * @return {ol.style.IconImage_} Icon image. */ -ol.style.IconImageCache.prototype.get = function(src, crossOrigin) { - var key = ol.style.IconImageCache.getKey(src, crossOrigin); +ol.style.IconImageCache.prototype.get = function(src, crossOrigin, color) { + var key = ol.style.IconImageCache.getKey(src, crossOrigin, color); return key in this.cache_ ? this.cache_[key] : null; }; @@ -52003,10 +42881,12 @@ ol.style.IconImageCache.prototype.get = function(src, crossOrigin) { /** * @param {string} src Src. * @param {?string} crossOrigin Cross origin. + * @param {ol.Color} color Color. * @param {ol.style.IconImage_} iconImage Icon image. */ -ol.style.IconImageCache.prototype.set = function(src, crossOrigin, iconImage) { - var key = ol.style.IconImageCache.getKey(src, crossOrigin); +ol.style.IconImageCache.prototype.set = function(src, crossOrigin, color, + iconImage) { + var key = ol.style.IconImageCache.getKey(src, crossOrigin, color); this.cache_[key] = iconImage; ++this.cacheSize_; }; @@ -52014,16 +42894,14 @@ ol.style.IconImageCache.prototype.set = function(src, crossOrigin, iconImage) { goog.provide('ol.RendererType'); goog.provide('ol.renderer.Map'); -goog.require('goog.Disposable'); goog.require('goog.asserts'); -goog.require('goog.dispose'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.functions'); -goog.require('goog.object'); goog.require('goog.vec.Mat4'); goog.require('ol'); +goog.require('ol.Disposable'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol.extent'); +goog.require('ol.functions'); goog.require('ol.layer.Layer'); goog.require('ol.renderer.Layer'); goog.require('ol.style.IconImageCache'); @@ -52042,10 +42920,9 @@ ol.RendererType = { }; - /** * @constructor - * @extends {goog.Disposable} + * @extends {ol.Disposable} * @param {Element} container Container. * @param {ol.Map} map Map. * @struct @@ -52069,12 +42946,12 @@ ol.renderer.Map = function(container, map) { /** * @private - * @type {Object.<string, goog.events.Key>} + * @type {Object.<string, ol.events.Key>} */ this.layerRendererListeners_ = {}; }; -goog.inherits(ol.renderer.Map, goog.Disposable); +goog.inherits(ol.renderer.Map, ol.Disposable); /** @@ -52109,8 +42986,9 @@ ol.renderer.Map.prototype.createLayerRenderer = goog.abstractMethod; * @inheritDoc */ ol.renderer.Map.prototype.disposeInternal = function() { - goog.object.forEach(this.layerRenderers_, goog.dispose); - goog.base(this, 'disposeInternal'); + for (var id in this.layerRenderers_) { + this.layerRenderers_[id].dispose(); + } }; @@ -52138,26 +43016,23 @@ ol.renderer.Map.expireIconCache_ = function(map, frameState) { * @return {T|undefined} Callback result. * @template S,T,U */ -ol.renderer.Map.prototype.forEachFeatureAtCoordinate = - function(coordinate, frameState, callback, thisArg, +ol.renderer.Map.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, callback, thisArg, layerFilter, thisArg2) { var result; var viewState = frameState.viewState; var viewResolution = viewState.resolution; - /** @type {Object.<string, boolean>} */ - var features = {}; - /** * @param {ol.Feature|ol.render.Feature} feature Feature. + * @param {ol.layer.Layer} layer Layer. * @return {?} Callback result. */ - function forEachFeatureAtCoordinate(feature) { + function forEachFeatureAtCoordinate(feature, layer) { goog.asserts.assert(feature !== undefined, 'received a feature'); var key = goog.getUid(feature).toString(); - if (!(key in features)) { - features[key] = true; - return callback.call(thisArg, feature, null); + var managed = frameState.layerStates[goog.getUid(layer)].managed; + if (!(key in frameState.skippedFeatureUids && !managed)) { + return callback.call(thisArg, feature, managed ? layer : null); } } @@ -52186,9 +43061,7 @@ ol.renderer.Map.prototype.forEachFeatureAtCoordinate = if (layer.getSource()) { result = layerRenderer.forEachFeatureAtCoordinate( layer.getSource().getWrapX() ? translatedCoordinate : coordinate, - frameState, - layerState.managed ? callback : forEachFeatureAtCoordinate, - thisArg); + frameState, forEachFeatureAtCoordinate, thisArg); } if (result) { return result; @@ -52213,8 +43086,7 @@ ol.renderer.Map.prototype.forEachFeatureAtCoordinate = * @return {T|undefined} Callback result. * @template S,T,U */ -ol.renderer.Map.prototype.forEachLayerAtPixel = - function(pixel, frameState, callback, thisArg, +ol.renderer.Map.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg, layerFilter, thisArg2) { var result; var viewState = frameState.viewState; @@ -52251,10 +43123,9 @@ ol.renderer.Map.prototype.forEachLayerAtPixel = * @return {boolean} Is there a feature at the given coordinate? * @template U */ -ol.renderer.Map.prototype.hasFeatureAtCoordinate = - function(coordinate, frameState, layerFilter, thisArg) { +ol.renderer.Map.prototype.hasFeatureAtCoordinate = function(coordinate, frameState, layerFilter, thisArg) { var hasFeature = this.forEachFeatureAtCoordinate( - coordinate, frameState, goog.functions.TRUE, this, layerFilter, thisArg); + coordinate, frameState, ol.functions.TRUE, this, layerFilter, thisArg); return hasFeature !== undefined; }; @@ -52272,9 +43143,8 @@ ol.renderer.Map.prototype.getLayerRenderer = function(layer) { } else { var layerRenderer = this.createLayerRenderer(layer); this.layerRenderers_[layerKey] = layerRenderer; - this.layerRendererListeners_[layerKey] = goog.events.listen(layerRenderer, - goog.events.EventType.CHANGE, this.handleLayerRendererChange_, - false, this); + this.layerRendererListeners_[layerKey] = ol.events.listen(layerRenderer, + ol.events.EventType.CHANGE, this.handleLayerRendererChange_, this); return layerRenderer; } @@ -52295,7 +43165,7 @@ ol.renderer.Map.prototype.getLayerRendererByKey = function(layerKey) { /** * @protected - * @return {Object.<number, ol.renderer.Layer>} Layer renderers. + * @return {Object.<string, ol.renderer.Layer>} Layer renderers. */ ol.renderer.Map.prototype.getLayerRenderers = function() { return this.layerRenderers_; @@ -52338,7 +43208,7 @@ ol.renderer.Map.prototype.removeLayerRendererByKey_ = function(layerKey) { goog.asserts.assert(layerKey in this.layerRendererListeners_, 'given layerKey (%s) exists in layerRendererListeners', layerKey); - goog.events.unlistenByKey(this.layerRendererListeners_[layerKey]); + ol.events.unlistenByKey(this.layerRendererListeners_[layerKey]); delete this.layerRendererListeners_[layerKey]; return layerRenderer; @@ -52357,12 +43227,11 @@ ol.renderer.Map.prototype.renderFrame = ol.nullFunction; * @param {olx.FrameState} frameState Frame state. * @private */ -ol.renderer.Map.prototype.removeUnusedLayerRenderers_ = - function(map, frameState) { +ol.renderer.Map.prototype.removeUnusedLayerRenderers_ = function(map, frameState) { var layerKey; for (layerKey in this.layerRenderers_) { if (!frameState || !(layerKey in frameState.layerStates)) { - goog.dispose(this.removeLayerRendererByKey_(layerKey)); + this.removeLayerRendererByKey_(layerKey).dispose(); } } }; @@ -52373,7 +43242,9 @@ ol.renderer.Map.prototype.removeUnusedLayerRenderers_ = * @protected */ ol.renderer.Map.prototype.scheduleExpireIconCache = function(frameState) { - frameState.postRenderFunctions.push(ol.renderer.Map.expireIconCache_); + frameState.postRenderFunctions.push( + /** @type {ol.PostRenderFunction} */ (ol.renderer.Map.expireIconCache_) + ); }; @@ -52381,13 +43252,13 @@ ol.renderer.Map.prototype.scheduleExpireIconCache = function(frameState) { * @param {!olx.FrameState} frameState Frame state. * @protected */ -ol.renderer.Map.prototype.scheduleRemoveUnusedLayerRenderers = - function(frameState) { +ol.renderer.Map.prototype.scheduleRemoveUnusedLayerRenderers = function(frameState) { var layerKey; for (layerKey in this.layerRenderers_) { if (!(layerKey in frameState.layerStates)) { frameState.postRenderFunctions.push( - goog.bind(this.removeUnusedLayerRenderers_, this)); + /** @type {ol.PostRenderFunction} */ (this.removeUnusedLayerRenderers_.bind(this)) + ); return; } } @@ -52395,9 +43266,9 @@ ol.renderer.Map.prototype.scheduleRemoveUnusedLayerRenderers = /** - * @param {ol.layer.LayerState} state1 - * @param {ol.layer.LayerState} state2 - * @return {number} + * @param {ol.LayerState} state1 First layer state. + * @param {ol.LayerState} state2 Second layer state. + * @return {number} The zIndex difference. */ ol.renderer.Map.sortByZIndex = function(state1, state2) { return state1.zIndex - state2.zIndex; @@ -52406,8 +43277,7 @@ ol.renderer.Map.sortByZIndex = function(state1, state2) { goog.provide('ol.structs.PriorityQueue'); goog.require('goog.asserts'); -goog.require('goog.object'); - +goog.require('ol.object'); /** @@ -52494,7 +43364,7 @@ ol.structs.PriorityQueue.prototype.assertValid = function() { ol.structs.PriorityQueue.prototype.clear = function() { this.elements_.length = 0; this.priorities_.length = 0; - goog.object.clear(this.queuedElements_); + ol.object.clear(this.queuedElements_); }; @@ -52705,24 +43575,16 @@ ol.structs.PriorityQueue.prototype.reprioritize = function() { this.heapify_(); }; -goog.provide('ol.TilePriorityFunction'); goog.provide('ol.TileQueue'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('ol.Coordinate'); +goog.require('goog.asserts'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol.TileState'); goog.require('ol.structs.PriorityQueue'); /** - * @typedef {function(ol.Tile, string, ol.Coordinate, number): number} - */ -ol.TilePriorityFunction; - - - -/** * @constructor * @extends {ol.structs.PriorityQueue.<Array>} * @param {ol.TilePriorityFunction} tilePriorityFunction @@ -52764,7 +43626,7 @@ ol.TileQueue = function(tilePriorityFunction, tileChangeCallback) { /** * @private - * @type {Object.<string,boolean>} + * @type {!Object.<string,boolean>} */ this.tilesLoadingKeys_ = {}; @@ -52779,8 +43641,8 @@ ol.TileQueue.prototype.enqueue = function(element) { var added = goog.base(this, 'enqueue', element); if (added) { var tile = element[0]; - goog.events.listen(tile, goog.events.EventType.CHANGE, - this.handleTileChange, false, this); + ol.events.listen(tile, ol.events.EventType.CHANGE, + this.handleTileChange, this); } return added; }; @@ -52795,16 +43657,16 @@ ol.TileQueue.prototype.getTilesLoading = function() { /** - * @param {goog.events.Event} event Event. + * @param {ol.events.Event} event Event. * @protected */ ol.TileQueue.prototype.handleTileChange = function(event) { var tile = /** @type {ol.Tile} */ (event.target); var state = tile.getState(); if (state === ol.TileState.LOADED || state === ol.TileState.ERROR || - state === ol.TileState.EMPTY) { - goog.events.unlisten(tile, goog.events.EventType.CHANGE, - this.handleTileChange, false, this); + state === ol.TileState.EMPTY || state === ol.TileState.ABORT) { + ol.events.unlisten(tile, ol.events.EventType.CHANGE, + this.handleTileChange, this); var tileKey = tile.getKey(); if (tileKey in this.tilesLoadingKeys_) { delete this.tilesLoadingKeys_[tileKey]; @@ -52812,6 +43674,7 @@ ol.TileQueue.prototype.handleTileChange = function(event) { } this.tileChangeCallback_(); } + goog.asserts.assert(Object.keys(this.tilesLoadingKeys_).length === this.tilesLoading_); }; @@ -52821,27 +43684,26 @@ ol.TileQueue.prototype.handleTileChange = function(event) { */ ol.TileQueue.prototype.loadMoreTiles = function(maxTotalLoading, maxNewLoads) { var newLoads = 0; - var tile; + var tile, tileKey; while (this.tilesLoading_ < maxTotalLoading && newLoads < maxNewLoads && this.getCount() > 0) { tile = /** @type {ol.Tile} */ (this.dequeue()[0]); - if (tile.getState() === ol.TileState.IDLE) { - tile.load(); - this.tilesLoadingKeys_[tile.getKey()] = true; + tileKey = tile.getKey(); + if (tile.getState() === ol.TileState.IDLE && !(tileKey in this.tilesLoadingKeys_)) { + this.tilesLoadingKeys_[tileKey] = true; ++this.tilesLoading_; ++newLoads; + tile.load(); } + goog.asserts.assert(Object.keys(this.tilesLoadingKeys_).length === this.tilesLoading_); } }; goog.provide('ol.Kinetic'); -goog.require('ol.Coordinate'); -goog.require('ol.PreRenderFunction'); goog.require('ol.animation'); - /** * @classdesc * Implementation of inertial deceleration for map movement. @@ -53014,7 +43876,6 @@ ol.interaction.InteractionProperty = { }; - /** * @classdesc * Abstract base class; normally only used for creating subclasses and not @@ -53127,8 +43988,7 @@ ol.interaction.Interaction.pan = function(map, view, delta, opt_duration) { * @param {ol.Coordinate=} opt_anchor Anchor coordinate. * @param {number=} opt_duration Duration. */ -ol.interaction.Interaction.rotate = - function(map, view, rotation, opt_anchor, opt_duration) { +ol.interaction.Interaction.rotate = function(map, view, rotation, opt_anchor, opt_duration) { rotation = view.constrainRotation(rotation, 0); ol.interaction.Interaction.rotateWithoutConstraints( map, view, rotation, opt_anchor, opt_duration); @@ -53142,8 +44002,7 @@ ol.interaction.Interaction.rotate = * @param {ol.Coordinate=} opt_anchor Anchor coordinate. * @param {number=} opt_duration Duration. */ -ol.interaction.Interaction.rotateWithoutConstraints = - function(map, view, rotation, opt_anchor, opt_duration) { +ol.interaction.Interaction.rotateWithoutConstraints = function(map, view, rotation, opt_anchor, opt_duration) { if (rotation !== undefined) { var currentRotation = view.getRotation(); var currentCenter = view.getCenter(); @@ -53182,8 +44041,7 @@ ol.interaction.Interaction.rotateWithoutConstraints = * will select the nearest resolution. If not defined 0 is * assumed. */ -ol.interaction.Interaction.zoom = - function(map, view, resolution, opt_anchor, opt_duration, opt_direction) { +ol.interaction.Interaction.zoom = function(map, view, resolution, opt_anchor, opt_duration, opt_direction) { resolution = view.constrainResolution(resolution, 0, opt_direction); ol.interaction.Interaction.zoomWithoutConstraints( map, view, resolution, opt_anchor, opt_duration); @@ -53197,8 +44055,7 @@ ol.interaction.Interaction.zoom = * @param {ol.Coordinate=} opt_anchor Anchor coordinate. * @param {number=} opt_duration Duration. */ -ol.interaction.Interaction.zoomByDelta = - function(map, view, delta, opt_anchor, opt_duration) { +ol.interaction.Interaction.zoomByDelta = function(map, view, delta, opt_anchor, opt_duration) { var currentResolution = view.getResolution(); var resolution = view.constrainResolution(currentResolution, delta, 0); ol.interaction.Interaction.zoomWithoutConstraints( @@ -53213,8 +44070,7 @@ ol.interaction.Interaction.zoomByDelta = * @param {ol.Coordinate=} opt_anchor Anchor coordinate. * @param {number=} opt_duration Duration. */ -ol.interaction.Interaction.zoomWithoutConstraints = - function(map, view, resolution, opt_anchor, opt_duration) { +ol.interaction.Interaction.zoomWithoutConstraints = function(map, view, resolution, opt_anchor, opt_duration) { if (resolution) { var currentResolution = view.getResolution(); var currentCenter = view.getCenter(); @@ -53250,7 +44106,6 @@ goog.require('ol.MapBrowserEvent.EventType'); goog.require('ol.interaction.Interaction'); - /** * @classdesc * Allows the user to zoom by double-clicking on the map. @@ -53294,7 +44149,7 @@ goog.inherits(ol.interaction.DoubleClickZoom, ol.interaction.Interaction); */ ol.interaction.DoubleClickZoom.handleEvent = function(mapBrowserEvent) { var stopEvent = false; - var browserEvent = mapBrowserEvent.browserEvent; + var browserEvent = mapBrowserEvent.originalEvent; if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.DBLCLICK) { var map = mapBrowserEvent.map; var anchor = mapBrowserEvent.coordinate; @@ -53309,26 +44164,15 @@ ol.interaction.DoubleClickZoom.handleEvent = function(mapBrowserEvent) { return !stopEvent; }; -goog.provide('ol.events.ConditionType'); goog.provide('ol.events.condition'); goog.require('goog.asserts'); -goog.require('goog.functions'); +goog.require('ol.functions'); goog.require('ol.MapBrowserEvent.EventType'); goog.require('ol.MapBrowserPointerEvent'); /** - * A function that takes an {@link ol.MapBrowserEvent} and returns a - * `{boolean}`. If the condition is met, true should be returned. - * - * @typedef {function(ol.MapBrowserEvent): boolean} - * @api stable - */ -ol.events.ConditionType; - - -/** * Return `true` if only the alt-key is pressed, `false` otherwise (e.g. when * additionally the shift-key is pressed). * @@ -53337,11 +44181,11 @@ ol.events.ConditionType; * @api stable */ ol.events.condition.altKeyOnly = function(mapBrowserEvent) { - var browserEvent = mapBrowserEvent.browserEvent; + var originalEvent = mapBrowserEvent.originalEvent; return ( - browserEvent.altKey && - !browserEvent.platformModifierKey && - !browserEvent.shiftKey); + originalEvent.altKey && + !(originalEvent.metaKey || originalEvent.ctrlKey) && + !originalEvent.shiftKey); }; @@ -53354,11 +44198,11 @@ ol.events.condition.altKeyOnly = function(mapBrowserEvent) { * @api stable */ ol.events.condition.altShiftKeysOnly = function(mapBrowserEvent) { - var browserEvent = mapBrowserEvent.browserEvent; + var originalEvent = mapBrowserEvent.originalEvent; return ( - browserEvent.altKey && - !browserEvent.platformModifierKey && - browserEvent.shiftKey); + originalEvent.altKey && + !(originalEvent.metaKey || originalEvent.ctrlKey) && + originalEvent.shiftKey); }; @@ -53370,7 +44214,7 @@ ol.events.condition.altShiftKeysOnly = function(mapBrowserEvent) { * @function * @api stable */ -ol.events.condition.always = goog.functions.TRUE; +ol.events.condition.always = ol.functions.TRUE; /** @@ -53386,6 +44230,22 @@ ol.events.condition.click = function(mapBrowserEvent) { /** + * Return `true` if the event has an "action"-producing mouse button. + * + * By definition, this includes left-click on windows/linux, and left-click + * without the ctrl key on Macs. + * + * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event. + * @return {boolean} The result. + */ +ol.events.condition.mouseActionButton = function(mapBrowserEvent) { + var originalEvent = mapBrowserEvent.originalEvent; + return originalEvent.button == 0 && + !(goog.userAgent.WEBKIT && ol.has.MAC && originalEvent.ctrlKey); +}; + + +/** * Return always false. * * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event. @@ -53393,7 +44253,7 @@ ol.events.condition.click = function(mapBrowserEvent) { * @function * @api stable */ -ol.events.condition.never = goog.functions.FALSE; +ol.events.condition.never = ol.functions.FALSE; /** @@ -53442,11 +44302,11 @@ ol.events.condition.doubleClick = function(mapBrowserEvent) { * @api stable */ ol.events.condition.noModifierKeys = function(mapBrowserEvent) { - var browserEvent = mapBrowserEvent.browserEvent; + var originalEvent = mapBrowserEvent.originalEvent; return ( - !browserEvent.altKey && - !browserEvent.platformModifierKey && - !browserEvent.shiftKey); + !originalEvent.altKey && + !(originalEvent.metaKey || originalEvent.ctrlKey) && + !originalEvent.shiftKey); }; @@ -53460,11 +44320,11 @@ ol.events.condition.noModifierKeys = function(mapBrowserEvent) { * @api stable */ ol.events.condition.platformModifierKeyOnly = function(mapBrowserEvent) { - var browserEvent = mapBrowserEvent.browserEvent; + var originalEvent = mapBrowserEvent.originalEvent; return ( - !browserEvent.altKey && - browserEvent.platformModifierKey && - !browserEvent.shiftKey); + !originalEvent.altKey && + (ol.has.MAC ? originalEvent.metaKey : originalEvent.ctrlKey) && + !originalEvent.shiftKey); }; @@ -53477,11 +44337,11 @@ ol.events.condition.platformModifierKeyOnly = function(mapBrowserEvent) { * @api stable */ ol.events.condition.shiftKeyOnly = function(mapBrowserEvent) { - var browserEvent = mapBrowserEvent.browserEvent; + var originalEvent = mapBrowserEvent.originalEvent; return ( - !browserEvent.altKey && - !browserEvent.platformModifierKey && - browserEvent.shiftKey); + !originalEvent.altKey && + !(originalEvent.metaKey || originalEvent.ctrlKey) && + originalEvent.shiftKey); }; @@ -53494,7 +44354,7 @@ ol.events.condition.shiftKeyOnly = function(mapBrowserEvent) { * @api */ ol.events.condition.targetNotEditable = function(mapBrowserEvent) { - var target = mapBrowserEvent.browserEvent.target; + var target = mapBrowserEvent.originalEvent.target; goog.asserts.assertInstanceof(target, Element, 'target should be an Element'); var tagName = target.tagName; @@ -53517,16 +44377,28 @@ ol.events.condition.mouseOnly = function(mapBrowserEvent) { return mapBrowserEvent.pointerEvent.pointerType == 'mouse'; }; + +/** + * Return `true` if the event originates from a primary pointer in + * contact with the surface or if the left mouse button is pressed. + * @see http://www.w3.org/TR/pointerevents/#button-states + * + * @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event. + * @return {boolean} True if the event originates from a primary pointer. + * @api + */ +ol.events.condition.primaryAction = function(mapBrowserEvent) { + var pointerEvent = mapBrowserEvent.pointerEvent; + return pointerEvent.isPrimary && pointerEvent.button === 0; +}; + goog.provide('ol.interaction.Pointer'); -goog.require('goog.functions'); -goog.require('goog.object'); goog.require('ol'); goog.require('ol.MapBrowserEvent.EventType'); goog.require('ol.MapBrowserPointerEvent'); -goog.require('ol.Pixel'); goog.require('ol.interaction.Interaction'); - +goog.require('ol.object'); /** @@ -53606,7 +44478,7 @@ goog.inherits(ol.interaction.Pointer, ol.interaction.Interaction); /** - * @param {Array.<ol.pointer.PointerEvent>} pointerEvents + * @param {Array.<ol.pointer.PointerEvent>} pointerEvents List of events. * @return {ol.Pixel} Centroid pixel. */ ol.interaction.Pointer.centroid = function(pointerEvents) { @@ -53627,8 +44499,7 @@ ol.interaction.Pointer.centroid = function(pointerEvents) { * or pointerup event. * @private */ -ol.interaction.Pointer.prototype.isPointerDraggingEvent_ = - function(mapBrowserEvent) { +ol.interaction.Pointer.prototype.isPointerDraggingEvent_ = function(mapBrowserEvent) { var type = mapBrowserEvent.type; return ( type === ol.MapBrowserEvent.EventType.POINTERDOWN || @@ -53641,8 +44512,7 @@ ol.interaction.Pointer.prototype.isPointerDraggingEvent_ = * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event. * @private */ -ol.interaction.Pointer.prototype.updateTrackedPointers_ = - function(mapBrowserEvent) { +ol.interaction.Pointer.prototype.updateTrackedPointers_ = function(mapBrowserEvent) { if (this.isPointerDraggingEvent_(mapBrowserEvent)) { var event = mapBrowserEvent.pointerEvent; @@ -53655,7 +44525,7 @@ ol.interaction.Pointer.prototype.updateTrackedPointers_ = // update only when there was a pointerdown event for this pointer this.trackedPointers_[event.pointerId] = event; } - this.targetPointers = goog.object.getValues(this.trackedPointers_); + this.targetPointers = ol.object.getValues(this.trackedPointers_); } }; @@ -53672,7 +44542,7 @@ ol.interaction.Pointer.handleDragEvent = ol.nullFunction; * @return {boolean} Capture dragging. * @this {ol.interaction.Pointer} */ -ol.interaction.Pointer.handleUpEvent = goog.functions.FALSE; +ol.interaction.Pointer.handleUpEvent = ol.functions.FALSE; /** @@ -53680,7 +44550,7 @@ ol.interaction.Pointer.handleUpEvent = goog.functions.FALSE; * @return {boolean} Capture dragging. * @this {ol.interaction.Pointer} */ -ol.interaction.Pointer.handleDownEvent = goog.functions.FALSE; +ol.interaction.Pointer.handleDownEvent = ol.functions.FALSE; /** @@ -53737,21 +44607,22 @@ ol.interaction.Pointer.handleEvent = function(mapBrowserEvent) { * @return {boolean} Should the event be stopped? * @protected */ -ol.interaction.Pointer.prototype.shouldStopEvent = goog.functions.identity; +ol.interaction.Pointer.prototype.shouldStopEvent = function(handled) { + return handled; +}; goog.provide('ol.interaction.DragPan'); goog.require('goog.asserts'); goog.require('ol.Kinetic'); -goog.require('ol.Pixel'); -goog.require('ol.PreRenderFunction'); + goog.require('ol.ViewHint'); goog.require('ol.coordinate'); +goog.require('ol.functions'); goog.require('ol.events.condition'); goog.require('ol.interaction.Pointer'); - /** * @classdesc * Allows the user to pan the map by dragging the map. @@ -53907,19 +44778,18 @@ ol.interaction.DragPan.handleDownEvent_ = function(mapBrowserEvent) { /** * @inheritDoc */ -ol.interaction.DragPan.prototype.shouldStopEvent = goog.functions.FALSE; +ol.interaction.DragPan.prototype.shouldStopEvent = ol.functions.FALSE; goog.provide('ol.interaction.DragRotate'); goog.require('ol'); goog.require('ol.ViewHint'); -goog.require('ol.events.ConditionType'); +goog.require('ol.functions'); goog.require('ol.events.condition'); goog.require('ol.interaction.Interaction'); goog.require('ol.interaction.Pointer'); - /** * @classdesc * Allows the user to rotate the map by clicking and dragging on the map, @@ -54024,8 +44894,8 @@ ol.interaction.DragRotate.handleDownEvent_ = function(mapBrowserEvent) { return false; } - var browserEvent = mapBrowserEvent.browserEvent; - if (browserEvent.isMouseActionButton() && this.condition_(mapBrowserEvent)) { + if (ol.events.condition.mouseActionButton(mapBrowserEvent) && + this.condition_(mapBrowserEvent)) { var map = mapBrowserEvent.map; map.getView().setHint(ol.ViewHint.INTERACTING, 1); map.render(); @@ -54040,21 +44910,20 @@ ol.interaction.DragRotate.handleDownEvent_ = function(mapBrowserEvent) { /** * @inheritDoc */ -ol.interaction.DragRotate.prototype.shouldStopEvent = goog.functions.FALSE; +ol.interaction.DragRotate.prototype.shouldStopEvent = ol.functions.FALSE; // FIXME add rotation goog.provide('ol.render.Box'); -goog.require('goog.Disposable'); goog.require('goog.asserts'); +goog.require('ol.Disposable'); goog.require('ol.geom.Polygon'); - /** * @constructor - * @extends {goog.Disposable} + * @extends {ol.Disposable} * @param {string} className CSS class name. */ ol.render.Box = function(className) { @@ -54092,7 +44961,7 @@ ol.render.Box = function(className) { this.endPixel_ = null; }; -goog.inherits(ol.render.Box, goog.Disposable); +goog.inherits(ol.render.Box, ol.Disposable); /** @@ -54100,7 +44969,6 @@ goog.inherits(ol.render.Box, goog.Disposable); */ ol.render.Box.prototype.disposeInternal = function() { this.setMap(null); - goog.base(this, 'disposeInternal'); }; @@ -54188,9 +45056,8 @@ ol.render.Box.prototype.getGeometry = function() { goog.provide('ol.DragBoxEvent'); goog.provide('ol.interaction.DragBox'); -goog.require('goog.events.Event'); +goog.require('ol.events.Event'); goog.require('ol'); -goog.require('ol.events.ConditionType'); goog.require('ol.events.condition'); goog.require('ol.interaction.Pointer'); goog.require('ol.render.Box'); @@ -54215,6 +45082,14 @@ ol.DragBoxEventType = { * @api stable */ BOXSTART: 'boxstart', + + /** + * Triggered on drag when box is active. + * @event ol.DragBoxEvent#boxdrag + * @api + */ + BOXDRAG: 'boxdrag', + /** * Triggered upon drag box end. * @event ol.DragBoxEvent#boxend @@ -54224,7 +45099,6 @@ ol.DragBoxEventType = { }; - /** * @classdesc * Events emitted by {@link ol.interaction.DragBox} instances are instances of @@ -54232,11 +45106,12 @@ ol.DragBoxEventType = { * * @param {string} type The event type. * @param {ol.Coordinate} coordinate The event coordinate. - * @extends {goog.events.Event} + * @param {ol.MapBrowserEvent} mapBrowserEvent Originating event. + * @extends {ol.events.Event} * @constructor * @implements {oli.DragBoxEvent} */ -ol.DragBoxEvent = function(type, coordinate) { +ol.DragBoxEvent = function(type, coordinate, mapBrowserEvent) { goog.base(this, type); /** @@ -54247,9 +45122,15 @@ ol.DragBoxEvent = function(type, coordinate) { */ this.coordinate = coordinate; -}; -goog.inherits(ol.DragBoxEvent, goog.events.Event); + /** + * @const + * @type {ol.MapBrowserEvent} + * @api + */ + this.mapBrowserEvent = mapBrowserEvent; +}; +goog.inherits(ol.DragBoxEvent, ol.events.Event); /** @@ -54298,11 +45179,35 @@ ol.interaction.DragBox = function(opt_options) { this.condition_ = options.condition ? options.condition : ol.events.condition.always; + /** + * @private + * @type {ol.interaction.DragBoxEndConditionType} + */ + this.boxEndCondition_ = options.boxEndCondition ? + options.boxEndCondition : ol.interaction.DragBox.defaultBoxEndCondition; }; goog.inherits(ol.interaction.DragBox, ol.interaction.Pointer); /** + * The default condition for determining whether the boxend event + * should fire. + * @param {ol.MapBrowserEvent} mapBrowserEvent The originating MapBrowserEvent + * leading to the box end. + * @param {ol.Pixel} startPixel The starting pixel of the box. + * @param {ol.Pixel} endPixel The end pixel of the box. + * @return {boolean} Whether or not the boxend condition should be fired. + */ +ol.interaction.DragBox.defaultBoxEndCondition = function(mapBrowserEvent, + startPixel, endPixel) { + var width = endPixel[0] - startPixel[0]; + var height = endPixel[1] - startPixel[1]; + return width * width + height * height >= + ol.DRAG_BOX_HYSTERESIS_PIXELS_SQUARED; +}; + + +/** * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event. * @this {ol.interaction.DragBox} * @private @@ -54313,6 +45218,9 @@ ol.interaction.DragBox.handleDragEvent_ = function(mapBrowserEvent) { } this.box_.setPixels(this.startPixel_, mapBrowserEvent.pixel); + + this.dispatchEvent(new ol.DragBoxEvent(ol.DragBoxEventType.BOXDRAG, + mapBrowserEvent.coordinate, mapBrowserEvent)); }; @@ -54348,14 +45256,11 @@ ol.interaction.DragBox.handleUpEvent_ = function(mapBrowserEvent) { this.box_.setMap(null); - var deltaX = mapBrowserEvent.pixel[0] - this.startPixel_[0]; - var deltaY = mapBrowserEvent.pixel[1] - this.startPixel_[1]; - - if (deltaX * deltaX + deltaY * deltaY >= - ol.DRAG_BOX_HYSTERESIS_PIXELS_SQUARED) { + if (this.boxEndCondition_(mapBrowserEvent, + this.startPixel_, mapBrowserEvent.pixel)) { this.onBoxEnd(mapBrowserEvent); this.dispatchEvent(new ol.DragBoxEvent(ol.DragBoxEventType.BOXEND, - mapBrowserEvent.coordinate)); + mapBrowserEvent.coordinate, mapBrowserEvent)); } return false; }; @@ -54372,13 +45277,13 @@ ol.interaction.DragBox.handleDownEvent_ = function(mapBrowserEvent) { return false; } - var browserEvent = mapBrowserEvent.browserEvent; - if (browserEvent.isMouseActionButton() && this.condition_(mapBrowserEvent)) { + if (ol.events.condition.mouseActionButton(mapBrowserEvent) && + this.condition_(mapBrowserEvent)) { this.startPixel_ = mapBrowserEvent.pixel; this.box_.setMap(mapBrowserEvent.map); this.box_.setPixels(this.startPixel_, this.startPixel_); this.dispatchEvent(new ol.DragBoxEvent(ol.DragBoxEventType.BOXSTART, - mapBrowserEvent.coordinate)); + mapBrowserEvent.coordinate, mapBrowserEvent)); return true; } else { return false; @@ -54395,7 +45300,6 @@ goog.require('ol.extent'); goog.require('ol.interaction.DragBox'); - /** * @classdesc * Allows the user to zoom the map by clicking and dragging on the map, @@ -54422,6 +45326,12 @@ ol.interaction.DragZoom = function(opt_options) { */ this.duration_ = options.duration !== undefined ? options.duration : 200; + /** + * @private + * @type {boolean} + */ + this.out_ = options.out !== undefined ? options.out : false; + goog.base(this, { condition: condition, className: options.className || 'ol-dragzoom' @@ -54445,6 +45355,17 @@ ol.interaction.DragZoom.prototype.onBoxEnd = function() { var extent = this.getGeometry().getExtent(); + if (this.out_) { + var mapExtent = view.calculateExtent(size); + var boxPixelExtent = ol.extent.createOrUpdateFromCoordinates([ + map.getPixelFromCoordinate(ol.extent.getBottomLeft(extent)), + map.getPixelFromCoordinate(ol.extent.getTopRight(extent))]); + var factor = view.getResolutionForExtent(boxPixelExtent, size); + + ol.extent.scaleFromCenter(mapExtent, 1 / factor); + extent = mapExtent; + } + var resolution = view.constrainResolution( view.getResolutionForExtent(extent, size)); @@ -54472,17 +45393,14 @@ ol.interaction.DragZoom.prototype.onBoxEnd = function() { goog.provide('ol.interaction.KeyboardPan'); goog.require('goog.asserts'); -goog.require('goog.events.KeyCodes'); -goog.require('goog.events.KeyHandler.EventType'); -goog.require('goog.functions'); goog.require('ol'); goog.require('ol.coordinate'); -goog.require('ol.events.ConditionType'); +goog.require('ol.events.EventType'); +goog.require('ol.events.KeyCode'); goog.require('ol.events.condition'); goog.require('ol.interaction.Interaction'); - /** * @classdesc * Allows the user to pan the map using keyboard arrows. @@ -54510,12 +45428,20 @@ ol.interaction.KeyboardPan = function(opt_options) { /** * @private + * @param {ol.MapBrowserEvent} mapBrowserEvent Browser event. + * @return {boolean} Combined condition result. + */ + this.defaultCondition_ = function(mapBrowserEvent) { + return ol.events.condition.noModifierKeys(mapBrowserEvent) && + ol.events.condition.targetNotEditable(mapBrowserEvent); + } + + /** + * @private * @type {ol.events.ConditionType} */ this.condition_ = options.condition !== undefined ? - options.condition : - goog.functions.and(ol.events.condition.noModifierKeys, - ol.events.condition.targetNotEditable); + options.condition : this.defaultCondition_ /** * @private @@ -54533,7 +45459,6 @@ ol.interaction.KeyboardPan = function(opt_options) { }; goog.inherits(ol.interaction.KeyboardPan, ol.interaction.Interaction); - /** * Handles the {@link ol.MapBrowserEvent map browser event} if it was a * `KeyEvent`, and decides the direction to pan to (if an arrow key was @@ -54545,25 +45470,24 @@ goog.inherits(ol.interaction.KeyboardPan, ol.interaction.Interaction); */ ol.interaction.KeyboardPan.handleEvent = function(mapBrowserEvent) { var stopEvent = false; - if (mapBrowserEvent.type == goog.events.KeyHandler.EventType.KEY) { - var keyEvent = /** @type {goog.events.KeyEvent} */ - (mapBrowserEvent.browserEvent); + if (mapBrowserEvent.type == ol.events.EventType.KEYDOWN) { + var keyEvent = mapBrowserEvent.originalEvent; var keyCode = keyEvent.keyCode; if (this.condition_(mapBrowserEvent) && - (keyCode == goog.events.KeyCodes.DOWN || - keyCode == goog.events.KeyCodes.LEFT || - keyCode == goog.events.KeyCodes.RIGHT || - keyCode == goog.events.KeyCodes.UP)) { + (keyCode == ol.events.KeyCode.DOWN || + keyCode == ol.events.KeyCode.LEFT || + keyCode == ol.events.KeyCode.RIGHT || + keyCode == ol.events.KeyCode.UP)) { var map = mapBrowserEvent.map; var view = map.getView(); goog.asserts.assert(view, 'map must have view'); var mapUnitsDelta = view.getResolution() * this.pixelDelta_; var deltaX = 0, deltaY = 0; - if (keyCode == goog.events.KeyCodes.DOWN) { + if (keyCode == ol.events.KeyCode.DOWN) { deltaY = -mapUnitsDelta; - } else if (keyCode == goog.events.KeyCodes.LEFT) { + } else if (keyCode == ol.events.KeyCode.LEFT) { deltaX = -mapUnitsDelta; - } else if (keyCode == goog.events.KeyCodes.RIGHT) { + } else if (keyCode == ol.events.KeyCode.RIGHT) { deltaX = mapUnitsDelta; } else { deltaY = mapUnitsDelta; @@ -54581,13 +45505,11 @@ ol.interaction.KeyboardPan.handleEvent = function(mapBrowserEvent) { goog.provide('ol.interaction.KeyboardZoom'); goog.require('goog.asserts'); -goog.require('goog.events.KeyHandler.EventType'); -goog.require('ol.events.ConditionType'); +goog.require('ol.events.EventType'); goog.require('ol.events.condition'); goog.require('ol.interaction.Interaction'); - /** * @classdesc * Allows the user to zoom the map using keyboard + and -. @@ -54647,9 +45569,9 @@ goog.inherits(ol.interaction.KeyboardZoom, ol.interaction.Interaction); */ ol.interaction.KeyboardZoom.handleEvent = function(mapBrowserEvent) { var stopEvent = false; - if (mapBrowserEvent.type == goog.events.KeyHandler.EventType.KEY) { - var keyEvent = /** @type {goog.events.KeyEvent} */ - (mapBrowserEvent.browserEvent); + if (mapBrowserEvent.type == ol.events.EventType.KEYDOWN || + mapBrowserEvent.type == ol.events.EventType.KEYPRESS) { + var keyEvent = mapBrowserEvent.originalEvent; var charCode = keyEvent.charCode; if (this.condition_(mapBrowserEvent) && (charCode == '+'.charCodeAt(0) || charCode == '-'.charCodeAt(0))) { @@ -54670,15 +45592,12 @@ ol.interaction.KeyboardZoom.handleEvent = function(mapBrowserEvent) { goog.provide('ol.interaction.MouseWheelZoom'); goog.require('goog.asserts'); -goog.require('goog.events.MouseWheelEvent'); -goog.require('goog.events.MouseWheelHandler.EventType'); goog.require('ol'); -goog.require('ol.Coordinate'); +goog.require('ol.events.EventType'); goog.require('ol.interaction.Interaction'); goog.require('ol.math'); - /** * @classdesc * Allows the user to zoom the map by scrolling the mouse wheel. @@ -54746,18 +45665,36 @@ goog.inherits(ol.interaction.MouseWheelZoom, ol.interaction.Interaction); */ ol.interaction.MouseWheelZoom.handleEvent = function(mapBrowserEvent) { var stopEvent = false; - if (mapBrowserEvent.type == - goog.events.MouseWheelHandler.EventType.MOUSEWHEEL) { + if (mapBrowserEvent.type == ol.events.EventType.WHEEL || + mapBrowserEvent.type == ol.events.EventType.MOUSEWHEEL) { var map = mapBrowserEvent.map; - var mouseWheelEvent = mapBrowserEvent.browserEvent; - goog.asserts.assertInstanceof(mouseWheelEvent, goog.events.MouseWheelEvent, - 'mouseWheelEvent should be of type MouseWheelEvent'); + var wheelEvent = /** @type {WheelEvent} */ (mapBrowserEvent.originalEvent); if (this.useAnchor_) { this.lastAnchor_ = mapBrowserEvent.coordinate; } - this.delta_ += mouseWheelEvent.deltaY; + // Delta normalisation inspired by + // https://github.com/mapbox/mapbox-gl-js/blob/001c7b9/js/ui/handler/scroll_zoom.js + //TODO There's more good stuff in there for inspiration to improve this interaction. + var delta; + if (mapBrowserEvent.type == ol.events.EventType.WHEEL) { + delta = wheelEvent.deltaY; + if (ol.has.FIREFOX && + wheelEvent.deltaMode === ol.global.WheelEvent.DOM_DELTA_PIXEL) { + delta /= ol.has.DEVICE_PIXEL_RATIO; + } + if (wheelEvent.deltaMode === ol.global.WheelEvent.DOM_DELTA_LINE) { + delta *= 40; + } + } else if (mapBrowserEvent.type == ol.events.EventType.MOUSEWHEEL) { + delta = -wheelEvent.wheelDeltaY; + if (ol.has.SAFARI) { + delta /= 3; + } + } + + this.delta_ += delta; if (this.startTime_ === undefined) { this.startTime_ = Date.now(); @@ -54766,9 +45703,9 @@ ol.interaction.MouseWheelZoom.handleEvent = function(mapBrowserEvent) { var duration = ol.MOUSEWHEELZOOM_TIMEOUT_DURATION; var timeLeft = Math.max(duration - (Date.now() - this.startTime_), 0); - goog.global.clearTimeout(this.timeoutId_); - this.timeoutId_ = goog.global.setTimeout( - goog.bind(this.doZoom_, this, map), timeLeft); + ol.global.clearTimeout(this.timeoutId_); + this.timeoutId_ = ol.global.setTimeout( + this.doZoom_.bind(this, map), timeLeft); mapBrowserEvent.preventDefault(); stopEvent = true; @@ -54815,16 +45752,13 @@ ol.interaction.MouseWheelZoom.prototype.setMouseAnchor = function(useAnchor) { goog.provide('ol.interaction.PinchRotate'); goog.require('goog.asserts'); -goog.require('goog.functions'); -goog.require('goog.style'); goog.require('ol'); -goog.require('ol.Coordinate'); +goog.require('ol.functions'); goog.require('ol.ViewHint'); goog.require('ol.interaction.Interaction'); goog.require('ol.interaction.Pointer'); - /** * @classdesc * Allows the user to rotate the map by twisting with two fingers @@ -54919,11 +45853,10 @@ ol.interaction.PinchRotate.handleDragEvent_ = function(mapBrowserEvent) { // rotate anchor point. // FIXME: should be the intersection point between the lines: // touch0,touch1 and previousTouch0,previousTouch1 - var viewportPosition = goog.style.getClientPosition(map.getViewport()); - var centroid = - ol.interaction.Pointer.centroid(this.targetPointers); - centroid[0] -= viewportPosition.x; - centroid[1] -= viewportPosition.y; + var viewportPosition = map.getViewport().getBoundingClientRect(); + var centroid = ol.interaction.Pointer.centroid(this.targetPointers); + centroid[0] -= viewportPosition.left; + centroid[1] -= viewportPosition.top; this.anchor_ = map.getCoordinateFromPixel(centroid); // rotate @@ -54987,21 +45920,18 @@ ol.interaction.PinchRotate.handleDownEvent_ = function(mapBrowserEvent) { /** * @inheritDoc */ -ol.interaction.PinchRotate.prototype.shouldStopEvent = goog.functions.FALSE; +ol.interaction.PinchRotate.prototype.shouldStopEvent = ol.functions.FALSE; goog.provide('ol.interaction.PinchZoom'); goog.require('goog.asserts'); -goog.require('goog.functions'); -goog.require('goog.style'); goog.require('ol'); -goog.require('ol.Coordinate'); +goog.require('ol.functions'); goog.require('ol.ViewHint'); goog.require('ol.interaction.Interaction'); goog.require('ol.interaction.Pointer'); - /** * @classdesc * Allows the user to zoom the map by pinching with two fingers @@ -55081,11 +46011,10 @@ ol.interaction.PinchZoom.handleDragEvent_ = function(mapBrowserEvent) { var resolution = view.getResolution(); // scale anchor point. - var viewportPosition = goog.style.getClientPosition(map.getViewport()); - var centroid = - ol.interaction.Pointer.centroid(this.targetPointers); - centroid[0] -= viewportPosition.x; - centroid[1] -= viewportPosition.y; + var viewportPosition = map.getViewport().getBoundingClientRect(); + var centroid = ol.interaction.Pointer.centroid(this.targetPointers); + centroid[0] -= viewportPosition.left; + centroid[1] -= viewportPosition.top; this.anchor_ = map.getCoordinateFromPixel(centroid); // scale, bypass the resolution constraint @@ -55147,7 +46076,7 @@ ol.interaction.PinchZoom.handleDownEvent_ = function(mapBrowserEvent) { /** * @inheritDoc */ -ol.interaction.PinchZoom.prototype.shouldStopEvent = goog.functions.FALSE; +ol.interaction.PinchZoom.prototype.shouldStopEvent = ol.functions.FALSE; goog.provide('ol.interaction'); @@ -55263,16 +46192,16 @@ ol.interaction.defaults = function(opt_options) { goog.provide('ol.layer.Group'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.object'); goog.require('ol.Collection'); goog.require('ol.CollectionEvent'); goog.require('ol.CollectionEventType'); goog.require('ol.Object'); goog.require('ol.ObjectEventType'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol.extent'); goog.require('ol.layer.Base'); +goog.require('ol.object'); goog.require('ol.source.State'); @@ -55284,7 +46213,6 @@ ol.layer.GroupProperty = { }; - /** * @classdesc * A {@link ol.Collection} of layers that are handled together. @@ -55300,7 +46228,7 @@ ol.layer.Group = function(opt_options) { var options = opt_options || {}; var baseOptions = /** @type {olx.layer.GroupOptions} */ - (goog.object.clone(options)); + (ol.object.assign({}, options)); delete baseOptions.layers; var layers = options.layers; @@ -55309,22 +46237,22 @@ ol.layer.Group = function(opt_options) { /** * @private - * @type {Array.<goog.events.Key>} + * @type {Array.<ol.events.Key>} */ this.layersListenerKeys_ = []; /** * @private - * @type {Object.<string, Array.<goog.events.Key>>} + * @type {Object.<string, Array.<ol.events.Key>>} */ this.listenerKeys_ = {}; - goog.events.listen(this, + ol.events.listen(this, ol.Object.getChangeEventType(ol.layer.GroupProperty.LAYERS), - this.handleLayersChanged_, false, this); + this.handleLayersChanged_, this); if (layers) { - if (goog.isArray(layers)) { + if (Array.isArray(layers)) { layers = new ol.Collection(layers.slice()); } else { goog.asserts.assertInstanceof(layers, ol.Collection, @@ -55352,34 +46280,34 @@ ol.layer.Group.prototype.handleLayerChange_ = function() { /** - * @param {goog.events.Event} event Event. + * @param {ol.events.Event} event Event. * @private */ ol.layer.Group.prototype.handleLayersChanged_ = function(event) { - this.layersListenerKeys_.forEach(goog.events.unlistenByKey); + this.layersListenerKeys_.forEach(ol.events.unlistenByKey); this.layersListenerKeys_.length = 0; var layers = this.getLayers(); this.layersListenerKeys_.push( - goog.events.listen(layers, ol.CollectionEventType.ADD, - this.handleLayersAdd_, false, this), - goog.events.listen(layers, ol.CollectionEventType.REMOVE, - this.handleLayersRemove_, false, this)); + ol.events.listen(layers, ol.CollectionEventType.ADD, + this.handleLayersAdd_, this), + ol.events.listen(layers, ol.CollectionEventType.REMOVE, + this.handleLayersRemove_, this)); - goog.object.forEach(this.listenerKeys_, function(keys) { - keys.forEach(goog.events.unlistenByKey); - }); - goog.object.clear(this.listenerKeys_); + for (var id in this.listenerKeys_) { + this.listenerKeys_[id].forEach(ol.events.unlistenByKey); + } + ol.object.clear(this.listenerKeys_); var layersArray = layers.getArray(); var i, ii, layer; for (i = 0, ii = layersArray.length; i < ii; i++) { layer = layersArray[i]; this.listenerKeys_[goog.getUid(layer).toString()] = [ - goog.events.listen(layer, ol.ObjectEventType.PROPERTYCHANGE, - this.handleLayerChange_, false, this), - goog.events.listen(layer, goog.events.EventType.CHANGE, - this.handleLayerChange_, false, this) + ol.events.listen(layer, ol.ObjectEventType.PROPERTYCHANGE, + this.handleLayerChange_, this), + ol.events.listen(layer, ol.events.EventType.CHANGE, + this.handleLayerChange_, this) ]; } @@ -55397,10 +46325,10 @@ ol.layer.Group.prototype.handleLayersAdd_ = function(collectionEvent) { goog.asserts.assert(!(key in this.listenerKeys_), 'listeners already registered'); this.listenerKeys_[key] = [ - goog.events.listen(layer, ol.ObjectEventType.PROPERTYCHANGE, - this.handleLayerChange_, false, this), - goog.events.listen(layer, goog.events.EventType.CHANGE, - this.handleLayerChange_, false, this) + ol.events.listen(layer, ol.ObjectEventType.PROPERTYCHANGE, + this.handleLayerChange_, this), + ol.events.listen(layer, ol.events.EventType.CHANGE, + this.handleLayerChange_, this) ]; this.changed(); }; @@ -55414,7 +46342,7 @@ ol.layer.Group.prototype.handleLayersRemove_ = function(collectionEvent) { var layer = /** @type {ol.layer.Base} */ (collectionEvent.element); var key = goog.getUid(layer).toString(); goog.asserts.assert(key in this.listenerKeys_, 'no listeners to unregister'); - this.listenerKeys_[key].forEach(goog.events.unlistenByKey); + this.listenerKeys_[key].forEach(ol.events.unlistenByKey); delete this.listenerKeys_[key]; this.changed(); }; @@ -55511,7 +46439,6 @@ goog.require('ol.proj.Projection'); goog.require('ol.proj.Units'); - /** * @classdesc * Projection object for web/spherical Mercator (EPSG:3857). @@ -55660,12 +46587,24 @@ ol.proj.EPSG3857.toEPSG4326 = function(input, opt_output, opt_dimension) { return output; }; +goog.provide('ol.sphere.WGS84'); + +goog.require('ol.Sphere'); + + +/** + * A sphere with radius equal to the semi-major axis of the WGS84 ellipsoid. + * @const + * @type {ol.Sphere} + */ +ol.sphere.WGS84 = new ol.Sphere(6378137); + goog.provide('ol.proj.EPSG4326'); goog.require('ol.proj'); goog.require('ol.proj.Projection'); goog.require('ol.proj.Units'); - +goog.require('ol.sphere.WGS84'); /** @@ -55689,6 +46628,7 @@ ol.proj.EPSG4326_ = function(code, opt_axisOrientation) { extent: ol.proj.EPSG4326.EXTENT, axisOrientation: opt_axisOrientation, global: true, + metersPerUnit: ol.proj.EPSG4326.METERS_PER_UNIT, worldExtent: ol.proj.EPSG4326.EXTENT }); }; @@ -55713,6 +46653,13 @@ ol.proj.EPSG4326.EXTENT = [-180, -90, 180, 90]; /** + * @const + * @type {number} + */ +ol.proj.EPSG4326.METERS_PER_UNIT = Math.PI * ol.sphere.WGS84.radius / 180; + + +/** * Projections equal to EPSG:4326. * * @const @@ -55759,7 +46706,6 @@ goog.provide('ol.layer.Image'); goog.require('ol.layer.Layer'); - /** * @classdesc * Server-rendered images that are available for arbitrary extents and @@ -55791,9 +46737,9 @@ ol.layer.Image.prototype.getSource; goog.provide('ol.layer.Tile'); -goog.require('goog.object'); goog.require('ol'); goog.require('ol.layer.Layer'); +goog.require('ol.object'); /** @@ -55805,7 +46751,6 @@ ol.layer.TileProperty = { }; - /** * @classdesc * For layer sources that provide pre-rendered, tiled images in grids that are @@ -55823,7 +46768,7 @@ ol.layer.TileProperty = { ol.layer.Tile = function(opt_options) { var options = opt_options ? opt_options : {}; - var baseOptions = goog.object.clone(options); + var baseOptions = ol.object.assign({}, options); delete baseOptions.preload; delete baseOptions.useInterimTilesOnError; @@ -55885,8 +46830,7 @@ ol.layer.Tile.prototype.getUseInterimTilesOnError = function() { * @observable * @api */ -ol.layer.Tile.prototype.setUseInterimTilesOnError = - function(useInterimTilesOnError) { +ol.layer.Tile.prototype.setUseInterimTilesOnError = function(useInterimTilesOnError) { this.set( ol.layer.TileProperty.USE_INTERIM_TILES_ON_ERROR, useInterimTilesOnError); }; @@ -55895,31 +46839,6 @@ goog.provide('ol.render.canvas'); /** - * @typedef {{fillStyle: string}} - */ -ol.render.canvas.FillState; - - -/** - * @typedef {{lineCap: string, - * lineDash: Array.<number>, - * lineJoin: string, - * lineWidth: number, - * miterLimit: number, - * strokeStyle: string}} - */ -ol.render.canvas.StrokeState; - - -/** - * @typedef {{font: string, - * textAlign: string, - * textBaseline: string}} - */ -ol.render.canvas.TextState; - - -/** * @const * @type {string} */ @@ -55988,28 +46907,24 @@ ol.render.canvas.defaultTextBaseline = 'middle'; */ ol.render.canvas.defaultLineWidth = 1; -goog.provide('ol.structs.IHasChecksum'); - - - -/** - * @interface - */ -ol.structs.IHasChecksum = function() { -}; - /** - * @return {string} The checksum. + * @param {CanvasRenderingContext2D} context Context. + * @param {number} rotation Rotation. + * @param {number} offsetX X offset. + * @param {number} offsetY Y offset. */ -ol.structs.IHasChecksum.prototype.getChecksum = function() { +ol.render.canvas.rotateAtOffset = function(context, rotation, offsetX, offsetY) { + if (rotation !== 0) { + context.translate(offsetX, offsetY); + context.rotate(rotation); + context.translate(-offsetX, -offsetY); + } }; goog.provide('ol.style.Fill'); goog.require('ol.color'); -goog.require('ol.structs.IHasChecksum'); - /** @@ -56018,7 +46933,6 @@ goog.require('ol.structs.IHasChecksum'); * * @constructor * @param {olx.style.FillOptions=} opt_options Options. - * @implements {ol.structs.IHasChecksum} * @api */ ol.style.Fill = function(opt_options) { @@ -56027,7 +46941,7 @@ ol.style.Fill = function(opt_options) { /** * @private - * @type {ol.Color|string} + * @type {ol.Color|ol.ColorLike} */ this.color_ = options.color !== undefined ? options.color : null; @@ -56041,7 +46955,7 @@ ol.style.Fill = function(opt_options) { /** * Get the fill color. - * @return {ol.Color|string} Color. + * @return {ol.Color|ol.ColorLike} Color. * @api */ ol.style.Fill.prototype.getColor = function() { @@ -56052,7 +46966,7 @@ ol.style.Fill.prototype.getColor = function() { /** * Set the color. * - * @param {ol.Color|string} color Color. + * @param {ol.Color|ol.ColorLike} color Color. * @api */ ol.style.Fill.prototype.setColor = function(color) { @@ -56062,12 +46976,19 @@ ol.style.Fill.prototype.setColor = function(color) { /** - * @inheritDoc + * @return {string} The checksum. */ ol.style.Fill.prototype.getChecksum = function() { if (this.checksum_ === undefined) { - this.checksum_ = 'f' + (this.color_ ? - ol.color.asString(this.color_) : '-'); + if ( + this.color_ instanceof CanvasPattern || + this.color_ instanceof CanvasGradient + ) { + this.checksum_ = goog.getUid(this.color_).toString(); + } else { + this.checksum_ = 'f' + (this.color_ ? + ol.color.asString(this.color_) : '-'); + } } return this.checksum_; @@ -56121,7 +47042,8 @@ goog.crypt.stringToByteArray = function(str) { /** * Turns an array of numbers into the string given by the concatenation of the * characters to which the numbers correspond. - * @param {Array<number>} bytes Array of numbers representing characters. + * @param {!Uint8Array|!Array<number>} bytes Array of numbers representing + * characters. * @return {string} Stringification of the array. */ goog.crypt.byteArrayToString = function(bytes) { @@ -56153,10 +47075,14 @@ goog.crypt.byteArrayToString = function(bytes) { * @return {string} Hex string. */ goog.crypt.byteArrayToHex = function(array) { - return goog.array.map(array, function(numByte) { - var hexByte = numByte.toString(16); - return hexByte.length > 1 ? hexByte : '0' + hexByte; - }).join(''); + return goog.array + .map( + array, + function(numByte) { + var hexByte = numByte.toString(16); + return hexByte.length > 1 ? hexByte : '0' + hexByte; + }) + .join(''); }; @@ -56167,8 +47093,8 @@ goog.crypt.byteArrayToHex = function(array) { * @return {!Array<number>} Array of {0,255} integers for the given string. */ goog.crypt.hexToByteArray = function(hexString) { - goog.asserts.assert(hexString.length % 2 == 0, - 'Key string length must be multiple of 2'); + goog.asserts.assert( + hexString.length % 2 == 0, 'Key string length must be multiple of 2'); var arr = []; for (var i = 0; i < hexString.length; i += 2) { arr.push(parseInt(hexString.substring(i, i + 2), 16)); @@ -56192,6 +47118,15 @@ goog.crypt.stringToUtf8ByteArray = function(str) { } else if (c < 2048) { out[p++] = (c >> 6) | 192; out[p++] = (c & 63) | 128; + } else if ( + ((c & 0xFC00) == 0xD800) && (i + 1) < str.length && + ((str.charCodeAt(i + 1) & 0xFC00) == 0xDC00)) { + // Surrogate Pair + c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF); + out[p++] = (c >> 18) | 240; + out[p++] = ((c >> 12) & 63) | 128; + out[p++] = ((c >> 6) & 63) | 128; + out[p++] = (c & 63) | 128; } else { out[p++] = (c >> 12) | 224; out[p++] = ((c >> 6) & 63) | 128; @@ -56217,11 +47152,20 @@ goog.crypt.utf8ByteArrayToString = function(bytes) { } else if (c1 > 191 && c1 < 224) { var c2 = bytes[pos++]; out[c++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63); + } else if (c1 > 239 && c1 < 365) { + // Surrogate Pair + var c2 = bytes[pos++]; + var c3 = bytes[pos++]; + var c4 = bytes[pos++]; + var u = ((c1 & 7) << 18 | (c2 & 63) << 12 | (c3 & 63) << 6 | c4 & 63) - + 0x10000; + out[c++] = String.fromCharCode(0xD800 + (u >> 10)); + out[c++] = String.fromCharCode(0xDC00 + (u & 1023)); } else { var c2 = bytes[pos++]; var c3 = bytes[pos++]; - out[c++] = String.fromCharCode( - (c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63); + out[c++] = + String.fromCharCode((c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63); } } return out.join(''); @@ -56230,14 +47174,13 @@ goog.crypt.utf8ByteArrayToString = function(bytes) { /** * XOR two byte arrays. - * @param {!ArrayBufferView|!Array<number>} bytes1 Byte array 1. - * @param {!ArrayBufferView|!Array<number>} bytes2 Byte array 2. + * @param {!Uint8Array|!Int8Array|!Array<number>} bytes1 Byte array 1. + * @param {!Uint8Array|!Int8Array|!Array<number>} bytes2 Byte array 2. * @return {!Array<number>} Resulting XOR of the two byte arrays. */ goog.crypt.xorByteArray = function(bytes1, bytes2) { goog.asserts.assert( - bytes1.length == bytes2.length, - 'XOR array lengths must match'); + bytes1.length == bytes2.length, 'XOR array lengths must match'); var result = []; for (var i = 0; i < bytes1.length; i++) { @@ -56475,16 +47418,14 @@ goog.crypt.Md5.prototype.compress_ = function(buf, opt_offset) { if (goog.isString(buf)) { for (var i = 0; i < 16; ++i) { X[i] = (buf.charCodeAt(opt_offset++)) | - (buf.charCodeAt(opt_offset++) << 8) | - (buf.charCodeAt(opt_offset++) << 16) | - (buf.charCodeAt(opt_offset++) << 24); + (buf.charCodeAt(opt_offset++) << 8) | + (buf.charCodeAt(opt_offset++) << 16) | + (buf.charCodeAt(opt_offset++) << 24); } } else { for (var i = 0; i < 16; ++i) { - X[i] = (buf[opt_offset++]) | - (buf[opt_offset++] << 8) | - (buf[opt_offset++] << 16) | - (buf[opt_offset++] << 24); + X[i] = (buf[opt_offset++]) | (buf[opt_offset++] << 8) | + (buf[opt_offset++] << 16) | (buf[opt_offset++] << 24); } } @@ -56725,9 +47666,9 @@ goog.crypt.Md5.prototype.update = function(bytes, opt_length) { goog.crypt.Md5.prototype.digest = function() { // This must accommodate at least 1 padding byte (0x80), 8 bytes of // total bitlength, and must end at a 64-byte boundary. - var pad = new Array((this.blockLength_ < 56 ? - this.blockSize : - this.blockSize * 2) - this.blockLength_); + var pad = new Array( + (this.blockLength_ < 56 ? this.blockSize : this.blockSize * 2) - + this.blockLength_); // Add padding: 0x80 0x00* pad[0] = 0x80; @@ -56738,7 +47679,7 @@ goog.crypt.Md5.prototype.digest = function() { var totalBits = this.totalLength_ * 8; for (var i = pad.length - 8; i < pad.length; ++i) { pad[i] = totalBits & 0xff; - totalBits /= 0x100; // Don't use bit-shifting here! + totalBits /= 0x100; // Don't use bit-shifting here! } this.update(pad); @@ -56757,8 +47698,6 @@ goog.provide('ol.style.Stroke'); goog.require('goog.crypt'); goog.require('goog.crypt.Md5'); goog.require('ol.color'); -goog.require('ol.structs.IHasChecksum'); - /** @@ -56770,7 +47709,6 @@ goog.require('ol.structs.IHasChecksum'); * * @constructor * @param {olx.style.StrokeOptions=} opt_options Options. - * @implements {ol.structs.IHasChecksum} * @api */ ol.style.Stroke = function(opt_options) { @@ -56908,6 +47846,12 @@ ol.style.Stroke.prototype.setLineCap = function(lineCap) { /** * Set the line dash. * + * Please note that Internet Explorer 10 and lower [do not support][mdn] the + * `setLineDash` method on the `CanvasRenderingContext2D` and therefore this + * property will have no visual effect in these browsers. + * + * [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash#Browser_compatibility + * * @param {Array.<number>} lineDash Line dash. * @api */ @@ -56954,7 +47898,7 @@ ol.style.Stroke.prototype.setWidth = function(width) { /** - * @inheritDoc + * @return {string} The checksum. */ ol.style.Stroke.prototype.getChecksum = function() { if (this.checksum_ === undefined) { @@ -56985,16 +47929,16 @@ goog.provide('ol.style.Circle'); goog.require('goog.asserts'); goog.require('ol'); goog.require('ol.color'); +goog.require('ol.colorlike'); +goog.require('ol.dom'); goog.require('ol.has'); goog.require('ol.render.canvas'); -goog.require('ol.structs.IHasChecksum'); goog.require('ol.style.Fill'); goog.require('ol.style.Image'); goog.require('ol.style.ImageState'); goog.require('ol.style.Stroke'); - /** * @classdesc * Set circle style for vector features. @@ -57002,7 +47946,6 @@ goog.require('ol.style.Stroke'); * @constructor * @param {olx.style.CircleOptions=} opt_options Options. * @extends {ol.style.Image} - * @implements {ol.structs.IHasChecksum} * @api */ ol.style.Circle = function(opt_options) { @@ -57211,15 +48154,8 @@ ol.style.Circle.prototype.unlistenImageChange = ol.nullFunction; /** - * @typedef {{strokeStyle: (string|undefined), strokeWidth: number, - * size: number, lineDash: Array.<number>}} - */ -ol.style.Circle.RenderOptions; - - -/** * @private - * @param {ol.style.AtlasManager|undefined} atlasManager + * @param {ol.style.AtlasManager|undefined} atlasManager An atlas manager. */ ol.style.Circle.prototype.render_ = function(atlasManager) { var imageSize; @@ -57242,7 +48178,7 @@ ol.style.Circle.prototype.render_ = function(atlasManager) { var size = 2 * (this.radius_ + strokeWidth) + 1; - /** @type {ol.style.Circle.RenderOptions} */ + /** @type {ol.style.CircleRenderOptions} */ var renderOptions = { strokeStyle: strokeStyle, strokeWidth: strokeWidth, @@ -57252,18 +48188,14 @@ ol.style.Circle.prototype.render_ = function(atlasManager) { if (atlasManager === undefined) { // no atlas manager is used, create a new canvas - this.canvas_ = /** @type {HTMLCanvasElement} */ - (document.createElement('CANVAS')); - this.canvas_.height = size; - this.canvas_.width = size; + var context = ol.dom.createCanvasContext2D(size, size); + this.canvas_ = context.canvas; // canvas.width and height are rounded to the closest integer size = this.canvas_.width; imageSize = size; // draw the circle on the canvas - var context = /** @type {CanvasRenderingContext2D} */ - (this.canvas_.getContext('2d')); this.draw_(renderOptions, context, 0, 0); this.createHitDetectionCanvas_(renderOptions); @@ -57276,12 +48208,12 @@ ol.style.Circle.prototype.render_ = function(atlasManager) { if (hasCustomHitDetectionImage) { // render the hit-detection image into a separate atlas image renderHitDetectionCallback = - goog.bind(this.drawHitDetectionCanvas_, this, renderOptions); + this.drawHitDetectionCanvas_.bind(this, renderOptions); } var id = this.getChecksum(); var info = atlasManager.add( - id, size, size, goog.bind(this.draw_, this, renderOptions), + id, size, size, this.draw_.bind(this, renderOptions), renderHitDetectionCallback); goog.asserts.assert(info, 'circle radius is too large'); @@ -57307,8 +48239,8 @@ ol.style.Circle.prototype.render_ = function(atlasManager) { /** * @private - * @param {ol.style.Circle.RenderOptions} renderOptions - * @param {CanvasRenderingContext2D} context + * @param {ol.style.CircleRenderOptions} renderOptions Render options. + * @param {CanvasRenderingContext2D} context The rendering context. * @param {number} x The origin for the symbol (x). * @param {number} y The origin for the symbol (y). */ @@ -57325,7 +48257,7 @@ ol.style.Circle.prototype.draw_ = function(renderOptions, context, x, y) { this.radius_, 0, 2 * Math.PI, true); if (this.fill_) { - context.fillStyle = ol.color.asString(this.fill_.getColor()); + context.fillStyle = ol.colorlike.asColorLike(this.fill_.getColor()); context.fill(); } if (this.stroke_) { @@ -57342,7 +48274,7 @@ ol.style.Circle.prototype.draw_ = function(renderOptions, context, x, y) { /** * @private - * @param {ol.style.Circle.RenderOptions} renderOptions + * @param {ol.style.CircleRenderOptions} renderOptions Render options. */ ol.style.Circle.prototype.createHitDetectionCanvas_ = function(renderOptions) { this.hitDetectionImageSize_ = [renderOptions.size, renderOptions.size]; @@ -57353,28 +48285,21 @@ ol.style.Circle.prototype.createHitDetectionCanvas_ = function(renderOptions) { // if no fill style is set, create an extra hit-detection image with a // default fill style - this.hitDetectionCanvas_ = /** @type {HTMLCanvasElement} */ - (document.createElement('CANVAS')); - var canvas = this.hitDetectionCanvas_; + var context = ol.dom.createCanvasContext2D(renderOptions.size, renderOptions.size); + this.hitDetectionCanvas_ = context.canvas; - canvas.height = renderOptions.size; - canvas.width = renderOptions.size; - - var context = /** @type {CanvasRenderingContext2D} */ - (canvas.getContext('2d')); this.drawHitDetectionCanvas_(renderOptions, context, 0, 0); }; /** * @private - * @param {ol.style.Circle.RenderOptions} renderOptions - * @param {CanvasRenderingContext2D} context + * @param {ol.style.CircleRenderOptions} renderOptions Render options. + * @param {CanvasRenderingContext2D} context The context. * @param {number} x The origin for the symbol (x). * @param {number} y The origin for the symbol (y). */ -ol.style.Circle.prototype.drawHitDetectionCanvas_ = - function(renderOptions, context, x, y) { +ol.style.Circle.prototype.drawHitDetectionCanvas_ = function(renderOptions, context, x, y) { // reset transform context.setTransform(1, 0, 0, 1, 0, 0); @@ -57401,7 +48326,7 @@ ol.style.Circle.prototype.drawHitDetectionCanvas_ = /** - * @inheritDoc + * @return {string} The checksum. */ ol.style.Circle.prototype.getChecksum = function() { var strokeChecksum = this.stroke_ ? @@ -57423,9 +48348,7 @@ ol.style.Circle.prototype.getChecksum = function() { return this.checksums_[0]; }; -goog.provide('ol.style.GeometryFunction'); goog.provide('ol.style.Style'); -goog.provide('ol.style.StyleFunction'); goog.provide('ol.style.defaultGeometryFunction'); goog.require('goog.asserts'); @@ -57437,7 +48360,6 @@ goog.require('ol.style.Image'); goog.require('ol.style.Stroke'); - /** * @classdesc * Container for vector feature rendering styles. Any changes made to the style @@ -57445,6 +48367,7 @@ goog.require('ol.style.Stroke'); * feature or layer that uses the style is re-rendered. * * @constructor + * @struct * @param {olx.style.StyleOptions=} opt_options Style options. * @api */ @@ -57585,7 +48508,7 @@ ol.style.Style.prototype.getZIndex = function() { ol.style.Style.prototype.setGeometry = function(geometry) { if (goog.isFunction(geometry)) { this.geometryFunction_ = geometry; - } else if (goog.isString(geometry)) { + } else if (typeof geometry === 'string') { this.geometryFunction_ = function(feature) { var result = feature.get(geometry); if (result) { @@ -57619,18 +48542,6 @@ ol.style.Style.prototype.setZIndex = function(zIndex) { /** - * A function that takes an {@link ol.Feature} and a `{number}` representing - * the view's resolution. The function should return an array of - * {@link ol.style.Style}. This way e.g. a vector layer can be styled. - * - * @typedef {function((ol.Feature|ol.render.Feature), number): - * (ol.style.Style|Array.<ol.style.Style>)} - * @api - */ -ol.style.StyleFunction; - - -/** * Convert the provided object into a style function. Functions passed through * unchanged. Arrays of ol.style.Style or single style objects wrapped in a * new style function. @@ -57648,7 +48559,7 @@ ol.style.createStyleFunction = function(obj) { * @type {Array.<ol.style.Style>} */ var styles; - if (goog.isArray(obj)) { + if (Array.isArray(obj)) { styles = obj; } else { goog.asserts.assertInstanceof(obj, ol.style.Style, @@ -57777,17 +48688,6 @@ ol.style.createDefaultEditingStyles = function() { /** - * A function that takes an {@link ol.Feature} as argument and returns an - * {@link ol.geom.Geometry} that will be rendered and styled for the feature. - * - * @typedef {function((ol.Feature|ol.render.Feature)): - * (ol.geom.Geometry|ol.render.Feature|undefined)} - * @api - */ -ol.style.GeometryFunction; - - -/** * Function that is called with a feature and returns its default geometry. * @param {ol.Feature|ol.render.Feature} feature Feature to get the geometry * for. @@ -57801,9 +48701,9 @@ ol.style.defaultGeometryFunction = function(feature) { goog.provide('ol.layer.Vector'); goog.require('goog.asserts'); -goog.require('goog.object'); goog.require('ol'); goog.require('ol.layer.Layer'); +goog.require('ol.object'); goog.require('ol.style.Style'); @@ -57815,7 +48715,6 @@ ol.layer.VectorProperty = { }; - /** * @classdesc * Vector data that is rendered client-side. @@ -57839,7 +48738,7 @@ ol.layer.Vector = function(opt_options) { goog.isFunction(options.renderOrder), 'renderOrder must be a comparator function'); - var baseOptions = goog.object.clone(options); + var baseOptions = ol.object.assign({}, options); delete baseOptions.style; delete baseOptions.renderBuffer; @@ -57988,8 +48887,9 @@ ol.layer.Vector.prototype.setStyle = function(style) { goog.provide('ol.layer.VectorTile'); -goog.require('goog.object'); +goog.require('goog.asserts'); goog.require('ol.layer.Vector'); +goog.require('ol.object'); /** @@ -58001,6 +48901,25 @@ ol.layer.VectorTileProperty = { }; +/** + * @enum {string} + * Render mode for vector tiles: + * * `'image'`: Vector tiles are rendered as images. Great performance, but + * point symbols and texts are always rotated with the view and pixels are + * scaled during zoom animations. + * * `'hybrid'`: Polygon and line elements are rendered as images, so pixels + * are scaled during zoom animations. Point symbols and texts are accurately + * rendered as vectors and can stay upright on rotated views. + * * `'vector'`: Vector tiles are rendered as vectors. Most accurate rendering + * even during animations, but slower performance than the other options. + * @api + */ +ol.layer.VectorTileRenderType = { + IMAGE: 'image', + HYBRID: 'hybrid', + VECTOR: 'vector' +}; + /** * @classdesc @@ -58017,7 +48936,7 @@ ol.layer.VectorTileProperty = { ol.layer.VectorTile = function(opt_options) { var options = opt_options ? opt_options : {}; - var baseOptions = goog.object.clone(options); + var baseOptions = ol.object.assign({}, options); delete baseOptions.preload; delete baseOptions.useInterimTilesOnError; @@ -58027,6 +48946,18 @@ ol.layer.VectorTile = function(opt_options) { this.setUseInterimTilesOnError(options.useInterimTilesOnError ? options.useInterimTilesOnError : true); + goog.asserts.assert(options.renderMode == undefined || + options.renderMode == ol.layer.VectorTileRenderType.IMAGE || + options.renderMode == ol.layer.VectorTileRenderType.HYBRID || + options.renderMode == ol.layer.VectorTileRenderType.VECTOR, + 'renderMode needs to be \'image\', \'hybrid\' or \'vector\''); + + /** + * @private + * @type {ol.layer.VectorTileRenderType|string} + */ + this.renderMode_ = options.renderMode || ol.layer.VectorTileRenderType.HYBRID; + }; goog.inherits(ol.layer.VectorTile, ol.layer.Vector); @@ -58043,12 +48974,11 @@ ol.layer.VectorTile.prototype.getPreload = function() { /** - * Return the associated {@link ol.source.VectorTile source} of the layer. - * @function - * @return {ol.source.VectorTile} Source. - * @api + * @return {ol.layer.VectorTileRenderType|string} The render mode. */ -ol.layer.VectorTile.prototype.getSource; +ol.layer.VectorTile.prototype.getRenderMode = function() { + return this.renderMode_; +}; /** @@ -58080,8 +49010,7 @@ ol.layer.VectorTile.prototype.setPreload = function(preload) { * @observable * @api */ -ol.layer.VectorTile.prototype.setUseInterimTilesOnError = - function(useInterimTilesOnError) { +ol.layer.VectorTile.prototype.setUseInterimTilesOnError = function(useInterimTilesOnError) { this.set( ol.layer.TileProperty.USE_INTERIM_TILES_ON_ERROR, useInterimTilesOnError); }; @@ -58092,12 +49021,13 @@ ol.layer.VectorTile.prototype.setUseInterimTilesOnError = goog.provide('ol.render.canvas.Immediate'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.vec.Mat4'); goog.require('ol.array'); goog.require('ol.color'); +goog.require('ol.colorlike'); goog.require('ol.extent'); +goog.require('ol.geom.GeometryType'); goog.require('ol.geom.flat.transform'); goog.require('ol.has'); goog.require('ol.render.VectorContext'); @@ -58105,7 +49035,6 @@ goog.require('ol.render.canvas'); goog.require('ol.vec.Mat4'); - /** * @classdesc * A concrete subclass of {@link ol.render.VectorContext} that implements @@ -58124,15 +49053,8 @@ goog.require('ol.vec.Mat4'); * @param {number} viewRotation View rotation. * @struct */ -ol.render.canvas.Immediate = - function(context, pixelRatio, extent, transform, viewRotation) { - - /** - * @private - * @type {!Object.<string, - * Array.<function(ol.render.canvas.Immediate)>>} - */ - this.callbacksByZIndex_ = {}; +ol.render.canvas.Immediate = function(context, pixelRatio, extent, transform, viewRotation) { + goog.base(this); /** * @private @@ -58166,31 +49088,31 @@ ol.render.canvas.Immediate = /** * @private - * @type {?ol.render.canvas.FillState} + * @type {?ol.CanvasFillState} */ this.contextFillState_ = null; /** * @private - * @type {?ol.render.canvas.StrokeState} + * @type {?ol.CanvasStrokeState} */ this.contextStrokeState_ = null; /** * @private - * @type {?ol.render.canvas.TextState} + * @type {?ol.CanvasTextState} */ this.contextTextState_ = null; /** * @private - * @type {?ol.render.canvas.FillState} + * @type {?ol.CanvasFillState} */ this.fillState_ = null; /** * @private - * @type {?ol.render.canvas.StrokeState} + * @type {?ol.CanvasStrokeState} */ this.strokeState_ = null; @@ -58298,19 +49220,19 @@ ol.render.canvas.Immediate = /** * @private - * @type {?ol.render.canvas.FillState} + * @type {?ol.CanvasFillState} */ this.textFillState_ = null; /** * @private - * @type {?ol.render.canvas.StrokeState} + * @type {?ol.CanvasStrokeState} */ this.textStrokeState_ = null; /** * @private - * @type {?ol.render.canvas.TextState} + * @type {?ol.CanvasTextState} */ this.textState_ = null; @@ -58327,6 +49249,7 @@ ol.render.canvas.Immediate = this.tmpLocalTransform_ = goog.vec.Mat4.createNumber(); }; +goog.inherits(ol.render.canvas.Immediate, ol.render.VectorContext); /** @@ -58336,8 +49259,7 @@ ol.render.canvas.Immediate = * @param {number} stride Stride. * @private */ -ol.render.canvas.Immediate.prototype.drawImages_ = - function(flatCoordinates, offset, end, stride) { +ol.render.canvas.Immediate.prototype.drawImages_ = function(flatCoordinates, offset, end, stride) { if (!this.image_) { return; } @@ -58362,8 +49284,8 @@ ol.render.canvas.Immediate.prototype.drawImages_ = var x = pixelCoordinates[i] - this.imageAnchorX_; var y = pixelCoordinates[i + 1] - this.imageAnchorY_; if (this.imageSnapToPixel_) { - x = (x + 0.5) | 0; - y = (y + 0.5) | 0; + x = Math.round(x); + y = Math.round(y); } if (rotation !== 0 || this.imageScale_ != 1) { var centerX = x + this.imageAnchorX_; @@ -58399,8 +49321,7 @@ ol.render.canvas.Immediate.prototype.drawImages_ = * @param {number} stride Stride. * @private */ -ol.render.canvas.Immediate.prototype.drawText_ = - function(flatCoordinates, offset, end, stride) { +ol.render.canvas.Immediate.prototype.drawText_ = function(flatCoordinates, offset, end, stride) { if (!this.textState_ || this.text_ === '') { return; } @@ -58454,19 +49375,21 @@ ol.render.canvas.Immediate.prototype.drawText_ = * @private * @return {number} end End. */ -ol.render.canvas.Immediate.prototype.moveToLineTo_ = - function(flatCoordinates, offset, end, stride, close) { +ol.render.canvas.Immediate.prototype.moveToLineTo_ = function(flatCoordinates, offset, end, stride, close) { var context = this.context_; var pixelCoordinates = ol.geom.flat.transform.transform2D( flatCoordinates, offset, end, stride, this.transform_, this.pixelCoordinates_); context.moveTo(pixelCoordinates[0], pixelCoordinates[1]); - var i; - for (i = 2; i < pixelCoordinates.length; i += 2) { + var length = pixelCoordinates.length; + if (close) { + length -= 2; + } + for (var i = 2; i < length; i += 2) { context.lineTo(pixelCoordinates[i], pixelCoordinates[i + 1]); } if (close) { - context.lineTo(pixelCoordinates[0], pixelCoordinates[1]); + context.closePath(); } return end; }; @@ -58480,49 +49403,25 @@ ol.render.canvas.Immediate.prototype.moveToLineTo_ = * @private * @return {number} End. */ -ol.render.canvas.Immediate.prototype.drawRings_ = - function(flatCoordinates, offset, ends, stride) { - var context = this.context_; +ol.render.canvas.Immediate.prototype.drawRings_ = function(flatCoordinates, offset, ends, stride) { var i, ii; for (i = 0, ii = ends.length; i < ii; ++i) { offset = this.moveToLineTo_( flatCoordinates, offset, ends[i], stride, true); - context.closePath(); // FIXME is this needed here? } return offset; }; /** - * Register a function to be called for rendering at a given zIndex. The - * function will be called asynchronously. The callback will receive a - * reference to {@link ol.render.canvas.Immediate} context for drawing. - * - * @param {number} zIndex Z index. - * @param {function(ol.render.canvas.Immediate)} callback Callback. - * @api - */ -ol.render.canvas.Immediate.prototype.drawAsync = function(zIndex, callback) { - var zIndexKey = zIndex.toString(); - var callbacks = this.callbacksByZIndex_[zIndexKey]; - if (callbacks !== undefined) { - callbacks.push(callback); - } else { - this.callbacksByZIndex_[zIndexKey] = [callback]; - } -}; - - -/** * Render a circle geometry into the canvas. Rendering is immediate and uses * the current fill and stroke styles. * - * @param {ol.geom.Circle} circleGeometry Circle geometry. + * @param {ol.geom.Circle} geometry Circle geometry. * @api */ -ol.render.canvas.Immediate.prototype.drawCircleGeometry = - function(circleGeometry) { - if (!ol.extent.intersects(this.extent_, circleGeometry.getExtent())) { +ol.render.canvas.Immediate.prototype.drawCircle = function(geometry) { + if (!ol.extent.intersects(this.extent_, geometry.getExtent())) { return; } if (this.fillState_ || this.strokeState_) { @@ -58533,7 +49432,7 @@ ol.render.canvas.Immediate.prototype.drawCircleGeometry = this.setContextStrokeState_(this.strokeState_); } var pixelCoordinates = ol.geom.transformSimpleGeometry2D( - circleGeometry, this.transform_, this.pixelCoordinates_); + geometry, this.transform_, this.pixelCoordinates_); var dx = pixelCoordinates[2] - pixelCoordinates[0]; var dy = pixelCoordinates[3] - pixelCoordinates[1]; var radius = Math.sqrt(dx * dx + dy * dy); @@ -58549,17 +49448,70 @@ ol.render.canvas.Immediate.prototype.drawCircleGeometry = } } if (this.text_ !== '') { - this.drawText_(circleGeometry.getCenter(), 0, 2, 2); + this.drawText_(geometry.getCenter(), 0, 2, 2); + } +}; + + +/** + * Set the rendering style. Note that since this is an immediate rendering API, + * any `zIndex` on the provided style will be ignored. + * + * @param {ol.style.Style} style The rendering style. + * @api + */ +ol.render.canvas.Immediate.prototype.setStyle = function(style) { + this.setFillStrokeStyle(style.getFill(), style.getStroke()); + this.setImageStyle(style.getImage()); + this.setTextStyle(style.getText()); +}; + + +/** + * Render a geometry into the canvas. Call + * {@link ol.render.canvas.Immediate#setStyle} first to set the rendering style. + * + * @param {ol.geom.Geometry|ol.render.Feature} geometry The geometry to render. + * @api + */ +ol.render.canvas.Immediate.prototype.drawGeometry = function(geometry) { + var type = geometry.getType(); + switch (type) { + case ol.geom.GeometryType.POINT: + this.drawPoint(/** @type {ol.geom.Point} */ (geometry)); + break; + case ol.geom.GeometryType.LINE_STRING: + this.drawLineString(/** @type {ol.geom.LineString} */ (geometry)); + break; + case ol.geom.GeometryType.POLYGON: + this.drawPolygon(/** @type {ol.geom.Polygon} */ (geometry)); + break; + case ol.geom.GeometryType.MULTI_POINT: + this.drawMultiPoint(/** @type {ol.geom.MultiPoint} */ (geometry)); + break; + case ol.geom.GeometryType.MULTI_LINE_STRING: + this.drawMultiLineString(/** @type {ol.geom.MultiLineString} */ (geometry)); + break; + case ol.geom.GeometryType.MULTI_POLYGON: + this.drawMultiPolygon(/** @type {ol.geom.MultiPolygon} */ (geometry)); + break; + case ol.geom.GeometryType.GEOMETRY_COLLECTION: + this.drawGeometryCollection(/** @type {ol.geom.GeometryCollection} */ (geometry)); + break; + case ol.geom.GeometryType.CIRCLE: + this.drawCircle(/** @type {ol.geom.Circle} */ (geometry)); + break; + default: + goog.asserts.fail('Unsupported geometry type: ' + type); } }; /** - * Render a feature into the canvas. In order to respect the zIndex of the - * style this method draws asynchronously and thus *after* calls to - * drawXxxxGeometry have been finished, effectively drawing the feature - * *on top* of everything else. You probably should be using an - * {@link ol.layer.Vector} instead of calling this method directly. + * Render a feature into the canvas. Note that any `zIndex` on the provided + * style will be ignored - features are rendered immediately in the order that + * this method is called. If you need `zIndex` support, you should be using an + * {@link ol.layer.Vector} instead. * * @param {ol.Feature} feature Feature. * @param {ol.style.Style} style Style. @@ -58571,20 +49523,9 @@ ol.render.canvas.Immediate.prototype.drawFeature = function(feature, style) { !ol.extent.intersects(this.extent_, geometry.getExtent())) { return; } - var zIndex = style.getZIndex(); - if (zIndex === undefined) { - zIndex = 0; - } - this.drawAsync(zIndex, function(render) { - render.setFillStrokeStyle(style.getFill(), style.getStroke()); - render.setImageStyle(style.getImage()); - render.setTextStyle(style.getText()); - var renderGeometry = - ol.render.canvas.Immediate.GEOMETRY_RENDERERS_[geometry.getType()]; - goog.asserts.assert(renderGeometry !== undefined, - 'renderGeometry should be defined'); - renderGeometry.call(render, geometry, null); - }); + this.setStyle(style); + goog.asserts.assert(geometry, 'geometry must be truthy'); + this.drawGeometry(geometry); }; @@ -58592,21 +49533,13 @@ ol.render.canvas.Immediate.prototype.drawFeature = function(feature, style) { * Render a GeometryCollection to the canvas. Rendering is immediate and * uses the current styles appropriate for each geometry in the collection. * - * @param {ol.geom.GeometryCollection} geometryCollectionGeometry Geometry - * collection. - * @param {ol.Feature} feature Feature. + * @param {ol.geom.GeometryCollection} geometry Geometry collection. */ -ol.render.canvas.Immediate.prototype.drawGeometryCollectionGeometry = - function(geometryCollectionGeometry, feature) { - var geometries = geometryCollectionGeometry.getGeometriesArray(); +ol.render.canvas.Immediate.prototype.drawGeometryCollection = function(geometry) { + var geometries = geometry.getGeometriesArray(); var i, ii; for (i = 0, ii = geometries.length; i < ii; ++i) { - var geometry = geometries[i]; - var geometryRenderer = - ol.render.canvas.Immediate.GEOMETRY_RENDERERS_[geometry.getType()]; - goog.asserts.assert(geometryRenderer !== undefined, - 'geometryRenderer should be defined'); - geometryRenderer.call(this, geometry, feature); + this.drawGeometry(geometries[i]); } }; @@ -58615,13 +49548,11 @@ ol.render.canvas.Immediate.prototype.drawGeometryCollectionGeometry = * Render a Point geometry into the canvas. Rendering is immediate and uses * the current style. * - * @param {ol.geom.Point|ol.render.Feature} pointGeometry Point geometry. - * @api + * @param {ol.geom.Point|ol.render.Feature} geometry Point geometry. */ -ol.render.canvas.Immediate.prototype.drawPointGeometry = - function(pointGeometry) { - var flatCoordinates = pointGeometry.getFlatCoordinates(); - var stride = pointGeometry.getStride(); +ol.render.canvas.Immediate.prototype.drawPoint = function(geometry) { + var flatCoordinates = geometry.getFlatCoordinates(); + var stride = geometry.getStride(); if (this.image_) { this.drawImages_(flatCoordinates, 0, flatCoordinates.length, stride); } @@ -58635,14 +49566,11 @@ ol.render.canvas.Immediate.prototype.drawPointGeometry = * Render a MultiPoint geometry into the canvas. Rendering is immediate and * uses the current style. * - * @param {ol.geom.MultiPoint|ol.render.Feature} multiPointGeometry MultiPoint - * geometry. - * @api + * @param {ol.geom.MultiPoint|ol.render.Feature} geometry MultiPoint geometry. */ -ol.render.canvas.Immediate.prototype.drawMultiPointGeometry = - function(multiPointGeometry) { - var flatCoordinates = multiPointGeometry.getFlatCoordinates(); - var stride = multiPointGeometry.getStride(); +ol.render.canvas.Immediate.prototype.drawMultiPoint = function(geometry) { + var flatCoordinates = geometry.getFlatCoordinates(); + var stride = geometry.getStride(); if (this.image_) { this.drawImages_(flatCoordinates, 0, flatCoordinates.length, stride); } @@ -58656,26 +49584,23 @@ ol.render.canvas.Immediate.prototype.drawMultiPointGeometry = * Render a LineString into the canvas. Rendering is immediate and uses * the current style. * - * @param {ol.geom.LineString|ol.render.Feature} lineStringGeometry Line - * string geometry. - * @api + * @param {ol.geom.LineString|ol.render.Feature} geometry LineString geometry. */ -ol.render.canvas.Immediate.prototype.drawLineStringGeometry = - function(lineStringGeometry) { - if (!ol.extent.intersects(this.extent_, lineStringGeometry.getExtent())) { +ol.render.canvas.Immediate.prototype.drawLineString = function(geometry) { + if (!ol.extent.intersects(this.extent_, geometry.getExtent())) { return; } if (this.strokeState_) { this.setContextStrokeState_(this.strokeState_); var context = this.context_; - var flatCoordinates = lineStringGeometry.getFlatCoordinates(); + var flatCoordinates = geometry.getFlatCoordinates(); context.beginPath(); this.moveToLineTo_(flatCoordinates, 0, flatCoordinates.length, - lineStringGeometry.getStride(), false); + geometry.getStride(), false); context.stroke(); } if (this.text_ !== '') { - var flatMidpoint = lineStringGeometry.getFlatMidpoint(); + var flatMidpoint = geometry.getFlatMidpoint(); this.drawText_(flatMidpoint, 0, 2, 2); } }; @@ -58685,23 +49610,21 @@ ol.render.canvas.Immediate.prototype.drawLineStringGeometry = * Render a MultiLineString geometry into the canvas. Rendering is immediate * and uses the current style. * - * @param {ol.geom.MultiLineString|ol.render.Feature} multiLineStringGeometry - * MultiLineString geometry. - * @api + * @param {ol.geom.MultiLineString|ol.render.Feature} geometry MultiLineString + * geometry. */ -ol.render.canvas.Immediate.prototype.drawMultiLineStringGeometry = - function(multiLineStringGeometry) { - var geometryExtent = multiLineStringGeometry.getExtent(); +ol.render.canvas.Immediate.prototype.drawMultiLineString = function(geometry) { + var geometryExtent = geometry.getExtent(); if (!ol.extent.intersects(this.extent_, geometryExtent)) { return; } if (this.strokeState_) { this.setContextStrokeState_(this.strokeState_); var context = this.context_; - var flatCoordinates = multiLineStringGeometry.getFlatCoordinates(); + var flatCoordinates = geometry.getFlatCoordinates(); var offset = 0; - var ends = multiLineStringGeometry.getEnds(); - var stride = multiLineStringGeometry.getStride(); + var ends = geometry.getEnds(); + var stride = geometry.getStride(); context.beginPath(); var i, ii; for (i = 0, ii = ends.length; i < ii; ++i) { @@ -58711,7 +49634,7 @@ ol.render.canvas.Immediate.prototype.drawMultiLineStringGeometry = context.stroke(); } if (this.text_ !== '') { - var flatMidpoints = multiLineStringGeometry.getFlatMidpoints(); + var flatMidpoints = geometry.getFlatMidpoints(); this.drawText_(flatMidpoints, 0, flatMidpoints.length, 2); } }; @@ -58721,13 +49644,10 @@ ol.render.canvas.Immediate.prototype.drawMultiLineStringGeometry = * Render a Polygon geometry into the canvas. Rendering is immediate and uses * the current style. * - * @param {ol.geom.Polygon|ol.render.Feature} polygonGeometry Polygon - * geometry. - * @api + * @param {ol.geom.Polygon|ol.render.Feature} geometry Polygon geometry. */ -ol.render.canvas.Immediate.prototype.drawPolygonGeometry = - function(polygonGeometry) { - if (!ol.extent.intersects(this.extent_, polygonGeometry.getExtent())) { +ol.render.canvas.Immediate.prototype.drawPolygon = function(geometry) { + if (!ol.extent.intersects(this.extent_, geometry.getExtent())) { return; } if (this.strokeState_ || this.fillState_) { @@ -58739,8 +49659,8 @@ ol.render.canvas.Immediate.prototype.drawPolygonGeometry = } var context = this.context_; context.beginPath(); - this.drawRings_(polygonGeometry.getOrientedFlatCoordinates(), - 0, polygonGeometry.getEnds(), polygonGeometry.getStride()); + this.drawRings_(geometry.getOrientedFlatCoordinates(), + 0, geometry.getEnds(), geometry.getStride()); if (this.fillState_) { context.fill(); } @@ -58749,7 +49669,7 @@ ol.render.canvas.Immediate.prototype.drawPolygonGeometry = } } if (this.text_ !== '') { - var flatInteriorPoint = polygonGeometry.getFlatInteriorPoint(); + var flatInteriorPoint = geometry.getFlatInteriorPoint(); this.drawText_(flatInteriorPoint, 0, 2, 2); } }; @@ -58758,12 +49678,10 @@ ol.render.canvas.Immediate.prototype.drawPolygonGeometry = /** * Render MultiPolygon geometry into the canvas. Rendering is immediate and * uses the current style. - * @param {ol.geom.MultiPolygon} multiPolygonGeometry MultiPolygon geometry. - * @api + * @param {ol.geom.MultiPolygon} geometry MultiPolygon geometry. */ -ol.render.canvas.Immediate.prototype.drawMultiPolygonGeometry = - function(multiPolygonGeometry) { - if (!ol.extent.intersects(this.extent_, multiPolygonGeometry.getExtent())) { +ol.render.canvas.Immediate.prototype.drawMultiPolygon = function(geometry) { + if (!ol.extent.intersects(this.extent_, geometry.getExtent())) { return; } if (this.strokeState_ || this.fillState_) { @@ -58774,10 +49692,10 @@ ol.render.canvas.Immediate.prototype.drawMultiPolygonGeometry = this.setContextStrokeState_(this.strokeState_); } var context = this.context_; - var flatCoordinates = multiPolygonGeometry.getOrientedFlatCoordinates(); + var flatCoordinates = geometry.getOrientedFlatCoordinates(); var offset = 0; - var endss = multiPolygonGeometry.getEndss(); - var stride = multiPolygonGeometry.getStride(); + var endss = geometry.getEndss(); + var stride = geometry.getStride(); var i, ii; for (i = 0, ii = endss.length; i < ii; ++i) { var ends = endss[i]; @@ -58792,41 +49710,17 @@ ol.render.canvas.Immediate.prototype.drawMultiPolygonGeometry = } } if (this.text_ !== '') { - var flatInteriorPoints = multiPolygonGeometry.getFlatInteriorPoints(); + var flatInteriorPoints = geometry.getFlatInteriorPoints(); this.drawText_(flatInteriorPoints, 0, flatInteriorPoints.length, 2); } }; /** - * @inheritDoc - */ -ol.render.canvas.Immediate.prototype.drawText = goog.abstractMethod; - - -/** - * FIXME: empty description for jsdoc - */ -ol.render.canvas.Immediate.prototype.flush = function() { - /** @type {Array.<number>} */ - var zs = Object.keys(this.callbacksByZIndex_).map(Number); - zs.sort(ol.array.numberSafeCompareFunction); - var i, ii, callbacks, j, jj; - for (i = 0, ii = zs.length; i < ii; ++i) { - callbacks = this.callbacksByZIndex_[zs[i].toString()]; - for (j = 0, jj = callbacks.length; j < jj; ++j) { - callbacks[j](this); - } - } -}; - - -/** - * @param {ol.render.canvas.FillState} fillState Fill state. + * @param {ol.CanvasFillState} fillState Fill state. * @private */ -ol.render.canvas.Immediate.prototype.setContextFillState_ = - function(fillState) { +ol.render.canvas.Immediate.prototype.setContextFillState_ = function(fillState) { var context = this.context_; var contextFillState = this.contextFillState_; if (!contextFillState) { @@ -58843,11 +49737,10 @@ ol.render.canvas.Immediate.prototype.setContextFillState_ = /** - * @param {ol.render.canvas.StrokeState} strokeState Stroke state. + * @param {ol.CanvasStrokeState} strokeState Stroke state. * @private */ -ol.render.canvas.Immediate.prototype.setContextStrokeState_ = - function(strokeState) { +ol.render.canvas.Immediate.prototype.setContextStrokeState_ = function(strokeState) { var context = this.context_; var contextStrokeState = this.contextStrokeState_; if (!contextStrokeState) { @@ -58872,7 +49765,7 @@ ol.render.canvas.Immediate.prototype.setContextStrokeState_ = contextStrokeState.lineCap = context.lineCap = strokeState.lineCap; } if (ol.has.CANVAS_LINE_DASH) { - if (!goog.array.equals( + if (!ol.array.equals( contextStrokeState.lineDash, strokeState.lineDash)) { context.setLineDash(contextStrokeState.lineDash = strokeState.lineDash); } @@ -58896,11 +49789,10 @@ ol.render.canvas.Immediate.prototype.setContextStrokeState_ = /** - * @param {ol.render.canvas.TextState} textState Text state. + * @param {ol.CanvasTextState} textState Text state. * @private */ -ol.render.canvas.Immediate.prototype.setContextTextState_ = - function(textState) { +ol.render.canvas.Immediate.prototype.setContextTextState_ = function(textState) { var context = this.context_; var contextTextState = this.contextTextState_; if (!contextTextState) { @@ -58933,16 +49825,14 @@ ol.render.canvas.Immediate.prototype.setContextTextState_ = * * @param {ol.style.Fill} fillStyle Fill style. * @param {ol.style.Stroke} strokeStyle Stroke style. - * @api */ -ol.render.canvas.Immediate.prototype.setFillStrokeStyle = - function(fillStyle, strokeStyle) { +ol.render.canvas.Immediate.prototype.setFillStrokeStyle = function(fillStyle, strokeStyle) { if (!fillStyle) { this.fillState_ = null; } else { var fillStyleColor = fillStyle.getColor(); this.fillState_ = { - fillStyle: ol.color.asString(fillStyleColor ? + fillStyle: ol.colorlike.asColorLike(fillStyleColor ? fillStyleColor : ol.render.canvas.defaultFillStyle) }; } @@ -58978,7 +49868,6 @@ ol.render.canvas.Immediate.prototype.setFillStrokeStyle = * the image style. * * @param {ol.style.Image} imageStyle Image style. - * @api */ ol.render.canvas.Immediate.prototype.setImageStyle = function(imageStyle) { if (!imageStyle) { @@ -59014,7 +49903,6 @@ ol.render.canvas.Immediate.prototype.setImageStyle = function(imageStyle) { * remove the text style. * * @param {ol.style.Text} textStyle Text style. - * @api */ ol.render.canvas.Immediate.prototype.setTextStyle = function(textStyle) { if (!textStyle) { @@ -59026,7 +49914,7 @@ ol.render.canvas.Immediate.prototype.setTextStyle = function(textStyle) { } else { var textFillStyleColor = textFillStyle.getColor(); this.textFillState_ = { - fillStyle: ol.color.asString(textFillStyleColor ? + fillStyle: ol.colorlike.asColorLike(textFillStyleColor ? textFillStyleColor : ol.render.canvas.defaultFillStyle) }; } @@ -59082,43 +49970,20 @@ ol.render.canvas.Immediate.prototype.setTextStyle = function(textStyle) { } }; - -/** - * @const - * @private - * @type {Object.<ol.geom.GeometryType, - * function(this: ol.render.canvas.Immediate, - * (ol.geom.Geometry|ol.render.Feature), Object)>} - */ -ol.render.canvas.Immediate.GEOMETRY_RENDERERS_ = { - 'Point': ol.render.canvas.Immediate.prototype.drawPointGeometry, - 'LineString': ol.render.canvas.Immediate.prototype.drawLineStringGeometry, - 'Polygon': ol.render.canvas.Immediate.prototype.drawPolygonGeometry, - 'MultiPoint': ol.render.canvas.Immediate.prototype.drawMultiPointGeometry, - 'MultiLineString': - ol.render.canvas.Immediate.prototype.drawMultiLineStringGeometry, - 'MultiPolygon': ol.render.canvas.Immediate.prototype.drawMultiPolygonGeometry, - 'GeometryCollection': - ol.render.canvas.Immediate.prototype.drawGeometryCollectionGeometry, - 'Circle': ol.render.canvas.Immediate.prototype.drawCircleGeometry -}; - goog.provide('ol.renderer.canvas.Layer'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.vec.Mat4'); -goog.require('ol.dom'); goog.require('ol.extent'); goog.require('ol.layer.Layer'); goog.require('ol.render.Event'); goog.require('ol.render.EventType'); +goog.require('ol.render.canvas'); goog.require('ol.render.canvas.Immediate'); goog.require('ol.renderer.Layer'); goog.require('ol.vec.Mat4'); - /** * @constructor * @extends {ol.renderer.Layer} @@ -59140,11 +50005,10 @@ goog.inherits(ol.renderer.canvas.Layer, ol.renderer.Layer); /** * @param {olx.FrameState} frameState Frame state. - * @param {ol.layer.LayerState} layerState Layer state. + * @param {ol.LayerState} layerState Layer state. * @param {CanvasRenderingContext2D} context Context. */ -ol.renderer.canvas.Layer.prototype.composeFrame = - function(frameState, layerState, context) { +ol.renderer.canvas.Layer.prototype.composeFrame = function(frameState, layerState, context) { this.dispatchPreComposeEvent(context, frameState); @@ -59158,6 +50022,9 @@ ol.renderer.canvas.Layer.prototype.composeFrame = goog.asserts.assert(extent !== undefined, 'layerState extent is defined'); var pixelRatio = frameState.pixelRatio; + var width = frameState.size[0] * pixelRatio; + var height = frameState.size[1] * pixelRatio; + var rotation = frameState.viewState.rotation; var topLeft = ol.extent.getTopLeft(extent); var topRight = ol.extent.getTopRight(extent); var bottomRight = ol.extent.getBottomRight(extent); @@ -59173,12 +50040,14 @@ ol.renderer.canvas.Layer.prototype.composeFrame = bottomLeft, bottomLeft); context.save(); + ol.render.canvas.rotateAtOffset(context, -rotation, width / 2, height / 2); context.beginPath(); context.moveTo(topLeft[0] * pixelRatio, topLeft[1] * pixelRatio); context.lineTo(topRight[0] * pixelRatio, topRight[1] * pixelRatio); context.lineTo(bottomRight[0] * pixelRatio, bottomRight[1] * pixelRatio); context.lineTo(bottomLeft[0] * pixelRatio, bottomLeft[1] * pixelRatio); context.clip(); + ol.render.canvas.rotateAtOffset(context, rotation, width / 2, height / 2); } var imageTransform = this.getImageTransform(); @@ -59190,24 +50059,12 @@ ol.renderer.canvas.Layer.prototype.composeFrame = // for performance reasons, context.setTransform is only used // when the view is rotated. see http://jsperf.com/canvas-transform - if (frameState.viewState.rotation === 0) { - var dx = goog.vec.Mat4.getElement(imageTransform, 0, 3); - var dy = goog.vec.Mat4.getElement(imageTransform, 1, 3); - var dw = image.width * goog.vec.Mat4.getElement(imageTransform, 0, 0); - var dh = image.height * goog.vec.Mat4.getElement(imageTransform, 1, 1); - context.drawImage(image, 0, 0, +image.width, +image.height, - Math.round(dx), Math.round(dy), Math.round(dw), Math.round(dh)); - } else { - context.setTransform( - goog.vec.Mat4.getElement(imageTransform, 0, 0), - goog.vec.Mat4.getElement(imageTransform, 1, 0), - goog.vec.Mat4.getElement(imageTransform, 0, 1), - goog.vec.Mat4.getElement(imageTransform, 1, 1), - goog.vec.Mat4.getElement(imageTransform, 0, 3), - goog.vec.Mat4.getElement(imageTransform, 1, 3)); - context.drawImage(image, 0, 0); - context.setTransform(1, 0, 0, 1, 0, 0); - } + var dx = goog.vec.Mat4.getElement(imageTransform, 0, 3); + var dy = goog.vec.Mat4.getElement(imageTransform, 1, 3); + var dw = image.width * goog.vec.Mat4.getElement(imageTransform, 0, 0); + var dh = image.height * goog.vec.Mat4.getElement(imageTransform, 1, 1); + context.drawImage(image, 0, 0, +image.width, +image.height, + Math.round(dx), Math.round(dy), Math.round(dw), Math.round(dh)); context.globalAlpha = alpha; if (clipped) { @@ -59227,10 +50084,13 @@ ol.renderer.canvas.Layer.prototype.composeFrame = * @param {goog.vec.Mat4.Number=} opt_transform Transform. * @private */ -ol.renderer.canvas.Layer.prototype.dispatchComposeEvent_ = - function(type, context, frameState, opt_transform) { +ol.renderer.canvas.Layer.prototype.dispatchComposeEvent_ = function(type, context, frameState, opt_transform) { var layer = this.getLayer(); if (layer.hasListener(type)) { + var width = frameState.size[0] * frameState.pixelRatio; + var height = frameState.size[1] * frameState.pixelRatio; + var rotation = frameState.viewState.rotation; + ol.render.canvas.rotateAtOffset(context, -rotation, width / 2, height / 2); var transform = opt_transform !== undefined ? opt_transform : this.getTransform(frameState, 0); var render = new ol.render.canvas.Immediate( @@ -59239,7 +50099,7 @@ ol.renderer.canvas.Layer.prototype.dispatchComposeEvent_ = var composeEvent = new ol.render.Event(type, layer, render, frameState, context, null); layer.dispatchEvent(composeEvent); - render.flush(); + ol.render.canvas.rotateAtOffset(context, rotation, width / 2, height / 2); } }; @@ -59250,8 +50110,7 @@ ol.renderer.canvas.Layer.prototype.dispatchComposeEvent_ = * @param {goog.vec.Mat4.Number=} opt_transform Transform. * @protected */ -ol.renderer.canvas.Layer.prototype.dispatchPostComposeEvent = - function(context, frameState, opt_transform) { +ol.renderer.canvas.Layer.prototype.dispatchPostComposeEvent = function(context, frameState, opt_transform) { this.dispatchComposeEvent_(ol.render.EventType.POSTCOMPOSE, context, frameState, opt_transform); }; @@ -59263,8 +50122,7 @@ ol.renderer.canvas.Layer.prototype.dispatchPostComposeEvent = * @param {goog.vec.Mat4.Number=} opt_transform Transform. * @protected */ -ol.renderer.canvas.Layer.prototype.dispatchPreComposeEvent = - function(context, frameState, opt_transform) { +ol.renderer.canvas.Layer.prototype.dispatchPreComposeEvent = function(context, frameState, opt_transform) { this.dispatchComposeEvent_(ol.render.EventType.PRECOMPOSE, context, frameState, opt_transform); }; @@ -59276,8 +50134,7 @@ ol.renderer.canvas.Layer.prototype.dispatchPreComposeEvent = * @param {goog.vec.Mat4.Number=} opt_transform Transform. * @protected */ -ol.renderer.canvas.Layer.prototype.dispatchRenderEvent = - function(context, frameState, opt_transform) { +ol.renderer.canvas.Layer.prototype.dispatchRenderEvent = function(context, frameState, opt_transform) { this.dispatchComposeEvent_(ol.render.EventType.RENDER, context, frameState, opt_transform); }; @@ -59301,8 +50158,7 @@ ol.renderer.canvas.Layer.prototype.getImageTransform = goog.abstractMethod; * @protected * @return {!goog.vec.Mat4.Number} Transform. */ -ol.renderer.canvas.Layer.prototype.getTransform = - function(frameState, offsetX) { +ol.renderer.canvas.Layer.prototype.getTransform = function(frameState, offsetX) { var viewState = frameState.viewState; var pixelRatio = frameState.pixelRatio; return ol.vec.Mat4.makeTransform2D(this.transform_, @@ -59318,7 +50174,7 @@ ol.renderer.canvas.Layer.prototype.getTransform = /** * @param {olx.FrameState} frameState Frame state. - * @param {ol.layer.LayerState} layerState Layer state. + * @param {ol.LayerState} layerState Layer state. * @return {boolean} whether composeFrame should be called. */ ol.renderer.canvas.Layer.prototype.prepareFrame = goog.abstractMethod; @@ -59328,59 +50184,15 @@ ol.renderer.canvas.Layer.prototype.prepareFrame = goog.abstractMethod; * @param {ol.Pixel} pixelOnMap Pixel. * @param {goog.vec.Mat4.Number} imageTransformInv The transformation matrix * to convert from a map pixel to a canvas pixel. - * @return {ol.Pixel} + * @return {ol.Pixel} The pixel. * @protected */ -ol.renderer.canvas.Layer.prototype.getPixelOnCanvas = - function(pixelOnMap, imageTransformInv) { +ol.renderer.canvas.Layer.prototype.getPixelOnCanvas = function(pixelOnMap, imageTransformInv) { var pixelOnCanvas = [0, 0]; ol.vec.Mat4.multVec2(imageTransformInv, pixelOnMap, pixelOnCanvas); return pixelOnCanvas; }; - -/** - * @param {ol.Size} size Size. - * @return {boolean} True when the canvas with the current size does not exceed - * the maximum dimensions. - */ -ol.renderer.canvas.Layer.testCanvasSize = (function() { - - /** - * @type {CanvasRenderingContext2D} - */ - var context = null; - - /** - * @type {ImageData} - */ - var imageData = null; - - return function(size) { - if (!context) { - context = ol.dom.createCanvasContext2D(1, 1); - imageData = context.createImageData(1, 1); - var data = imageData.data; - data[0] = 42; - data[1] = 84; - data[2] = 126; - data[3] = 255; - } - var canvas = context.canvas; - var good = size[0] <= canvas.width && size[1] <= canvas.height; - if (!good) { - canvas.width = size[0]; - canvas.height = size[1]; - var x = size[0] - 1; - var y = size[1] - 1; - context.putImageData(imageData, x, y); - var result = context.getImageData(x, y, 1, 1); - good = goog.array.equals(imageData.data, result.data); - } - return good; - }; -})(); - goog.provide('ol.render.IReplayGroup'); goog.require('ol.render.VectorContext'); @@ -59409,7 +50221,6 @@ ol.render.REPLAY_ORDER = [ ]; - /** * @interface */ @@ -59417,6 +50228,11 @@ ol.render.IReplayGroup = function() { }; +/* eslint-disable valid-jsdoc */ +// TODO: enable valid-jsdoc for @interface methods when this issue is resolved +// https://github.com/eslint/eslint/issues/4887 + + /** * @param {number|undefined} zIndex Z index. * @param {ol.render.ReplayType} replayType Replay type. @@ -59442,19 +50258,19 @@ goog.provide('ol.render.canvas.Replay'); goog.provide('ol.render.canvas.ReplayGroup'); goog.provide('ol.render.canvas.TextReplay'); -goog.require('goog.array'); goog.require('goog.asserts'); -goog.require('goog.object'); goog.require('goog.vec.Mat4'); goog.require('ol'); goog.require('ol.array'); goog.require('ol.color'); +goog.require('ol.colorlike'); goog.require('ol.dom'); goog.require('ol.extent'); goog.require('ol.extent.Relationship'); goog.require('ol.geom.flat.simplify'); goog.require('ol.geom.flat.transform'); goog.require('ol.has'); +goog.require('ol.object'); goog.require('ol.render.IReplayGroup'); goog.require('ol.render.VectorContext'); goog.require('ol.render.canvas'); @@ -59481,7 +50297,6 @@ ol.render.canvas.Instruction = { }; - /** * @constructor * @extends {ol.render.VectorContext} @@ -59573,6 +50388,12 @@ ol.render.canvas.Replay = function(tolerance, maxExtent, resolution) { * @type {!goog.vec.Mat4.Number} */ this.tmpLocalTransform_ = goog.vec.Mat4.createNumber(); + + /** + * @private + * @type {!goog.vec.Mat4.Number} + */ + this.tmpLocalTransformInv_ = goog.vec.Mat4.createNumber(); }; goog.inherits(ol.render.canvas.Replay, ol.render.VectorContext); @@ -59586,8 +50407,7 @@ goog.inherits(ol.render.canvas.Replay, ol.render.VectorContext); * @protected * @return {number} My end. */ -ol.render.canvas.Replay.prototype.appendFlatCoordinates = - function(flatCoordinates, offset, end, stride, close) { +ol.render.canvas.Replay.prototype.appendFlatCoordinates = function(flatCoordinates, offset, end, stride, close) { var myEnd = this.coordinates.length; var extent = this.getBufferedMaxExtent(); @@ -59680,12 +50500,13 @@ ol.render.canvas.Replay.prototype.replay_ = function( goog.asserts.assert(pixelCoordinates === this.pixelCoordinates_, 'pixelCoordinates should be the same as this.pixelCoordinates_'); } - var skipFeatures = !goog.object.isEmpty(skippedFeaturesHash); + var skipFeatures = !ol.object.isEmpty(skippedFeaturesHash); var i = 0; // instruction index var ii = instructions.length; // end of instructions var d = 0; // data index var dd; // end of per-instruction data var localTransform = this.tmpLocalTransform_; + var localTransformInv = this.tmpLocalTransformInv_; var prevX, prevY, roundX, roundY; while (i < ii) { var instruction = instructions[i]; @@ -59699,8 +50520,7 @@ ol.render.canvas.Replay.prototype.replay_ = function( !feature.getGeometry()) { i = /** @type {number} */ (instruction[2]); } else if (opt_hitExtent !== undefined && !ol.extent.intersects( - /** @type {Array<number>} */ (opt_hitExtent), - feature.getGeometry().getExtent())) { + opt_hitExtent, feature.getGeometry().getExtent())) { i = /** @type {number} */ (instruction[2]); } else { ++i; @@ -59756,8 +50576,8 @@ ol.render.canvas.Replay.prototype.replay_ = function( x = pixelCoordinates[d] - anchorX; y = pixelCoordinates[d + 1] - anchorY; if (snapToPixel) { - x = (x + 0.5) | 0; - y = (y + 0.5) | 0; + x = Math.round(x); + y = Math.round(y); } if (scale != 1 || rotation !== 0) { var centerX = x + anchorX; @@ -59765,7 +50585,7 @@ ol.render.canvas.Replay.prototype.replay_ = function( ol.vec.Mat4.makeTransform2D( localTransform, centerX, centerY, scale, scale, rotation, -centerX, -centerY); - context.setTransform( + context.transform( goog.vec.Mat4.getElement(localTransform, 0, 0), goog.vec.Mat4.getElement(localTransform, 1, 0), goog.vec.Mat4.getElement(localTransform, 0, 1), @@ -59778,14 +50598,24 @@ ol.render.canvas.Replay.prototype.replay_ = function( context.globalAlpha = alpha * opacity; } - context.drawImage(image, originX, originY, width, height, - x, y, width * pixelRatio, height * pixelRatio); + var w = (width + originX > image.width) ? image.width - originX : width; + var h = (height + originY > image.height) ? image.height - originY : height; + + context.drawImage(image, originX, originY, w, h, + x, y, w * pixelRatio, h * pixelRatio); if (opacity != 1) { context.globalAlpha = alpha; } if (scale != 1 || rotation !== 0) { - context.setTransform(1, 0, 0, 1, 0, 0); + goog.vec.Mat4.invert(localTransform, localTransformInv); + context.transform( + goog.vec.Mat4.getElement(localTransformInv, 0, 0), + goog.vec.Mat4.getElement(localTransformInv, 1, 0), + goog.vec.Mat4.getElement(localTransformInv, 0, 1), + goog.vec.Mat4.getElement(localTransformInv, 1, 1), + goog.vec.Mat4.getElement(localTransformInv, 0, 3), + goog.vec.Mat4.getElement(localTransformInv, 1, 3)); } } ++i; @@ -59797,7 +50627,7 @@ ol.render.canvas.Replay.prototype.replay_ = function( goog.asserts.assert(goog.isNumber(instruction[2]), '3rd instruction should be a number'); dd = /** @type {number} */ (instruction[2]); - goog.asserts.assert(goog.isString(instruction[3]), + goog.asserts.assert(typeof instruction[3] === 'string', '4th instruction should be a string'); text = /** @type {string} */ (instruction[3]); goog.asserts.assert(goog.isNumber(instruction[4]), @@ -59812,10 +50642,10 @@ ol.render.canvas.Replay.prototype.replay_ = function( goog.asserts.assert(goog.isNumber(instruction[7]), '8th instruction should be a number'); scale = /** @type {number} */ (instruction[7]) * pixelRatio; - goog.asserts.assert(goog.isBoolean(instruction[8]), + goog.asserts.assert(typeof instruction[8] === 'boolean', '9th instruction should be a boolean'); fill = /** @type {boolean} */ (instruction[8]); - goog.asserts.assert(goog.isBoolean(instruction[9]), + goog.asserts.assert(typeof instruction[9] === 'boolean', '10th instruction should be a boolean'); stroke = /** @type {boolean} */ (instruction[9]); for (; d < dd; d += 2) { @@ -59824,7 +50654,7 @@ ol.render.canvas.Replay.prototype.replay_ = function( if (scale != 1 || rotation !== 0) { ol.vec.Mat4.makeTransform2D( localTransform, x, y, scale, scale, rotation, -x, -y); - context.setTransform( + context.transform( goog.vec.Mat4.getElement(localTransform, 0, 0), goog.vec.Mat4.getElement(localTransform, 1, 0), goog.vec.Mat4.getElement(localTransform, 0, 1), @@ -59861,7 +50691,14 @@ ol.render.canvas.Replay.prototype.replay_ = function( } if (scale != 1 || rotation !== 0) { - context.setTransform(1, 0, 0, 1, 0, 0); + goog.vec.Mat4.invert(localTransform, localTransformInv); + context.transform( + goog.vec.Mat4.getElement(localTransformInv, 0, 0), + goog.vec.Mat4.getElement(localTransformInv, 1, 0), + goog.vec.Mat4.getElement(localTransformInv, 0, 1), + goog.vec.Mat4.getElement(localTransformInv, 1, 1), + goog.vec.Mat4.getElement(localTransformInv, 0, 3), + goog.vec.Mat4.getElement(localTransformInv, 1, 3)); } } ++i; @@ -59911,19 +50748,21 @@ ol.render.canvas.Replay.prototype.replay_ = function( ++i; break; case ol.render.canvas.Instruction.SET_FILL_STYLE: - goog.asserts.assert(goog.isString(instruction[1]), - '2nd instruction should be a string'); - context.fillStyle = /** @type {string} */ (instruction[1]); + goog.asserts.assert( + ol.colorlike.isColorLike(instruction[1]), + '2nd instruction should be a string, ' + + 'CanvasPattern, or CanvasGradient'); + context.fillStyle = /** @type {ol.ColorLike} */ (instruction[1]); ++i; break; case ol.render.canvas.Instruction.SET_STROKE_STYLE: - goog.asserts.assert(goog.isString(instruction[1]), + goog.asserts.assert(typeof instruction[1] === 'string', '2nd instruction should be a string'); goog.asserts.assert(goog.isNumber(instruction[2]), '3rd instruction should be a number'); - goog.asserts.assert(goog.isString(instruction[3]), + goog.asserts.assert(typeof instruction[3] === 'string', '4rd instruction should be a string'); - goog.asserts.assert(goog.isString(instruction[4]), + goog.asserts.assert(typeof instruction[4] === 'string', '5th instruction should be a string'); goog.asserts.assert(goog.isNumber(instruction[5]), '6th instruction should be a number'); @@ -59945,11 +50784,11 @@ ol.render.canvas.Replay.prototype.replay_ = function( ++i; break; case ol.render.canvas.Instruction.SET_TEXT_STYLE: - goog.asserts.assert(goog.isString(instruction[1]), + goog.asserts.assert(typeof instruction[1] === 'string', '2nd instruction should be a string'); - goog.asserts.assert(goog.isString(instruction[2]), + goog.asserts.assert(typeof instruction[2] === 'string', '3rd instruction should be a string'); - goog.asserts.assert(goog.isString(instruction[3]), + goog.asserts.assert(typeof instruction[3] === 'string', '4th instruction should be a string'); context.font = /** @type {string} */ (instruction[1]); context.textAlign = /** @type {string} */ (instruction[2]); @@ -60014,8 +50853,7 @@ ol.render.canvas.Replay.prototype.replayHitDetection = function( /** * @private */ -ol.render.canvas.Replay.prototype.reverseHitDetectionInstructions_ = - function() { +ol.render.canvas.Replay.prototype.reverseHitDetectionInstructions_ = function() { var hitDetectionInstructions = this.hitDetectionInstructions; // step 1 - reverse array hitDetectionInstructions.reverse(); @@ -60080,7 +50918,6 @@ ol.render.canvas.Replay.prototype.getBufferedMaxExtent = function() { }; - /** * @constructor * @extends {ol.render.canvas.Replay} @@ -60183,8 +51020,7 @@ goog.inherits(ol.render.canvas.ImageReplay, ol.render.canvas.Replay); * @private * @return {number} My end. */ -ol.render.canvas.ImageReplay.prototype.drawCoordinates_ = - function(flatCoordinates, offset, end, stride) { +ol.render.canvas.ImageReplay.prototype.drawCoordinates_ = function(flatCoordinates, offset, end, stride) { return this.appendFlatCoordinates( flatCoordinates, offset, end, stride, false); }; @@ -60193,8 +51029,7 @@ ol.render.canvas.ImageReplay.prototype.drawCoordinates_ = /** * @inheritDoc */ -ol.render.canvas.ImageReplay.prototype.drawPointGeometry = - function(pointGeometry, feature) { +ol.render.canvas.ImageReplay.prototype.drawPoint = function(pointGeometry, feature) { if (!this.image_) { return; } @@ -60246,8 +51081,7 @@ ol.render.canvas.ImageReplay.prototype.drawPointGeometry = /** * @inheritDoc */ -ol.render.canvas.ImageReplay.prototype.drawMultiPointGeometry = - function(multiPointGeometry, feature) { +ol.render.canvas.ImageReplay.prototype.drawMultiPoint = function(multiPointGeometry, feature) { if (!this.image_) { return; } @@ -60350,7 +51184,6 @@ ol.render.canvas.ImageReplay.prototype.setImageStyle = function(imageStyle) { }; - /** * @constructor * @extends {ol.render.canvas.Replay} @@ -60408,8 +51241,7 @@ goog.inherits(ol.render.canvas.LineStringReplay, ol.render.canvas.Replay); * @private * @return {number} end. */ -ol.render.canvas.LineStringReplay.prototype.drawFlatCoordinates_ = - function(flatCoordinates, offset, end, stride) { +ol.render.canvas.LineStringReplay.prototype.drawFlatCoordinates_ = function(flatCoordinates, offset, end, stride) { var myBegin = this.coordinates.length; var myEnd = this.appendFlatCoordinates( flatCoordinates, offset, end, stride, false); @@ -60456,7 +51288,7 @@ ol.render.canvas.LineStringReplay.prototype.setStrokeStyle_ = function() { goog.asserts.assert(miterLimit !== undefined, 'miterLimit should be defined'); if (state.currentStrokeStyle != strokeStyle || state.currentLineCap != lineCap || - !goog.array.equals(state.currentLineDash, lineDash) || + !ol.array.equals(state.currentLineDash, lineDash) || state.currentLineJoin != lineJoin || state.currentLineWidth != lineWidth || state.currentMiterLimit != miterLimit) { @@ -60482,8 +51314,7 @@ ol.render.canvas.LineStringReplay.prototype.setStrokeStyle_ = function() { /** * @inheritDoc */ -ol.render.canvas.LineStringReplay.prototype.drawLineStringGeometry = - function(lineStringGeometry, feature) { +ol.render.canvas.LineStringReplay.prototype.drawLineString = function(lineStringGeometry, feature) { var state = this.state_; goog.asserts.assert(state, 'state should not be null'); var strokeStyle = state.strokeStyle; @@ -60510,8 +51341,7 @@ ol.render.canvas.LineStringReplay.prototype.drawLineStringGeometry = /** * @inheritDoc */ -ol.render.canvas.LineStringReplay.prototype.drawMultiLineStringGeometry = - function(multiLineStringGeometry, feature) { +ol.render.canvas.LineStringReplay.prototype.drawMultiLineString = function(multiLineStringGeometry, feature) { var state = this.state_; goog.asserts.assert(state, 'state should not be null'); var strokeStyle = state.strokeStyle; @@ -60557,8 +51387,7 @@ ol.render.canvas.LineStringReplay.prototype.finish = function() { /** * @inheritDoc */ -ol.render.canvas.LineStringReplay.prototype.setFillStrokeStyle = - function(fillStyle, strokeStyle) { +ol.render.canvas.LineStringReplay.prototype.setFillStrokeStyle = function(fillStyle, strokeStyle) { goog.asserts.assert(this.state_, 'this.state_ should not be null'); goog.asserts.assert(!fillStyle, 'fillStyle should be null'); goog.asserts.assert(strokeStyle, 'strokeStyle should not be null'); @@ -60589,7 +51418,6 @@ ol.render.canvas.LineStringReplay.prototype.setFillStrokeStyle = }; - /** * @constructor * @extends {ol.render.canvas.Replay} @@ -60605,14 +51433,14 @@ ol.render.canvas.PolygonReplay = function(tolerance, maxExtent, resolution) { /** * @private - * @type {{currentFillStyle: (string|undefined), + * @type {{currentFillStyle: (ol.ColorLike|undefined), * currentStrokeStyle: (string|undefined), * currentLineCap: (string|undefined), * currentLineDash: Array.<number>, * currentLineJoin: (string|undefined), * currentLineWidth: (number|undefined), * currentMiterLimit: (number|undefined), - * fillStyle: (string|undefined), + * fillStyle: (ol.ColorLike|undefined), * strokeStyle: (string|undefined), * lineCap: (string|undefined), * lineDash: Array.<number>, @@ -60649,8 +51477,7 @@ goog.inherits(ol.render.canvas.PolygonReplay, ol.render.canvas.Replay); * @private * @return {number} End. */ -ol.render.canvas.PolygonReplay.prototype.drawFlatCoordinatess_ = - function(flatCoordinates, offset, ends, stride) { +ol.render.canvas.PolygonReplay.prototype.drawFlatCoordinatess_ = function(flatCoordinates, offset, ends, stride) { var state = this.state_; var beginPathInstruction = [ol.render.canvas.Instruction.BEGIN_PATH]; this.instructions.push(beginPathInstruction); @@ -60690,8 +51517,7 @@ ol.render.canvas.PolygonReplay.prototype.drawFlatCoordinatess_ = /** * @inheritDoc */ -ol.render.canvas.PolygonReplay.prototype.drawCircleGeometry = - function(circleGeometry, feature) { +ol.render.canvas.PolygonReplay.prototype.drawCircle = function(circleGeometry, feature) { var state = this.state_; goog.asserts.assert(state, 'state should not be null'); var fillStyle = state.fillStyle; @@ -60743,8 +51569,7 @@ ol.render.canvas.PolygonReplay.prototype.drawCircleGeometry = /** * @inheritDoc */ -ol.render.canvas.PolygonReplay.prototype.drawPolygonGeometry = - function(polygonGeometry, feature) { +ol.render.canvas.PolygonReplay.prototype.drawPolygon = function(polygonGeometry, feature) { var state = this.state_; goog.asserts.assert(state, 'state should not be null'); var fillStyle = state.fillStyle; @@ -60779,8 +51604,7 @@ ol.render.canvas.PolygonReplay.prototype.drawPolygonGeometry = /** * @inheritDoc */ -ol.render.canvas.PolygonReplay.prototype.drawMultiPolygonGeometry = - function(multiPolygonGeometry, feature) { +ol.render.canvas.PolygonReplay.prototype.drawMultiPolygon = function(multiPolygonGeometry, feature) { var state = this.state_; goog.asserts.assert(state, 'state should not be null'); var fillStyle = state.fillStyle; @@ -60857,15 +51681,14 @@ ol.render.canvas.PolygonReplay.prototype.getBufferedMaxExtent = function() { /** * @inheritDoc */ -ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyle = - function(fillStyle, strokeStyle) { +ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyle = function(fillStyle, strokeStyle) { goog.asserts.assert(this.state_, 'this.state_ should not be null'); goog.asserts.assert(fillStyle || strokeStyle, 'fillStyle or strokeStyle should not be null'); var state = this.state_; if (fillStyle) { var fillStyleColor = fillStyle.getColor(); - state.fillStyle = ol.color.asString(fillStyleColor ? + state.fillStyle = ol.colorlike.asColorLike(fillStyleColor ? fillStyleColor : ol.render.canvas.defaultFillStyle); } else { state.fillStyle = undefined; @@ -60950,7 +51773,6 @@ ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyles_ = function() { }; - /** * @constructor * @extends {ol.render.canvas.Replay} @@ -60966,19 +51788,19 @@ ol.render.canvas.TextReplay = function(tolerance, maxExtent, resolution) { /** * @private - * @type {?ol.render.canvas.FillState} + * @type {?ol.CanvasFillState} */ this.replayFillState_ = null; /** * @private - * @type {?ol.render.canvas.StrokeState} + * @type {?ol.CanvasStrokeState} */ this.replayStrokeState_ = null; /** * @private - * @type {?ol.render.canvas.TextState} + * @type {?ol.CanvasTextState} */ this.replayTextState_ = null; @@ -61014,19 +51836,19 @@ ol.render.canvas.TextReplay = function(tolerance, maxExtent, resolution) { /** * @private - * @type {?ol.render.canvas.FillState} + * @type {?ol.CanvasFillState} */ this.textFillState_ = null; /** * @private - * @type {?ol.render.canvas.StrokeState} + * @type {?ol.CanvasStrokeState} */ this.textStrokeState_ = null; /** * @private - * @type {?ol.render.canvas.TextState} + * @type {?ol.CanvasTextState} */ this.textState_ = null; @@ -61037,8 +51859,7 @@ goog.inherits(ol.render.canvas.TextReplay, ol.render.canvas.Replay); /** * @inheritDoc */ -ol.render.canvas.TextReplay.prototype.drawText = - function(flatCoordinates, offset, end, stride, geometry, feature) { +ol.render.canvas.TextReplay.prototype.drawText = function(flatCoordinates, offset, end, stride, geometry, feature) { if (this.text_ === '' || !this.textState_ || (!this.textFillState_ && !this.textStrokeState_)) { return; @@ -61067,11 +51888,10 @@ ol.render.canvas.TextReplay.prototype.drawText = /** - * @param {ol.render.canvas.FillState} fillState Fill state. + * @param {ol.CanvasFillState} fillState Fill state. * @private */ -ol.render.canvas.TextReplay.prototype.setReplayFillState_ = - function(fillState) { +ol.render.canvas.TextReplay.prototype.setReplayFillState_ = function(fillState) { var replayFillState = this.replayFillState_; if (replayFillState && replayFillState.fillStyle == fillState.fillStyle) { @@ -61092,11 +51912,10 @@ ol.render.canvas.TextReplay.prototype.setReplayFillState_ = /** - * @param {ol.render.canvas.StrokeState} strokeState Stroke state. + * @param {ol.CanvasStrokeState} strokeState Stroke state. * @private */ -ol.render.canvas.TextReplay.prototype.setReplayStrokeState_ = - function(strokeState) { +ol.render.canvas.TextReplay.prototype.setReplayStrokeState_ = function(strokeState) { var replayStrokeState = this.replayStrokeState_; if (replayStrokeState && replayStrokeState.lineCap == strokeState.lineCap && @@ -61135,11 +51954,10 @@ ol.render.canvas.TextReplay.prototype.setReplayStrokeState_ = /** - * @param {ol.render.canvas.TextState} textState Text state. + * @param {ol.CanvasTextState} textState Text state. * @private */ -ol.render.canvas.TextReplay.prototype.setReplayTextState_ = - function(textState) { +ol.render.canvas.TextReplay.prototype.setReplayTextState_ = function(textState) { var replayTextState = this.replayTextState_; if (replayTextState && replayTextState.font == textState.font && @@ -61177,7 +51995,7 @@ ol.render.canvas.TextReplay.prototype.setTextStyle = function(textStyle) { this.textFillState_ = null; } else { var textFillStyleColor = textFillStyle.getColor(); - var fillStyle = ol.color.asString(textFillStyleColor ? + var fillStyle = ol.colorlike.asColorLike(textFillStyleColor ? textFillStyleColor : ol.render.canvas.defaultFillStyle); if (!this.textFillState_) { this.textFillState_ = { @@ -61264,7 +52082,6 @@ ol.render.canvas.TextReplay.prototype.setTextStyle = function(textStyle) { }; - /** * @constructor * @implements {ol.render.IReplayGroup} @@ -61392,8 +52209,7 @@ ol.render.canvas.ReplayGroup.prototype.forEachFeatureAtCoordinate = function( /** * @inheritDoc */ -ol.render.canvas.ReplayGroup.prototype.getReplay = - function(zIndex, replayType) { +ol.render.canvas.ReplayGroup.prototype.getReplay = function(zIndex, replayType) { var zIndexKey = zIndex !== undefined ? zIndex.toString() : '0'; var replays = this.replaysByZIndex_[zIndexKey]; if (replays === undefined) { @@ -61418,7 +52234,7 @@ ol.render.canvas.ReplayGroup.prototype.getReplay = * @inheritDoc */ ol.render.canvas.ReplayGroup.prototype.isEmpty = function() { - return goog.object.isEmpty(this.replaysByZIndex_); + return ol.object.isEmpty(this.replaysByZIndex_); }; @@ -61429,9 +52245,11 @@ ol.render.canvas.ReplayGroup.prototype.isEmpty = function() { * @param {number} viewRotation View rotation. * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features * to skip. + * @param {Array.<ol.render.ReplayType>=} opt_replayTypes Ordered replay types + * to replay. Default is {@link ol.render.REPLAY_ORDER} */ -ol.render.canvas.ReplayGroup.prototype.replay = function( - context, pixelRatio, transform, viewRotation, skippedFeaturesHash) { +ol.render.canvas.ReplayGroup.prototype.replay = function(context, pixelRatio, + transform, viewRotation, skippedFeaturesHash, opt_replayTypes) { /** @type {Array.<number>} */ var zs = Object.keys(this.replaysByZIndex_).map(Number); @@ -61456,11 +52274,12 @@ ol.render.canvas.ReplayGroup.prototype.replay = function( context.closePath(); context.clip(); + var replayTypes = opt_replayTypes ? opt_replayTypes : ol.render.REPLAY_ORDER; var i, ii, j, jj, replays, replay; for (i = 0, ii = zs.length; i < ii; ++i) { replays = this.replaysByZIndex_[zs[i].toString()]; - for (j = 0, jj = ol.render.REPLAY_ORDER.length; j < jj; ++j) { - replay = replays[ol.render.REPLAY_ORDER[j]]; + for (j = 0, jj = replayTypes.length; j < jj; ++j) { + replay = replays[replayTypes[j]]; if (replay !== undefined) { replay.replay(context, pixelRatio, transform, viewRotation, skippedFeaturesHash); @@ -61491,7 +52310,9 @@ ol.render.canvas.ReplayGroup.prototype.replayHitDetection_ = function( featureCallback, opt_hitExtent) { /** @type {Array.<number>} */ var zs = Object.keys(this.replaysByZIndex_).map(Number); - zs.sort(function(a, b) { return b - a; }); + zs.sort(function(a, b) { + return b - a; + }); var i, ii, j, replays, replay, result; for (i = 0, ii = zs.length; i < ii; ++i) { @@ -61533,7 +52354,6 @@ goog.require('ol.extent'); goog.require('ol.geom.GeometryType'); - /** * Lightweight, read-only, {@link ol.Feature} and {@link ol.geom.Geometry} like * structure, optimized for rendering and styling. Geometry access through the @@ -61627,13 +52447,19 @@ ol.render.Feature.prototype.getExtent = function() { /** * @return {Array.<number>} Flat coordinates. */ -ol.render.Feature.prototype.getFlatCoordinates = - ol.render.Feature.prototype.getOrientedFlatCoordinates = function() { +ol.render.Feature.prototype.getOrientedFlatCoordinates = function() { return this.flatCoordinates_; }; /** + * @return {Array.<number>} Flat coordinates. + */ +ol.render.Feature.prototype.getFlatCoordinates = + ol.render.Feature.prototype.getOrientedFlatCoordinates; + + +/** * Get the feature for working with its geometry. * @return {ol.render.Feature} Feature. * @api @@ -61731,15 +52557,14 @@ ol.renderer.vector.getTolerance = function(resolution, pixelRatio) { * @param {ol.Feature} feature Feature. * @private */ -ol.renderer.vector.renderCircleGeometry_ = - function(replayGroup, geometry, style, feature) { +ol.renderer.vector.renderCircleGeometry_ = function(replayGroup, geometry, style, feature) { var fillStyle = style.getFill(); var strokeStyle = style.getStroke(); if (fillStyle || strokeStyle) { var polygonReplay = replayGroup.getReplay( style.getZIndex(), ol.render.ReplayType.POLYGON); polygonReplay.setFillStrokeStyle(fillStyle, strokeStyle); - polygonReplay.drawCircleGeometry(geometry, feature); + polygonReplay.drawCircle(geometry, feature); } var textStyle = style.getText(); if (textStyle) { @@ -61756,7 +52581,7 @@ ol.renderer.vector.renderCircleGeometry_ = * @param {ol.Feature|ol.render.Feature} feature Feature. * @param {ol.style.Style} style Style. * @param {number} squaredTolerance Squared tolerance. - * @param {function(this: T, goog.events.Event)} listener Listener function. + * @param {function(this: T, ol.events.Event)} listener Listener function. * @param {T} thisArg Value to use as `this` when executing `listener`. * @return {boolean} `true` if style is loading. * @template T @@ -61817,8 +52642,7 @@ ol.renderer.vector.renderFeature_ = function( * @param {ol.Feature} feature Feature. * @private */ -ol.renderer.vector.renderGeometryCollectionGeometry_ = - function(replayGroup, geometry, style, feature) { +ol.renderer.vector.renderGeometryCollectionGeometry_ = function(replayGroup, geometry, style, feature) { var geometries = geometry.getGeometriesArray(); var i, ii; for (i = 0, ii = geometries.length; i < ii; ++i) { @@ -61838,14 +52662,13 @@ ol.renderer.vector.renderGeometryCollectionGeometry_ = * @param {ol.Feature|ol.render.Feature} feature Feature. * @private */ -ol.renderer.vector.renderLineStringGeometry_ = - function(replayGroup, geometry, style, feature) { +ol.renderer.vector.renderLineStringGeometry_ = function(replayGroup, geometry, style, feature) { var strokeStyle = style.getStroke(); if (strokeStyle) { var lineStringReplay = replayGroup.getReplay( style.getZIndex(), ol.render.ReplayType.LINE_STRING); lineStringReplay.setFillStrokeStyle(null, strokeStyle); - lineStringReplay.drawLineStringGeometry(geometry, feature); + lineStringReplay.drawLineString(geometry, feature); } var textStyle = style.getText(); if (textStyle) { @@ -61864,14 +52687,13 @@ ol.renderer.vector.renderLineStringGeometry_ = * @param {ol.Feature|ol.render.Feature} feature Feature. * @private */ -ol.renderer.vector.renderMultiLineStringGeometry_ = - function(replayGroup, geometry, style, feature) { +ol.renderer.vector.renderMultiLineStringGeometry_ = function(replayGroup, geometry, style, feature) { var strokeStyle = style.getStroke(); if (strokeStyle) { var lineStringReplay = replayGroup.getReplay( style.getZIndex(), ol.render.ReplayType.LINE_STRING); lineStringReplay.setFillStrokeStyle(null, strokeStyle); - lineStringReplay.drawMultiLineStringGeometry(geometry, feature); + lineStringReplay.drawMultiLineString(geometry, feature); } var textStyle = style.getText(); if (textStyle) { @@ -61892,15 +52714,14 @@ ol.renderer.vector.renderMultiLineStringGeometry_ = * @param {ol.Feature} feature Feature. * @private */ -ol.renderer.vector.renderMultiPolygonGeometry_ = - function(replayGroup, geometry, style, feature) { +ol.renderer.vector.renderMultiPolygonGeometry_ = function(replayGroup, geometry, style, feature) { var fillStyle = style.getFill(); var strokeStyle = style.getStroke(); if (strokeStyle || fillStyle) { var polygonReplay = replayGroup.getReplay( style.getZIndex(), ol.render.ReplayType.POLYGON); polygonReplay.setFillStrokeStyle(fillStyle, strokeStyle); - polygonReplay.drawMultiPolygonGeometry(geometry, feature); + polygonReplay.drawMultiPolygon(geometry, feature); } var textStyle = style.getText(); if (textStyle) { @@ -61921,8 +52742,7 @@ ol.renderer.vector.renderMultiPolygonGeometry_ = * @param {ol.Feature|ol.render.Feature} feature Feature. * @private */ -ol.renderer.vector.renderPointGeometry_ = - function(replayGroup, geometry, style, feature) { +ol.renderer.vector.renderPointGeometry_ = function(replayGroup, geometry, style, feature) { var imageStyle = style.getImage(); if (imageStyle) { if (imageStyle.getImageState() != ol.style.ImageState.LOADED) { @@ -61931,7 +52751,7 @@ ol.renderer.vector.renderPointGeometry_ = var imageReplay = replayGroup.getReplay( style.getZIndex(), ol.render.ReplayType.IMAGE); imageReplay.setImageStyle(imageStyle); - imageReplay.drawPointGeometry(geometry, feature); + imageReplay.drawPoint(geometry, feature); } var textStyle = style.getText(); if (textStyle) { @@ -61951,8 +52771,7 @@ ol.renderer.vector.renderPointGeometry_ = * @param {ol.Feature|ol.render.Feature} feature Feature. * @private */ -ol.renderer.vector.renderMultiPointGeometry_ = - function(replayGroup, geometry, style, feature) { +ol.renderer.vector.renderMultiPointGeometry_ = function(replayGroup, geometry, style, feature) { var imageStyle = style.getImage(); if (imageStyle) { if (imageStyle.getImageState() != ol.style.ImageState.LOADED) { @@ -61961,7 +52780,7 @@ ol.renderer.vector.renderMultiPointGeometry_ = var imageReplay = replayGroup.getReplay( style.getZIndex(), ol.render.ReplayType.IMAGE); imageReplay.setImageStyle(imageStyle); - imageReplay.drawMultiPointGeometry(geometry, feature); + imageReplay.drawMultiPoint(geometry, feature); } var textStyle = style.getText(); if (textStyle) { @@ -61982,15 +52801,14 @@ ol.renderer.vector.renderMultiPointGeometry_ = * @param {ol.Feature|ol.render.Feature} feature Feature. * @private */ -ol.renderer.vector.renderPolygonGeometry_ = - function(replayGroup, geometry, style, feature) { +ol.renderer.vector.renderPolygonGeometry_ = function(replayGroup, geometry, style, feature) { var fillStyle = style.getFill(); var strokeStyle = style.getStroke(); if (fillStyle || strokeStyle) { var polygonReplay = replayGroup.getReplay( style.getZIndex(), ol.render.ReplayType.POLYGON); polygonReplay.setFillStrokeStyle(fillStyle, strokeStyle); - polygonReplay.drawPolygonGeometry(geometry, feature); + polygonReplay.drawPolygon(geometry, feature); } var textStyle = style.getText(); if (textStyle) { @@ -62028,7 +52846,6 @@ goog.require('ol.ImageBase'); goog.require('ol.ImageState'); - /** * @constructor * @extends {ol.ImageBase} @@ -62104,7 +52921,7 @@ ol.ImageCanvas.prototype.load = function() { goog.asserts.assert(this.loader_, 'this.loader_ must be set'); this.state = ol.ImageState.LOADING; this.changed(); - this.loader_(goog.bind(this.handleLoad_, this)); + this.loader_(this.handleLoad_.bind(this)); } }; @@ -62116,22 +52933,8 @@ ol.ImageCanvas.prototype.getImage = function(opt_context) { return this.canvas_; }; - -/** - * A function that is called to trigger asynchronous canvas drawing. It is - * called with a "done" callback that should be called when drawing is done. - * If any error occurs during drawing, the "done" callback should be called with - * that error. - * - * @typedef {function(function(Error))} - */ -ol.ImageCanvasLoader; - goog.provide('ol.reproj'); -goog.require('goog.labs.userAgent.browser'); -goog.require('goog.labs.userAgent.platform'); -goog.require('goog.math'); goog.require('ol.dom'); goog.require('ol.extent'); goog.require('ol.math'); @@ -62148,8 +52951,18 @@ goog.require('ol.proj'); * @type {boolean} * @private */ -ol.reproj.browserAntialiasesClip_ = !goog.labs.userAgent.browser.isChrome() || - goog.labs.userAgent.platform.isIos(); +ol.reproj.browserAntialiasesClip_ = (function(winNav, winChrome) { + // Adapted from http://stackoverflow.com/questions/4565112/javascript-how-to-find-out-if-the-user-browser-is-chrome + var isOpera = winNav.userAgent.indexOf('OPR') > -1; + var isIEedge = winNav.userAgent.indexOf('Edge') > -1; + return !( + !winNav.userAgent.match('CriOS') && // Not Chrome on iOS + winChrome !== null && winChrome !== undefined && // Has chrome in window + winNav.vendor === 'Google Inc.' && // Vendor is Google. + isOpera == false && // Not Opera + isIEedge == false // Not Edge + ); +})(goog.global.navigator, goog.global.chrome) /** @@ -62190,7 +53003,7 @@ ol.reproj.calculateSourceResolution = function(sourceProj, targetProj, sourceProj.getPointResolution(sourceResolution, sourceCenter) / sourceResolution; - if (goog.math.isFiniteNumber(compensationFactor) && compensationFactor > 0) { + if (isFinite(compensationFactor) && compensationFactor > 0) { sourceResolution /= compensationFactor; } @@ -62230,12 +53043,13 @@ ol.reproj.enlargeClipPoint_ = function(centroidX, centroidY, x, y) { * @param {Array.<{extent: ol.Extent, * image: (HTMLCanvasElement|Image|HTMLVideoElement)}>} sources * Array of sources. + * @param {number} gutter Gutter of the sources. * @param {boolean=} opt_renderEdges Render reprojection edges. * @return {HTMLCanvasElement} Canvas with reprojected data. */ ol.reproj.render = function(width, height, pixelRatio, sourceResolution, sourceExtent, targetResolution, targetExtent, - triangulation, sources, opt_renderEdges) { + triangulation, sources, gutter, opt_renderEdges) { var context = ol.dom.createCanvasContext2D(Math.round(pixelRatio * width), Math.round(pixelRatio * height)); @@ -62257,17 +53071,20 @@ ol.reproj.render = function(width, height, pixelRatio, Math.round(pixelRatio * canvasWidthInUnits / sourceResolution), Math.round(pixelRatio * canvasHeightInUnits / sourceResolution)); - stitchContext.scale(pixelRatio / sourceResolution, - pixelRatio / sourceResolution); - stitchContext.translate(-sourceDataExtent[0], sourceDataExtent[3]); + var stitchScale = pixelRatio / sourceResolution; sources.forEach(function(src, i, arr) { - var xPos = src.extent[0]; - var yPos = -src.extent[3]; + var xPos = src.extent[0] - sourceDataExtent[0]; + var yPos = -(src.extent[3] - sourceDataExtent[3]); var srcWidth = ol.extent.getWidth(src.extent); var srcHeight = ol.extent.getHeight(src.extent); - stitchContext.drawImage(src.image, xPos, yPos, srcWidth, srcHeight); + stitchContext.drawImage( + src.image, + gutter, gutter, + src.image.width - 2 * gutter, src.image.height - 2 * gutter, + xPos * stitchScale, yPos * stitchScale, + srcWidth * stitchScale, srcHeight * stitchScale); }); var targetTopLeft = ol.extent.getTopLeft(targetExtent); @@ -62389,22 +53206,12 @@ ol.reproj.render = function(width, height, pixelRatio, goog.provide('ol.reproj.Triangulation'); goog.require('goog.asserts'); -goog.require('goog.math'); goog.require('ol.extent'); +goog.require('ol.math'); goog.require('ol.proj'); /** - * Single triangle; consists of 3 source points and 3 target points. - * - * @typedef {{source: Array.<ol.Coordinate>, - * target: Array.<ol.Coordinate>}} - */ -ol.reproj.Triangle; - - - -/** * @classdesc * Class containing triangulation of the given target extent. * Used for determining source data and the reprojection itself. @@ -62436,8 +53243,8 @@ ol.reproj.Triangulation = function(sourceProj, targetProj, targetExtent, var transformInv = ol.proj.getTransform(this.targetProj_, this.sourceProj_); /** - * @param {ol.Coordinate} c - * @return {ol.Coordinate} + * @param {ol.Coordinate} c A coordinate. + * @return {ol.Coordinate} Transformed coordinate. * @private */ this.transformInv_ = function(c) { @@ -62461,7 +53268,7 @@ ol.reproj.Triangulation = function(sourceProj, targetProj, targetExtent, this.errorThresholdSquared_ = errorThreshold * errorThreshold; /** - * @type {Array.<ol.reproj.Triangle>} + * @type {Array.<ol.ReprojTriangle>} * @private */ this.triangles_ = []; @@ -62561,12 +53368,12 @@ ol.reproj.Triangulation = function(sourceProj, targetProj, targetExtent, /** * Adds triangle to the triangulation. - * @param {ol.Coordinate} a - * @param {ol.Coordinate} b - * @param {ol.Coordinate} c - * @param {ol.Coordinate} aSrc - * @param {ol.Coordinate} bSrc - * @param {ol.Coordinate} cSrc + * @param {ol.Coordinate} a The target a coordinate. + * @param {ol.Coordinate} b The target b coordinate. + * @param {ol.Coordinate} c The target c coordinate. + * @param {ol.Coordinate} aSrc The source a coordinate. + * @param {ol.Coordinate} bSrc The source b coordinate. + * @param {ol.Coordinate} cSrc The source c coordinate. * @private */ ol.reproj.Triangulation.prototype.addTriangle_ = function(a, b, c, @@ -62583,14 +53390,14 @@ ol.reproj.Triangulation.prototype.addTriangle_ = function(a, b, c, * (and reprojects the vertices) if valid. * Performs quad subdivision if needed to increase precision. * - * @param {ol.Coordinate} a - * @param {ol.Coordinate} b - * @param {ol.Coordinate} c - * @param {ol.Coordinate} d - * @param {ol.Coordinate} aSrc - * @param {ol.Coordinate} bSrc - * @param {ol.Coordinate} cSrc - * @param {ol.Coordinate} dSrc + * @param {ol.Coordinate} a The target a coordinate. + * @param {ol.Coordinate} b The target b coordinate. + * @param {ol.Coordinate} c The target c coordinate. + * @param {ol.Coordinate} d The target d coordinate. + * @param {ol.Coordinate} aSrc The source a coordinate. + * @param {ol.Coordinate} bSrc The source b coordinate. + * @param {ol.Coordinate} cSrc The source c coordinate. + * @param {ol.Coordinate} dSrc The source d coordinate. * @param {number} maxSubdivision Maximal allowed subdivision of the quad. * @private */ @@ -62651,10 +53458,10 @@ ol.reproj.Triangulation.prototype.addQuad_ = function(a, b, c, d, if (wrapsX) { goog.asserts.assert(this.sourceWorldWidth_); var centerSrcEstimX = - (goog.math.modulo(aSrc[0], this.sourceWorldWidth_) + - goog.math.modulo(cSrc[0], this.sourceWorldWidth_)) / 2; + (ol.math.modulo(aSrc[0], this.sourceWorldWidth_) + + ol.math.modulo(cSrc[0], this.sourceWorldWidth_)) / 2; dx = centerSrcEstimX - - goog.math.modulo(centerSrc[0], this.sourceWorldWidth_); + ol.math.modulo(centerSrc[0], this.sourceWorldWidth_); } else { dx = (aSrc[0] + cSrc[0]) / 2 - centerSrc[0]; } @@ -62722,18 +53529,17 @@ ol.reproj.Triangulation.prototype.calculateSourceExtent = function() { /** - * @return {Array.<ol.reproj.Triangle>} Array of the calculated triangles. + * @return {Array.<ol.ReprojTriangle>} Array of the calculated triangles. */ ol.reproj.Triangulation.prototype.getTriangles = function() { return this.triangles_; }; goog.provide('ol.reproj.Image'); -goog.provide('ol.reproj.ImageFunctionType'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol.ImageBase'); goog.require('ol.ImageState'); goog.require('ol.extent'); @@ -62743,13 +53549,6 @@ goog.require('ol.reproj.Triangulation'); /** - * @typedef {function(ol.Extent, number, number) : ol.ImageBase} - */ -ol.reproj.ImageFunctionType; - - - -/** * @classdesc * Class encapsulating single reprojected image. * See {@link ol.source.Image}. @@ -62761,7 +53560,7 @@ ol.reproj.ImageFunctionType; * @param {ol.Extent} targetExtent Target extent. * @param {number} targetResolution Target resolution. * @param {number} pixelRatio Pixel ratio. - * @param {ol.reproj.ImageFunctionType} getImageFunction + * @param {ol.ReprojImageFunctionType} getImageFunction * Function returning source images (extent, resolution, pixelRatio). */ ol.reproj.Image = function(sourceProj, targetProj, @@ -62833,7 +53632,7 @@ ol.reproj.Image = function(sourceProj, targetProj, /** * @private - * @type {goog.events.Key} + * @type {?ol.events.Key} */ this.sourceListenerKey_ = null; @@ -62894,7 +53693,7 @@ ol.reproj.Image.prototype.reproject_ = function() { this.targetResolution_, this.targetExtent_, this.triangulation_, [{ extent: this.sourceImage_.getExtent(), image: this.sourceImage_.getImage() - }]); + }], 0); } this.state = sourceState; this.changed(); @@ -62914,15 +53713,15 @@ ol.reproj.Image.prototype.load = function() { sourceState == ol.ImageState.ERROR) { this.reproject_(); } else { - this.sourceListenerKey_ = this.sourceImage_.listen( - goog.events.EventType.CHANGE, function(e) { + this.sourceListenerKey_ = ol.events.listen(this.sourceImage_, + ol.events.EventType.CHANGE, function(e) { var sourceState = this.sourceImage_.getState(); if (sourceState == ol.ImageState.LOADED || sourceState == ol.ImageState.ERROR) { this.unlistenSource_(); this.reproject_(); } - }, false, this); + }, this); this.sourceImage_.load(); } } @@ -62935,17 +53734,15 @@ ol.reproj.Image.prototype.load = function() { ol.reproj.Image.prototype.unlistenSource_ = function() { goog.asserts.assert(this.sourceListenerKey_, 'this.sourceListenerKey_ should not be null'); - goog.events.unlistenByKey(this.sourceListenerKey_); + ol.events.unlistenByKey(this.sourceListenerKey_); this.sourceListenerKey_ = null; }; goog.provide('ol.source.Image'); goog.provide('ol.source.ImageEvent'); -goog.require('goog.array'); goog.require('goog.asserts'); -goog.require('goog.events.Event'); -goog.require('ol.Attribution'); +goog.require('ol.events.Event'); goog.require('ol.ImageState'); goog.require('ol.array'); goog.require('ol.extent'); @@ -62955,18 +53752,6 @@ goog.require('ol.source.Source'); /** - * @typedef {{attributions: (Array.<ol.Attribution>|undefined), - * extent: (null|ol.Extent|undefined), - * logo: (string|olx.LogoOptions|undefined), - * projection: ol.proj.ProjectionLike, - * resolutions: (Array.<number>|undefined), - * state: (ol.source.State|undefined)}} - */ -ol.source.ImageOptions; - - - -/** * @classdesc * Abstract base class; normally only used for creating subclasses and not * instantiated in apps. @@ -62974,7 +53759,7 @@ ol.source.ImageOptions; * * @constructor * @extends {ol.source.Source} - * @param {ol.source.ImageOptions} options Single image source options. + * @param {ol.SourceImageOptions} options Single image source options. * @api */ ol.source.Image = function(options) { @@ -62994,7 +53779,7 @@ ol.source.Image = function(options) { this.resolutions_ = options.resolutions !== undefined ? options.resolutions : null; goog.asserts.assert(!this.resolutions_ || - goog.array.isSorted(this.resolutions_, + ol.array.isSorted(this.resolutions_, function(a, b) { return b - a; }, true), 'resolutions must be null or sorted in descending order'); @@ -63030,8 +53815,7 @@ ol.source.Image.prototype.getResolutions = function() { * @param {number} resolution Resolution. * @return {number} Resolution. */ -ol.source.Image.prototype.findNearestResolution = - function(resolution) { +ol.source.Image.prototype.findNearestResolution = function(resolution) { if (this.resolutions_) { var idx = ol.array.linearFindNearest(this.resolutions_, resolution, 0); resolution = this.resolutions_[idx]; @@ -63047,8 +53831,7 @@ ol.source.Image.prototype.findNearestResolution = * @param {ol.proj.Projection} projection Projection. * @return {ol.ImageBase} Single image. */ -ol.source.Image.prototype.getImage = - function(extent, resolution, pixelRatio, projection) { +ol.source.Image.prototype.getImage = function(extent, resolution, pixelRatio, projection) { var sourceProjection = this.getProjection(); if (!ol.ENABLE_RASTER_REPROJECTION || !sourceProjection || @@ -63074,10 +53857,10 @@ ol.source.Image.prototype.getImage = this.reprojectedImage_ = new ol.reproj.Image( sourceProjection, projection, extent, resolution, pixelRatio, - goog.bind(function(extent, resolution, pixelRatio) { + function(extent, resolution, pixelRatio) { return this.getImageInternal(extent, resolution, pixelRatio, sourceProjection); - }, this)); + }.bind(this)); this.reprojectedRevision_ = this.getRevision(); return this.reprojectedImage_; @@ -63098,7 +53881,7 @@ ol.source.Image.prototype.getImageInternal = goog.abstractMethod; /** * Handle image change events. - * @param {goog.events.Event} event Event. + * @param {ol.events.Event} event Event. * @protected */ ol.source.Image.prototype.handleImageChange = function(event) { @@ -63119,6 +53902,8 @@ ol.source.Image.prototype.handleImageChange = function(event) { new ol.source.ImageEvent(ol.source.ImageEventType.IMAGELOADERROR, image)); break; + default: + // pass } }; @@ -63134,14 +53919,13 @@ ol.source.Image.defaultImageLoadFunction = function(image, src) { }; - /** * @classdesc * Events emitted by {@link ol.source.Image} instances are instances of this * type. * * @constructor - * @extends {goog.events.Event} + * @extends {ol.events.Event} * @implements {oli.source.ImageEvent} * @param {string} type Type. * @param {ol.Image} image The image. @@ -63158,7 +53942,7 @@ ol.source.ImageEvent = function(type, image) { this.image = image; }; -goog.inherits(ol.source.ImageEvent, goog.events.Event); +goog.inherits(ol.source.ImageEvent, ol.events.Event); /** @@ -63191,20 +53975,18 @@ ol.source.ImageEventType = { goog.provide('ol.source.ImageCanvas'); -goog.require('ol.CanvasFunctionType'); goog.require('ol.ImageCanvas'); goog.require('ol.extent'); goog.require('ol.source.Image'); - /** * @classdesc * Base class for image sources where a canvas element is the image. * * @constructor * @extends {ol.source.Image} - * @param {olx.source.ImageCanvasOptions} options + * @param {olx.source.ImageCanvasOptions} options Constructor options. * @api */ ol.source.ImageCanvas = function(options) { @@ -63214,8 +53996,7 @@ ol.source.ImageCanvas = function(options) { logo: options.logo, projection: options.projection, resolutions: options.resolutions, - state: options.state !== undefined ? - /** @type {ol.source.State} */ (options.state) : undefined + state: options.state }); /** @@ -63250,8 +54031,7 @@ goog.inherits(ol.source.ImageCanvas, ol.source.Image); /** * @inheritDoc */ -ol.source.ImageCanvas.prototype.getImageInternal = - function(extent, resolution, pixelRatio, projection) { +ol.source.ImageCanvas.prototype.getImageInternal = function(extent, resolution, pixelRatio, projection) { resolution = this.findNearestResolution(resolution); var canvas = this.canvas_; @@ -63282,18 +54062,16 @@ ol.source.ImageCanvas.prototype.getImageInternal = }; goog.provide('ol.Feature'); -goog.provide('ol.FeatureStyleFunction'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol'); goog.require('ol.Object'); goog.require('ol.geom.Geometry'); goog.require('ol.style.Style'); - /** * @classdesc * A vector object for geographic features with a geometry and other @@ -63371,24 +54149,24 @@ ol.Feature = function(opt_geometryOrProperties) { /** * @private - * @type {goog.events.Key} + * @type {?ol.events.Key} */ this.geometryChangeKey_ = null; - goog.events.listen( + ol.events.listen( this, ol.Object.getChangeEventType(this.geometryName_), - this.handleGeometryChanged_, false, this); + this.handleGeometryChanged_, this); if (opt_geometryOrProperties !== undefined) { if (opt_geometryOrProperties instanceof ol.geom.Geometry || !opt_geometryOrProperties) { - var geometry = /** @type {ol.geom.Geometry} */ (opt_geometryOrProperties); + var geometry = opt_geometryOrProperties; this.setGeometry(geometry); } else { goog.asserts.assert(goog.isObject(opt_geometryOrProperties), 'opt_geometryOrProperties should be an Object'); - var properties = /** @type {Object.<string, *>} */ - (opt_geometryOrProperties); + /** @type {Object.<string, *>} */ + var properties = opt_geometryOrProperties; this.setProperties(properties); } } @@ -63493,13 +54271,13 @@ ol.Feature.prototype.handleGeometryChange_ = function() { */ ol.Feature.prototype.handleGeometryChanged_ = function() { if (this.geometryChangeKey_) { - goog.events.unlistenByKey(this.geometryChangeKey_); + ol.events.unlistenByKey(this.geometryChangeKey_); this.geometryChangeKey_ = null; } var geometry = this.getGeometry(); if (geometry) { - this.geometryChangeKey_ = goog.events.listen(geometry, - goog.events.EventType.CHANGE, this.handleGeometryChange_, false, this); + this.geometryChangeKey_ = ol.events.listen(geometry, + ol.events.EventType.CHANGE, this.handleGeometryChange_, this); } this.changed(); }; @@ -63557,30 +54335,18 @@ ol.Feature.prototype.setId = function(id) { * @api stable */ ol.Feature.prototype.setGeometryName = function(name) { - goog.events.unlisten( + ol.events.unlisten( this, ol.Object.getChangeEventType(this.geometryName_), - this.handleGeometryChanged_, false, this); + this.handleGeometryChanged_, this); this.geometryName_ = name; - goog.events.listen( + ol.events.listen( this, ol.Object.getChangeEventType(this.geometryName_), - this.handleGeometryChanged_, false, this); + this.handleGeometryChanged_, this); this.handleGeometryChanged_(); }; /** - * A function that returns an array of {@link ol.style.Style styles} given a - * resolution. The `this` keyword inside the function references the - * {@link ol.Feature} to be styled. - * - * @typedef {function(this: ol.Feature, number): - * (ol.style.Style|Array.<ol.style.Style>)} - * @api stable - */ -ol.FeatureStyleFunction; - - -/** * Convert the provided object into a feature style function. Functions passed * through unchanged. Arrays of ol.style.Style or single style objects wrapped * in a new feature style function. @@ -63598,7 +54364,7 @@ ol.Feature.createStyleFunction = function(obj) { * @type {Array.<ol.style.Style>} */ var styles; - if (goog.isArray(obj)) { + if (Array.isArray(obj)) { styles = obj; } else { goog.asserts.assertInstanceof(obj, ol.style.Style, @@ -63612,5847 +54378,15 @@ ol.Feature.createStyleFunction = function(obj) { return styleFunction; }; -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Common events for the network classes. - */ - - -goog.provide('goog.net.EventType'); - - -/** - * Event names for network events - * @enum {string} - */ -goog.net.EventType = { - COMPLETE: 'complete', - SUCCESS: 'success', - ERROR: 'error', - ABORT: 'abort', - READY: 'ready', - READY_STATE_CHANGE: 'readystatechange', - TIMEOUT: 'timeout', - INCREMENTAL_DATA: 'incrementaldata', - PROGRESS: 'progress' -}; - -// Copyright 2013 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -goog.provide('goog.Thenable'); - - - -/** - * Provides a more strict interface for Thenables in terms of - * http://promisesaplus.com for interop with {@see goog.Promise}. - * - * @interface - * @extends {IThenable<TYPE>} - * @template TYPE - */ -goog.Thenable = function() {}; - - -/** - * Adds callbacks that will operate on the result of the Thenable, returning a - * new child Promise. - * - * If the Thenable is fulfilled, the {@code onFulfilled} callback will be - * invoked with the fulfillment value as argument, and the child Promise will - * be fulfilled with the return value of the callback. If the callback throws - * an exception, the child Promise will be rejected with the thrown value - * instead. - * - * If the Thenable is rejected, the {@code onRejected} callback will be invoked - * with the rejection reason as argument, and the child Promise will be rejected - * with the return value of the callback or thrown value. - * - * @param {?(function(this:THIS, TYPE): VALUE)=} opt_onFulfilled A - * function that will be invoked with the fulfillment value if the Promise - * is fullfilled. - * @param {?(function(this:THIS, *): *)=} opt_onRejected A function that will - * be invoked with the rejection reason if the Promise is rejected. - * @param {THIS=} opt_context An optional context object that will be the - * execution context for the callbacks. By default, functions are executed - * with the default this. - * - * @return {RESULT} A new Promise that will receive the result - * of the fulfillment or rejection callback. - * @template VALUE - * @template THIS - * - * When a Promise (or thenable) is returned from the fulfilled callback, - * the result is the payload of that promise, not the promise itself. - * - * @template RESULT := type('goog.Promise', - * cond(isUnknown(VALUE), unknown(), - * mapunion(VALUE, (V) => - * cond(isTemplatized(V) && sub(rawTypeOf(V), 'IThenable'), - * templateTypeOf(V, 0), - * cond(sub(V, 'Thenable'), - * unknown(), - * V))))) - * =: - * - */ -goog.Thenable.prototype.then = function(opt_onFulfilled, opt_onRejected, - opt_context) {}; - - -/** - * An expando property to indicate that an object implements - * {@code goog.Thenable}. - * - * {@see addImplementation}. - * - * @const - */ -goog.Thenable.IMPLEMENTED_BY_PROP = '$goog_Thenable'; - - -/** - * Marks a given class (constructor) as an implementation of Thenable, so - * that we can query that fact at runtime. The class must have already - * implemented the interface. - * Exports a 'then' method on the constructor prototype, so that the objects - * also implement the extern {@see goog.Thenable} interface for interop with - * other Promise implementations. - * @param {function(new:goog.Thenable,...?)} ctor The class constructor. The - * corresponding class must have already implemented the interface. - */ -goog.Thenable.addImplementation = function(ctor) { - goog.exportProperty(ctor.prototype, 'then', ctor.prototype.then); - if (COMPILED) { - ctor.prototype[goog.Thenable.IMPLEMENTED_BY_PROP] = true; - } else { - // Avoids dictionary access in uncompiled mode. - ctor.prototype.$goog_Thenable = true; - } -}; - - -/** - * @param {*} object - * @return {boolean} Whether a given instance implements {@code goog.Thenable}. - * The class/superclass of the instance must call {@code addImplementation}. - */ -goog.Thenable.isImplementedBy = function(object) { - if (!object) { - return false; - } - try { - if (COMPILED) { - return !!object[goog.Thenable.IMPLEMENTED_BY_PROP]; - } - return !!object.$goog_Thenable; - } catch (e) { - // Property access seems to be forbidden. - return false; - } -}; - -// Copyright 2015 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Simple freelist. - * - * An anterative to goog.structs.SimplePool, it imposes the requirement that the - * objects in the list contain a "next" property that can be used to maintain - * the pool. - */ - -goog.provide('goog.async.FreeList'); - - -/** - * @template ITEM - */ -goog.async.FreeList = goog.defineClass(null, { - /** - * @param {function():ITEM} create - * @param {function(ITEM):void} reset - * @param {number} limit - */ - constructor: function(create, reset, limit) { - /** @const {number} */ - this.limit_ = limit; - /** @const {function()} */ - this.create_ = create; - /** @const {function(ITEM):void} */ - this.reset_ = reset; - - /** @type {number} */ - this.occupants_ = 0; - /** @type {ITEM} */ - this.head_ = null; - }, - - /** - * @return {ITEM} - */ - get: function() { - var item; - if (this.occupants_ > 0) { - this.occupants_--; - item = this.head_; - this.head_ = item.next; - item.next = null; - } else { - item = this.create_(); - } - return item; - }, - - /** - * @param {ITEM} item An item available for possible future reuse. - */ - put: function(item) { - this.reset_(item); - if (this.occupants_ < this.limit_) { - this.occupants_++; - item.next = this.head_; - this.head_ = item; - } - }, - - /** - * Visible for testing. - * @package - * @return {number} - */ - occupants: function() { - return this.occupants_; - } -}); - - - - -// Copyright 2015 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -goog.provide('goog.async.WorkItem'); -goog.provide('goog.async.WorkQueue'); - -goog.require('goog.asserts'); -goog.require('goog.async.FreeList'); - - -// TODO(johnlenz): generalize the WorkQueue if this is used by more -// than goog.async.run. - - - -/** - * A low GC workqueue. The key elements of this design: - * - avoids the need for goog.bind or equivalent by carrying scope - * - avoids the need for array reallocation by using a linked list - * - minimizes work entry objects allocation by recycling objects - * @constructor - * @final - * @struct - */ -goog.async.WorkQueue = function() { - this.workHead_ = null; - this.workTail_ = null; -}; - - -/** @define {number} The maximum number of entries to keep for recycling. */ -goog.define('goog.async.WorkQueue.DEFAULT_MAX_UNUSED', 100); - - -/** @const @private {goog.async.FreeList<goog.async.WorkItem>} */ -goog.async.WorkQueue.freelist_ = new goog.async.FreeList( - function() {return new goog.async.WorkItem(); }, - function(item) {item.reset()}, - goog.async.WorkQueue.DEFAULT_MAX_UNUSED); - - -/** - * @param {function()} fn - * @param {Object|null|undefined} scope - */ -goog.async.WorkQueue.prototype.add = function(fn, scope) { - var item = this.getUnusedItem_(); - item.set(fn, scope); - - if (this.workTail_) { - this.workTail_.next = item; - this.workTail_ = item; - } else { - goog.asserts.assert(!this.workHead_); - this.workHead_ = item; - this.workTail_ = item; - } -}; - - -/** - * @return {goog.async.WorkItem} - */ -goog.async.WorkQueue.prototype.remove = function() { - var item = null; - - if (this.workHead_) { - item = this.workHead_; - this.workHead_ = this.workHead_.next; - if (!this.workHead_) { - this.workTail_ = null; - } - item.next = null; - } - return item; -}; - - -/** - * @param {goog.async.WorkItem} item - */ -goog.async.WorkQueue.prototype.returnUnused = function(item) { - goog.async.WorkQueue.freelist_.put(item); -}; - - -/** - * @return {goog.async.WorkItem} - * @private - */ -goog.async.WorkQueue.prototype.getUnusedItem_ = function() { - return goog.async.WorkQueue.freelist_.get(); -}; - - - -/** - * @constructor - * @final - * @struct - */ -goog.async.WorkItem = function() { - /** @type {?function()} */ - this.fn = null; - /** @type {Object|null|undefined} */ - this.scope = null; - /** @type {?goog.async.WorkItem} */ - this.next = null; -}; - - -/** - * @param {function()} fn - * @param {Object|null|undefined} scope - */ -goog.async.WorkItem.prototype.set = function(fn, scope) { - this.fn = fn; - this.scope = scope; - this.next = null; -}; - - -/** Reset the work item so they don't prevent GC before reuse */ -goog.async.WorkItem.prototype.reset = function() { - this.fn = null; - this.scope = null; - this.next = null; -}; - -// Copyright 2013 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Simple notifiers for the Closure testing framework. - * - * @author johnlenz@google.com (John Lenz) - */ - -goog.provide('goog.testing.watchers'); - - -/** @private {!Array<function()>} */ -goog.testing.watchers.resetWatchers_ = []; - - -/** - * Fires clock reset watching functions. - */ -goog.testing.watchers.signalClockReset = function() { - var watchers = goog.testing.watchers.resetWatchers_; - for (var i = 0; i < watchers.length; i++) { - goog.testing.watchers.resetWatchers_[i](); - } -}; - - -/** - * Enqueues a function to be called when the clock used for setTimeout is reset. - * @param {function()} fn - */ -goog.testing.watchers.watchClockReset = function(fn) { - goog.testing.watchers.resetWatchers_.push(fn); -}; - - -// Copyright 2013 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -goog.provide('goog.async.run'); - -goog.require('goog.async.WorkQueue'); -goog.require('goog.async.nextTick'); -goog.require('goog.async.throwException'); -goog.require('goog.testing.watchers'); - - -/** - * Fires the provided callback just before the current callstack unwinds, or as - * soon as possible after the current JS execution context. - * @param {function(this:THIS)} callback - * @param {THIS=} opt_context Object to use as the "this value" when calling - * the provided function. - * @template THIS - */ -goog.async.run = function(callback, opt_context) { - if (!goog.async.run.schedule_) { - goog.async.run.initializeRunner_(); - } - if (!goog.async.run.workQueueScheduled_) { - // Nothing is currently scheduled, schedule it now. - goog.async.run.schedule_(); - goog.async.run.workQueueScheduled_ = true; - } - - goog.async.run.workQueue_.add(callback, opt_context); -}; - - -/** - * Initializes the function to use to process the work queue. - * @private - */ -goog.async.run.initializeRunner_ = function() { - // If native Promises are available in the browser, just schedule the callback - // on a fulfilled promise, which is specified to be async, but as fast as - // possible. - if (goog.global.Promise && goog.global.Promise.resolve) { - var promise = goog.global.Promise.resolve(undefined); - goog.async.run.schedule_ = function() { - promise.then(goog.async.run.processWorkQueue); - }; - } else { - goog.async.run.schedule_ = function() { - goog.async.nextTick(goog.async.run.processWorkQueue); - }; - } -}; - - -/** - * Forces goog.async.run to use nextTick instead of Promise. - * - * This should only be done in unit tests. It's useful because MockClock - * replaces nextTick, but not the browser Promise implementation, so it allows - * Promise-based code to be tested with MockClock. - * - * However, we also want to run promises if the MockClock is no longer in - * control so we schedule a backup "setTimeout" to the unmocked timeout if - * provided. - * - * @param {function(function())=} opt_realSetTimeout - */ -goog.async.run.forceNextTick = function(opt_realSetTimeout) { - goog.async.run.schedule_ = function() { - goog.async.nextTick(goog.async.run.processWorkQueue); - if (opt_realSetTimeout) { - opt_realSetTimeout(goog.async.run.processWorkQueue); - } - }; -}; - - -/** - * The function used to schedule work asynchronousely. - * @private {function()} - */ -goog.async.run.schedule_; - - -/** @private {boolean} */ -goog.async.run.workQueueScheduled_ = false; - - -/** @private {!goog.async.WorkQueue} */ -goog.async.run.workQueue_ = new goog.async.WorkQueue(); - - -if (goog.DEBUG) { - /** - * Reset the work queue. - * @private - */ - goog.async.run.resetQueue_ = function() { - goog.async.run.workQueueScheduled_ = false; - goog.async.run.workQueue_ = new goog.async.WorkQueue(); - }; - - // If there is a clock implemenation in use for testing - // and it is reset, reset the queue. - goog.testing.watchers.watchClockReset(goog.async.run.resetQueue_); -} - - -/** - * Run any pending goog.async.run work items. This function is not intended - * for general use, but for use by entry point handlers to run items ahead of - * goog.async.nextTick. - */ -goog.async.run.processWorkQueue = function() { - // NOTE: additional work queue items may be added while processing. - var item = null; - while (item = goog.async.run.workQueue_.remove()) { - try { - item.fn.call(item.scope); - } catch (e) { - goog.async.throwException(e); - } - goog.async.run.workQueue_.returnUnused(item); - } - - // There are no more work items, allow processing to be scheduled again. - goog.async.run.workQueueScheduled_ = false; -}; - -// Copyright 2013 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -goog.provide('goog.promise.Resolver'); - - - -/** - * Resolver interface for promises. The resolver is a convenience interface that - * bundles the promise and its associated resolve and reject functions together, - * for cases where the resolver needs to be persisted internally. - * - * @interface - * @template TYPE - */ -goog.promise.Resolver = function() {}; - - -/** - * The promise that created this resolver. - * @type {!goog.Promise<TYPE>} - */ -goog.promise.Resolver.prototype.promise; - - -/** - * Resolves this resolver with the specified value. - * @type {function((TYPE|goog.Promise<TYPE>|Thenable)=)} - */ -goog.promise.Resolver.prototype.resolve; - - -/** - * Rejects this resolver with the specified reason. - * @type {function(*=): void} - */ -goog.promise.Resolver.prototype.reject; - -// Copyright 2013 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -goog.provide('goog.Promise'); - -goog.require('goog.Thenable'); -goog.require('goog.asserts'); -goog.require('goog.async.FreeList'); -goog.require('goog.async.run'); -goog.require('goog.async.throwException'); -goog.require('goog.debug.Error'); -goog.require('goog.promise.Resolver'); - - - -/** - * Promises provide a result that may be resolved asynchronously. A Promise may - * be resolved by being fulfilled with a fulfillment value, rejected with a - * rejection reason, or blocked by another Promise. A Promise is said to be - * settled if it is either fulfilled or rejected. Once settled, the Promise - * result is immutable. - * - * Promises may represent results of any type, including undefined. Rejection - * reasons are typically Errors, but may also be of any type. Closure Promises - * allow for optional type annotations that enforce that fulfillment values are - * of the appropriate types at compile time. - * - * The result of a Promise is accessible by calling {@code then} and registering - * {@code onFulfilled} and {@code onRejected} callbacks. Once the Promise - * is settled, the relevant callbacks are invoked with the fulfillment value or - * rejection reason as argument. Callbacks are always invoked in the order they - * were registered, even when additional {@code then} calls are made from inside - * another callback. A callback is always run asynchronously sometime after the - * scope containing the registering {@code then} invocation has returned. - * - * If a Promise is resolved with another Promise, the first Promise will block - * until the second is settled, and then assumes the same result as the second - * Promise. This allows Promises to depend on the results of other Promises, - * linking together multiple asynchronous operations. - * - * This implementation is compatible with the Promises/A+ specification and - * passes that specification's conformance test suite. A Closure Promise may be - * resolved with a Promise instance (or sufficiently compatible Promise-like - * object) created by other Promise implementations. From the specification, - * Promise-like objects are known as "Thenables". - * - * @see http://promisesaplus.com/ - * - * @param {function( - * this:RESOLVER_CONTEXT, - * function((TYPE|IThenable<TYPE>|Thenable)=), - * function(*=)): void} resolver - * Initialization function that is invoked immediately with {@code resolve} - * and {@code reject} functions as arguments. The Promise is resolved or - * rejected with the first argument passed to either function. - * @param {RESOLVER_CONTEXT=} opt_context An optional context for executing the - * resolver function. If unspecified, the resolver function will be executed - * in the default scope. - * @constructor - * @struct - * @final - * @implements {goog.Thenable<TYPE>} - * @template TYPE,RESOLVER_CONTEXT - */ -goog.Promise = function(resolver, opt_context) { - /** - * The internal state of this Promise. Either PENDING, FULFILLED, REJECTED, or - * BLOCKED. - * @private {goog.Promise.State_} - */ - this.state_ = goog.Promise.State_.PENDING; - - /** - * The settled result of the Promise. Immutable once set with either a - * fulfillment value or rejection reason. - * @private {*} - */ - this.result_ = undefined; - - /** - * For Promises created by calling {@code then()}, the originating parent. - * @private {goog.Promise} - */ - this.parent_ = null; - - /** - * The linked list of {@code onFulfilled} and {@code onRejected} callbacks - * added to this Promise by calls to {@code then()}. - * @private {?goog.Promise.CallbackEntry_} - */ - this.callbackEntries_ = null; - - /** - * The tail of the linked list of {@code onFulfilled} and {@code onRejected} - * callbacks added to this Promise by calls to {@code then()}. - * @private {?goog.Promise.CallbackEntry_} - */ - this.callbackEntriesTail_ = null; - - /** - * Whether the Promise is in the queue of Promises to execute. - * @private {boolean} - */ - this.executing_ = false; - - if (goog.Promise.UNHANDLED_REJECTION_DELAY > 0) { - /** - * A timeout ID used when the {@code UNHANDLED_REJECTION_DELAY} is greater - * than 0 milliseconds. The ID is set when the Promise is rejected, and - * cleared only if an {@code onRejected} callback is invoked for the - * Promise (or one of its descendants) before the delay is exceeded. - * - * If the rejection is not handled before the timeout completes, the - * rejection reason is passed to the unhandled rejection handler. - * @private {number} - */ - this.unhandledRejectionId_ = 0; - } else if (goog.Promise.UNHANDLED_REJECTION_DELAY == 0) { - /** - * When the {@code UNHANDLED_REJECTION_DELAY} is set to 0 milliseconds, a - * boolean that is set if the Promise is rejected, and reset to false if an - * {@code onRejected} callback is invoked for the Promise (or one of its - * descendants). If the rejection is not handled before the next timestep, - * the rejection reason is passed to the unhandled rejection handler. - * @private {boolean} - */ - this.hadUnhandledRejection_ = false; - } - - if (goog.Promise.LONG_STACK_TRACES) { - /** - * A list of stack trace frames pointing to the locations where this Promise - * was created or had callbacks added to it. Saved to add additional context - * to stack traces when an exception is thrown. - * @private {!Array<string>} - */ - this.stack_ = []; - this.addStackTrace_(new Error('created')); - - /** - * Index of the most recently executed stack frame entry. - * @private {number} - */ - this.currentStep_ = 0; - } - - // As an optimization, we can skip this if resolver is goog.nullFunction. - // This value is passed internally when creating a promise which will be - // resolved through a more optimized path. - if (resolver != goog.nullFunction) { - try { - var self = this; - resolver.call( - opt_context, - function(value) { - self.resolve_(goog.Promise.State_.FULFILLED, value); - }, - function(reason) { - if (goog.DEBUG && - !(reason instanceof goog.Promise.CancellationError)) { - try { - // Promise was rejected. Step up one call frame to see why. - if (reason instanceof Error) { - throw reason; - } else { - throw new Error('Promise rejected.'); - } - } catch (e) { - // Only thrown so browser dev tools can catch rejections of - // promises when the option to break on caught exceptions is - // activated. - } - } - self.resolve_(goog.Promise.State_.REJECTED, reason); - }); - } catch (e) { - this.resolve_(goog.Promise.State_.REJECTED, e); - } - } -}; - - -/** - * @define {boolean} Whether traces of {@code then} calls should be included in - * exceptions thrown - */ -goog.define('goog.Promise.LONG_STACK_TRACES', false); - - -/** - * @define {number} The delay in milliseconds before a rejected Promise's reason - * is passed to the rejection handler. By default, the rejection handler - * rethrows the rejection reason so that it appears in the developer console or - * {@code window.onerror} handler. - * - * Rejections are rethrown as quickly as possible by default. A negative value - * disables rejection handling entirely. - */ -goog.define('goog.Promise.UNHANDLED_REJECTION_DELAY', 0); - - -/** - * The possible internal states for a Promise. These states are not directly - * observable to external callers. - * @enum {number} - * @private - */ -goog.Promise.State_ = { - /** The Promise is waiting for resolution. */ - PENDING: 0, - - /** The Promise is blocked waiting for the result of another Thenable. */ - BLOCKED: 1, - - /** The Promise has been resolved with a fulfillment value. */ - FULFILLED: 2, - - /** The Promise has been resolved with a rejection reason. */ - REJECTED: 3 -}; - - - -/** - * Entries in the callback chain. Each call to {@code then}, - * {@code thenCatch}, or {@code thenAlways} creates an entry containing the - * functions that may be invoked once the Promise is settled. - * - * @private @final @struct @constructor - */ -goog.Promise.CallbackEntry_ = function() { - /** @type {?goog.Promise} */ - this.child = null; - /** @type {Function} */ - this.onFulfilled = null; - /** @type {Function} */ - this.onRejected = null; - /** @type {?} */ - this.context = null; - /** @type {?goog.Promise.CallbackEntry_} */ - this.next = null; - - /** - * A boolean value to indicate this is a "thenAlways" callback entry. - * Unlike a normal "then/thenVoid" a "thenAlways doesn't participate - * in "cancel" considerations but is simply an observer and requires - * special handling. - * @type {boolean} - */ - this.always = false; -}; - - -/** clear the object prior to reuse */ -goog.Promise.CallbackEntry_.prototype.reset = function() { - this.child = null; - this.onFulfilled = null; - this.onRejected = null; - this.context = null; - this.always = false; -}; - - -/** - * @define {number} The number of currently unused objects to keep around for - * reuse. - */ -goog.define('goog.Promise.DEFAULT_MAX_UNUSED', 100); - - -/** @const @private {goog.async.FreeList<!goog.Promise.CallbackEntry_>} */ -goog.Promise.freelist_ = new goog.async.FreeList( - function() { - return new goog.Promise.CallbackEntry_(); - }, - function(item) { - item.reset(); - }, - goog.Promise.DEFAULT_MAX_UNUSED); - - -/** - * @param {Function} onFulfilled - * @param {Function} onRejected - * @param {?} context - * @return {!goog.Promise.CallbackEntry_} - * @private - */ -goog.Promise.getCallbackEntry_ = function(onFulfilled, onRejected, context) { - var entry = goog.Promise.freelist_.get(); - entry.onFulfilled = onFulfilled; - entry.onRejected = onRejected; - entry.context = context; - return entry; -}; - - -/** - * @param {!goog.Promise.CallbackEntry_} entry - * @private - */ -goog.Promise.returnEntry_ = function(entry) { - goog.Promise.freelist_.put(entry); -}; - - -// NOTE: this is the same template expression as is used for -// goog.IThenable.prototype.then - - -/** - * @param {VALUE=} opt_value - * @return {RESULT} A new Promise that is immediately resolved - * with the given value. If the input value is already a goog.Promise, it - * will be returned immediately without creating a new instance. - * @template VALUE - * @template RESULT := type('goog.Promise', - * cond(isUnknown(VALUE), unknown(), - * mapunion(VALUE, (V) => - * cond(isTemplatized(V) && sub(rawTypeOf(V), 'IThenable'), - * templateTypeOf(V, 0), - * cond(sub(V, 'Thenable'), - * unknown(), - * V))))) - * =: - */ -goog.Promise.resolve = function(opt_value) { - if (opt_value instanceof goog.Promise) { - // Avoid creating a new object if we already have a promise object - // of the correct type. - return opt_value; - } - - // Passing goog.nullFunction will cause the constructor to take an optimized - // path that skips calling the resolver function. - var promise = new goog.Promise(goog.nullFunction); - promise.resolve_(goog.Promise.State_.FULFILLED, opt_value); - return promise; -}; - - -/** - * @param {*=} opt_reason - * @return {!goog.Promise} A new Promise that is immediately rejected with the - * given reason. - */ -goog.Promise.reject = function(opt_reason) { - return new goog.Promise(function(resolve, reject) { - reject(opt_reason); - }); -}; - - -/** - * This is identical to - * {@code goog.Promise.resolve(value).then(onFulfilled, onRejected)}, but it - * avoids creating an unnecessary wrapper Promise when {@code value} is already - * thenable. - * - * @param {?(goog.Thenable<TYPE>|Thenable|TYPE)} value - * @param {function(TYPE): ?} onFulfilled - * @param {function(*): *} onRejected - * @template TYPE - * @private - */ -goog.Promise.resolveThen_ = function(value, onFulfilled, onRejected) { - var isThenable = goog.Promise.maybeThen_( - value, onFulfilled, onRejected, null); - if (!isThenable) { - goog.async.run(goog.partial(onFulfilled, value)); - } -}; - - -/** - * @param {!Array<?(goog.Promise<TYPE>|goog.Thenable<TYPE>|Thenable|*)>} - * promises - * @return {!goog.Promise<TYPE>} A Promise that receives the result of the - * first Promise (or Promise-like) input to settle immediately after it - * settles. - * @template TYPE - */ -goog.Promise.race = function(promises) { - return new goog.Promise(function(resolve, reject) { - if (!promises.length) { - resolve(undefined); - } - for (var i = 0, promise; i < promises.length; i++) { - promise = promises[i]; - goog.Promise.resolveThen_(promise, resolve, reject); - } - }); -}; - - -/** - * @param {!Array<?(goog.Promise<TYPE>|goog.Thenable<TYPE>|Thenable|*)>} - * promises - * @return {!goog.Promise<!Array<TYPE>>} A Promise that receives a list of - * every fulfilled value once every input Promise (or Promise-like) is - * successfully fulfilled, or is rejected with the first rejection reason - * immediately after it is rejected. - * @template TYPE - */ -goog.Promise.all = function(promises) { - return new goog.Promise(function(resolve, reject) { - var toFulfill = promises.length; - var values = []; - - if (!toFulfill) { - resolve(values); - return; - } - - var onFulfill = function(index, value) { - toFulfill--; - values[index] = value; - if (toFulfill == 0) { - resolve(values); - } - }; - - var onReject = function(reason) { - reject(reason); - }; - - for (var i = 0, promise; i < promises.length; i++) { - promise = promises[i]; - goog.Promise.resolveThen_( - promise, goog.partial(onFulfill, i), onReject); - } - }); -}; - - -/** - * @param {!Array<?(goog.Promise<TYPE>|goog.Thenable<TYPE>|Thenable|*)>} - * promises - * @return {!goog.Promise<!Array<{ - * fulfilled: boolean, - * value: (TYPE|undefined), - * reason: (*|undefined)}>>} A Promise that resolves with a list of - * result objects once all input Promises (or Promise-like) have - * settled. Each result object contains a 'fulfilled' boolean indicating - * whether an input Promise was fulfilled or rejected. For fulfilled - * Promises, the resulting value is stored in the 'value' field. For - * rejected Promises, the rejection reason is stored in the 'reason' - * field. - * @template TYPE - */ -goog.Promise.allSettled = function(promises) { - return new goog.Promise(function(resolve, reject) { - var toSettle = promises.length; - var results = []; - - if (!toSettle) { - resolve(results); - return; - } - - var onSettled = function(index, fulfilled, result) { - toSettle--; - results[index] = fulfilled ? - {fulfilled: true, value: result} : - {fulfilled: false, reason: result}; - if (toSettle == 0) { - resolve(results); - } - }; - - for (var i = 0, promise; i < promises.length; i++) { - promise = promises[i]; - goog.Promise.resolveThen_(promise, - goog.partial(onSettled, i, true /* fulfilled */), - goog.partial(onSettled, i, false /* fulfilled */)); - } - }); -}; - - -/** - * @param {!Array<?(goog.Promise<TYPE>|goog.Thenable<TYPE>|Thenable|*)>} - * promises - * @return {!goog.Promise<TYPE>} A Promise that receives the value of the first - * input to be fulfilled, or is rejected with a list of every rejection - * reason if all inputs are rejected. - * @template TYPE - */ -goog.Promise.firstFulfilled = function(promises) { - return new goog.Promise(function(resolve, reject) { - var toReject = promises.length; - var reasons = []; - - if (!toReject) { - resolve(undefined); - return; - } - - var onFulfill = function(value) { - resolve(value); - }; - - var onReject = function(index, reason) { - toReject--; - reasons[index] = reason; - if (toReject == 0) { - reject(reasons); - } - }; - - for (var i = 0, promise; i < promises.length; i++) { - promise = promises[i]; - goog.Promise.resolveThen_( - promise, onFulfill, goog.partial(onReject, i)); - } - }); -}; - - -/** - * @return {!goog.promise.Resolver<TYPE>} Resolver wrapping the promise and its - * resolve / reject functions. Resolving or rejecting the resolver - * resolves or rejects the promise. - * @template TYPE - */ -goog.Promise.withResolver = function() { - var resolve, reject; - var promise = new goog.Promise(function(rs, rj) { - resolve = rs; - reject = rj; - }); - return new goog.Promise.Resolver_(promise, resolve, reject); -}; - - -/** - * Adds callbacks that will operate on the result of the Promise, returning a - * new child Promise. - * - * If the Promise is fulfilled, the {@code onFulfilled} callback will be invoked - * with the fulfillment value as argument, and the child Promise will be - * fulfilled with the return value of the callback. If the callback throws an - * exception, the child Promise will be rejected with the thrown value instead. - * - * If the Promise is rejected, the {@code onRejected} callback will be invoked - * with the rejection reason as argument, and the child Promise will be resolved - * with the return value or rejected with the thrown value of the callback. - * - * @override - */ -goog.Promise.prototype.then = function( - opt_onFulfilled, opt_onRejected, opt_context) { - - if (opt_onFulfilled != null) { - goog.asserts.assertFunction(opt_onFulfilled, - 'opt_onFulfilled should be a function.'); - } - if (opt_onRejected != null) { - goog.asserts.assertFunction(opt_onRejected, - 'opt_onRejected should be a function. Did you pass opt_context ' + - 'as the second argument instead of the third?'); - } - - if (goog.Promise.LONG_STACK_TRACES) { - this.addStackTrace_(new Error('then')); - } - - return this.addChildPromise_( - goog.isFunction(opt_onFulfilled) ? opt_onFulfilled : null, - goog.isFunction(opt_onRejected) ? opt_onRejected : null, - opt_context); -}; -goog.Thenable.addImplementation(goog.Promise); - - -/** - * Adds callbacks that will operate on the result of the Promise without - * returning a child Promise (unlike "then"). - * - * If the Promise is fulfilled, the {@code onFulfilled} callback will be invoked - * with the fulfillment value as argument. - * - * If the Promise is rejected, the {@code onRejected} callback will be invoked - * with the rejection reason as argument. - * - * @param {?(function(this:THIS, TYPE):?)=} opt_onFulfilled A - * function that will be invoked with the fulfillment value if the Promise - * is fulfilled. - * @param {?(function(this:THIS, *): *)=} opt_onRejected A function that will - * be invoked with the rejection reason if the Promise is rejected. - * @param {THIS=} opt_context An optional context object that will be the - * execution context for the callbacks. By default, functions are executed - * with the default this. - * @package - * @template THIS - */ -goog.Promise.prototype.thenVoid = function( - opt_onFulfilled, opt_onRejected, opt_context) { - - if (opt_onFulfilled != null) { - goog.asserts.assertFunction(opt_onFulfilled, - 'opt_onFulfilled should be a function.'); - } - if (opt_onRejected != null) { - goog.asserts.assertFunction(opt_onRejected, - 'opt_onRejected should be a function. Did you pass opt_context ' + - 'as the second argument instead of the third?'); - } - - if (goog.Promise.LONG_STACK_TRACES) { - this.addStackTrace_(new Error('then')); - } - - // Note: no default rejection handler is provided here as we need to - // distinguish unhandled rejections. - this.addCallbackEntry_(goog.Promise.getCallbackEntry_( - opt_onFulfilled || goog.nullFunction, - opt_onRejected || null, - opt_context)); -}; - - -/** - * Adds a callback that will be invoked when the Promise is settled (fulfilled - * or rejected). The callback receives no argument, and no new child Promise is - * created. This is useful for ensuring that cleanup takes place after certain - * asynchronous operations. Callbacks added with {@code thenAlways} will be - * executed in the same order with other calls to {@code then}, - * {@code thenAlways}, or {@code thenCatch}. - * - * Since it does not produce a new child Promise, cancellation propagation is - * not prevented by adding callbacks with {@code thenAlways}. A Promise that has - * a cleanup handler added with {@code thenAlways} will be canceled if all of - * its children created by {@code then} (or {@code thenCatch}) are canceled. - * Additionally, since any rejections are not passed to the callback, it does - * not stop the unhandled rejection handler from running. - * - * @param {function(this:THIS): void} onSettled A function that will be invoked - * when the Promise is settled (fulfilled or rejected). - * @param {THIS=} opt_context An optional context object that will be the - * execution context for the callbacks. By default, functions are executed - * in the global scope. - * @return {!goog.Promise<TYPE>} This Promise, for chaining additional calls. - * @template THIS - */ -goog.Promise.prototype.thenAlways = function(onSettled, opt_context) { - if (goog.Promise.LONG_STACK_TRACES) { - this.addStackTrace_(new Error('thenAlways')); - } - - var entry = goog.Promise.getCallbackEntry_(onSettled, onSettled, opt_context); - entry.always = true; - this.addCallbackEntry_(entry); - return this; -}; - - -/** - * Adds a callback that will be invoked only if the Promise is rejected. This - * is equivalent to {@code then(null, onRejected)}. - * - * @param {!function(this:THIS, *): *} onRejected A function that will be - * invoked with the rejection reason if the Promise is rejected. - * @param {THIS=} opt_context An optional context object that will be the - * execution context for the callbacks. By default, functions are executed - * in the global scope. - * @return {!goog.Promise} A new Promise that will receive the result of the - * callback. - * @template THIS - */ -goog.Promise.prototype.thenCatch = function(onRejected, opt_context) { - if (goog.Promise.LONG_STACK_TRACES) { - this.addStackTrace_(new Error('thenCatch')); - } - return this.addChildPromise_(null, onRejected, opt_context); -}; - - -/** - * Cancels the Promise if it is still pending by rejecting it with a cancel - * Error. No action is performed if the Promise is already resolved. - * - * All child Promises of the canceled Promise will be rejected with the same - * cancel error, as with normal Promise rejection. If the Promise to be canceled - * is the only child of a pending Promise, the parent Promise will also be - * canceled. Cancellation may propagate upward through multiple generations. - * - * @param {string=} opt_message An optional debugging message for describing the - * cancellation reason. - */ -goog.Promise.prototype.cancel = function(opt_message) { - if (this.state_ == goog.Promise.State_.PENDING) { - goog.async.run(function() { - var err = new goog.Promise.CancellationError(opt_message); - this.cancelInternal_(err); - }, this); - } -}; - - -/** - * Cancels this Promise with the given error. - * - * @param {!Error} err The cancellation error. - * @private - */ -goog.Promise.prototype.cancelInternal_ = function(err) { - if (this.state_ == goog.Promise.State_.PENDING) { - if (this.parent_) { - // Cancel the Promise and remove it from the parent's child list. - this.parent_.cancelChild_(this, err); - this.parent_ = null; - } else { - this.resolve_(goog.Promise.State_.REJECTED, err); - } - } -}; - - -/** - * Cancels a child Promise from the list of callback entries. If the Promise has - * not already been resolved, reject it with a cancel error. If there are no - * other children in the list of callback entries, propagate the cancellation - * by canceling this Promise as well. - * - * @param {!goog.Promise} childPromise The Promise to cancel. - * @param {!Error} err The cancel error to use for rejecting the Promise. - * @private - */ -goog.Promise.prototype.cancelChild_ = function(childPromise, err) { - if (!this.callbackEntries_) { - return; - } - var childCount = 0; - var childEntry = null; - var beforeChildEntry = null; - - // Find the callback entry for the childPromise, and count whether there are - // additional child Promises. - for (var entry = this.callbackEntries_; entry; entry = entry.next) { - if (!entry.always) { - childCount++; - if (entry.child == childPromise) { - childEntry = entry; - } - if (childEntry && childCount > 1) { - break; - } - } - if (!childEntry) { - beforeChildEntry = entry; - } - } - - // Can a child entry be missing? - - // If the child Promise was the only child, cancel this Promise as well. - // Otherwise, reject only the child Promise with the cancel error. - if (childEntry) { - if (this.state_ == goog.Promise.State_.PENDING && childCount == 1) { - this.cancelInternal_(err); - } else { - if (beforeChildEntry) { - this.removeEntryAfter_(beforeChildEntry); - } else { - this.popEntry_(); - } - - this.executeCallback_( - childEntry, goog.Promise.State_.REJECTED, err); - } - } -}; - - -/** - * Adds a callback entry to the current Promise, and schedules callback - * execution if the Promise has already been settled. - * - * @param {goog.Promise.CallbackEntry_} callbackEntry Record containing - * {@code onFulfilled} and {@code onRejected} callbacks to execute after - * the Promise is settled. - * @private - */ -goog.Promise.prototype.addCallbackEntry_ = function(callbackEntry) { - if (!this.hasEntry_() && - (this.state_ == goog.Promise.State_.FULFILLED || - this.state_ == goog.Promise.State_.REJECTED)) { - this.scheduleCallbacks_(); - } - this.queueEntry_(callbackEntry); -}; - - -/** - * Creates a child Promise and adds it to the callback entry list. The result of - * the child Promise is determined by the state of the parent Promise and the - * result of the {@code onFulfilled} or {@code onRejected} callbacks as - * specified in the Promise resolution procedure. - * - * @see http://promisesaplus.com/#the__method - * - * @param {?function(this:THIS, TYPE): - * (RESULT|goog.Promise<RESULT>|Thenable)} onFulfilled A callback that - * will be invoked if the Promise is fullfilled, or null. - * @param {?function(this:THIS, *): *} onRejected A callback that will be - * invoked if the Promise is rejected, or null. - * @param {THIS=} opt_context An optional execution context for the callbacks. - * in the default calling context. - * @return {!goog.Promise} The child Promise. - * @template RESULT,THIS - * @private - */ -goog.Promise.prototype.addChildPromise_ = function( - onFulfilled, onRejected, opt_context) { - - /** @type {goog.Promise.CallbackEntry_} */ - var callbackEntry = goog.Promise.getCallbackEntry_(null, null, null); - - callbackEntry.child = new goog.Promise(function(resolve, reject) { - // Invoke onFulfilled, or resolve with the parent's value if absent. - callbackEntry.onFulfilled = onFulfilled ? function(value) { - try { - var result = onFulfilled.call(opt_context, value); - resolve(result); - } catch (err) { - reject(err); - } - } : resolve; - - // Invoke onRejected, or reject with the parent's reason if absent. - callbackEntry.onRejected = onRejected ? function(reason) { - try { - var result = onRejected.call(opt_context, reason); - if (!goog.isDef(result) && - reason instanceof goog.Promise.CancellationError) { - // Propagate cancellation to children if no other result is returned. - reject(reason); - } else { - resolve(result); - } - } catch (err) { - reject(err); - } - } : reject; - }); - - callbackEntry.child.parent_ = this; - this.addCallbackEntry_(callbackEntry); - return callbackEntry.child; -}; - - -/** - * Unblocks the Promise and fulfills it with the given value. - * - * @param {TYPE} value - * @private - */ -goog.Promise.prototype.unblockAndFulfill_ = function(value) { - goog.asserts.assert(this.state_ == goog.Promise.State_.BLOCKED); - this.state_ = goog.Promise.State_.PENDING; - this.resolve_(goog.Promise.State_.FULFILLED, value); -}; - - -/** - * Unblocks the Promise and rejects it with the given rejection reason. - * - * @param {*} reason - * @private - */ -goog.Promise.prototype.unblockAndReject_ = function(reason) { - goog.asserts.assert(this.state_ == goog.Promise.State_.BLOCKED); - this.state_ = goog.Promise.State_.PENDING; - this.resolve_(goog.Promise.State_.REJECTED, reason); -}; - - -/** - * Attempts to resolve a Promise with a given resolution state and value. This - * is a no-op if the given Promise has already been resolved. - * - * If the given result is a Thenable (such as another Promise), the Promise will - * be settled with the same state and result as the Thenable once it is itself - * settled. - * - * If the given result is not a Thenable, the Promise will be settled (fulfilled - * or rejected) with that result based on the given state. - * - * @see http://promisesaplus.com/#the_promise_resolution_procedure - * - * @param {goog.Promise.State_} state - * @param {*} x The result to apply to the Promise. - * @private - */ -goog.Promise.prototype.resolve_ = function(state, x) { - if (this.state_ != goog.Promise.State_.PENDING) { - return; - } - - if (this == x) { - state = goog.Promise.State_.REJECTED; - x = new TypeError('Promise cannot resolve to itself'); - } - - this.state_ = goog.Promise.State_.BLOCKED; - var isThenable = goog.Promise.maybeThen_( - x, this.unblockAndFulfill_, this.unblockAndReject_, this); - if (isThenable) { - return; - } - - this.result_ = x; - this.state_ = state; - // Since we can no longer be canceled, remove link to parent, so that the - // child promise does not keep the parent promise alive. - this.parent_ = null; - this.scheduleCallbacks_(); - - if (state == goog.Promise.State_.REJECTED && - !(x instanceof goog.Promise.CancellationError)) { - goog.Promise.addUnhandledRejection_(this, x); - } -}; - - -/** - * Invokes the "then" method of an input value if that value is a Thenable. This - * is a no-op if the value is not thenable. - * - * @param {*} value A potentially thenable value. - * @param {!Function} onFulfilled - * @param {!Function} onRejected - * @param {*} context - * @return {boolean} Whether the input value was thenable. - * @private - */ -goog.Promise.maybeThen_ = function(value, onFulfilled, onRejected, context) { - if (value instanceof goog.Promise) { - value.thenVoid(onFulfilled, onRejected, context); - return true; - } else if (goog.Thenable.isImplementedBy(value)) { - value = /** @type {!goog.Thenable} */ (value); - value.then(onFulfilled, onRejected, context); - return true; - } else if (goog.isObject(value)) { - try { - var then = value['then']; - if (goog.isFunction(then)) { - goog.Promise.tryThen_( - value, then, onFulfilled, onRejected, context); - return true; - } - } catch (e) { - onRejected.call(context, e); - return true; - } - } - - return false; -}; - - -/** - * Attempts to call the {@code then} method on an object in the hopes that it is - * a Promise-compatible instance. This allows interoperation between different - * Promise implementations, however a non-compliant object may cause a Promise - * to hang indefinitely. If the {@code then} method throws an exception, the - * dependent Promise will be rejected with the thrown value. - * - * @see http://promisesaplus.com/#point-70 - * - * @param {Thenable} thenable An object with a {@code then} method that may be - * compatible with the Promise/A+ specification. - * @param {!Function} then The {@code then} method of the Thenable object. - * @param {!Function} onFulfilled - * @param {!Function} onRejected - * @param {*} context - * @private - */ -goog.Promise.tryThen_ = function( - thenable, then, onFulfilled, onRejected, context) { - - var called = false; - var resolve = function(value) { - if (!called) { - called = true; - onFulfilled.call(context, value); - } - }; - - var reject = function(reason) { - if (!called) { - called = true; - onRejected.call(context, reason); - } - }; - - try { - then.call(thenable, resolve, reject); - } catch (e) { - reject(e); - } -}; - - -/** - * Executes the pending callbacks of a settled Promise after a timeout. - * - * Section 2.2.4 of the Promises/A+ specification requires that Promise - * callbacks must only be invoked from a call stack that only contains Promise - * implementation code, which we accomplish by invoking callback execution after - * a timeout. If {@code startExecution_} is called multiple times for the same - * Promise, the callback chain will be evaluated only once. Additional callbacks - * may be added during the evaluation phase, and will be executed in the same - * event loop. - * - * All Promises added to the waiting list during the same browser event loop - * will be executed in one batch to avoid using a separate timeout per Promise. - * - * @private - */ -goog.Promise.prototype.scheduleCallbacks_ = function() { - if (!this.executing_) { - this.executing_ = true; - goog.async.run(this.executeCallbacks_, this); - } -}; - - -/** - * @return {boolean} Whether there are any pending callbacks queued. - * @private - */ -goog.Promise.prototype.hasEntry_ = function() { - return !!this.callbackEntries_; -}; - - -/** - * @param {goog.Promise.CallbackEntry_} entry - * @private - */ -goog.Promise.prototype.queueEntry_ = function(entry) { - goog.asserts.assert(entry.onFulfilled != null); - - if (this.callbackEntriesTail_) { - this.callbackEntriesTail_.next = entry; - this.callbackEntriesTail_ = entry; - } else { - // It the work queue was empty set the head too. - this.callbackEntries_ = entry; - this.callbackEntriesTail_ = entry; - } -}; - - -/** - * @return {goog.Promise.CallbackEntry_} entry - * @private - */ -goog.Promise.prototype.popEntry_ = function() { - var entry = null; - if (this.callbackEntries_) { - entry = this.callbackEntries_; - this.callbackEntries_ = entry.next; - entry.next = null; - } - // It the work queue is empty clear the tail too. - if (!this.callbackEntries_) { - this.callbackEntriesTail_ = null; - } - - if (entry != null) { - goog.asserts.assert(entry.onFulfilled != null); - } - return entry; -}; - - -/** - * @param {goog.Promise.CallbackEntry_} previous - * @private - */ -goog.Promise.prototype.removeEntryAfter_ = function(previous) { - goog.asserts.assert(this.callbackEntries_); - goog.asserts.assert(previous != null); - // If the last entry is being removed, update the tail - if (previous.next == this.callbackEntriesTail_) { - this.callbackEntriesTail_ = previous; - } - - previous.next = previous.next.next; -}; - - -/** - * Executes all pending callbacks for this Promise. - * - * @private - */ -goog.Promise.prototype.executeCallbacks_ = function() { - var entry = null; - while (entry = this.popEntry_()) { - if (goog.Promise.LONG_STACK_TRACES) { - this.currentStep_++; - } - this.executeCallback_(entry, this.state_, this.result_); - } - this.executing_ = false; -}; - - -/** - * Executes a pending callback for this Promise. Invokes an {@code onFulfilled} - * or {@code onRejected} callback based on the settled state of the Promise. - * - * @param {!goog.Promise.CallbackEntry_} callbackEntry An entry containing the - * onFulfilled and/or onRejected callbacks for this step. - * @param {goog.Promise.State_} state The resolution status of the Promise, - * either FULFILLED or REJECTED. - * @param {*} result The settled result of the Promise. - * @private - */ -goog.Promise.prototype.executeCallback_ = function( - callbackEntry, state, result) { - // Cancel an unhandled rejection if the then/thenVoid call had an onRejected. - if (state == goog.Promise.State_.REJECTED && - callbackEntry.onRejected && !callbackEntry.always) { - this.removeUnhandledRejection_(); - } - - if (callbackEntry.child) { - // When the parent is settled, the child no longer needs to hold on to it, - // as the parent can no longer be canceled. - callbackEntry.child.parent_ = null; - goog.Promise.invokeCallback_(callbackEntry, state, result); - } else { - // Callbacks created with thenAlways or thenVoid do not have the rejection - // handling code normally set up in the child Promise. - try { - callbackEntry.always ? - callbackEntry.onFulfilled.call(callbackEntry.context) : - goog.Promise.invokeCallback_(callbackEntry, state, result); - } catch (err) { - goog.Promise.handleRejection_.call(null, err); - } - } - goog.Promise.returnEntry_(callbackEntry); -}; - - -/** - * Executes the onFulfilled or onRejected callback for a callbackEntry. - * - * @param {!goog.Promise.CallbackEntry_} callbackEntry - * @param {goog.Promise.State_} state - * @param {*} result - * @private - */ -goog.Promise.invokeCallback_ = function(callbackEntry, state, result) { - if (state == goog.Promise.State_.FULFILLED) { - callbackEntry.onFulfilled.call(callbackEntry.context, result); - } else if (callbackEntry.onRejected) { - callbackEntry.onRejected.call(callbackEntry.context, result); - } -}; - - -/** - * Records a stack trace entry for functions that call {@code then} or the - * Promise constructor. May be disabled by unsetting {@code LONG_STACK_TRACES}. - * - * @param {!Error} err An Error object created by the calling function for - * providing a stack trace. - * @private - */ -goog.Promise.prototype.addStackTrace_ = function(err) { - if (goog.Promise.LONG_STACK_TRACES && goog.isString(err.stack)) { - // Extract the third line of the stack trace, which is the entry for the - // user function that called into Promise code. - var trace = err.stack.split('\n', 4)[3]; - var message = err.message; - - // Pad the message to align the traces. - message += Array(11 - message.length).join(' '); - this.stack_.push(message + trace); - } -}; - - -/** - * Adds extra stack trace information to an exception for the list of - * asynchronous {@code then} calls that have been run for this Promise. Stack - * trace information is recorded in {@see #addStackTrace_}, and appended to - * rethrown errors when {@code LONG_STACK_TRACES} is enabled. - * - * @param {*} err An unhandled exception captured during callback execution. - * @private - */ -goog.Promise.prototype.appendLongStack_ = function(err) { - if (goog.Promise.LONG_STACK_TRACES && - err && goog.isString(err.stack) && this.stack_.length) { - var longTrace = ['Promise trace:']; - - for (var promise = this; promise; promise = promise.parent_) { - for (var i = this.currentStep_; i >= 0; i--) { - longTrace.push(promise.stack_[i]); - } - longTrace.push('Value: ' + - '[' + (promise.state_ == goog.Promise.State_.REJECTED ? - 'REJECTED' : 'FULFILLED') + '] ' + - '<' + String(promise.result_) + '>'); - } - err.stack += '\n\n' + longTrace.join('\n'); - } -}; - - -/** - * Marks this rejected Promise as having being handled. Also marks any parent - * Promises in the rejected state as handled. The rejection handler will no - * longer be invoked for this Promise (if it has not been called already). - * - * @private - */ -goog.Promise.prototype.removeUnhandledRejection_ = function() { - if (goog.Promise.UNHANDLED_REJECTION_DELAY > 0) { - for (var p = this; p && p.unhandledRejectionId_; p = p.parent_) { - goog.global.clearTimeout(p.unhandledRejectionId_); - p.unhandledRejectionId_ = 0; - } - } else if (goog.Promise.UNHANDLED_REJECTION_DELAY == 0) { - for (var p = this; p && p.hadUnhandledRejection_; p = p.parent_) { - p.hadUnhandledRejection_ = false; - } - } -}; - - -/** - * Marks this rejected Promise as unhandled. If no {@code onRejected} callback - * is called for this Promise before the {@code UNHANDLED_REJECTION_DELAY} - * expires, the reason will be passed to the unhandled rejection handler. The - * handler typically rethrows the rejection reason so that it becomes visible in - * the developer console. - * - * @param {!goog.Promise} promise The rejected Promise. - * @param {*} reason The Promise rejection reason. - * @private - */ -goog.Promise.addUnhandledRejection_ = function(promise, reason) { - if (goog.Promise.UNHANDLED_REJECTION_DELAY > 0) { - promise.unhandledRejectionId_ = goog.global.setTimeout(function() { - promise.appendLongStack_(reason); - goog.Promise.handleRejection_.call(null, reason); - }, goog.Promise.UNHANDLED_REJECTION_DELAY); - - } else if (goog.Promise.UNHANDLED_REJECTION_DELAY == 0) { - promise.hadUnhandledRejection_ = true; - goog.async.run(function() { - if (promise.hadUnhandledRejection_) { - promise.appendLongStack_(reason); - goog.Promise.handleRejection_.call(null, reason); - } - }); - } -}; - - -/** - * A method that is invoked with the rejection reasons for Promises that are - * rejected but have no {@code onRejected} callbacks registered yet. - * @type {function(*)} - * @private - */ -goog.Promise.handleRejection_ = goog.async.throwException; - - -/** - * Sets a handler that will be called with reasons from unhandled rejected - * Promises. If the rejected Promise (or one of its descendants) has an - * {@code onRejected} callback registered, the rejection will be considered - * handled, and the rejection handler will not be called. - * - * By default, unhandled rejections are rethrown so that the error may be - * captured by the developer console or a {@code window.onerror} handler. - * - * @param {function(*)} handler A function that will be called with reasons from - * rejected Promises. Defaults to {@code goog.async.throwException}. - */ -goog.Promise.setUnhandledRejectionHandler = function(handler) { - goog.Promise.handleRejection_ = handler; -}; - - - -/** - * Error used as a rejection reason for canceled Promises. - * - * @param {string=} opt_message - * @constructor - * @extends {goog.debug.Error} - * @final - */ -goog.Promise.CancellationError = function(opt_message) { - goog.Promise.CancellationError.base(this, 'constructor', opt_message); -}; -goog.inherits(goog.Promise.CancellationError, goog.debug.Error); - - -/** @override */ -goog.Promise.CancellationError.prototype.name = 'cancel'; - - - -/** - * Internal implementation of the resolver interface. - * - * @param {!goog.Promise<TYPE>} promise - * @param {function((TYPE|goog.Promise<TYPE>|Thenable)=)} resolve - * @param {function(*=): void} reject - * @implements {goog.promise.Resolver<TYPE>} - * @final @struct - * @constructor - * @private - * @template TYPE - */ -goog.Promise.Resolver_ = function(promise, resolve, reject) { - /** @const */ - this.promise = promise; - - /** @const */ - this.resolve = resolve; - - /** @const */ - this.reject = reject; -}; - -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview A timer class to which other classes and objects can - * listen on. This is only an abstraction above setInterval. - * - * @see ../demos/timers.html - */ - -goog.provide('goog.Timer'); - -goog.require('goog.Promise'); -goog.require('goog.events.EventTarget'); - - - -/** - * Class for handling timing events. - * - * @param {number=} opt_interval Number of ms between ticks (Default: 1ms). - * @param {Object=} opt_timerObject An object that has setTimeout, setInterval, - * clearTimeout and clearInterval (eg Window). - * @constructor - * @extends {goog.events.EventTarget} - */ -goog.Timer = function(opt_interval, opt_timerObject) { - goog.events.EventTarget.call(this); - - /** - * Number of ms between ticks - * @type {number} - * @private - */ - this.interval_ = opt_interval || 1; - - /** - * An object that implements setTimeout, setInterval, clearTimeout and - * clearInterval. We default to the window object. Changing this on - * goog.Timer.prototype changes the object for all timer instances which can - * be useful if your environment has some other implementation of timers than - * the window object. - * @type {Object} - * @private - */ - this.timerObject_ = opt_timerObject || goog.Timer.defaultTimerObject; - - /** - * Cached tick_ bound to the object for later use in the timer. - * @type {Function} - * @private - */ - this.boundTick_ = goog.bind(this.tick_, this); - - /** - * Firefox browser often fires the timer event sooner - * (sometimes MUCH sooner) than the requested timeout. So we - * compare the time to when the event was last fired, and - * reschedule if appropriate. See also goog.Timer.intervalScale - * @type {number} - * @private - */ - this.last_ = goog.now(); -}; -goog.inherits(goog.Timer, goog.events.EventTarget); - - -/** - * Maximum timeout value. - * - * Timeout values too big to fit into a signed 32-bit integer may cause - * overflow in FF, Safari, and Chrome, resulting in the timeout being - * scheduled immediately. It makes more sense simply not to schedule these - * timeouts, since 24.8 days is beyond a reasonable expectation for the - * browser to stay open. - * - * @type {number} - * @private - */ -goog.Timer.MAX_TIMEOUT_ = 2147483647; - - -/** - * A timer ID that cannot be returned by any known implmentation of - * Window.setTimeout. Passing this value to window.clearTimeout should - * therefore be a no-op. - * - * @const {number} - * @private - */ -goog.Timer.INVALID_TIMEOUT_ID_ = -1; - - -/** - * Whether this timer is enabled - * @type {boolean} - */ -goog.Timer.prototype.enabled = false; - - -/** - * An object that implements setTimout, setInterval, clearTimeout and - * clearInterval. We default to the global object. Changing - * goog.Timer.defaultTimerObject changes the object for all timer instances - * which can be useful if your environment has some other implementation of - * timers you'd like to use. - * @type {Object} - */ -goog.Timer.defaultTimerObject = goog.global; - - -/** - * A variable that controls the timer error correction. If the - * timer is called before the requested interval times - * intervalScale, which often happens on mozilla, the timer is - * rescheduled. See also this.last_ - * @type {number} - */ -goog.Timer.intervalScale = 0.8; - - -/** - * Variable for storing the result of setInterval - * @type {?number} - * @private - */ -goog.Timer.prototype.timer_ = null; - - -/** - * Gets the interval of the timer. - * @return {number} interval Number of ms between ticks. - */ -goog.Timer.prototype.getInterval = function() { - return this.interval_; -}; - - -/** - * Sets the interval of the timer. - * @param {number} interval Number of ms between ticks. - */ -goog.Timer.prototype.setInterval = function(interval) { - this.interval_ = interval; - if (this.timer_ && this.enabled) { - // Stop and then start the timer to reset the interval. - this.stop(); - this.start(); - } else if (this.timer_) { - this.stop(); - } -}; - - -/** - * Callback for the setTimeout used by the timer - * @private - */ -goog.Timer.prototype.tick_ = function() { - if (this.enabled) { - var elapsed = goog.now() - this.last_; - if (elapsed > 0 && - elapsed < this.interval_ * goog.Timer.intervalScale) { - this.timer_ = this.timerObject_.setTimeout(this.boundTick_, - this.interval_ - elapsed); - return; - } - - // Prevents setInterval from registering a duplicate timeout when called - // in the timer event handler. - if (this.timer_) { - this.timerObject_.clearTimeout(this.timer_); - this.timer_ = null; - } - - this.dispatchTick(); - // The timer could be stopped in the timer event handler. - if (this.enabled) { - this.timer_ = this.timerObject_.setTimeout(this.boundTick_, - this.interval_); - this.last_ = goog.now(); - } - } -}; - - -/** - * Dispatches the TICK event. This is its own method so subclasses can override. - */ -goog.Timer.prototype.dispatchTick = function() { - this.dispatchEvent(goog.Timer.TICK); -}; - - -/** - * Starts the timer. - */ -goog.Timer.prototype.start = function() { - this.enabled = true; - - // If there is no interval already registered, start it now - if (!this.timer_) { - // IMPORTANT! - // window.setInterval in FireFox has a bug - it fires based on - // absolute time, rather than on relative time. What this means - // is that if a computer is sleeping/hibernating for 24 hours - // and the timer interval was configured to fire every 1000ms, - // then after the PC wakes up the timer will fire, in rapid - // succession, 3600*24 times. - // This bug is described here and is already fixed, but it will - // take time to propagate, so for now I am switching this over - // to setTimeout logic. - // https://bugzilla.mozilla.org/show_bug.cgi?id=376643 - // - this.timer_ = this.timerObject_.setTimeout(this.boundTick_, - this.interval_); - this.last_ = goog.now(); - } -}; - - -/** - * Stops the timer. - */ -goog.Timer.prototype.stop = function() { - this.enabled = false; - if (this.timer_) { - this.timerObject_.clearTimeout(this.timer_); - this.timer_ = null; - } -}; - - -/** @override */ -goog.Timer.prototype.disposeInternal = function() { - goog.Timer.superClass_.disposeInternal.call(this); - this.stop(); - delete this.timerObject_; -}; - - -/** - * Constant for the timer's event type - * @type {string} - */ -goog.Timer.TICK = 'tick'; - - -/** - * Calls the given function once, after the optional pause. - * - * The function is always called asynchronously, even if the delay is 0. This - * is a common trick to schedule a function to run after a batch of browser - * event processing. - * - * @param {function(this:SCOPE)|{handleEvent:function()}|null} listener Function - * or object that has a handleEvent method. - * @param {number=} opt_delay Milliseconds to wait; default is 0. - * @param {SCOPE=} opt_handler Object in whose scope to call the listener. - * @return {number} A handle to the timer ID. - * @template SCOPE - */ -goog.Timer.callOnce = function(listener, opt_delay, opt_handler) { - if (goog.isFunction(listener)) { - if (opt_handler) { - listener = goog.bind(listener, opt_handler); - } - } else if (listener && typeof listener.handleEvent == 'function') { - // using typeof to prevent strict js warning - listener = goog.bind(listener.handleEvent, listener); - } else { - throw Error('Invalid listener argument'); - } - - if (opt_delay > goog.Timer.MAX_TIMEOUT_) { - // Timeouts greater than MAX_INT return immediately due to integer - // overflow in many browsers. Since MAX_INT is 24.8 days, just don't - // schedule anything at all. - return goog.Timer.INVALID_TIMEOUT_ID_; - } else { - return goog.Timer.defaultTimerObject.setTimeout( - listener, opt_delay || 0); - } -}; - - -/** - * Clears a timeout initiated by callOnce - * @param {?number} timerId a timer ID. - */ -goog.Timer.clear = function(timerId) { - goog.Timer.defaultTimerObject.clearTimeout(timerId); -}; - - -/** - * @param {number} delay Milliseconds to wait. - * @param {(RESULT|goog.Thenable<RESULT>|Thenable)=} opt_result The value - * with which the promise will be resolved. - * @return {!goog.Promise<RESULT>} A promise that will be resolved after - * the specified delay, unless it is canceled first. - * @template RESULT - */ -goog.Timer.promise = function(delay, opt_result) { - var timerKey = null; - return new goog.Promise(function(resolve, reject) { - timerKey = goog.Timer.callOnce(function() { - resolve(opt_result); - }, delay); - if (timerKey == goog.Timer.INVALID_TIMEOUT_ID_) { - reject(new Error('Failed to schedule timer.')); - } - }).thenCatch(function(error) { - // Clear the timer. The most likely reason is "cancel" signal. - goog.Timer.clear(timerKey); - throw error; - }); -}; - -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview JSON utility functions. - * @author arv@google.com (Erik Arvidsson) - */ - - -goog.provide('goog.json'); -goog.provide('goog.json.Replacer'); -goog.provide('goog.json.Reviver'); -goog.provide('goog.json.Serializer'); - - -/** - * @define {boolean} If true, use the native JSON parsing API. - * NOTE(ruilopes): EXPERIMENTAL, handle with care. Setting this to true might - * break your code. The default {@code goog.json.parse} implementation is able - * to handle invalid JSON, such as JSPB. - */ -goog.define('goog.json.USE_NATIVE_JSON', false); - - -/** - * Tests if a string is an invalid JSON string. This only ensures that we are - * not using any invalid characters - * @param {string} s The string to test. - * @return {boolean} True if the input is a valid JSON string. - */ -goog.json.isValid = function(s) { - // All empty whitespace is not valid. - if (/^\s*$/.test(s)) { - return false; - } - - // This is taken from http://www.json.org/json2.js which is released to the - // public domain. - // Changes: We dissallow \u2028 Line separator and \u2029 Paragraph separator - // inside strings. We also treat \u2028 and \u2029 as whitespace which they - // are in the RFC but IE and Safari does not match \s to these so we need to - // include them in the reg exps in all places where whitespace is allowed. - // We allowed \x7f inside strings because some tools don't escape it, - // e.g. http://www.json.org/java/org/json/JSONObject.java - - // Parsing happens in three stages. In the first stage, we run the text - // against regular expressions that look for non-JSON patterns. We are - // especially concerned with '()' and 'new' because they can cause invocation, - // and '=' because it can cause mutation. But just to be safe, we want to - // reject all unexpected forms. - - // We split the first stage into 4 regexp operations in order to work around - // crippling inefficiencies in IE's and Safari's regexp engines. First we - // replace all backslash pairs with '@' (a non-JSON character). Second, we - // replace all simple value tokens with ']' characters. Third, we delete all - // open brackets that follow a colon or comma or that begin the text. Finally, - // we look to see that the remaining characters are only whitespace or ']' or - // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. - - // Don't make these static since they have the global flag. - var backslashesRe = /\\["\\\/bfnrtu]/g; - var simpleValuesRe = - /"[^"\\\n\r\u2028\u2029\x00-\x08\x0a-\x1f]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g; - var openBracketsRe = /(?:^|:|,)(?:[\s\u2028\u2029]*\[)+/g; - var remainderRe = /^[\],:{}\s\u2028\u2029]*$/; - - return remainderRe.test(s.replace(backslashesRe, '@'). - replace(simpleValuesRe, ']'). - replace(openBracketsRe, '')); -}; - - -/** - * Parses a JSON string and returns the result. This throws an exception if - * the string is an invalid JSON string. - * - * Note that this is very slow on large strings. If you trust the source of - * the string then you should use unsafeParse instead. - * - * @param {*} s The JSON string to parse. - * @throws Error if s is invalid JSON. - * @return {Object} The object generated from the JSON string, or null. - */ -goog.json.parse = goog.json.USE_NATIVE_JSON ? - /** @type {function(*):Object} */ (goog.global['JSON']['parse']) : - function(s) { - var o = String(s); - if (goog.json.isValid(o)) { - /** @preserveTry */ - try { - return /** @type {Object} */ (eval('(' + o + ')')); - } catch (ex) { - } - } - throw Error('Invalid JSON string: ' + o); - }; - - -/** - * Parses a JSON string and returns the result. This uses eval so it is open - * to security issues and it should only be used if you trust the source. - * - * @param {string} s The JSON string to parse. - * @return {Object} The object generated from the JSON string. - */ -goog.json.unsafeParse = goog.json.USE_NATIVE_JSON ? - /** @type {function(string):Object} */ (goog.global['JSON']['parse']) : - function(s) { - return /** @type {Object} */ (eval('(' + s + ')')); - }; - - -/** - * JSON replacer, as defined in Section 15.12.3 of the ES5 spec. - * @see http://ecma-international.org/ecma-262/5.1/#sec-15.12.3 - * - * TODO(nicksantos): Array should also be a valid replacer. - * - * @typedef {function(this:Object, string, *): *} - */ -goog.json.Replacer; - - -/** - * JSON reviver, as defined in Section 15.12.2 of the ES5 spec. - * @see http://ecma-international.org/ecma-262/5.1/#sec-15.12.3 - * - * @typedef {function(this:Object, string, *): *} - */ -goog.json.Reviver; - - -/** - * Serializes an object or a value to a JSON string. - * - * @param {*} object The object to serialize. - * @param {?goog.json.Replacer=} opt_replacer A replacer function - * called for each (key, value) pair that determines how the value - * should be serialized. By defult, this just returns the value - * and allows default serialization to kick in. - * @throws Error if there are loops in the object graph. - * @return {string} A JSON string representation of the input. - */ -goog.json.serialize = goog.json.USE_NATIVE_JSON ? - /** @type {function(*, ?goog.json.Replacer=):string} */ - (goog.global['JSON']['stringify']) : - function(object, opt_replacer) { - // NOTE(nicksantos): Currently, we never use JSON.stringify. - // - // The last time I evaluated this, JSON.stringify had subtle bugs and - // behavior differences on all browsers, and the performance win was not - // large enough to justify all the issues. This may change in the future - // as browser implementations get better. - // - // assertSerialize in json_test contains if branches for the cases - // that fail. - return new goog.json.Serializer(opt_replacer).serialize(object); - }; - - - -/** - * Class that is used to serialize JSON objects to a string. - * @param {?goog.json.Replacer=} opt_replacer Replacer. - * @constructor - */ -goog.json.Serializer = function(opt_replacer) { - /** - * @type {goog.json.Replacer|null|undefined} - * @private - */ - this.replacer_ = opt_replacer; -}; - - -/** - * Serializes an object or a value to a JSON string. - * - * @param {*} object The object to serialize. - * @throws Error if there are loops in the object graph. - * @return {string} A JSON string representation of the input. - */ -goog.json.Serializer.prototype.serialize = function(object) { - var sb = []; - this.serializeInternal(object, sb); - return sb.join(''); -}; - - -/** - * Serializes a generic value to a JSON string - * @protected - * @param {*} object The object to serialize. - * @param {Array<string>} sb Array used as a string builder. - * @throws Error if there are loops in the object graph. - */ -goog.json.Serializer.prototype.serializeInternal = function(object, sb) { - if (object == null) { - // undefined == null so this branch covers undefined as well as null - sb.push('null'); - return; - } - - if (typeof object == 'object') { - if (goog.isArray(object)) { - this.serializeArray(object, sb); - return; - } else if (object instanceof String || - object instanceof Number || - object instanceof Boolean) { - object = object.valueOf(); - // Fall through to switch below. - } else { - this.serializeObject_(/** @type {Object} */ (object), sb); - return; - } - } - - switch (typeof object) { - case 'string': - this.serializeString_(object, sb); - break; - case 'number': - this.serializeNumber_(object, sb); - break; - case 'boolean': - sb.push(object); - break; - case 'function': - sb.push('null'); - break; - default: - throw Error('Unknown type: ' + typeof object); - } -}; - - -/** - * Character mappings used internally for goog.string.quote - * @private - * @type {!Object} - */ -goog.json.Serializer.charToJsonCharCache_ = { - '\"': '\\"', - '\\': '\\\\', - '/': '\\/', - '\b': '\\b', - '\f': '\\f', - '\n': '\\n', - '\r': '\\r', - '\t': '\\t', - - '\x0B': '\\u000b' // '\v' is not supported in JScript -}; - - -/** - * Regular expression used to match characters that need to be replaced. - * The S60 browser has a bug where unicode characters are not matched by - * regular expressions. The condition below detects such behaviour and - * adjusts the regular expression accordingly. - * @private - * @type {!RegExp} - */ -goog.json.Serializer.charsToReplace_ = /\uffff/.test('\uffff') ? - /[\\\"\x00-\x1f\x7f-\uffff]/g : /[\\\"\x00-\x1f\x7f-\xff]/g; - - -/** - * Serializes a string to a JSON string - * @private - * @param {string} s The string to serialize. - * @param {Array<string>} sb Array used as a string builder. - */ -goog.json.Serializer.prototype.serializeString_ = function(s, sb) { - // The official JSON implementation does not work with international - // characters. - sb.push('"', s.replace(goog.json.Serializer.charsToReplace_, function(c) { - // caching the result improves performance by a factor 2-3 - var rv = goog.json.Serializer.charToJsonCharCache_[c]; - if (!rv) { - rv = '\\u' + (c.charCodeAt(0) | 0x10000).toString(16).substr(1); - goog.json.Serializer.charToJsonCharCache_[c] = rv; - } - return rv; - }), '"'); -}; - - -/** - * Serializes a number to a JSON string - * @private - * @param {number} n The number to serialize. - * @param {Array<string>} sb Array used as a string builder. - */ -goog.json.Serializer.prototype.serializeNumber_ = function(n, sb) { - sb.push(isFinite(n) && !isNaN(n) ? n : 'null'); -}; - - -/** - * Serializes an array to a JSON string - * @param {Array<string>} arr The array to serialize. - * @param {Array<string>} sb Array used as a string builder. - * @protected - */ -goog.json.Serializer.prototype.serializeArray = function(arr, sb) { - var l = arr.length; - sb.push('['); - var sep = ''; - for (var i = 0; i < l; i++) { - sb.push(sep); - - var value = arr[i]; - this.serializeInternal( - this.replacer_ ? this.replacer_.call(arr, String(i), value) : value, - sb); - - sep = ','; - } - sb.push(']'); -}; - - -/** - * Serializes an object to a JSON string - * @private - * @param {Object} obj The object to serialize. - * @param {Array<string>} sb Array used as a string builder. - */ -goog.json.Serializer.prototype.serializeObject_ = function(obj, sb) { - sb.push('{'); - var sep = ''; - for (var key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - var value = obj[key]; - // Skip functions. - if (typeof value != 'function') { - sb.push(sep); - this.serializeString_(key, sb); - sb.push(':'); - - this.serializeInternal( - this.replacer_ ? this.replacer_.call(obj, key, value) : value, - sb); - - sep = ','; - } - } - } - sb.push('}'); -}; - -// Copyright 2007 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Error codes shared between goog.net.IframeIo and - * goog.net.XhrIo. - */ - -goog.provide('goog.net.ErrorCode'); - - -/** - * Error codes - * @enum {number} - */ -goog.net.ErrorCode = { - - /** - * There is no error condition. - */ - NO_ERROR: 0, - - /** - * The most common error from iframeio, unfortunately, is that the browser - * responded with an error page that is classed as a different domain. The - * situations, are when a browser error page is shown -- 404, access denied, - * DNS failure, connection reset etc.) - * - */ - ACCESS_DENIED: 1, - - /** - * Currently the only case where file not found will be caused is when the - * code is running on the local file system and a non-IE browser makes a - * request to a file that doesn't exist. - */ - FILE_NOT_FOUND: 2, - - /** - * If Firefox shows a browser error page, such as a connection reset by - * server or access denied, then it will fail silently without the error or - * load handlers firing. - */ - FF_SILENT_ERROR: 3, - - /** - * Custom error provided by the client through the error check hook. - */ - CUSTOM_ERROR: 4, - - /** - * Exception was thrown while processing the request. - */ - EXCEPTION: 5, - - /** - * The Http response returned a non-successful http status code. - */ - HTTP_ERROR: 6, - - /** - * The request was aborted. - */ - ABORT: 7, - - /** - * The request timed out. - */ - TIMEOUT: 8, - - /** - * The resource is not available offline. - */ - OFFLINE: 9 -}; - - -/** - * Returns a friendly error message for an error code. These messages are for - * debugging and are not localized. - * @param {goog.net.ErrorCode} errorCode An error code. - * @return {string} A message for debugging. - */ -goog.net.ErrorCode.getDebugMessage = function(errorCode) { - switch (errorCode) { - case goog.net.ErrorCode.NO_ERROR: - return 'No Error'; - - case goog.net.ErrorCode.ACCESS_DENIED: - return 'Access denied to content document'; - - case goog.net.ErrorCode.FILE_NOT_FOUND: - return 'File not found'; - - case goog.net.ErrorCode.FF_SILENT_ERROR: - return 'Firefox silently errored'; - - case goog.net.ErrorCode.CUSTOM_ERROR: - return 'Application custom error'; - - case goog.net.ErrorCode.EXCEPTION: - return 'An exception occurred'; - - case goog.net.ErrorCode.HTTP_ERROR: - return 'Http response at 400 or 500 level'; - - case goog.net.ErrorCode.ABORT: - return 'Request was aborted'; - - case goog.net.ErrorCode.TIMEOUT: - return 'Request timed out'; - - case goog.net.ErrorCode.OFFLINE: - return 'The resource is not available offline'; - - default: - return 'Unrecognized error code'; - } -}; - -// Copyright 2011 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Constants for HTTP status codes. - */ - -goog.provide('goog.net.HttpStatus'); - - -/** - * HTTP Status Codes defined in RFC 2616 and RFC 6585. - * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html - * @see http://tools.ietf.org/html/rfc6585 - * @enum {number} - */ -goog.net.HttpStatus = { - // Informational 1xx - CONTINUE: 100, - SWITCHING_PROTOCOLS: 101, - - // Successful 2xx - OK: 200, - CREATED: 201, - ACCEPTED: 202, - NON_AUTHORITATIVE_INFORMATION: 203, - NO_CONTENT: 204, - RESET_CONTENT: 205, - PARTIAL_CONTENT: 206, - - // Redirection 3xx - MULTIPLE_CHOICES: 300, - MOVED_PERMANENTLY: 301, - FOUND: 302, - SEE_OTHER: 303, - NOT_MODIFIED: 304, - USE_PROXY: 305, - TEMPORARY_REDIRECT: 307, - - // Client Error 4xx - BAD_REQUEST: 400, - UNAUTHORIZED: 401, - PAYMENT_REQUIRED: 402, - FORBIDDEN: 403, - NOT_FOUND: 404, - METHOD_NOT_ALLOWED: 405, - NOT_ACCEPTABLE: 406, - PROXY_AUTHENTICATION_REQUIRED: 407, - REQUEST_TIMEOUT: 408, - CONFLICT: 409, - GONE: 410, - LENGTH_REQUIRED: 411, - PRECONDITION_FAILED: 412, - REQUEST_ENTITY_TOO_LARGE: 413, - REQUEST_URI_TOO_LONG: 414, - UNSUPPORTED_MEDIA_TYPE: 415, - REQUEST_RANGE_NOT_SATISFIABLE: 416, - EXPECTATION_FAILED: 417, - PRECONDITION_REQUIRED: 428, - TOO_MANY_REQUESTS: 429, - REQUEST_HEADER_FIELDS_TOO_LARGE: 431, - - // Server Error 5xx - INTERNAL_SERVER_ERROR: 500, - NOT_IMPLEMENTED: 501, - BAD_GATEWAY: 502, - SERVICE_UNAVAILABLE: 503, - GATEWAY_TIMEOUT: 504, - HTTP_VERSION_NOT_SUPPORTED: 505, - NETWORK_AUTHENTICATION_REQUIRED: 511, - - /* - * IE returns this code for 204 due to its use of URLMon, which returns this - * code for 'Operation Aborted'. The status text is 'Unknown', the response - * headers are ''. Known to occur on IE 6 on XP through IE9 on Win7. - */ - QUIRK_IE_NO_CONTENT: 1223 -}; - - -/** - * Returns whether the given status should be considered successful. - * - * Successful codes are OK (200), CREATED (201), ACCEPTED (202), - * NO CONTENT (204), PARTIAL CONTENT (206), NOT MODIFIED (304), - * and IE's no content code (1223). - * - * @param {number} status The status code to test. - * @return {boolean} Whether the status code should be considered successful. - */ -goog.net.HttpStatus.isSuccess = function(status) { - switch (status) { - case goog.net.HttpStatus.OK: - case goog.net.HttpStatus.CREATED: - case goog.net.HttpStatus.ACCEPTED: - case goog.net.HttpStatus.NO_CONTENT: - case goog.net.HttpStatus.PARTIAL_CONTENT: - case goog.net.HttpStatus.NOT_MODIFIED: - case goog.net.HttpStatus.QUIRK_IE_NO_CONTENT: - return true; - - default: - return false; - } -}; - -// Copyright 2013 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -goog.provide('goog.net.XhrLike'); - - - -/** - * Interface for the common parts of XMLHttpRequest. - * - * Mostly copied from externs/w3c_xml.js. - * - * @interface - * @see http://www.w3.org/TR/XMLHttpRequest/ - */ -goog.net.XhrLike = function() {}; - - -/** - * Typedef that refers to either native or custom-implemented XHR objects. - * @typedef {!goog.net.XhrLike|!XMLHttpRequest} - */ -goog.net.XhrLike.OrNative; - - -/** - * @type {function()|null|undefined} - * @see http://www.w3.org/TR/XMLHttpRequest/#handler-xhr-onreadystatechange - */ -goog.net.XhrLike.prototype.onreadystatechange; - - -/** - * @type {string} - * @see http://www.w3.org/TR/XMLHttpRequest/#the-responsetext-attribute - */ -goog.net.XhrLike.prototype.responseText; - - -/** - * @type {Document} - * @see http://www.w3.org/TR/XMLHttpRequest/#the-responsexml-attribute - */ -goog.net.XhrLike.prototype.responseXML; - - -/** - * @type {number} - * @see http://www.w3.org/TR/XMLHttpRequest/#readystate - */ -goog.net.XhrLike.prototype.readyState; - - -/** - * @type {number} - * @see http://www.w3.org/TR/XMLHttpRequest/#status - */ -goog.net.XhrLike.prototype.status; - - -/** - * @type {string} - * @see http://www.w3.org/TR/XMLHttpRequest/#statustext - */ -goog.net.XhrLike.prototype.statusText; - - -/** - * @param {string} method - * @param {string} url - * @param {?boolean=} opt_async - * @param {?string=} opt_user - * @param {?string=} opt_password - * @see http://www.w3.org/TR/XMLHttpRequest/#the-open()-method - */ -goog.net.XhrLike.prototype.open = function(method, url, opt_async, opt_user, - opt_password) {}; - - -/** - * @param {ArrayBuffer|ArrayBufferView|Blob|Document|FormData|string=} opt_data - * @see http://www.w3.org/TR/XMLHttpRequest/#the-send()-method - */ -goog.net.XhrLike.prototype.send = function(opt_data) {}; - - -/** - * @see http://www.w3.org/TR/XMLHttpRequest/#the-abort()-method - */ -goog.net.XhrLike.prototype.abort = function() {}; - - -/** - * @param {string} header - * @param {string} value - * @see http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method - */ -goog.net.XhrLike.prototype.setRequestHeader = function(header, value) {}; - - -/** - * @param {string} header - * @return {string} - * @see http://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method - */ -goog.net.XhrLike.prototype.getResponseHeader = function(header) {}; - - -/** - * @return {string} - * @see http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method - */ -goog.net.XhrLike.prototype.getAllResponseHeaders = function() {}; - -// Copyright 2010 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Interface for a factory for creating XMLHttpRequest objects - * and metadata about them. - * @author dbk@google.com (David Barrett-Kahn) - */ - -goog.provide('goog.net.XmlHttpFactory'); - -/** @suppress {extraRequire} Typedef. */ -goog.require('goog.net.XhrLike'); - - - -/** - * Abstract base class for an XmlHttpRequest factory. - * @constructor - */ -goog.net.XmlHttpFactory = function() { -}; - - -/** - * Cache of options - we only actually call internalGetOptions once. - * @type {Object} - * @private - */ -goog.net.XmlHttpFactory.prototype.cachedOptions_ = null; - - -/** - * @return {!goog.net.XhrLike.OrNative} A new XhrLike instance. - */ -goog.net.XmlHttpFactory.prototype.createInstance = goog.abstractMethod; - - -/** - * @return {Object} Options describing how xhr objects obtained from this - * factory should be used. - */ -goog.net.XmlHttpFactory.prototype.getOptions = function() { - return this.cachedOptions_ || - (this.cachedOptions_ = this.internalGetOptions()); -}; - - -/** - * Override this method in subclasses to preserve the caching offered by - * getOptions(). - * @return {Object} Options describing how xhr objects obtained from this - * factory should be used. - * @protected - */ -goog.net.XmlHttpFactory.prototype.internalGetOptions = goog.abstractMethod; - -// Copyright 2010 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Implementation of XmlHttpFactory which allows construction from - * simple factory methods. - * @author dbk@google.com (David Barrett-Kahn) - */ - -goog.provide('goog.net.WrapperXmlHttpFactory'); - -/** @suppress {extraRequire} Typedef. */ -goog.require('goog.net.XhrLike'); -goog.require('goog.net.XmlHttpFactory'); - - - -/** - * An xhr factory subclass which can be constructed using two factory methods. - * This exists partly to allow the preservation of goog.net.XmlHttp.setFactory() - * with an unchanged signature. - * @param {function():!goog.net.XhrLike.OrNative} xhrFactory - * A function which returns a new XHR object. - * @param {function():!Object} optionsFactory A function which returns the - * options associated with xhr objects from this factory. - * @extends {goog.net.XmlHttpFactory} - * @constructor - * @final - */ -goog.net.WrapperXmlHttpFactory = function(xhrFactory, optionsFactory) { - goog.net.XmlHttpFactory.call(this); - - /** - * XHR factory method. - * @type {function() : !goog.net.XhrLike.OrNative} - * @private - */ - this.xhrFactory_ = xhrFactory; - - /** - * Options factory method. - * @type {function() : !Object} - * @private - */ - this.optionsFactory_ = optionsFactory; -}; -goog.inherits(goog.net.WrapperXmlHttpFactory, goog.net.XmlHttpFactory); - - -/** @override */ -goog.net.WrapperXmlHttpFactory.prototype.createInstance = function() { - return this.xhrFactory_(); -}; - - -/** @override */ -goog.net.WrapperXmlHttpFactory.prototype.getOptions = function() { - return this.optionsFactory_(); -}; - - -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Low level handling of XMLHttpRequest. - * @author arv@google.com (Erik Arvidsson) - * @author dbk@google.com (David Barrett-Kahn) - */ - -goog.provide('goog.net.DefaultXmlHttpFactory'); -goog.provide('goog.net.XmlHttp'); -goog.provide('goog.net.XmlHttp.OptionType'); -goog.provide('goog.net.XmlHttp.ReadyState'); -goog.provide('goog.net.XmlHttpDefines'); - -goog.require('goog.asserts'); -goog.require('goog.net.WrapperXmlHttpFactory'); -goog.require('goog.net.XmlHttpFactory'); - - -/** - * Static class for creating XMLHttpRequest objects. - * @return {!goog.net.XhrLike.OrNative} A new XMLHttpRequest object. - */ -goog.net.XmlHttp = function() { - return goog.net.XmlHttp.factory_.createInstance(); -}; - - -/** - * @define {boolean} Whether to assume XMLHttpRequest exists. Setting this to - * true bypasses the ActiveX probing code. - * NOTE(ruilopes): Due to the way JSCompiler works, this define *will not* strip - * out the ActiveX probing code from binaries. To achieve this, use - * {@code goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR} instead. - * TODO(ruilopes): Collapse both defines. - */ -goog.define('goog.net.XmlHttp.ASSUME_NATIVE_XHR', false); - - -/** @const */ -goog.net.XmlHttpDefines = {}; - - -/** - * @define {boolean} Whether to assume XMLHttpRequest exists. Setting this to - * true eliminates the ActiveX probing code. - */ -goog.define('goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR', false); - - -/** - * Gets the options to use with the XMLHttpRequest objects obtained using - * the static methods. - * @return {Object} The options. - */ -goog.net.XmlHttp.getOptions = function() { - return goog.net.XmlHttp.factory_.getOptions(); -}; - - -/** - * Type of options that an XmlHttp object can have. - * @enum {number} - */ -goog.net.XmlHttp.OptionType = { - /** - * Whether a goog.nullFunction should be used to clear the onreadystatechange - * handler instead of null. - */ - USE_NULL_FUNCTION: 0, - - /** - * NOTE(user): In IE if send() errors on a *local* request the readystate - * is still changed to COMPLETE. We need to ignore it and allow the - * try/catch around send() to pick up the error. - */ - LOCAL_REQUEST_ERROR: 1 -}; - - -/** - * Status constants for XMLHTTP, matches: - * http://msdn.microsoft.com/library/default.asp?url=/library/ - * en-us/xmlsdk/html/0e6a34e4-f90c-489d-acff-cb44242fafc6.asp - * @enum {number} - */ -goog.net.XmlHttp.ReadyState = { - /** - * Constant for when xmlhttprequest.readyState is uninitialized - */ - UNINITIALIZED: 0, - - /** - * Constant for when xmlhttprequest.readyState is loading. - */ - LOADING: 1, - - /** - * Constant for when xmlhttprequest.readyState is loaded. - */ - LOADED: 2, - - /** - * Constant for when xmlhttprequest.readyState is in an interactive state. - */ - INTERACTIVE: 3, - - /** - * Constant for when xmlhttprequest.readyState is completed - */ - COMPLETE: 4 -}; - - -/** - * The global factory instance for creating XMLHttpRequest objects. - * @type {goog.net.XmlHttpFactory} - * @private - */ -goog.net.XmlHttp.factory_; - - -/** - * Sets the factories for creating XMLHttpRequest objects and their options. - * @param {Function} factory The factory for XMLHttpRequest objects. - * @param {Function} optionsFactory The factory for options. - * @deprecated Use setGlobalFactory instead. - */ -goog.net.XmlHttp.setFactory = function(factory, optionsFactory) { - goog.net.XmlHttp.setGlobalFactory(new goog.net.WrapperXmlHttpFactory( - goog.asserts.assert(factory), - goog.asserts.assert(optionsFactory))); -}; - - -/** - * Sets the global factory object. - * @param {!goog.net.XmlHttpFactory} factory New global factory object. - */ -goog.net.XmlHttp.setGlobalFactory = function(factory) { - goog.net.XmlHttp.factory_ = factory; -}; - - - -/** - * Default factory to use when creating xhr objects. You probably shouldn't be - * instantiating this directly, but rather using it via goog.net.XmlHttp. - * @extends {goog.net.XmlHttpFactory} - * @constructor - */ -goog.net.DefaultXmlHttpFactory = function() { - goog.net.XmlHttpFactory.call(this); -}; -goog.inherits(goog.net.DefaultXmlHttpFactory, goog.net.XmlHttpFactory); - - -/** @override */ -goog.net.DefaultXmlHttpFactory.prototype.createInstance = function() { - var progId = this.getProgId_(); - if (progId) { - return new ActiveXObject(progId); - } else { - return new XMLHttpRequest(); - } -}; - - -/** @override */ -goog.net.DefaultXmlHttpFactory.prototype.internalGetOptions = function() { - var progId = this.getProgId_(); - var options = {}; - if (progId) { - options[goog.net.XmlHttp.OptionType.USE_NULL_FUNCTION] = true; - options[goog.net.XmlHttp.OptionType.LOCAL_REQUEST_ERROR] = true; - } - return options; -}; - - -/** - * The ActiveX PROG ID string to use to create xhr's in IE. Lazily initialized. - * @type {string|undefined} - * @private - */ -goog.net.DefaultXmlHttpFactory.prototype.ieProgId_; - - -/** - * Initialize the private state used by other functions. - * @return {string} The ActiveX PROG ID string to use to create xhr's in IE. - * @private - */ -goog.net.DefaultXmlHttpFactory.prototype.getProgId_ = function() { - if (goog.net.XmlHttp.ASSUME_NATIVE_XHR || - goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR) { - return ''; - } - - // The following blog post describes what PROG IDs to use to create the - // XMLHTTP object in Internet Explorer: - // http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx - // However we do not (yet) fully trust that this will be OK for old versions - // of IE on Win9x so we therefore keep the last 2. - if (!this.ieProgId_ && typeof XMLHttpRequest == 'undefined' && - typeof ActiveXObject != 'undefined') { - // Candidate Active X types. - var ACTIVE_X_IDENTS = ['MSXML2.XMLHTTP.6.0', 'MSXML2.XMLHTTP.3.0', - 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP']; - for (var i = 0; i < ACTIVE_X_IDENTS.length; i++) { - var candidate = ACTIVE_X_IDENTS[i]; - /** @preserveTry */ - try { - new ActiveXObject(candidate); - // NOTE(user): cannot assign progid and return candidate in one line - // because JSCompiler complaings: BUG 658126 - this.ieProgId_ = candidate; - return candidate; - } catch (e) { - // do nothing; try next choice - } - } - - // couldn't find any matches - throw Error('Could not create ActiveXObject. ActiveX might be disabled,' + - ' or MSXML might not be installed'); - } - - return /** @type {string} */ (this.ieProgId_); -}; - - -//Set the global factory to an instance of the default factory. -goog.net.XmlHttp.setGlobalFactory(new goog.net.DefaultXmlHttpFactory()); - -// Copyright 2008 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Simple utilities for dealing with URI strings. - * - * This is intended to be a lightweight alternative to constructing goog.Uri - * objects. Whereas goog.Uri adds several kilobytes to the binary regardless - * of how much of its functionality you use, this is designed to be a set of - * mostly-independent utilities so that the compiler includes only what is - * necessary for the task. Estimated savings of porting is 5k pre-gzip and - * 1.5k post-gzip. To ensure the savings remain, future developers should - * avoid adding new functionality to existing functions, but instead create - * new ones and factor out shared code. - * - * Many of these utilities have limited functionality, tailored to common - * cases. The query parameter utilities assume that the parameter keys are - * already encoded, since most keys are compile-time alphanumeric strings. The - * query parameter mutation utilities also do not tolerate fragment identifiers. - * - * By design, these functions can be slower than goog.Uri equivalents. - * Repeated calls to some of functions may be quadratic in behavior for IE, - * although the effect is somewhat limited given the 2kb limit. - * - * One advantage of the limited functionality here is that this approach is - * less sensitive to differences in URI encodings than goog.Uri, since these - * functions operate on strings directly, rather than decoding them and - * then re-encoding. - * - * Uses features of RFC 3986 for parsing/formatting URIs: - * http://www.ietf.org/rfc/rfc3986.txt - * - * @author gboyer@google.com (Garrett Boyer) - The "lightened" design. - */ - -goog.provide('goog.uri.utils'); -goog.provide('goog.uri.utils.ComponentIndex'); -goog.provide('goog.uri.utils.QueryArray'); -goog.provide('goog.uri.utils.QueryValue'); -goog.provide('goog.uri.utils.StandardQueryParam'); - -goog.require('goog.asserts'); -goog.require('goog.string'); - - -/** - * Character codes inlined to avoid object allocations due to charCode. - * @enum {number} - * @private - */ -goog.uri.utils.CharCode_ = { - AMPERSAND: 38, - EQUAL: 61, - HASH: 35, - QUESTION: 63 -}; - - -/** - * Builds a URI string from already-encoded parts. - * - * No encoding is performed. Any component may be omitted as either null or - * undefined. - * - * @param {?string=} opt_scheme The scheme such as 'http'. - * @param {?string=} opt_userInfo The user name before the '@'. - * @param {?string=} opt_domain The domain such as 'www.google.com', already - * URI-encoded. - * @param {(string|number|null)=} opt_port The port number. - * @param {?string=} opt_path The path, already URI-encoded. If it is not - * empty, it must begin with a slash. - * @param {?string=} opt_queryData The URI-encoded query data. - * @param {?string=} opt_fragment The URI-encoded fragment identifier. - * @return {string} The fully combined URI. - */ -goog.uri.utils.buildFromEncodedParts = function(opt_scheme, opt_userInfo, - opt_domain, opt_port, opt_path, opt_queryData, opt_fragment) { - var out = ''; - - if (opt_scheme) { - out += opt_scheme + ':'; - } - - if (opt_domain) { - out += '//'; - - if (opt_userInfo) { - out += opt_userInfo + '@'; - } - - out += opt_domain; - - if (opt_port) { - out += ':' + opt_port; - } - } - - if (opt_path) { - out += opt_path; - } - - if (opt_queryData) { - out += '?' + opt_queryData; - } - - if (opt_fragment) { - out += '#' + opt_fragment; - } - - return out; -}; - - -/** - * A regular expression for breaking a URI into its component parts. - * - * {@link http://www.ietf.org/rfc/rfc3986.txt} says in Appendix B - * As the "first-match-wins" algorithm is identical to the "greedy" - * disambiguation method used by POSIX regular expressions, it is natural and - * commonplace to use a regular expression for parsing the potential five - * components of a URI reference. - * - * The following line is the regular expression for breaking-down a - * well-formed URI reference into its components. - * - * <pre> - * ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? - * 12 3 4 5 6 7 8 9 - * </pre> - * - * The numbers in the second line above are only to assist readability; they - * indicate the reference points for each subexpression (i.e., each paired - * parenthesis). We refer to the value matched for subexpression <n> as $<n>. - * For example, matching the above expression to - * <pre> - * http://www.ics.uci.edu/pub/ietf/uri/#Related - * </pre> - * results in the following subexpression matches: - * <pre> - * $1 = http: - * $2 = http - * $3 = //www.ics.uci.edu - * $4 = www.ics.uci.edu - * $5 = /pub/ietf/uri/ - * $6 = <undefined> - * $7 = <undefined> - * $8 = #Related - * $9 = Related - * </pre> - * where <undefined> indicates that the component is not present, as is the - * case for the query component in the above example. Therefore, we can - * determine the value of the five components as - * <pre> - * scheme = $2 - * authority = $4 - * path = $5 - * query = $7 - * fragment = $9 - * </pre> - * - * The regular expression has been modified slightly to expose the - * userInfo, domain, and port separately from the authority. - * The modified version yields - * <pre> - * $1 = http scheme - * $2 = <undefined> userInfo -\ - * $3 = www.ics.uci.edu domain | authority - * $4 = <undefined> port -/ - * $5 = /pub/ietf/uri/ path - * $6 = <undefined> query without ? - * $7 = Related fragment without # - * </pre> - * @type {!RegExp} - * @private - */ -goog.uri.utils.splitRe_ = new RegExp( - '^' + - '(?:' + - '([^:/?#.]+)' + // scheme - ignore special characters - // used by other URL parts such as :, - // ?, /, #, and . - ':)?' + - '(?://' + - '(?:([^/?#]*)@)?' + // userInfo - '([^/#?]*?)' + // domain - '(?::([0-9]+))?' + // port - '(?=[/#?]|$)' + // authority-terminating character - ')?' + - '([^?#]+)?' + // path - '(?:\\?([^#]*))?' + // query - '(?:#(.*))?' + // fragment - '$'); - - -/** - * The index of each URI component in the return value of goog.uri.utils.split. - * @enum {number} - */ -goog.uri.utils.ComponentIndex = { - SCHEME: 1, - USER_INFO: 2, - DOMAIN: 3, - PORT: 4, - PATH: 5, - QUERY_DATA: 6, - FRAGMENT: 7 -}; - - -/** - * Splits a URI into its component parts. - * - * Each component can be accessed via the component indices; for example: - * <pre> - * goog.uri.utils.split(someStr)[goog.uri.utils.CompontentIndex.QUERY_DATA]; - * </pre> - * - * @param {string} uri The URI string to examine. - * @return {!Array<string|undefined>} Each component still URI-encoded. - * Each component that is present will contain the encoded value, whereas - * components that are not present will be undefined or empty, depending - * on the browser's regular expression implementation. Never null, since - * arbitrary strings may still look like path names. - */ -goog.uri.utils.split = function(uri) { - // See @return comment -- never null. - return /** @type {!Array<string|undefined>} */ ( - uri.match(goog.uri.utils.splitRe_)); -}; - - -/** - * @param {?string} uri A possibly null string. - * @param {boolean=} opt_preserveReserved If true, percent-encoding of RFC-3986 - * reserved characters will not be removed. - * @return {?string} The string URI-decoded, or null if uri is null. - * @private - */ -goog.uri.utils.decodeIfPossible_ = function(uri, opt_preserveReserved) { - if (!uri) { - return uri; - } - - return opt_preserveReserved ? decodeURI(uri) : decodeURIComponent(uri); -}; - - -/** - * Gets a URI component by index. - * - * It is preferred to use the getPathEncoded() variety of functions ahead, - * since they are more readable. - * - * @param {goog.uri.utils.ComponentIndex} componentIndex The component index. - * @param {string} uri The URI to examine. - * @return {?string} The still-encoded component, or null if the component - * is not present. - * @private - */ -goog.uri.utils.getComponentByIndex_ = function(componentIndex, uri) { - // Convert undefined, null, and empty string into null. - return goog.uri.utils.split(uri)[componentIndex] || null; -}; - - -/** - * @param {string} uri The URI to examine. - * @return {?string} The protocol or scheme, or null if none. Does not - * include trailing colons or slashes. - */ -goog.uri.utils.getScheme = function(uri) { - return goog.uri.utils.getComponentByIndex_( - goog.uri.utils.ComponentIndex.SCHEME, uri); -}; - - -/** - * Gets the effective scheme for the URL. If the URL is relative then the - * scheme is derived from the page's location. - * @param {string} uri The URI to examine. - * @return {string} The protocol or scheme, always lower case. - */ -goog.uri.utils.getEffectiveScheme = function(uri) { - var scheme = goog.uri.utils.getScheme(uri); - if (!scheme && goog.global.self && goog.global.self.location) { - var protocol = goog.global.self.location.protocol; - scheme = protocol.substr(0, protocol.length - 1); - } - // NOTE: When called from a web worker in Firefox 3.5, location maybe null. - // All other browsers with web workers support self.location from the worker. - return scheme ? scheme.toLowerCase() : ''; -}; - - -/** - * @param {string} uri The URI to examine. - * @return {?string} The user name still encoded, or null if none. - */ -goog.uri.utils.getUserInfoEncoded = function(uri) { - return goog.uri.utils.getComponentByIndex_( - goog.uri.utils.ComponentIndex.USER_INFO, uri); -}; - - -/** - * @param {string} uri The URI to examine. - * @return {?string} The decoded user info, or null if none. - */ -goog.uri.utils.getUserInfo = function(uri) { - return goog.uri.utils.decodeIfPossible_( - goog.uri.utils.getUserInfoEncoded(uri)); -}; - - -/** - * @param {string} uri The URI to examine. - * @return {?string} The domain name still encoded, or null if none. - */ -goog.uri.utils.getDomainEncoded = function(uri) { - return goog.uri.utils.getComponentByIndex_( - goog.uri.utils.ComponentIndex.DOMAIN, uri); -}; - - -/** - * @param {string} uri The URI to examine. - * @return {?string} The decoded domain, or null if none. - */ -goog.uri.utils.getDomain = function(uri) { - return goog.uri.utils.decodeIfPossible_( - goog.uri.utils.getDomainEncoded(uri), true /* opt_preserveReserved */); -}; - - -/** - * @param {string} uri The URI to examine. - * @return {?number} The port number, or null if none. - */ -goog.uri.utils.getPort = function(uri) { - // Coerce to a number. If the result of getComponentByIndex_ is null or - // non-numeric, the number coersion yields NaN. This will then return - // null for all non-numeric cases (though also zero, which isn't a relevant - // port number). - return Number(goog.uri.utils.getComponentByIndex_( - goog.uri.utils.ComponentIndex.PORT, uri)) || null; -}; - - -/** - * @param {string} uri The URI to examine. - * @return {?string} The path still encoded, or null if none. Includes the - * leading slash, if any. - */ -goog.uri.utils.getPathEncoded = function(uri) { - return goog.uri.utils.getComponentByIndex_( - goog.uri.utils.ComponentIndex.PATH, uri); -}; - - -/** - * @param {string} uri The URI to examine. - * @return {?string} The decoded path, or null if none. Includes the leading - * slash, if any. - */ -goog.uri.utils.getPath = function(uri) { - return goog.uri.utils.decodeIfPossible_( - goog.uri.utils.getPathEncoded(uri), true /* opt_preserveReserved */); -}; - - -/** - * @param {string} uri The URI to examine. - * @return {?string} The query data still encoded, or null if none. Does not - * include the question mark itself. - */ -goog.uri.utils.getQueryData = function(uri) { - return goog.uri.utils.getComponentByIndex_( - goog.uri.utils.ComponentIndex.QUERY_DATA, uri); -}; - - -/** - * @param {string} uri The URI to examine. - * @return {?string} The fragment identifier, or null if none. Does not - * include the hash mark itself. - */ -goog.uri.utils.getFragmentEncoded = function(uri) { - // The hash mark may not appear in any other part of the URL. - var hashIndex = uri.indexOf('#'); - return hashIndex < 0 ? null : uri.substr(hashIndex + 1); -}; - - -/** - * @param {string} uri The URI to examine. - * @param {?string} fragment The encoded fragment identifier, or null if none. - * Does not include the hash mark itself. - * @return {string} The URI with the fragment set. - */ -goog.uri.utils.setFragmentEncoded = function(uri, fragment) { - return goog.uri.utils.removeFragment(uri) + (fragment ? '#' + fragment : ''); -}; - - -/** - * @param {string} uri The URI to examine. - * @return {?string} The decoded fragment identifier, or null if none. Does - * not include the hash mark. - */ -goog.uri.utils.getFragment = function(uri) { - return goog.uri.utils.decodeIfPossible_( - goog.uri.utils.getFragmentEncoded(uri)); -}; - - -/** - * Extracts everything up to the port of the URI. - * @param {string} uri The URI string. - * @return {string} Everything up to and including the port. - */ -goog.uri.utils.getHost = function(uri) { - var pieces = goog.uri.utils.split(uri); - return goog.uri.utils.buildFromEncodedParts( - pieces[goog.uri.utils.ComponentIndex.SCHEME], - pieces[goog.uri.utils.ComponentIndex.USER_INFO], - pieces[goog.uri.utils.ComponentIndex.DOMAIN], - pieces[goog.uri.utils.ComponentIndex.PORT]); -}; - - -/** - * Extracts the path of the URL and everything after. - * @param {string} uri The URI string. - * @return {string} The URI, starting at the path and including the query - * parameters and fragment identifier. - */ -goog.uri.utils.getPathAndAfter = function(uri) { - var pieces = goog.uri.utils.split(uri); - return goog.uri.utils.buildFromEncodedParts(null, null, null, null, - pieces[goog.uri.utils.ComponentIndex.PATH], - pieces[goog.uri.utils.ComponentIndex.QUERY_DATA], - pieces[goog.uri.utils.ComponentIndex.FRAGMENT]); -}; - - -/** - * Gets the URI with the fragment identifier removed. - * @param {string} uri The URI to examine. - * @return {string} Everything preceding the hash mark. - */ -goog.uri.utils.removeFragment = function(uri) { - // The hash mark may not appear in any other part of the URL. - var hashIndex = uri.indexOf('#'); - return hashIndex < 0 ? uri : uri.substr(0, hashIndex); -}; - - -/** - * Ensures that two URI's have the exact same domain, scheme, and port. - * - * Unlike the version in goog.Uri, this checks protocol, and therefore is - * suitable for checking against the browser's same-origin policy. - * - * @param {string} uri1 The first URI. - * @param {string} uri2 The second URI. - * @return {boolean} Whether they have the same scheme, domain and port. - */ -goog.uri.utils.haveSameDomain = function(uri1, uri2) { - var pieces1 = goog.uri.utils.split(uri1); - var pieces2 = goog.uri.utils.split(uri2); - return pieces1[goog.uri.utils.ComponentIndex.DOMAIN] == - pieces2[goog.uri.utils.ComponentIndex.DOMAIN] && - pieces1[goog.uri.utils.ComponentIndex.SCHEME] == - pieces2[goog.uri.utils.ComponentIndex.SCHEME] && - pieces1[goog.uri.utils.ComponentIndex.PORT] == - pieces2[goog.uri.utils.ComponentIndex.PORT]; -}; - - -/** - * Asserts that there are no fragment or query identifiers, only in uncompiled - * mode. - * @param {string} uri The URI to examine. - * @private - */ -goog.uri.utils.assertNoFragmentsOrQueries_ = function(uri) { - // NOTE: would use goog.asserts here, but jscompiler doesn't know that - // indexOf has no side effects. - if (goog.DEBUG && (uri.indexOf('#') >= 0 || uri.indexOf('?') >= 0)) { - throw Error('goog.uri.utils: Fragment or query identifiers are not ' + - 'supported: [' + uri + ']'); - } -}; - - -/** - * Supported query parameter values by the parameter serializing utilities. - * - * If a value is null or undefined, the key-value pair is skipped, as an easy - * way to omit parameters conditionally. Non-array parameters are converted - * to a string and URI encoded. Array values are expanded into multiple - * &key=value pairs, with each element stringized and URI-encoded. - * - * @typedef {*} - */ -goog.uri.utils.QueryValue; - - -/** - * An array representing a set of query parameters with alternating keys - * and values. - * - * Keys are assumed to be URI encoded already and live at even indices. See - * goog.uri.utils.QueryValue for details on how parameter values are encoded. - * - * Example: - * <pre> - * var data = [ - * // Simple param: ?name=BobBarker - * 'name', 'BobBarker', - * // Conditional param -- may be omitted entirely. - * 'specialDietaryNeeds', hasDietaryNeeds() ? getDietaryNeeds() : null, - * // Multi-valued param: &house=LosAngeles&house=NewYork&house=null - * 'house', ['LosAngeles', 'NewYork', null] - * ]; - * </pre> - * - * @typedef {!Array<string|goog.uri.utils.QueryValue>} - */ -goog.uri.utils.QueryArray; - - -/** - * Parses encoded query parameters and calls callback function for every - * parameter found in the string. - * - * Missing value of parameter (e.g. “…&key&…”) is treated as if the value was an - * empty string. Keys may be empty strings (e.g. “…&=value&…”) which also means - * that “…&=&…” and “…&&…” will result in an empty key and value. - * - * @param {string} encodedQuery Encoded query string excluding question mark at - * the beginning. - * @param {function(string, string)} callback Function called for every - * parameter found in query string. The first argument (name) will not be - * urldecoded (so the function is consistent with buildQueryData), but the - * second will. If the parameter has no value (i.e. “=” was not present) - * the second argument (value) will be an empty string. - */ -goog.uri.utils.parseQueryData = function(encodedQuery, callback) { - if (!encodedQuery) { - return; - } - var pairs = encodedQuery.split('&'); - for (var i = 0; i < pairs.length; i++) { - var indexOfEquals = pairs[i].indexOf('='); - var name = null; - var value = null; - if (indexOfEquals >= 0) { - name = pairs[i].substring(0, indexOfEquals); - value = pairs[i].substring(indexOfEquals + 1); - } else { - name = pairs[i]; - } - callback(name, value ? goog.string.urlDecode(value) : ''); - } -}; - - -/** - * Appends a URI and query data in a string buffer with special preconditions. - * - * Internal implementation utility, performing very few object allocations. - * - * @param {!Array<string|undefined>} buffer A string buffer. The first element - * must be the base URI, and may have a fragment identifier. If the array - * contains more than one element, the second element must be an ampersand, - * and may be overwritten, depending on the base URI. Undefined elements - * are treated as empty-string. - * @return {string} The concatenated URI and query data. - * @private - */ -goog.uri.utils.appendQueryData_ = function(buffer) { - if (buffer[1]) { - // At least one query parameter was added. We need to check the - // punctuation mark, which is currently an ampersand, and also make sure - // there aren't any interfering fragment identifiers. - var baseUri = /** @type {string} */ (buffer[0]); - var hashIndex = baseUri.indexOf('#'); - if (hashIndex >= 0) { - // Move the fragment off the base part of the URI into the end. - buffer.push(baseUri.substr(hashIndex)); - buffer[0] = baseUri = baseUri.substr(0, hashIndex); - } - var questionIndex = baseUri.indexOf('?'); - if (questionIndex < 0) { - // No question mark, so we need a question mark instead of an ampersand. - buffer[1] = '?'; - } else if (questionIndex == baseUri.length - 1) { - // Question mark is the very last character of the existing URI, so don't - // append an additional delimiter. - buffer[1] = undefined; - } - } - - return buffer.join(''); -}; - - -/** - * Appends key=value pairs to an array, supporting multi-valued objects. - * @param {string} key The key prefix. - * @param {goog.uri.utils.QueryValue} value The value to serialize. - * @param {!Array<string>} pairs The array to which the 'key=value' strings - * should be appended. - * @private - */ -goog.uri.utils.appendKeyValuePairs_ = function(key, value, pairs) { - if (goog.isArray(value)) { - // Convince the compiler it's an array. - goog.asserts.assertArray(value); - for (var j = 0; j < value.length; j++) { - // Convert to string explicitly, to short circuit the null and array - // logic in this function -- this ensures that null and undefined get - // written as literal 'null' and 'undefined', and arrays don't get - // expanded out but instead encoded in the default way. - goog.uri.utils.appendKeyValuePairs_(key, String(value[j]), pairs); - } - } else if (value != null) { - // Skip a top-level null or undefined entirely. - pairs.push('&', key, - // Check for empty string. Zero gets encoded into the url as literal - // strings. For empty string, skip the equal sign, to be consistent - // with UriBuilder.java. - value === '' ? '' : '=', - goog.string.urlEncode(value)); - } -}; - - -/** - * Builds a buffer of query data from a sequence of alternating keys and values. - * - * @param {!Array<string|undefined>} buffer A string buffer to append to. The - * first element appended will be an '&', and may be replaced by the caller. - * @param {!goog.uri.utils.QueryArray|!Arguments} keysAndValues An array with - * alternating keys and values -- see the typedef. - * @param {number=} opt_startIndex A start offset into the arary, defaults to 0. - * @return {!Array<string|undefined>} The buffer argument. - * @private - */ -goog.uri.utils.buildQueryDataBuffer_ = function( - buffer, keysAndValues, opt_startIndex) { - goog.asserts.assert(Math.max(keysAndValues.length - (opt_startIndex || 0), - 0) % 2 == 0, 'goog.uri.utils: Key/value lists must be even in length.'); - - for (var i = opt_startIndex || 0; i < keysAndValues.length; i += 2) { - goog.uri.utils.appendKeyValuePairs_( - keysAndValues[i], keysAndValues[i + 1], buffer); - } - - return buffer; -}; - - -/** - * Builds a query data string from a sequence of alternating keys and values. - * Currently generates "&key&" for empty args. - * - * @param {goog.uri.utils.QueryArray} keysAndValues Alternating keys and - * values. See the typedef. - * @param {number=} opt_startIndex A start offset into the arary, defaults to 0. - * @return {string} The encoded query string, in the form 'a=1&b=2'. - */ -goog.uri.utils.buildQueryData = function(keysAndValues, opt_startIndex) { - var buffer = goog.uri.utils.buildQueryDataBuffer_( - [], keysAndValues, opt_startIndex); - buffer[0] = ''; // Remove the leading ampersand. - return buffer.join(''); -}; - - -/** - * Builds a buffer of query data from a map. - * - * @param {!Array<string|undefined>} buffer A string buffer to append to. The - * first element appended will be an '&', and may be replaced by the caller. - * @param {!Object<string, goog.uri.utils.QueryValue>} map An object where keys - * are URI-encoded parameter keys, and the values conform to the contract - * specified in the goog.uri.utils.QueryValue typedef. - * @return {!Array<string|undefined>} The buffer argument. - * @private - */ -goog.uri.utils.buildQueryDataBufferFromMap_ = function(buffer, map) { - for (var key in map) { - goog.uri.utils.appendKeyValuePairs_(key, map[key], buffer); - } - - return buffer; -}; - - -/** - * Builds a query data string from a map. - * Currently generates "&key&" for empty args. - * - * @param {!Object<string, goog.uri.utils.QueryValue>} map An object where keys - * are URI-encoded parameter keys, and the values are arbitrary types - * or arrays. Keys with a null value are dropped. - * @return {string} The encoded query string, in the form 'a=1&b=2'. - */ -goog.uri.utils.buildQueryDataFromMap = function(map) { - var buffer = goog.uri.utils.buildQueryDataBufferFromMap_([], map); - buffer[0] = ''; - return buffer.join(''); -}; - - -/** - * Appends URI parameters to an existing URI. - * - * The variable arguments may contain alternating keys and values. Keys are - * assumed to be already URI encoded. The values should not be URI-encoded, - * and will instead be encoded by this function. - * <pre> - * appendParams('http://www.foo.com?existing=true', - * 'key1', 'value1', - * 'key2', 'value?willBeEncoded', - * 'key3', ['valueA', 'valueB', 'valueC'], - * 'key4', null); - * result: 'http://www.foo.com?existing=true&' + - * 'key1=value1&' + - * 'key2=value%3FwillBeEncoded&' + - * 'key3=valueA&key3=valueB&key3=valueC' - * </pre> - * - * A single call to this function will not exhibit quadratic behavior in IE, - * whereas multiple repeated calls may, although the effect is limited by - * fact that URL's generally can't exceed 2kb. - * - * @param {string} uri The original URI, which may already have query data. - * @param {...(goog.uri.utils.QueryArray|string|goog.uri.utils.QueryValue)} var_args - * An array or argument list conforming to goog.uri.utils.QueryArray. - * @return {string} The URI with all query parameters added. - */ -goog.uri.utils.appendParams = function(uri, var_args) { - return goog.uri.utils.appendQueryData_( - arguments.length == 2 ? - goog.uri.utils.buildQueryDataBuffer_([uri], arguments[1], 0) : - goog.uri.utils.buildQueryDataBuffer_([uri], arguments, 1)); -}; - - -/** - * Appends query parameters from a map. - * - * @param {string} uri The original URI, which may already have query data. - * @param {!Object<goog.uri.utils.QueryValue>} map An object where keys are - * URI-encoded parameter keys, and the values are arbitrary types or arrays. - * Keys with a null value are dropped. - * @return {string} The new parameters. - */ -goog.uri.utils.appendParamsFromMap = function(uri, map) { - return goog.uri.utils.appendQueryData_( - goog.uri.utils.buildQueryDataBufferFromMap_([uri], map)); -}; - - -/** - * Appends a single URI parameter. - * - * Repeated calls to this can exhibit quadratic behavior in IE6 due to the - * way string append works, though it should be limited given the 2kb limit. - * - * @param {string} uri The original URI, which may already have query data. - * @param {string} key The key, which must already be URI encoded. - * @param {*=} opt_value The value, which will be stringized and encoded - * (assumed not already to be encoded). If omitted, undefined, or null, the - * key will be added as a valueless parameter. - * @return {string} The URI with the query parameter added. - */ -goog.uri.utils.appendParam = function(uri, key, opt_value) { - var paramArr = [uri, '&', key]; - if (goog.isDefAndNotNull(opt_value)) { - paramArr.push('=', goog.string.urlEncode(opt_value)); - } - return goog.uri.utils.appendQueryData_(paramArr); -}; - - -/** - * Finds the next instance of a query parameter with the specified name. - * - * Does not instantiate any objects. - * - * @param {string} uri The URI to search. May contain a fragment identifier - * if opt_hashIndex is specified. - * @param {number} startIndex The index to begin searching for the key at. A - * match may be found even if this is one character after the ampersand. - * @param {string} keyEncoded The URI-encoded key. - * @param {number} hashOrEndIndex Index to stop looking at. If a hash - * mark is present, it should be its index, otherwise it should be the - * length of the string. - * @return {number} The position of the first character in the key's name, - * immediately after either a question mark or a dot. - * @private - */ -goog.uri.utils.findParam_ = function( - uri, startIndex, keyEncoded, hashOrEndIndex) { - var index = startIndex; - var keyLength = keyEncoded.length; - - // Search for the key itself and post-filter for surronuding punctuation, - // rather than expensively building a regexp. - while ((index = uri.indexOf(keyEncoded, index)) >= 0 && - index < hashOrEndIndex) { - var precedingChar = uri.charCodeAt(index - 1); - // Ensure that the preceding character is '&' or '?'. - if (precedingChar == goog.uri.utils.CharCode_.AMPERSAND || - precedingChar == goog.uri.utils.CharCode_.QUESTION) { - // Ensure the following character is '&', '=', '#', or NaN - // (end of string). - var followingChar = uri.charCodeAt(index + keyLength); - if (!followingChar || - followingChar == goog.uri.utils.CharCode_.EQUAL || - followingChar == goog.uri.utils.CharCode_.AMPERSAND || - followingChar == goog.uri.utils.CharCode_.HASH) { - return index; - } - } - index += keyLength + 1; - } - - return -1; -}; - - -/** - * Regular expression for finding a hash mark or end of string. - * @type {RegExp} - * @private - */ -goog.uri.utils.hashOrEndRe_ = /#|$/; - - -/** - * Determines if the URI contains a specific key. - * - * Performs no object instantiations. - * - * @param {string} uri The URI to process. May contain a fragment - * identifier. - * @param {string} keyEncoded The URI-encoded key. Case-sensitive. - * @return {boolean} Whether the key is present. - */ -goog.uri.utils.hasParam = function(uri, keyEncoded) { - return goog.uri.utils.findParam_(uri, 0, keyEncoded, - uri.search(goog.uri.utils.hashOrEndRe_)) >= 0; -}; - - -/** - * Gets the first value of a query parameter. - * @param {string} uri The URI to process. May contain a fragment. - * @param {string} keyEncoded The URI-encoded key. Case-sensitive. - * @return {?string} The first value of the parameter (URI-decoded), or null - * if the parameter is not found. - */ -goog.uri.utils.getParamValue = function(uri, keyEncoded) { - var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_); - var foundIndex = goog.uri.utils.findParam_( - uri, 0, keyEncoded, hashOrEndIndex); - - if (foundIndex < 0) { - return null; - } else { - var endPosition = uri.indexOf('&', foundIndex); - if (endPosition < 0 || endPosition > hashOrEndIndex) { - endPosition = hashOrEndIndex; - } - // Progress forth to the end of the "key=" or "key&" substring. - foundIndex += keyEncoded.length + 1; - // Use substr, because it (unlike substring) will return empty string - // if foundIndex > endPosition. - return goog.string.urlDecode( - uri.substr(foundIndex, endPosition - foundIndex)); - } -}; - - -/** - * Gets all values of a query parameter. - * @param {string} uri The URI to process. May contain a fragment. - * @param {string} keyEncoded The URI-encoded key. Case-sensitive. - * @return {!Array<string>} All URI-decoded values with the given key. - * If the key is not found, this will have length 0, but never be null. - */ -goog.uri.utils.getParamValues = function(uri, keyEncoded) { - var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_); - var position = 0; - var foundIndex; - var result = []; - - while ((foundIndex = goog.uri.utils.findParam_( - uri, position, keyEncoded, hashOrEndIndex)) >= 0) { - // Find where this parameter ends, either the '&' or the end of the - // query parameters. - position = uri.indexOf('&', foundIndex); - if (position < 0 || position > hashOrEndIndex) { - position = hashOrEndIndex; - } - - // Progress forth to the end of the "key=" or "key&" substring. - foundIndex += keyEncoded.length + 1; - // Use substr, because it (unlike substring) will return empty string - // if foundIndex > position. - result.push(goog.string.urlDecode(uri.substr( - foundIndex, position - foundIndex))); - } - - return result; -}; - - -/** - * Regexp to find trailing question marks and ampersands. - * @type {RegExp} - * @private - */ -goog.uri.utils.trailingQueryPunctuationRe_ = /[?&]($|#)/; - - -/** - * Removes all instances of a query parameter. - * @param {string} uri The URI to process. Must not contain a fragment. - * @param {string} keyEncoded The URI-encoded key. - * @return {string} The URI with all instances of the parameter removed. - */ -goog.uri.utils.removeParam = function(uri, keyEncoded) { - var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_); - var position = 0; - var foundIndex; - var buffer = []; - - // Look for a query parameter. - while ((foundIndex = goog.uri.utils.findParam_( - uri, position, keyEncoded, hashOrEndIndex)) >= 0) { - // Get the portion of the query string up to, but not including, the ? - // or & starting the parameter. - buffer.push(uri.substring(position, foundIndex)); - // Progress to immediately after the '&'. If not found, go to the end. - // Avoid including the hash mark. - position = Math.min((uri.indexOf('&', foundIndex) + 1) || hashOrEndIndex, - hashOrEndIndex); - } - - // Append everything that is remaining. - buffer.push(uri.substr(position)); - - // Join the buffer, and remove trailing punctuation that remains. - return buffer.join('').replace( - goog.uri.utils.trailingQueryPunctuationRe_, '$1'); -}; - - -/** - * Replaces all existing definitions of a parameter with a single definition. - * - * Repeated calls to this can exhibit quadratic behavior due to the need to - * find existing instances and reconstruct the string, though it should be - * limited given the 2kb limit. Consider using appendParams to append multiple - * parameters in bulk. - * - * @param {string} uri The original URI, which may already have query data. - * @param {string} keyEncoded The key, which must already be URI encoded. - * @param {*} value The value, which will be stringized and encoded (assumed - * not already to be encoded). - * @return {string} The URI with the query parameter added. - */ -goog.uri.utils.setParam = function(uri, keyEncoded, value) { - return goog.uri.utils.appendParam( - goog.uri.utils.removeParam(uri, keyEncoded), keyEncoded, value); -}; - - -/** - * Generates a URI path using a given URI and a path with checks to - * prevent consecutive "//". The baseUri passed in must not contain - * query or fragment identifiers. The path to append may not contain query or - * fragment identifiers. - * - * @param {string} baseUri URI to use as the base. - * @param {string} path Path to append. - * @return {string} Updated URI. - */ -goog.uri.utils.appendPath = function(baseUri, path) { - goog.uri.utils.assertNoFragmentsOrQueries_(baseUri); - - // Remove any trailing '/' - if (goog.string.endsWith(baseUri, '/')) { - baseUri = baseUri.substr(0, baseUri.length - 1); - } - // Remove any leading '/' - if (goog.string.startsWith(path, '/')) { - path = path.substr(1); - } - return goog.string.buildString(baseUri, '/', path); -}; - - -/** - * Replaces the path. - * @param {string} uri URI to use as the base. - * @param {string} path New path. - * @return {string} Updated URI. - */ -goog.uri.utils.setPath = function(uri, path) { - // Add any missing '/'. - if (!goog.string.startsWith(path, '/')) { - path = '/' + path; - } - var parts = goog.uri.utils.split(uri); - return goog.uri.utils.buildFromEncodedParts( - parts[goog.uri.utils.ComponentIndex.SCHEME], - parts[goog.uri.utils.ComponentIndex.USER_INFO], - parts[goog.uri.utils.ComponentIndex.DOMAIN], - parts[goog.uri.utils.ComponentIndex.PORT], - path, - parts[goog.uri.utils.ComponentIndex.QUERY_DATA], - parts[goog.uri.utils.ComponentIndex.FRAGMENT]); -}; - - -/** - * Standard supported query parameters. - * @enum {string} - */ -goog.uri.utils.StandardQueryParam = { - - /** Unused parameter for unique-ifying. */ - RANDOM: 'zx' -}; - - -/** - * Sets the zx parameter of a URI to a random value. - * @param {string} uri Any URI. - * @return {string} That URI with the "zx" parameter added or replaced to - * contain a random string. - */ -goog.uri.utils.makeUnique = function(uri) { - return goog.uri.utils.setParam(uri, - goog.uri.utils.StandardQueryParam.RANDOM, goog.string.getRandomString()); -}; - -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Wrapper class for handling XmlHttpRequests. - * - * One off requests can be sent through goog.net.XhrIo.send() or an - * instance can be created to send multiple requests. Each request uses its - * own XmlHttpRequest object and handles clearing of the event callback to - * ensure no leaks. - * - * XhrIo is event based, it dispatches events on success, failure, finishing, - * ready-state change, or progress. - * - * The ready-state or timeout event fires first, followed by - * a generic completed event. Then the abort, error, or success event - * is fired as appropriate. Progress events are fired as they are - * received. Lastly, the ready event will fire to indicate that the - * object may be used to make another request. - * - * The error event may also be called before completed and - * ready-state-change if the XmlHttpRequest.open() or .send() methods throw. - * - * This class does not support multiple requests, queuing, or prioritization. - * - * When progress events are supported by the browser, and progress is - * enabled via .setProgressEventsEnabled(true), the - * goog.net.EventType.PROGRESS event will be the re-dispatched browser - * progress event. - * - * Tested = IE6, FF1.5, Safari, Opera 8.5 - * - * TODO(user): Error cases aren't playing nicely in Safari. - * - */ - - -goog.provide('goog.net.XhrIo'); -goog.provide('goog.net.XhrIo.ResponseType'); - -goog.require('goog.Timer'); -goog.require('goog.array'); -goog.require('goog.asserts'); -goog.require('goog.debug.entryPointRegistry'); -goog.require('goog.events.EventTarget'); -goog.require('goog.json'); -goog.require('goog.log'); -goog.require('goog.net.ErrorCode'); -goog.require('goog.net.EventType'); -goog.require('goog.net.HttpStatus'); -goog.require('goog.net.XmlHttp'); -goog.require('goog.object'); -goog.require('goog.string'); -goog.require('goog.structs'); -goog.require('goog.structs.Map'); -goog.require('goog.uri.utils'); -goog.require('goog.userAgent'); - -goog.forwardDeclare('goog.Uri'); - - - -/** - * Basic class for handling XMLHttpRequests. - * @param {goog.net.XmlHttpFactory=} opt_xmlHttpFactory Factory to use when - * creating XMLHttpRequest objects. - * @constructor - * @extends {goog.events.EventTarget} - */ -goog.net.XhrIo = function(opt_xmlHttpFactory) { - goog.net.XhrIo.base(this, 'constructor'); - - /** - * Map of default headers to add to every request, use: - * XhrIo.headers.set(name, value) - * @type {!goog.structs.Map} - */ - this.headers = new goog.structs.Map(); - - /** - * Optional XmlHttpFactory - * @private {goog.net.XmlHttpFactory} - */ - this.xmlHttpFactory_ = opt_xmlHttpFactory || null; - - /** - * Whether XMLHttpRequest is active. A request is active from the time send() - * is called until onReadyStateChange() is complete, or error() or abort() - * is called. - * @private {boolean} - */ - this.active_ = false; - - /** - * The XMLHttpRequest object that is being used for the transfer. - * @private {?goog.net.XhrLike.OrNative} - */ - this.xhr_ = null; - - /** - * The options to use with the current XMLHttpRequest object. - * @private {Object} - */ - this.xhrOptions_ = null; - - /** - * Last URL that was requested. - * @private {string|goog.Uri} - */ - this.lastUri_ = ''; - - /** - * Method for the last request. - * @private {string} - */ - this.lastMethod_ = ''; - - /** - * Last error code. - * @private {!goog.net.ErrorCode} - */ - this.lastErrorCode_ = goog.net.ErrorCode.NO_ERROR; - - /** - * Last error message. - * @private {Error|string} - */ - this.lastError_ = ''; - - /** - * Used to ensure that we don't dispatch an multiple ERROR events. This can - * happen in IE when it does a synchronous load and one error is handled in - * the ready statte change and one is handled due to send() throwing an - * exception. - * @private {boolean} - */ - this.errorDispatched_ = false; - - /** - * Used to make sure we don't fire the complete event from inside a send call. - * @private {boolean} - */ - this.inSend_ = false; - - /** - * Used in determining if a call to {@link #onReadyStateChange_} is from - * within a call to this.xhr_.open. - * @private {boolean} - */ - this.inOpen_ = false; - - /** - * Used in determining if a call to {@link #onReadyStateChange_} is from - * within a call to this.xhr_.abort. - * @private {boolean} - */ - this.inAbort_ = false; - - /** - * Number of milliseconds after which an incomplete request will be aborted - * and a {@link goog.net.EventType.TIMEOUT} event raised; 0 means no timeout - * is set. - * @private {number} - */ - this.timeoutInterval_ = 0; - - /** - * Timer to track request timeout. - * @private {?number} - */ - this.timeoutId_ = null; - - /** - * The requested type for the response. The empty string means use the default - * XHR behavior. - * @private {goog.net.XhrIo.ResponseType} - */ - this.responseType_ = goog.net.XhrIo.ResponseType.DEFAULT; - - /** - * Whether a "credentialed" request is to be sent (one that is aware of - * cookies and authentication). This is applicable only for cross-domain - * requests and more recent browsers that support this part of the HTTP Access - * Control standard. - * - * @see http://www.w3.org/TR/XMLHttpRequest/#the-withcredentials-attribute - * - * @private {boolean} - */ - this.withCredentials_ = false; - - /** - * Whether progress events are enabled for this request. This is - * disabled by default because setting a progress event handler - * causes pre-flight OPTIONS requests to be sent for CORS requests, - * even in cases where a pre-flight request would not otherwise be - * sent. - * - * @see http://xhr.spec.whatwg.org/#security-considerations - * - * Note that this can cause problems for Firefox 22 and below, as an - * older "LSProgressEvent" will be dispatched by the browser. That - * progress event is no longer supported, and can lead to failures, - * including throwing exceptions. - * - * @see http://bugzilla.mozilla.org/show_bug.cgi?id=845631 - * @see b/23469793 - * - * @private {boolean} - */ - this.progressEventsEnabled_ = false; - - /** - * True if we can use XMLHttpRequest's timeout directly. - * @private {boolean} - */ - this.useXhr2Timeout_ = false; -}; -goog.inherits(goog.net.XhrIo, goog.events.EventTarget); - - -/** - * Response types that may be requested for XMLHttpRequests. - * @enum {string} - * @see http://www.w3.org/TR/XMLHttpRequest/#the-responsetype-attribute - */ -goog.net.XhrIo.ResponseType = { - DEFAULT: '', - TEXT: 'text', - DOCUMENT: 'document', - // Not supported as of Chrome 10.0.612.1 dev - BLOB: 'blob', - ARRAY_BUFFER: 'arraybuffer' -}; - - -/** - * A reference to the XhrIo logger - * @private {goog.debug.Logger} - * @const - */ -goog.net.XhrIo.prototype.logger_ = - goog.log.getLogger('goog.net.XhrIo'); - - -/** - * The Content-Type HTTP header name - * @type {string} - */ -goog.net.XhrIo.CONTENT_TYPE_HEADER = 'Content-Type'; - - -/** - * The pattern matching the 'http' and 'https' URI schemes - * @type {!RegExp} - */ -goog.net.XhrIo.HTTP_SCHEME_PATTERN = /^https?$/i; - - -/** - * The methods that typically come along with form data. We set different - * headers depending on whether the HTTP action is one of these. - */ -goog.net.XhrIo.METHODS_WITH_FORM_DATA = ['POST', 'PUT']; - - -/** - * The Content-Type HTTP header value for a url-encoded form - * @type {string} - */ -goog.net.XhrIo.FORM_CONTENT_TYPE = - 'application/x-www-form-urlencoded;charset=utf-8'; - - -/** - * The XMLHttpRequest Level two timeout delay ms property name. - * - * @see http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute - * - * @private {string} - * @const - */ -goog.net.XhrIo.XHR2_TIMEOUT_ = 'timeout'; - - -/** - * The XMLHttpRequest Level two ontimeout handler property name. - * - * @see http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute - * - * @private {string} - * @const - */ -goog.net.XhrIo.XHR2_ON_TIMEOUT_ = 'ontimeout'; - - -/** - * All non-disposed instances of goog.net.XhrIo created - * by {@link goog.net.XhrIo.send} are in this Array. - * @see goog.net.XhrIo.cleanup - * @private {!Array<!goog.net.XhrIo>} - */ -goog.net.XhrIo.sendInstances_ = []; - - -/** - * Static send that creates a short lived instance of XhrIo to send the - * request. - * @see goog.net.XhrIo.cleanup - * @param {string|goog.Uri} url Uri to make request to. - * @param {?function(this:goog.net.XhrIo, ?)=} opt_callback Callback function - * for when request is complete. - * @param {string=} opt_method Send method, default: GET. - * @param {ArrayBuffer|ArrayBufferView|Blob|Document|FormData|string=} - * opt_content Body data. - * @param {Object|goog.structs.Map=} opt_headers Map of headers to add to the - * request. - * @param {number=} opt_timeoutInterval Number of milliseconds after which an - * incomplete request will be aborted; 0 means no timeout is set. - * @param {boolean=} opt_withCredentials Whether to send credentials with the - * request. Default to false. See {@link goog.net.XhrIo#setWithCredentials}. - * @return {!goog.net.XhrIo} The sent XhrIo. - */ -goog.net.XhrIo.send = function(url, opt_callback, opt_method, opt_content, - opt_headers, opt_timeoutInterval, - opt_withCredentials) { - var x = new goog.net.XhrIo(); - goog.net.XhrIo.sendInstances_.push(x); - if (opt_callback) { - x.listen(goog.net.EventType.COMPLETE, opt_callback); - } - x.listenOnce(goog.net.EventType.READY, x.cleanupSend_); - if (opt_timeoutInterval) { - x.setTimeoutInterval(opt_timeoutInterval); - } - if (opt_withCredentials) { - x.setWithCredentials(opt_withCredentials); - } - x.send(url, opt_method, opt_content, opt_headers); - return x; -}; - - -/** - * Disposes all non-disposed instances of goog.net.XhrIo created by - * {@link goog.net.XhrIo.send}. - * {@link goog.net.XhrIo.send} cleans up the goog.net.XhrIo instance - * it creates when the request completes or fails. However, if - * the request never completes, then the goog.net.XhrIo is not disposed. - * This can occur if the window is unloaded before the request completes. - * We could have {@link goog.net.XhrIo.send} return the goog.net.XhrIo - * it creates and make the client of {@link goog.net.XhrIo.send} be - * responsible for disposing it in this case. However, this makes things - * significantly more complicated for the client, and the whole point - * of {@link goog.net.XhrIo.send} is that it's simple and easy to use. - * Clients of {@link goog.net.XhrIo.send} should call - * {@link goog.net.XhrIo.cleanup} when doing final - * cleanup on window unload. - */ -goog.net.XhrIo.cleanup = function() { - var instances = goog.net.XhrIo.sendInstances_; - while (instances.length) { - instances.pop().dispose(); - } -}; - - -/** - * Installs exception protection for all entry point introduced by - * goog.net.XhrIo instances which are not protected by - * {@link goog.debug.ErrorHandler#protectWindowSetTimeout}, - * {@link goog.debug.ErrorHandler#protectWindowSetInterval}, or - * {@link goog.events.protectBrowserEventEntryPoint}. - * - * @param {goog.debug.ErrorHandler} errorHandler Error handler with which to - * protect the entry point(s). - */ -goog.net.XhrIo.protectEntryPoints = function(errorHandler) { - goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ = - errorHandler.protectEntryPoint( - goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_); -}; - - -/** - * Disposes of the specified goog.net.XhrIo created by - * {@link goog.net.XhrIo.send} and removes it from - * {@link goog.net.XhrIo.pendingStaticSendInstances_}. - * @private - */ -goog.net.XhrIo.prototype.cleanupSend_ = function() { - this.dispose(); - goog.array.remove(goog.net.XhrIo.sendInstances_, this); -}; - - -/** - * Returns the number of milliseconds after which an incomplete request will be - * aborted, or 0 if no timeout is set. - * @return {number} Timeout interval in milliseconds. - */ -goog.net.XhrIo.prototype.getTimeoutInterval = function() { - return this.timeoutInterval_; -}; - - -/** - * Sets the number of milliseconds after which an incomplete request will be - * aborted and a {@link goog.net.EventType.TIMEOUT} event raised; 0 means no - * timeout is set. - * @param {number} ms Timeout interval in milliseconds; 0 means none. - */ -goog.net.XhrIo.prototype.setTimeoutInterval = function(ms) { - this.timeoutInterval_ = Math.max(0, ms); -}; - - -/** - * Sets the desired type for the response. At time of writing, this is only - * supported in very recent versions of WebKit (10.0.612.1 dev and later). - * - * If this is used, the response may only be accessed via {@link #getResponse}. - * - * @param {goog.net.XhrIo.ResponseType} type The desired type for the response. - */ -goog.net.XhrIo.prototype.setResponseType = function(type) { - this.responseType_ = type; -}; - - -/** - * Gets the desired type for the response. - * @return {goog.net.XhrIo.ResponseType} The desired type for the response. - */ -goog.net.XhrIo.prototype.getResponseType = function() { - return this.responseType_; -}; - - -/** - * Sets whether a "credentialed" request that is aware of cookie and - * authentication information should be made. This option is only supported by - * browsers that support HTTP Access Control. As of this writing, this option - * is not supported in IE. - * - * @param {boolean} withCredentials Whether this should be a "credentialed" - * request. - */ -goog.net.XhrIo.prototype.setWithCredentials = function(withCredentials) { - this.withCredentials_ = withCredentials; -}; - - -/** - * Gets whether a "credentialed" request is to be sent. - * @return {boolean} The desired type for the response. - */ -goog.net.XhrIo.prototype.getWithCredentials = function() { - return this.withCredentials_; -}; - - -/** - * Sets whether progress events are enabled for this request. Note - * that progress events require pre-flight OPTIONS request handling - * for CORS requests, and may cause trouble with older browsers. See - * progressEventsEnabled_ for details. - * @param {boolean} enabled Whether progress events should be enabled. - */ -goog.net.XhrIo.prototype.setProgressEventsEnabled = function(enabled) { - this.progressEventsEnabled_ = enabled; -}; - - -/** - * Gets whether progress events are enabled. - * @return {boolean} Whether progress events are enabled for this request. - */ -goog.net.XhrIo.prototype.getProgressEventsEnabled = function() { - return this.progressEventsEnabled_; -}; - - -/** - * Instance send that actually uses XMLHttpRequest to make a server call. - * @param {string|goog.Uri} url Uri to make request to. - * @param {string=} opt_method Send method, default: GET. - * @param {ArrayBuffer|ArrayBufferView|Blob|Document|FormData|string=} - * opt_content Body data. - * @param {Object|goog.structs.Map=} opt_headers Map of headers to add to the - * request. - */ -goog.net.XhrIo.prototype.send = function(url, opt_method, opt_content, - opt_headers) { - if (this.xhr_) { - throw Error('[goog.net.XhrIo] Object is active with another request=' + - this.lastUri_ + '; newUri=' + url); - } - - var method = opt_method ? opt_method.toUpperCase() : 'GET'; - - this.lastUri_ = url; - this.lastError_ = ''; - this.lastErrorCode_ = goog.net.ErrorCode.NO_ERROR; - this.lastMethod_ = method; - this.errorDispatched_ = false; - this.active_ = true; - - // Use the factory to create the XHR object and options - this.xhr_ = this.createXhr(); - this.xhrOptions_ = this.xmlHttpFactory_ ? - this.xmlHttpFactory_.getOptions() : goog.net.XmlHttp.getOptions(); - - // Set up the onreadystatechange callback - this.xhr_.onreadystatechange = goog.bind(this.onReadyStateChange_, this); - - // Set up upload/download progress events, if progress events are supported. - if (this.getProgressEventsEnabled() && 'onprogress' in this.xhr_) { - this.xhr_.onprogress = goog.bind(this.onProgressHandler_, this); - if (this.xhr_.upload) { - this.xhr_.upload.onprogress = goog.bind(this.onProgressHandler_, this); - } - } - - /** - * Try to open the XMLHttpRequest (always async), if an error occurs here it - * is generally permission denied - * @preserveTry - */ - try { - goog.log.fine(this.logger_, this.formatMsg_('Opening Xhr')); - this.inOpen_ = true; - this.xhr_.open(method, String(url), true); // Always async! - this.inOpen_ = false; - } catch (err) { - goog.log.fine(this.logger_, - this.formatMsg_('Error opening Xhr: ' + err.message)); - this.error_(goog.net.ErrorCode.EXCEPTION, err); - return; - } - - // We can't use null since this won't allow requests with form data to have a - // content length specified which will cause some proxies to return a 411 - // error. - var content = opt_content || ''; - - var headers = this.headers.clone(); - - // Add headers specific to this request - if (opt_headers) { - goog.structs.forEach(opt_headers, function(value, key) { - headers.set(key, value); - }); - } - - // Find whether a content type header is set, ignoring case. - // HTTP header names are case-insensitive. See: - // http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 - var contentTypeKey = goog.array.find(headers.getKeys(), - goog.net.XhrIo.isContentTypeHeader_); - - var contentIsFormData = (goog.global['FormData'] && - (content instanceof goog.global['FormData'])); - if (goog.array.contains(goog.net.XhrIo.METHODS_WITH_FORM_DATA, method) && - !contentTypeKey && !contentIsFormData) { - // For requests typically with form data, default to the url-encoded form - // content type unless this is a FormData request. For FormData, - // the browser will automatically add a multipart/form-data content type - // with an appropriate multipart boundary. - headers.set(goog.net.XhrIo.CONTENT_TYPE_HEADER, - goog.net.XhrIo.FORM_CONTENT_TYPE); - } - - // Add the headers to the Xhr object - headers.forEach(function(value, key) { - this.xhr_.setRequestHeader(key, value); - }, this); - - if (this.responseType_) { - this.xhr_.responseType = this.responseType_; - } - - if (goog.object.containsKey(this.xhr_, 'withCredentials')) { - this.xhr_.withCredentials = this.withCredentials_; - } - - /** - * Try to send the request, or other wise report an error (404 not found). - * @preserveTry - */ - try { - this.cleanUpTimeoutTimer_(); // Paranoid, should never be running. - if (this.timeoutInterval_ > 0) { - this.useXhr2Timeout_ = goog.net.XhrIo.shouldUseXhr2Timeout_(this.xhr_); - goog.log.fine(this.logger_, this.formatMsg_('Will abort after ' + - this.timeoutInterval_ + 'ms if incomplete, xhr2 ' + - this.useXhr2Timeout_)); - if (this.useXhr2Timeout_) { - this.xhr_[goog.net.XhrIo.XHR2_TIMEOUT_] = this.timeoutInterval_; - this.xhr_[goog.net.XhrIo.XHR2_ON_TIMEOUT_] = - goog.bind(this.timeout_, this); - } else { - this.timeoutId_ = goog.Timer.callOnce(this.timeout_, - this.timeoutInterval_, this); - } - } - goog.log.fine(this.logger_, this.formatMsg_('Sending request')); - this.inSend_ = true; - this.xhr_.send(content); - this.inSend_ = false; - - } catch (err) { - goog.log.fine(this.logger_, this.formatMsg_('Send error: ' + err.message)); - this.error_(goog.net.ErrorCode.EXCEPTION, err); - } -}; - - -/** - * Determines if the argument is an XMLHttpRequest that supports the level 2 - * timeout value and event. - * - * Currently, FF 21.0 OS X has the fields but won't actually call the timeout - * handler. Perhaps the confusion in the bug referenced below hasn't - * entirely been resolved. - * - * @see http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute - * @see https://bugzilla.mozilla.org/show_bug.cgi?id=525816 - * - * @param {!goog.net.XhrLike.OrNative} xhr The request. - * @return {boolean} True if the request supports level 2 timeout. - * @private - */ -goog.net.XhrIo.shouldUseXhr2Timeout_ = function(xhr) { - return goog.userAgent.IE && - goog.userAgent.isVersionOrHigher(9) && - goog.isNumber(xhr[goog.net.XhrIo.XHR2_TIMEOUT_]) && - goog.isDef(xhr[goog.net.XhrIo.XHR2_ON_TIMEOUT_]); -}; - - -/** - * @param {string} header An HTTP header key. - * @return {boolean} Whether the key is a content type header (ignoring - * case. - * @private - */ -goog.net.XhrIo.isContentTypeHeader_ = function(header) { - return goog.string.caseInsensitiveEquals( - goog.net.XhrIo.CONTENT_TYPE_HEADER, header); -}; - - -/** - * Creates a new XHR object. - * @return {!goog.net.XhrLike.OrNative} The newly created XHR object. - * @protected - */ -goog.net.XhrIo.prototype.createXhr = function() { - return this.xmlHttpFactory_ ? - this.xmlHttpFactory_.createInstance() : goog.net.XmlHttp(); -}; - - -/** - * The request didn't complete after {@link goog.net.XhrIo#timeoutInterval_} - * milliseconds; raises a {@link goog.net.EventType.TIMEOUT} event and aborts - * the request. - * @private - */ -goog.net.XhrIo.prototype.timeout_ = function() { - if (typeof goog == 'undefined') { - // If goog is undefined then the callback has occurred as the application - // is unloading and will error. Thus we let it silently fail. - } else if (this.xhr_) { - this.lastError_ = 'Timed out after ' + this.timeoutInterval_ + - 'ms, aborting'; - this.lastErrorCode_ = goog.net.ErrorCode.TIMEOUT; - goog.log.fine(this.logger_, this.formatMsg_(this.lastError_)); - this.dispatchEvent(goog.net.EventType.TIMEOUT); - this.abort(goog.net.ErrorCode.TIMEOUT); - } -}; - - -/** - * Something errorred, so inactivate, fire error callback and clean up - * @param {goog.net.ErrorCode} errorCode The error code. - * @param {Error} err The error object. - * @private - */ -goog.net.XhrIo.prototype.error_ = function(errorCode, err) { - this.active_ = false; - if (this.xhr_) { - this.inAbort_ = true; - this.xhr_.abort(); // Ensures XHR isn't hung (FF) - this.inAbort_ = false; - } - this.lastError_ = err; - this.lastErrorCode_ = errorCode; - this.dispatchErrors_(); - this.cleanUpXhr_(); -}; - - -/** - * Dispatches COMPLETE and ERROR in case of an error. This ensures that we do - * not dispatch multiple error events. - * @private - */ -goog.net.XhrIo.prototype.dispatchErrors_ = function() { - if (!this.errorDispatched_) { - this.errorDispatched_ = true; - this.dispatchEvent(goog.net.EventType.COMPLETE); - this.dispatchEvent(goog.net.EventType.ERROR); - } -}; - - -/** - * Abort the current XMLHttpRequest - * @param {goog.net.ErrorCode=} opt_failureCode Optional error code to use - - * defaults to ABORT. - */ -goog.net.XhrIo.prototype.abort = function(opt_failureCode) { - if (this.xhr_ && this.active_) { - goog.log.fine(this.logger_, this.formatMsg_('Aborting')); - this.active_ = false; - this.inAbort_ = true; - this.xhr_.abort(); - this.inAbort_ = false; - this.lastErrorCode_ = opt_failureCode || goog.net.ErrorCode.ABORT; - this.dispatchEvent(goog.net.EventType.COMPLETE); - this.dispatchEvent(goog.net.EventType.ABORT); - this.cleanUpXhr_(); - } -}; - - -/** - * Nullifies all callbacks to reduce risks of leaks. - * @override - * @protected - */ -goog.net.XhrIo.prototype.disposeInternal = function() { - if (this.xhr_) { - // We explicitly do not call xhr_.abort() unless active_ is still true. - // This is to avoid unnecessarily aborting a successful request when - // dispose() is called in a callback triggered by a complete response, but - // in which browser cleanup has not yet finished. - // (See http://b/issue?id=1684217.) - if (this.active_) { - this.active_ = false; - this.inAbort_ = true; - this.xhr_.abort(); - this.inAbort_ = false; - } - this.cleanUpXhr_(true); - } - - goog.net.XhrIo.base(this, 'disposeInternal'); -}; - - -/** - * Internal handler for the XHR object's readystatechange event. This method - * checks the status and the readystate and fires the correct callbacks. - * If the request has ended, the handlers are cleaned up and the XHR object is - * nullified. - * @private - */ -goog.net.XhrIo.prototype.onReadyStateChange_ = function() { - if (this.isDisposed()) { - // This method is the target of an untracked goog.Timer.callOnce(). - return; - } - if (!this.inOpen_ && !this.inSend_ && !this.inAbort_) { - // Were not being called from within a call to this.xhr_.send - // this.xhr_.abort, or this.xhr_.open, so this is an entry point - this.onReadyStateChangeEntryPoint_(); - } else { - this.onReadyStateChangeHelper_(); - } -}; - - -/** - * Used to protect the onreadystatechange handler entry point. Necessary - * as {#onReadyStateChange_} maybe called from within send or abort, this - * method is only called when {#onReadyStateChange_} is called as an - * entry point. - * {@see #protectEntryPoints} - * @private - */ -goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ = function() { - this.onReadyStateChangeHelper_(); -}; - - -/** - * Helper for {@link #onReadyStateChange_}. This is used so that - * entry point calls to {@link #onReadyStateChange_} can be routed through - * {@link #onReadyStateChangeEntryPoint_}. - * @private - */ -goog.net.XhrIo.prototype.onReadyStateChangeHelper_ = function() { - if (!this.active_) { - // can get called inside abort call - return; - } - - if (typeof goog == 'undefined') { - // NOTE(user): If goog is undefined then the callback has occurred as the - // application is unloading and will error. Thus we let it silently fail. - - } else if ( - this.xhrOptions_[goog.net.XmlHttp.OptionType.LOCAL_REQUEST_ERROR] && - this.getReadyState() == goog.net.XmlHttp.ReadyState.COMPLETE && - this.getStatus() == 2) { - // NOTE(user): In IE if send() errors on a *local* request the readystate - // is still changed to COMPLETE. We need to ignore it and allow the - // try/catch around send() to pick up the error. - goog.log.fine(this.logger_, this.formatMsg_( - 'Local request error detected and ignored')); - - } else { - - // In IE when the response has been cached we sometimes get the callback - // from inside the send call and this usually breaks code that assumes that - // XhrIo is asynchronous. If that is the case we delay the callback - // using a timer. - if (this.inSend_ && - this.getReadyState() == goog.net.XmlHttp.ReadyState.COMPLETE) { - goog.Timer.callOnce(this.onReadyStateChange_, 0, this); - return; - } - - this.dispatchEvent(goog.net.EventType.READY_STATE_CHANGE); - - // readyState indicates the transfer has finished - if (this.isComplete()) { - goog.log.fine(this.logger_, this.formatMsg_('Request complete')); - - this.active_ = false; - - try { - // Call the specific callbacks for success or failure. Only call the - // success if the status is 200 (HTTP_OK) or 304 (HTTP_CACHED) - if (this.isSuccess()) { - this.dispatchEvent(goog.net.EventType.COMPLETE); - this.dispatchEvent(goog.net.EventType.SUCCESS); - } else { - this.lastErrorCode_ = goog.net.ErrorCode.HTTP_ERROR; - this.lastError_ = - this.getStatusText() + ' [' + this.getStatus() + ']'; - this.dispatchErrors_(); - } - } finally { - this.cleanUpXhr_(); - } - } - } -}; - - -/** - * Internal handler for the XHR object's onprogress event. - * @param {!ProgressEvent} e XHR progress event. - * @private - */ -goog.net.XhrIo.prototype.onProgressHandler_ = function(e) { - goog.asserts.assert(e.type === goog.net.EventType.PROGRESS, - 'goog.net.EventType.PROGRESS is of the same type as raw XHR progress.'); - // Redispatch the progress event. - this.dispatchEvent(e); -}; - - -/** - * Remove the listener to protect against leaks, and nullify the XMLHttpRequest - * object. - * @param {boolean=} opt_fromDispose If this is from the dispose (don't want to - * fire any events). - * @private - */ -goog.net.XhrIo.prototype.cleanUpXhr_ = function(opt_fromDispose) { - if (this.xhr_) { - // Cancel any pending timeout event handler. - this.cleanUpTimeoutTimer_(); - - // Save reference so we can mark it as closed after the READY event. The - // READY event may trigger another request, thus we must nullify this.xhr_ - var xhr = this.xhr_; - var clearedOnReadyStateChange = - this.xhrOptions_[goog.net.XmlHttp.OptionType.USE_NULL_FUNCTION] ? - goog.nullFunction : null; - this.xhr_ = null; - this.xhrOptions_ = null; - - if (!opt_fromDispose) { - this.dispatchEvent(goog.net.EventType.READY); - } - - try { - // NOTE(user): Not nullifying in FireFox can still leak if the callbacks - // are defined in the same scope as the instance of XhrIo. But, IE doesn't - // allow you to set the onreadystatechange to NULL so nullFunction is - // used. - xhr.onreadystatechange = clearedOnReadyStateChange; - } catch (e) { - // This seems to occur with a Gears HTTP request. Delayed the setting of - // this onreadystatechange until after READY is sent out and catching the - // error to see if we can track down the problem. - goog.log.error(this.logger_, - 'Problem encountered resetting onreadystatechange: ' + e.message); - } - } -}; - - -/** - * Make sure the timeout timer isn't running. - * @private - */ -goog.net.XhrIo.prototype.cleanUpTimeoutTimer_ = function() { - if (this.xhr_ && this.useXhr2Timeout_) { - this.xhr_[goog.net.XhrIo.XHR2_ON_TIMEOUT_] = null; - } - if (goog.isNumber(this.timeoutId_)) { - goog.Timer.clear(this.timeoutId_); - this.timeoutId_ = null; - } -}; - - -/** - * @return {boolean} Whether there is an active request. - */ -goog.net.XhrIo.prototype.isActive = function() { - return !!this.xhr_; -}; - - -/** - * @return {boolean} Whether the request has completed. - */ -goog.net.XhrIo.prototype.isComplete = function() { - return this.getReadyState() == goog.net.XmlHttp.ReadyState.COMPLETE; -}; - - -/** - * @return {boolean} Whether the request completed with a success. - */ -goog.net.XhrIo.prototype.isSuccess = function() { - var status = this.getStatus(); - // A zero status code is considered successful for local files. - return goog.net.HttpStatus.isSuccess(status) || - status === 0 && !this.isLastUriEffectiveSchemeHttp_(); -}; - - -/** - * @return {boolean} whether the effective scheme of the last URI that was - * fetched was 'http' or 'https'. - * @private - */ -goog.net.XhrIo.prototype.isLastUriEffectiveSchemeHttp_ = function() { - var scheme = goog.uri.utils.getEffectiveScheme(String(this.lastUri_)); - return goog.net.XhrIo.HTTP_SCHEME_PATTERN.test(scheme); -}; - - -/** - * Get the readystate from the Xhr object - * Will only return correct result when called from the context of a callback - * @return {goog.net.XmlHttp.ReadyState} goog.net.XmlHttp.ReadyState.*. - */ -goog.net.XhrIo.prototype.getReadyState = function() { - return this.xhr_ ? - /** @type {goog.net.XmlHttp.ReadyState} */ (this.xhr_.readyState) : - goog.net.XmlHttp.ReadyState.UNINITIALIZED; -}; - - -/** - * Get the status from the Xhr object - * Will only return correct result when called from the context of a callback - * @return {number} Http status. - */ -goog.net.XhrIo.prototype.getStatus = function() { - /** - * IE doesn't like you checking status until the readystate is greater than 2 - * (i.e. it is receiving or complete). The try/catch is used for when the - * page is unloading and an ERROR_NOT_AVAILABLE may occur when accessing xhr_. - * @preserveTry - */ - try { - return this.getReadyState() > goog.net.XmlHttp.ReadyState.LOADED ? - this.xhr_.status : -1; - } catch (e) { - return -1; - } -}; - - -/** - * Get the status text from the Xhr object - * Will only return correct result when called from the context of a callback - * @return {string} Status text. - */ -goog.net.XhrIo.prototype.getStatusText = function() { - /** - * IE doesn't like you checking status until the readystate is greater than 2 - * (i.e. it is recieving or complete). The try/catch is used for when the - * page is unloading and an ERROR_NOT_AVAILABLE may occur when accessing xhr_. - * @preserveTry - */ - try { - return this.getReadyState() > goog.net.XmlHttp.ReadyState.LOADED ? - this.xhr_.statusText : ''; - } catch (e) { - goog.log.fine(this.logger_, 'Can not get status: ' + e.message); - return ''; - } -}; - - -/** - * Get the last Uri that was requested - * @return {string} Last Uri. - */ -goog.net.XhrIo.prototype.getLastUri = function() { - return String(this.lastUri_); -}; - - -/** - * Get the response text from the Xhr object - * Will only return correct result when called from the context of a callback. - * @return {string} Result from the server, or '' if no result available. - */ -goog.net.XhrIo.prototype.getResponseText = function() { - /** @preserveTry */ - try { - return this.xhr_ ? this.xhr_.responseText : ''; - } catch (e) { - // http://www.w3.org/TR/XMLHttpRequest/#the-responsetext-attribute - // states that responseText should return '' (and responseXML null) - // when the state is not LOADING or DONE. Instead, IE can - // throw unexpected exceptions, for example when a request is aborted - // or no data is available yet. - goog.log.fine(this.logger_, 'Can not get responseText: ' + e.message); - return ''; - } -}; - - -/** - * Get the response body from the Xhr object. This property is only available - * in IE since version 7 according to MSDN: - * http://msdn.microsoft.com/en-us/library/ie/ms534368(v=vs.85).aspx - * Will only return correct result when called from the context of a callback. - * - * One option is to construct a VBArray from the returned object and convert - * it to a JavaScript array using the toArray method: - * {@code (new window['VBArray'](xhrIo.getResponseBody())).toArray()} - * This will result in an array of numbers in the range of [0..255] - * - * Another option is to use the VBScript CStr method to convert it into a - * string as outlined in http://stackoverflow.com/questions/1919972 - * - * @return {Object} Binary result from the server or null if not available. - */ -goog.net.XhrIo.prototype.getResponseBody = function() { - /** @preserveTry */ - try { - if (this.xhr_ && 'responseBody' in this.xhr_) { - return this.xhr_['responseBody']; - } - } catch (e) { - // IE can throw unexpected exceptions, for example when a request is aborted - // or no data is yet available. - goog.log.fine(this.logger_, 'Can not get responseBody: ' + e.message); - } - return null; -}; - - -/** - * Get the response XML from the Xhr object - * Will only return correct result when called from the context of a callback. - * @return {Document} The DOM Document representing the XML file, or null - * if no result available. - */ -goog.net.XhrIo.prototype.getResponseXml = function() { - /** @preserveTry */ - try { - return this.xhr_ ? this.xhr_.responseXML : null; - } catch (e) { - goog.log.fine(this.logger_, 'Can not get responseXML: ' + e.message); - return null; - } -}; - - -/** - * Get the response and evaluates it as JSON from the Xhr object - * Will only return correct result when called from the context of a callback - * @param {string=} opt_xssiPrefix Optional XSSI prefix string to use for - * stripping of the response before parsing. This needs to be set only if - * your backend server prepends the same prefix string to the JSON response. - * @return {Object|undefined} JavaScript object. - */ -goog.net.XhrIo.prototype.getResponseJson = function(opt_xssiPrefix) { - if (!this.xhr_) { - return undefined; - } - - var responseText = this.xhr_.responseText; - if (opt_xssiPrefix && responseText.indexOf(opt_xssiPrefix) == 0) { - responseText = responseText.substring(opt_xssiPrefix.length); - } - - return goog.json.parse(responseText); -}; - - -/** - * Get the response as the type specificed by {@link #setResponseType}. At time - * of writing, this is only directly supported in very recent versions of WebKit - * (10.0.612.1 dev and later). If the field is not supported directly, we will - * try to emulate it. - * - * Emulating the response means following the rules laid out at - * http://www.w3.org/TR/XMLHttpRequest/#the-response-attribute - * - * On browsers with no support for this (Chrome < 10, Firefox < 4, etc), only - * response types of DEFAULT or TEXT may be used, and the response returned will - * be the text response. - * - * On browsers with Mozilla's draft support for array buffers (Firefox 4, 5), - * only response types of DEFAULT, TEXT, and ARRAY_BUFFER may be used, and the - * response returned will be either the text response or the Mozilla - * implementation of the array buffer response. - * - * On browsers will full support, any valid response type supported by the - * browser may be used, and the response provided by the browser will be - * returned. - * - * @return {*} The response. - */ -goog.net.XhrIo.prototype.getResponse = function() { - /** @preserveTry */ - try { - if (!this.xhr_) { - return null; - } - if ('response' in this.xhr_) { - return this.xhr_.response; - } - switch (this.responseType_) { - case goog.net.XhrIo.ResponseType.DEFAULT: - case goog.net.XhrIo.ResponseType.TEXT: - return this.xhr_.responseText; - // DOCUMENT and BLOB don't need to be handled here because they are - // introduced in the same spec that adds the .response field, and would - // have been caught above. - // ARRAY_BUFFER needs an implementation for Firefox 4, where it was - // implemented using a draft spec rather than the final spec. - case goog.net.XhrIo.ResponseType.ARRAY_BUFFER: - if ('mozResponseArrayBuffer' in this.xhr_) { - return this.xhr_.mozResponseArrayBuffer; - } - } - // Fell through to a response type that is not supported on this browser. - goog.log.error(this.logger_, - 'Response type ' + this.responseType_ + ' is not ' + - 'supported on this browser'); - return null; - } catch (e) { - goog.log.fine(this.logger_, 'Can not get response: ' + e.message); - return null; - } -}; - - -/** - * Get the value of the response-header with the given name from the Xhr object - * Will only return correct result when called from the context of a callback - * and the request has completed - * @param {string} key The name of the response-header to retrieve. - * @return {string|undefined} The value of the response-header named key. - */ -goog.net.XhrIo.prototype.getResponseHeader = function(key) { - return this.xhr_ && this.isComplete() ? - this.xhr_.getResponseHeader(key) : undefined; -}; - - -/** - * Gets the text of all the headers in the response. - * Will only return correct result when called from the context of a callback - * and the request has completed. - * @return {string} The value of the response headers or empty string. - */ -goog.net.XhrIo.prototype.getAllResponseHeaders = function() { - return this.xhr_ && this.isComplete() ? - this.xhr_.getAllResponseHeaders() : ''; -}; - - -/** - * Returns all response headers as a key-value map. - * Multiple values for the same header key can be combined into one, - * separated by a comma and a space. - * Note that the native getResponseHeader method for retrieving a single header - * does a case insensitive match on the header name. This method does not - * include any case normalization logic, it will just return a key-value - * representation of the headers. - * See: http://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method - * @return {!Object<string, string>} An object with the header keys as keys - * and header values as values. - */ -goog.net.XhrIo.prototype.getResponseHeaders = function() { - var headersObject = {}; - var headersArray = this.getAllResponseHeaders().split('\r\n'); - for (var i = 0; i < headersArray.length; i++) { - if (goog.string.isEmptyOrWhitespace(headersArray[i])) { - continue; - } - var keyValue = goog.string.splitLimit(headersArray[i], ': ', 2); - if (headersObject[keyValue[0]]) { - headersObject[keyValue[0]] += ', ' + keyValue[1]; - } else { - headersObject[keyValue[0]] = keyValue[1]; - } - } - return headersObject; -}; - - -/** - * Get the last error message - * @return {goog.net.ErrorCode} Last error code. - */ -goog.net.XhrIo.prototype.getLastErrorCode = function() { - return this.lastErrorCode_; -}; - - -/** - * Get the last error message - * @return {string} Last error message. - */ -goog.net.XhrIo.prototype.getLastError = function() { - return goog.isString(this.lastError_) ? this.lastError_ : - String(this.lastError_); -}; - - -/** - * Adds the last method, status and URI to the message. This is used to add - * this information to the logging calls. - * @param {string} msg The message text that we want to add the extra text to. - * @return {string} The message with the extra text appended. - * @private - */ -goog.net.XhrIo.prototype.formatMsg_ = function(msg) { - return msg + ' [' + this.lastMethod_ + ' ' + this.lastUri_ + ' ' + - this.getStatus() + ']'; -}; - - -// Register the xhr handler as an entry point, so that -// it can be monitored for exception handling, etc. -goog.debug.entryPointRegistry.register( - /** - * @param {function(!Function): !Function} transformer The transforming - * function. - */ - function(transformer) { - goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ = - transformer(goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_); - }); - -goog.provide('ol.TileLoadFunctionType'); -goog.provide('ol.TileVectorLoadFunctionType'); - - -/** - * A function that takes an {@link ol.Tile} for the tile and a - * `{string}` for the url as arguments. - * - * @typedef {function(ol.Tile, string)} - * @api - */ -ol.TileLoadFunctionType; - - -/** - * A function that is called with a tile url for the features to load and - * a callback that takes the loaded features as argument. - * - * @typedef {function(string, function(Array.<ol.Feature>))} - * @api - */ -ol.TileVectorLoadFunctionType; - goog.provide('ol.VectorTile'); goog.require('ol.Tile'); -goog.require('ol.TileCoord'); -goog.require('ol.TileLoadFunctionType'); goog.require('ol.TileState'); +goog.require('ol.dom'); goog.require('ol.proj.Projection'); /** - * @typedef {{ - * dirty: boolean, - * renderedRenderOrder: (null|function(ol.Feature, ol.Feature):number), - * renderedRevision: number, - * replayGroup: ol.render.IReplayGroup}} - */ -ol.TileReplayState; - - - -/** * @constructor * @extends {ol.Tile} * @param {ol.TileCoord} tileCoord Tile coordinate. @@ -69460,15 +54394,19 @@ ol.TileReplayState; * @param {string} src Data source url. * @param {ol.format.Feature} format Feature format. * @param {ol.TileLoadFunctionType} tileLoadFunction Tile load function. - * @param {ol.proj.Projection} projection Feature projection. */ -ol.VectorTile = - function(tileCoord, state, src, format, tileLoadFunction, projection) { +ol.VectorTile = function(tileCoord, state, src, format, tileLoadFunction) { goog.base(this, tileCoord, state); /** * @private + * @type {CanvasRenderingContext2D} + */ + this.context_ = ol.dom.createCanvasContext2D(); + + /** + * @private * @type {ol.format.Feature} */ this.format_ = format; @@ -69486,10 +54424,11 @@ ol.VectorTile = this.loader_; /** + * Data projection * @private * @type {ol.proj.Projection} */ - this.projection_ = projection; + this.projection_; /** * @private @@ -69499,7 +54438,9 @@ ol.VectorTile = dirty: false, renderedRenderOrder: null, renderedRevision: -1, - replayGroup: null + renderedTileRevision: -1, + replayGroup: null, + skippedFeatures: [] }; /** @@ -69519,10 +54460,19 @@ goog.inherits(ol.VectorTile, ol.Tile); /** + * @return {CanvasRenderingContext2D} The rendering context. + */ +ol.VectorTile.prototype.getContext = function() { + return this.context_; +}; + + +/** * @inheritDoc */ -ol.VectorTile.prototype.disposeInternal = function() { - goog.base(this, 'disposeInternal'); +ol.VectorTile.prototype.getImage = function() { + return this.replayState_.renderedTileRevision == -1 ? + null : this.context_.canvas; }; @@ -69545,7 +54495,7 @@ ol.VectorTile.prototype.getFeatures = function() { /** - * @return {ol.TileReplayState} + * @return {ol.TileReplayState} The replay state. */ ol.VectorTile.prototype.getReplayState = function() { return this.replayState_; @@ -69575,13 +54525,14 @@ ol.VectorTile.prototype.load = function() { if (this.state == ol.TileState.IDLE) { this.setState(ol.TileState.LOADING); this.tileLoadFunction_(this, this.url_); - this.loader_(null, NaN, this.projection_); + this.loader_(null, NaN, null); } }; /** * @param {Array.<ol.Feature>} features Features. + * @api */ ol.VectorTile.prototype.setFeatures = function(features) { this.features_ = features; @@ -69590,7 +54541,9 @@ ol.VectorTile.prototype.setFeatures = function(features) { /** + * Set the projection of the features that were added with {@link #setFeatures}. * @param {ol.proj.Projection} projection Feature projection. + * @api */ ol.VectorTile.prototype.setProjection = function(projection) { this.projection_ = projection; @@ -69628,296 +54581,11 @@ ol.format.FormatType = { XML: 'xml' }; -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview - * XML utilities. - * - */ - -goog.provide('goog.dom.xml'); - -goog.require('goog.dom'); -goog.require('goog.dom.NodeType'); -goog.require('goog.userAgent'); - - -/** - * Max XML size for MSXML2. Used to prevent potential DoS attacks. - * @type {number} - */ -goog.dom.xml.MAX_XML_SIZE_KB = 2 * 1024; // In kB - - -/** - * Max XML size for MSXML2. Used to prevent potential DoS attacks. - * @type {number} - */ -goog.dom.xml.MAX_ELEMENT_DEPTH = 256; // Same default as MSXML6. - - -/** - * Check for ActiveXObject support by the browser. - * @return {boolean} true if browser has ActiveXObject support. - * @private - */ -goog.dom.xml.hasActiveXObjectSupport_ = function() { - if (!goog.userAgent.IE) { - // Avoid raising useless exception in case code is not compiled - // and browser is not MSIE. - return false; - } - try { - // Due to lot of changes in IE 9, 10 & 11 behaviour and ActiveX being - // totally disableable using MSIE's security level, trying to create the - // ActiveXOjbect is a lot more reliable than testing for the existance of - // window.ActiveXObject - new ActiveXObject('MSXML2.DOMDocument'); - return true; - } catch (e) { - return false; - } -}; - - -/** - * True if browser has ActiveXObject support. - * Possible override if this test become wrong in coming IE versions. - * @type {boolean} - */ -goog.dom.xml.ACTIVEX_SUPPORT = - goog.userAgent.IE && goog.dom.xml.hasActiveXObjectSupport_(); - - -/** - * Creates an XML document appropriate for the current JS runtime - * @param {string=} opt_rootTagName The root tag name. - * @param {string=} opt_namespaceUri Namespace URI of the document element. - * @param {boolean=} opt_preferActiveX Whether to default to ActiveXObject to - * create Document in IE. Use this if you need xpath support in IE (e.g., - * selectSingleNode or selectNodes), but be aware that the ActiveXObject does - * not support various DOM-specific Document methods and attributes. - * @return {Document} The new document. - * @throws {Error} if browser does not support creating new documents or - * namespace is provided without a root tag name. - */ -goog.dom.xml.createDocument = function(opt_rootTagName, opt_namespaceUri, - opt_preferActiveX) { - if (opt_namespaceUri && !opt_rootTagName) { - throw Error("Can't create document with namespace and no root tag"); - } - // If document.implementation.createDocument is available and they haven't - // explicitly opted to use ActiveXObject when possible. - if (document.implementation && document.implementation.createDocument && - !(goog.dom.xml.ACTIVEX_SUPPORT && opt_preferActiveX)) { - return document.implementation.createDocument(opt_namespaceUri || '', - opt_rootTagName || '', null); - } else if (goog.dom.xml.ACTIVEX_SUPPORT) { - var doc = goog.dom.xml.createMsXmlDocument_(); - if (doc) { - if (opt_rootTagName) { - doc.appendChild(doc.createNode(goog.dom.NodeType.ELEMENT, - opt_rootTagName, - opt_namespaceUri || '')); - } - return doc; - } - } - throw Error('Your browser does not support creating new documents'); -}; - - -/** - * Creates an XML document from a string - * @param {string} xml The text. - * @param {boolean=} opt_preferActiveX Whether to default to ActiveXObject to - * create Document in IE. Use this if you need xpath support in IE (e.g., - * selectSingleNode or selectNodes), but be aware that the ActiveXObject does - * not support various DOM-specific Document methods and attributes. - * @return {Document} XML document from the text. - * @throws {Error} if browser does not support loading XML documents. - */ -goog.dom.xml.loadXml = function(xml, opt_preferActiveX) { - if (typeof DOMParser != 'undefined' && - !(goog.dom.xml.ACTIVEX_SUPPORT && opt_preferActiveX)) { - return new DOMParser().parseFromString(xml, 'application/xml'); - } else if (goog.dom.xml.ACTIVEX_SUPPORT) { - var doc = goog.dom.xml.createMsXmlDocument_(); - doc.loadXML(xml); - return doc; - } - throw Error('Your browser does not support loading xml documents'); -}; - - -/** - * Serializes an XML document or subtree to string. - * @param {Document|Element} xml The document or the root node of the subtree. - * @return {string} The serialized XML. - * @throws {Error} if browser does not support XML serialization. - */ -goog.dom.xml.serialize = function(xml) { - // Compatible with IE/ActiveXObject. - var text = xml.xml; - if (text) { - return text; - } - // Compatible with Firefox, Opera and WebKit. - if (typeof XMLSerializer != 'undefined') { - return new XMLSerializer().serializeToString(xml); - } - throw Error('Your browser does not support serializing XML documents'); -}; - - -/** - * Selects a single node using an Xpath expression and a root node - * @param {Node} node The root node. - * @param {string} path Xpath selector. - * @return {Node} The selected node, or null if no matching node. - */ -goog.dom.xml.selectSingleNode = function(node, path) { - if (typeof node.selectSingleNode != 'undefined') { - var doc = goog.dom.getOwnerDocument(node); - if (typeof doc.setProperty != 'undefined') { - doc.setProperty('SelectionLanguage', 'XPath'); - } - return node.selectSingleNode(path); - } else if (document.implementation.hasFeature('XPath', '3.0')) { - var doc = goog.dom.getOwnerDocument(node); - var resolver = doc.createNSResolver(doc.documentElement); - var result = doc.evaluate(path, node, resolver, - XPathResult.FIRST_ORDERED_NODE_TYPE, null); - return result.singleNodeValue; - } - // This browser does not support xpath for the given node. If IE, ensure XML - // Document was created using ActiveXObject - // TODO(joeltine): This should throw instead of return null. - return null; -}; - - -/** - * Selects multiple nodes using an Xpath expression and a root node - * @param {Node} node The root node. - * @param {string} path Xpath selector. - * @return {(NodeList|Array<Node>)} The selected nodes, or empty array if no - * matching nodes. - */ -goog.dom.xml.selectNodes = function(node, path) { - if (typeof node.selectNodes != 'undefined') { - var doc = goog.dom.getOwnerDocument(node); - if (typeof doc.setProperty != 'undefined') { - doc.setProperty('SelectionLanguage', 'XPath'); - } - return node.selectNodes(path); - } else if (document.implementation.hasFeature('XPath', '3.0')) { - var doc = goog.dom.getOwnerDocument(node); - var resolver = doc.createNSResolver(doc.documentElement); - var nodes = doc.evaluate(path, node, resolver, - XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); - var results = []; - var count = nodes.snapshotLength; - for (var i = 0; i < count; i++) { - results.push(nodes.snapshotItem(i)); - } - return results; - } else { - // This browser does not support xpath for the given node. If IE, ensure XML - // Document was created using ActiveXObject. - // TODO(joeltine): This should throw instead of return empty array. - return []; - } -}; - - -/** - * Sets multiple attributes on an element. Differs from goog.dom.setProperties - * in that it exclusively uses the element's setAttributes method. Use this - * when you need to ensure that the exact property is available as an attribute - * and can be read later by the native getAttribute method. - * @param {!Element} element XML or DOM element to set attributes on. - * @param {!Object<string, string>} attributes Map of property:value pairs. - */ -goog.dom.xml.setAttributes = function(element, attributes) { - for (var key in attributes) { - if (attributes.hasOwnProperty(key)) { - element.setAttribute(key, attributes[key]); - } - } -}; - - -/** - * Creates an instance of the MSXML2.DOMDocument. - * @return {Document} The new document. - * @private - */ -goog.dom.xml.createMsXmlDocument_ = function() { - var doc = new ActiveXObject('MSXML2.DOMDocument'); - if (doc) { - // Prevent potential vulnerabilities exposed by MSXML2, see - // http://b/1707300 and http://wiki/Main/ISETeamXMLAttacks for details. - doc.resolveExternals = false; - doc.validateOnParse = false; - // Add a try catch block because accessing these properties will throw an - // error on unsupported MSXML versions. This affects Windows machines - // running IE6 or IE7 that are on XP SP2 or earlier without MSXML updates. - // See http://msdn.microsoft.com/en-us/library/ms766391(VS.85).aspx for - // specific details on which MSXML versions support these properties. - try { - doc.setProperty('ProhibitDTD', true); - doc.setProperty('MaxXMLSize', goog.dom.xml.MAX_XML_SIZE_KB); - doc.setProperty('MaxElementDepth', goog.dom.xml.MAX_ELEMENT_DEPTH); - } catch (e) { - // No-op. - } - } - return doc; -}; - goog.provide('ol.xml'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom.NodeType'); -goog.require('goog.dom.xml'); -goog.require('goog.object'); -goog.require('goog.userAgent'); - - -/** - * When using {@link ol.xml.makeChildAppender} or - * {@link ol.xml.makeSimpleNodeFactory}, the top `objectStack` item needs to - * have this structure. - * @typedef {{node:Node}} - */ -ol.xml.NodeStackItem; - - -/** - * @typedef {function(Node, Array.<*>)} - */ -ol.xml.Parser; - - -/** - * @typedef {function(Node, *, Array.<*>)} - */ -ol.xml.Serializer; +goog.require('ol.array'); /** @@ -69927,45 +54595,20 @@ ol.xml.Serializer; * @const * @type {Document} */ -ol.xml.DOCUMENT = goog.dom.xml.createDocument(); +ol.xml.DOCUMENT = document.implementation.createDocument('', '', null); /** * @param {string} namespaceURI Namespace URI. * @param {string} qualifiedName Qualified name. * @return {Node} Node. - * @private */ -ol.xml.createElementNS_ = function(namespaceURI, qualifiedName) { +ol.xml.createElementNS = function(namespaceURI, qualifiedName) { return ol.xml.DOCUMENT.createElementNS(namespaceURI, qualifiedName); }; /** - * @param {string} namespaceURI Namespace URI. - * @param {string} qualifiedName Qualified name. - * @return {Node} Node. - * @private - */ -ol.xml.createElementNSActiveX_ = function(namespaceURI, qualifiedName) { - if (!namespaceURI) { - namespaceURI = ''; - } - return ol.xml.DOCUMENT.createNode(1, qualifiedName, namespaceURI); -}; - - -/** - * @param {string} namespaceURI Namespace URI. - * @param {string} qualifiedName Qualified name. - * @return {Node} Node. - */ -ol.xml.createElementNS = - (document.implementation && document.implementation.createDocument) ? - ol.xml.createElementNS_ : ol.xml.createElementNSActiveX_; - - -/** * Recursively grab all text content of child nodes into a single string. * @param {Node} node Node. * @param {boolean} normalizeWhitespace Normalize whitespace: remove all line @@ -69983,9 +54626,9 @@ ol.xml.getAllTextContent = function(node, normalizeWhitespace) { * @param {Node} node Node. * @param {boolean} normalizeWhitespace Normalize whitespace: remove all line * breaks. - * @param {Array.<String|string>} accumulator Accumulator. + * @param {Array.<string>} accumulator Accumulator. * @private - * @return {Array.<String|string>} Accumulator. + * @return {Array.<string>} Accumulator. */ ol.xml.getAllTextContent_ = function(node, normalizeWhitespace, accumulator) { if (node.nodeType == goog.dom.NodeType.CDATA_SECTION || @@ -70007,103 +54650,30 @@ ol.xml.getAllTextContent_ = function(node, normalizeWhitespace, accumulator) { /** - * @param {Node} node Node. - * @private - * @return {string} Local name. - */ -ol.xml.getLocalName_ = function(node) { - return node.localName; -}; - - -/** - * @param {Node} node Node. - * @private - * @return {string} Local name. - */ -ol.xml.getLocalNameIE_ = function(node) { - var localName = node.localName; - if (localName !== undefined) { - return localName; - } - var baseName = node.baseName; - goog.asserts.assert(baseName, - 'Failed to get localName/baseName of node %s', node); - return baseName; -}; - - -/** - * @param {Node} node Node. - * @return {string} Local name. - */ -ol.xml.getLocalName = goog.userAgent.IE ? - ol.xml.getLocalNameIE_ : ol.xml.getLocalName_; - - -/** * @param {?} value Value. - * @private * @return {boolean} Is document. */ -ol.xml.isDocument_ = function(value) { +ol.xml.isDocument = function(value) { return value instanceof Document; }; /** * @param {?} value Value. - * @private - * @return {boolean} Is document. - */ -ol.xml.isDocumentIE_ = function(value) { - return goog.isObject(value) && value.nodeType == goog.dom.NodeType.DOCUMENT; -}; - - -/** - * @param {?} value Value. - * @return {boolean} Is document. - */ -ol.xml.isDocument = goog.userAgent.IE ? - ol.xml.isDocumentIE_ : ol.xml.isDocument_; - - -/** - * @param {?} value Value. - * @private * @return {boolean} Is node. */ -ol.xml.isNode_ = function(value) { +ol.xml.isNode = function(value) { return value instanceof Node; }; /** - * @param {?} value Value. - * @private - * @return {boolean} Is node. - */ -ol.xml.isNodeIE_ = function(value) { - return goog.isObject(value) && value.nodeType !== undefined; -}; - - -/** - * @param {?} value Value. - * @return {boolean} Is node. - */ -ol.xml.isNode = goog.userAgent.IE ? ol.xml.isNodeIE_ : ol.xml.isNode_; - - -/** * @param {Node} node Node. * @param {?string} namespaceURI Namespace URI. * @param {string} name Attribute name. * @return {string} Value - * @private */ -ol.xml.getAttributeNS_ = function(node, namespaceURI, name) { +ol.xml.getAttributeNS = function(node, namespaceURI, name) { return node.getAttributeNS(namespaceURI, name) || ''; }; @@ -70112,121 +54682,14 @@ ol.xml.getAttributeNS_ = function(node, namespaceURI, name) { * @param {Node} node Node. * @param {?string} namespaceURI Namespace URI. * @param {string} name Attribute name. - * @return {string} Value - * @private - */ -ol.xml.getAttributeNSActiveX_ = function(node, namespaceURI, name) { - var attributeValue = ''; - var attributeNode = ol.xml.getAttributeNodeNS(node, namespaceURI, name); - if (attributeNode !== undefined) { - attributeValue = attributeNode.nodeValue; - } - return attributeValue; -}; - - -/** - * @param {Node} node Node. - * @param {?string} namespaceURI Namespace URI. - * @param {string} name Attribute name. - * @return {string} Value - */ -ol.xml.getAttributeNS = - (document.implementation && document.implementation.createDocument) ? - ol.xml.getAttributeNS_ : ol.xml.getAttributeNSActiveX_; - - -/** - * @param {Node} node Node. - * @param {?string} namespaceURI Namespace URI. - * @param {string} name Attribute name. - * @return {?Node} Attribute node or null if none found. - * @private - */ -ol.xml.getAttributeNodeNS_ = function(node, namespaceURI, name) { - return node.getAttributeNodeNS(namespaceURI, name); -}; - - -/** - * @param {Node} node Node. - * @param {?string} namespaceURI Namespace URI. - * @param {string} name Attribute name. - * @return {?Node} Attribute node or null if none found. - * @private - */ -ol.xml.getAttributeNodeNSActiveX_ = function(node, namespaceURI, name) { - var attributeNode = null; - var attributes = node.attributes; - var potentialNode, fullName; - for (var i = 0, len = attributes.length; i < len; ++i) { - potentialNode = attributes[i]; - if (potentialNode.namespaceURI == namespaceURI) { - fullName = (potentialNode.prefix) ? - (potentialNode.prefix + ':' + name) : name; - if (fullName == potentialNode.nodeName) { - attributeNode = potentialNode; - break; - } - } - } - return attributeNode; -}; - - -/** - * @param {Node} node Node. - * @param {?string} namespaceURI Namespace URI. - * @param {string} name Attribute name. - * @return {?Node} Attribute node or null if none found. - */ -ol.xml.getAttributeNodeNS = - (document.implementation && document.implementation.createDocument) ? - ol.xml.getAttributeNodeNS_ : ol.xml.getAttributeNodeNSActiveX_; - - -/** - * @param {Node} node Node. - * @param {?string} namespaceURI Namespace URI. - * @param {string} name Attribute name. * @param {string|number} value Value. - * @private */ -ol.xml.setAttributeNS_ = function(node, namespaceURI, name, value) { +ol.xml.setAttributeNS = function(node, namespaceURI, name, value) { node.setAttributeNS(namespaceURI, name, value); }; /** - * @param {Node} node Node. - * @param {?string} namespaceURI Namespace URI. - * @param {string} name Attribute name. - * @param {string|number} value Value. - * @private - */ -ol.xml.setAttributeNSActiveX_ = function(node, namespaceURI, name, value) { - if (namespaceURI) { - var attribute = node.ownerDocument.createNode(2, name, namespaceURI); - attribute.nodeValue = value; - node.setAttributeNode(attribute); - } else { - node.setAttribute(name, value); - } -}; - - -/** - * @param {Node} node Node. - * @param {?string} namespaceURI Namespace URI. - * @param {string} name Attribute name. - * @param {string|number} value Value. - */ -ol.xml.setAttributeNS = - (document.implementation && document.implementation.createDocument) ? - ol.xml.setAttributeNS_ : ol.xml.setAttributeNSActiveX_; - - -/** * Parse an XML string to an XML Document. * @param {string} xml XML. * @return {Document} Document. @@ -70243,7 +54706,7 @@ ol.xml.parse = function(xml) { * @param {function(this: T, Node, Array.<*>): (Array.<*>|undefined)} * valueReader Value reader. * @param {T=} opt_this The object to use as `this` in `valueReader`. - * @return {ol.xml.Parser} Parser. + * @return {ol.XmlParser} Parser. * @template T */ ol.xml.makeArrayExtender = function(valueReader, opt_this) { @@ -70255,13 +54718,13 @@ ol.xml.makeArrayExtender = function(valueReader, opt_this) { function(node, objectStack) { var value = valueReader.call(opt_this, node, objectStack); if (value !== undefined) { - goog.asserts.assert(goog.isArray(value), + goog.asserts.assert(Array.isArray(value), 'valueReader function is expected to return an array of values'); var array = /** @type {Array.<*>} */ (objectStack[objectStack.length - 1]); - goog.asserts.assert(goog.isArray(array), + goog.asserts.assert(Array.isArray(array), 'objectStack is supposed to be an array of arrays'); - goog.array.extend(array, value); + ol.array.extend(array, value); } }); }; @@ -70272,7 +54735,7 @@ ol.xml.makeArrayExtender = function(valueReader, opt_this) { * object stack. * @param {function(this: T, Node, Array.<*>): *} valueReader Value reader. * @param {T=} opt_this The object to use as `this` in `valueReader`. - * @return {ol.xml.Parser} Parser. + * @return {ol.XmlParser} Parser. * @template T */ ol.xml.makeArrayPusher = function(valueReader, opt_this) { @@ -70286,7 +54749,7 @@ ol.xml.makeArrayPusher = function(valueReader, opt_this) { node, objectStack); if (value !== undefined) { var array = objectStack[objectStack.length - 1]; - goog.asserts.assert(goog.isArray(array), + goog.asserts.assert(Array.isArray(array), 'objectStack is supposed to be an array of arrays'); array.push(value); } @@ -70299,7 +54762,7 @@ ol.xml.makeArrayPusher = function(valueReader, opt_this) { * top of the stack. * @param {function(this: T, Node, Array.<*>): *} valueReader Value reader. * @param {T=} opt_this The object to use as `this` in `valueReader`. - * @return {ol.xml.Parser} Parser. + * @return {ol.XmlParser} Parser. * @template T */ ol.xml.makeReplacer = function(valueReader, opt_this) { @@ -70324,11 +54787,10 @@ ol.xml.makeReplacer = function(valueReader, opt_this) { * @param {function(this: T, Node, Array.<*>): *} valueReader Value reader. * @param {string=} opt_property Property. * @param {T=} opt_this The object to use as `this` in `valueReader`. - * @return {ol.xml.Parser} Parser. + * @return {ol.XmlParser} Parser. * @template T */ -ol.xml.makeObjectPropertyPusher = - function(valueReader, opt_property, opt_this) { +ol.xml.makeObjectPropertyPusher = function(valueReader, opt_property, opt_this) { goog.asserts.assert(valueReader !== undefined, 'undefined valueReader, expected function(this: T, Node, Array.<*>)'); return ( @@ -70346,7 +54808,12 @@ ol.xml.makeObjectPropertyPusher = opt_property : node.localName; goog.asserts.assert(goog.isObject(object), 'entity from stack was not an object'); - var array = goog.object.setIfUndefined(object, property, []); + var array; + if (property in object) { + array = object[property]; + } else { + array = object[property] = []; + } array.push(value); } }); @@ -70358,11 +54825,10 @@ ol.xml.makeObjectPropertyPusher = * @param {function(this: T, Node, Array.<*>): *} valueReader Value reader. * @param {string=} opt_property Property. * @param {T=} opt_this The object to use as `this` in `valueReader`. - * @return {ol.xml.Parser} Parser. + * @return {ol.XmlParser} Parser. * @template T */ -ol.xml.makeObjectPropertySetter = - function(valueReader, opt_property, opt_this) { +ol.xml.makeObjectPropertySetter = function(valueReader, opt_property, opt_this) { goog.asserts.assert(valueReader !== undefined, 'undefined valueReader, expected function(this: T, Node, Array.<*>)'); return ( @@ -70389,11 +54855,11 @@ ol.xml.makeObjectPropertySetter = /** * Create a serializer that appends nodes written by its `nodeWriter` to its * designated parent. The parent is the `node` of the - * {@link ol.xml.NodeStackItem} at the top of the `objectStack`. + * {@link ol.XmlNodeStackItem} at the top of the `objectStack`. * @param {function(this: T, Node, V, Array.<*>)} * nodeWriter Node writer. * @param {T=} opt_this The object to use as `this` in `nodeWriter`. - * @return {ol.xml.Serializer} Serializer. + * @return {ol.XmlSerializer} Serializer. * @template T, V */ ol.xml.makeChildAppender = function(nodeWriter, opt_this) { @@ -70422,7 +54888,7 @@ ol.xml.makeChildAppender = function(nodeWriter, opt_this) { * @param {function(this: T, Node, V, Array.<*>)} * nodeWriter Node writer. * @param {T=} opt_this The object to use as `this` in `nodeWriter`. - * @return {ol.xml.Serializer} Serializer. + * @return {ol.XmlSerializer} Serializer. * @template T, V */ ol.xml.makeArraySerializer = function(nodeWriter, opt_this) { @@ -70539,7 +55005,7 @@ ol.xml.makeStructureNS = function(namespaceURIs, structure, opt_structureNS) { /** * Parse a node using the parsers and object stack. - * @param {Object.<string, Object.<string, ol.xml.Parser>>} parsersNS + * @param {Object.<string, Object.<string, ol.XmlParser>>} parsersNS * Parsers by namespace. * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. @@ -70562,7 +55028,7 @@ ol.xml.parseNode = function(parsersNS, node, objectStack, opt_this) { /** * Push an object on top of the stack, parse and return the popped object. * @param {T} object Object. - * @param {Object.<string, Object.<string, ol.xml.Parser>>} parsersNS + * @param {Object.<string, Object.<string, ol.XmlParser>>} parsersNS * Parsers by namespace. * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. @@ -70580,7 +55046,7 @@ ol.xml.pushParseAndPop = function( /** * Walk through an array of `values` and call a serializer for each value. - * @param {Object.<string, Object.<string, ol.xml.Serializer>>} serializersNS + * @param {Object.<string, Object.<string, ol.XmlSerializer>>} serializersNS * Namespaced serializers. * @param {function(this: T, *, Array.<*>, (string|undefined)): (Node|undefined)} nodeFactory * Node factory. The `nodeFactory` creates the node whose namespace and name @@ -70620,7 +55086,7 @@ ol.xml.serialize = function( /** * @param {O} object Object. - * @param {Object.<string, Object.<string, ol.xml.Serializer>>} serializersNS + * @param {Object.<string, Object.<string, ol.XmlSerializer>>} serializersNS * Namespaced serializers. * @param {function(this: T, *, Array.<*>, (string|undefined)): (Node|undefined)} nodeFactory * Node factory. The `nodeFactory` creates the node whose namespace and name @@ -70649,57 +55115,18 @@ ol.xml.pushSerializeAndPop = function(object, return objectStack.pop(); }; -goog.provide('ol.FeatureLoader'); -goog.provide('ol.FeatureUrlFunction'); goog.provide('ol.featureloader'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.net.EventType'); -goog.require('goog.net.XhrIo'); -goog.require('goog.net.XhrIo.ResponseType'); goog.require('ol.TileState'); goog.require('ol.VectorTile'); goog.require('ol.format.FormatType'); goog.require('ol.proj'); goog.require('ol.proj.Projection'); -goog.require('ol.proj.Units'); goog.require('ol.xml'); /** - * {@link ol.source.Vector} sources use a function of this type to load - * features. - * - * This function takes an {@link ol.Extent} representing the area to be loaded, - * a `{number}` representing the resolution (map units per pixel) and an - * {@link ol.proj.Projection} for the projection as arguments. `this` within - * the function is bound to the {@link ol.source.Vector} it's called from. - * - * The function is responsible for loading the features and adding them to the - * source. - * @api - * @typedef {function(this:ol.source.Vector, ol.Extent, number, - * ol.proj.Projection)} - */ -ol.FeatureLoader; - - -/** - * {@link ol.source.Vector} sources use a function of this type to get the url - * to load features from. - * - * This function takes an {@link ol.Extent} representing the area to be loaded, - * a `{number}` representing the resolution (map units per pixel) and an - * {@link ol.proj.Projection} for the projection as arguments and returns a - * `{string}` representing the URL. - * @api - * @typedef {function(ol.Extent, number, ol.proj.Projection) : string} - */ -ol.FeatureUrlFunction; - - -/** * @param {string|ol.FeatureUrlFunction} url Feature URL service. * @param {ol.format.Feature} format Feature format. * @param {function(this:ol.VectorTile, Array.<ol.Feature>, ol.proj.Projection)|function(this:ol.source.Vector, Array.<ol.Feature>)} success @@ -70719,68 +55146,47 @@ ol.featureloader.loadFeaturesXhr = function(url, format, success, failure) { * @this {ol.source.Vector|ol.VectorTile} */ function(extent, resolution, projection) { - var xhrIo = new goog.net.XhrIo(); - xhrIo.setResponseType( - format.getType() == ol.format.FormatType.ARRAY_BUFFER ? - goog.net.XhrIo.ResponseType.ARRAY_BUFFER : - goog.net.XhrIo.ResponseType.TEXT); - goog.events.listen(xhrIo, goog.net.EventType.COMPLETE, - /** - * @param {Event} event Event. - * @private - * @this {ol.source.Vector} - */ - function(event) { - var xhrIo = event.target; - goog.asserts.assertInstanceof(xhrIo, goog.net.XhrIo, - 'event.target/xhrIo is an instance of goog.net.XhrIo'); - if (xhrIo.isSuccess()) { - var type = format.getType(); - /** @type {Document|Node|Object|string|undefined} */ - var source; - if (type == ol.format.FormatType.JSON) { - source = xhrIo.getResponseText(); - } else if (type == ol.format.FormatType.TEXT) { - source = xhrIo.getResponseText(); - } else if (type == ol.format.FormatType.XML) { - if (!goog.userAgent.IE) { - source = xhrIo.getResponseXml(); - } - if (!source) { - source = ol.xml.parse(xhrIo.getResponseText()); - } - } else if (type == ol.format.FormatType.ARRAY_BUFFER) { - source = xhrIo.getResponse(); - } else { - goog.asserts.fail('unexpected format type'); - } - if (source) { - if (ol.ENABLE_VECTOR_TILE && this instanceof ol.VectorTile) { - var dataUnits = format.readProjection(source).getUnits(); - if (dataUnits === ol.proj.Units.TILE_PIXELS) { - projection = new ol.proj.Projection({ - code: this.getProjection().getCode(), - units: dataUnits - }); - this.setProjection(projection); - } - } - success.call(this, format.readFeatures(source, - {featureProjection: projection})); - } else { - goog.asserts.fail('undefined or null source'); - } - } else { - failure.call(this); - } - goog.dispose(xhrIo); - }, false, this); - if (goog.isFunction(url)) { - xhrIo.send(url(extent, resolution, projection)); - } else { - xhrIo.send(url); + var xhr = new XMLHttpRequest(); + xhr.open('GET', + goog.isFunction(url) ? url(extent, resolution, projection) : url, + true); + if (format.getType() == ol.format.FormatType.ARRAY_BUFFER) { + xhr.responseType = 'arraybuffer'; } - + /** + * @param {Event} event Event. + * @private + */ + xhr.onload = function(event) { + if (xhr.status >= 200 && xhr.status < 300) { + var type = format.getType(); + /** @type {Document|Node|Object|string|undefined} */ + var source; + if (type == ol.format.FormatType.JSON || + type == ol.format.FormatType.TEXT) { + source = xhr.responseText; + } else if (type == ol.format.FormatType.XML) { + source = xhr.responseXML; + if (!source) { + source = ol.xml.parse(xhr.responseText); + } + } else if (type == ol.format.FormatType.ARRAY_BUFFER) { + source = /** @type {ArrayBuffer} */ (xhr.response); + } else { + goog.asserts.fail('unexpected format type'); + } + if (source) { + success.call(this, format.readFeatures(source, + {featureProjection: projection}), + format.readProjection(source)); + } else { + goog.asserts.fail('undefined or null source'); + } + } else { + failure.call(this); + } + }.bind(this); + xhr.send(); }); }; @@ -70798,9 +55204,11 @@ ol.featureloader.tile = function(url, format) { return ol.featureloader.loadFeaturesXhr(url, format, /** * @param {Array.<ol.Feature>} features The loaded features. + * @param {ol.proj.Projection} dataProjection Data projection. * @this {ol.VectorTile} */ - function(features) { + function(features, dataProjection) { + this.setProjection(dataProjection); this.setFeatures(features); }, /** @@ -70825,25 +55233,16 @@ ol.featureloader.xhr = function(url, format) { return ol.featureloader.loadFeaturesXhr(url, format, /** * @param {Array.<ol.Feature>} features The loaded features. + * @param {ol.proj.Projection} dataProjection Data projection. * @this {ol.source.Vector} */ - function(features) { + function(features, dataProjection) { this.addFeatures(features); }, /* FIXME handle error */ ol.nullFunction); }; -goog.provide('ol.LoadingStrategy'); goog.provide('ol.loadingstrategy'); -goog.require('ol.TileCoord'); - - -/** - * @typedef {function(ol.Extent, number): Array.<ol.Extent>} - * @api - */ -ol.LoadingStrategy; - /** * Strategy function for loading all features with a single request. @@ -70918,11 +55317,10 @@ var define; https://github.com/mourner/rbush */ -(function () { 'use strict'; +(function () { +'use strict'; function rbush(maxEntries, format) { - - // jshint newcap: false, validthis: true if (!(this instanceof rbush)) return new rbush(maxEntries, format); // max entries in a node is 9 by default; min node fill is 40% for best performance @@ -71147,12 +55545,11 @@ rbush.prototype = { M = Math.ceil(N / Math.pow(M, height - 1)); } - // TODO eliminate recursion? - node = { children: [], height: height, - bbox: null + bbox: null, + leaf: false }; // split the items into M mostly square tiles @@ -71214,7 +55611,7 @@ rbush.prototype = { } } - node = targetNode; + node = targetNode || node.children[0]; } return node; @@ -71258,7 +55655,9 @@ rbush.prototype = { var newNode = { children: node.children.splice(splitIndex, node.children.length - splitIndex), - height: node.height + height: node.height, + bbox: null, + leaf: false }; if (node.leaf) newNode.leaf = true; @@ -71274,7 +55673,9 @@ rbush.prototype = { // split root node this.data = { children: [node, newNode], - height: node.height + 1 + height: node.height + 1, + bbox: null, + leaf: false }; calcBBox(this.data, this.toBBox); }, @@ -71378,8 +55779,6 @@ rbush.prototype = { // because the algorithms are very sensitive to sorting functions performance, // so they should be dead simple and without inner calls - // jshint evil: true - var compareArr = ['return a', ' - b', ';']; this.compareMinX = new Function('a', 'b', compareArr.join(format[0])); @@ -71523,7 +55922,7 @@ function swap(arr, i, j) { // export as AMD/CommonJS module or global variable -if (typeof define === 'function' && define.amd) define('rbush', function() { return rbush; }); +if (typeof define === 'function' && define.amd) define('rbush', function () { return rbush; }); else if (typeof module !== 'undefined') module.exports = rbush; else if (typeof self !== 'undefined') self.rbush = rbush; else window.rbush = rbush; @@ -71536,10 +55935,9 @@ ol.ext.rbush = module.exports; goog.provide('ol.structs.RBush'); goog.require('goog.asserts'); -goog.require('goog.object'); goog.require('ol.ext.rbush'); goog.require('ol.extent'); - +goog.require('ol.object'); /** @@ -71732,8 +56130,7 @@ ol.structs.RBush.prototype.forEach = function(callback, opt_this) { * @return {*} Callback return value. * @template S */ -ol.structs.RBush.prototype.forEachInExtent = - function(extent, callback, opt_this) { +ol.structs.RBush.prototype.forEachInExtent = function(extent, callback, opt_this) { if (goog.DEBUG) { ++this.readers_; try { @@ -71771,7 +56168,7 @@ ol.structs.RBush.prototype.forEach_ = function(values, callback, opt_this) { * @return {boolean} Is empty. */ ol.structs.RBush.prototype.isEmpty = function() { - return goog.object.isEmpty(this.items_); + return ol.object.isEmpty(this.items_); }; @@ -71800,23 +56197,20 @@ goog.provide('ol.source.Vector'); goog.provide('ol.source.VectorEvent'); goog.provide('ol.source.VectorEventType'); -goog.require('goog.array'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.Event'); -goog.require('goog.events.EventType'); -goog.require('goog.object'); goog.require('ol'); goog.require('ol.Collection'); goog.require('ol.CollectionEventType'); -goog.require('ol.Extent'); goog.require('ol.Feature'); -goog.require('ol.FeatureLoader'); -goog.require('ol.LoadingStrategy'); goog.require('ol.ObjectEventType'); +goog.require('ol.array'); +goog.require('ol.events'); +goog.require('ol.events.Event'); +goog.require('ol.events.EventType'); goog.require('ol.extent'); goog.require('ol.featureloader'); goog.require('ol.loadingstrategy'); +goog.require('ol.object'); goog.require('ol.proj'); goog.require('ol.source.Source'); goog.require('ol.source.State'); @@ -71858,7 +56252,6 @@ ol.source.VectorEventType = { }; - /** * @classdesc * Provides a source of features for vector layers. Vector features provided @@ -71889,13 +56282,25 @@ ol.source.Vector = function(opt_options) { */ this.loader_ = ol.nullFunction; + /** + * @private + * @type {ol.format.Feature|undefined} + */ + this.format_ = options.format; + + /** + * @private + * @type {string|ol.FeatureUrlFunction|undefined} + */ + this.url_ = options.url; + if (options.loader !== undefined) { this.loader_ = options.loader; - } else if (options.url !== undefined) { - goog.asserts.assert(options.format !== undefined, + } else if (this.url_ !== undefined) { + goog.asserts.assert(this.format_ !== undefined, 'format must be set when url is set'); // create a XHR feature loader for "url" and "format" - this.loader_ = ol.featureloader.xhr(options.url, options.format); + this.loader_ = ol.featureloader.xhr(this.url_, this.format_); } /** @@ -71942,7 +56347,7 @@ ol.source.Vector = function(opt_options) { /** * @private - * @type {Object.<string, Array.<goog.events.Key>>} + * @type {Object.<string, Array.<ol.events.Key>>} */ this.featureChangeKeys_ = {}; @@ -71956,7 +56361,7 @@ ol.source.Vector = function(opt_options) { if (options.features instanceof ol.Collection) { collection = options.features; features = collection.getArray(); - } else if (goog.isArray(options.features)) { + } else if (Array.isArray(options.features)) { features = options.features; } if (!useSpatialIndex && collection === undefined) { @@ -72016,29 +56421,27 @@ ol.source.Vector.prototype.addFeatureInternal = function(feature) { /** - * @param {string} featureKey - * @param {ol.Feature} feature + * @param {string} featureKey Unique identifier for the feature. + * @param {ol.Feature} feature The feature. * @private */ ol.source.Vector.prototype.setupChangeEvents_ = function(featureKey, feature) { goog.asserts.assert(!(featureKey in this.featureChangeKeys_), 'key (%s) not yet registered in featureChangeKey', featureKey); this.featureChangeKeys_[featureKey] = [ - goog.events.listen(feature, - goog.events.EventType.CHANGE, - this.handleFeatureChange_, false, this), - goog.events.listen(feature, - ol.ObjectEventType.PROPERTYCHANGE, - this.handleFeatureChange_, false, this) + ol.events.listen(feature, ol.events.EventType.CHANGE, + this.handleFeatureChange_, this), + ol.events.listen(feature, ol.ObjectEventType.PROPERTYCHANGE, + this.handleFeatureChange_, this) ]; }; /** - * @param {string} featureKey - * @param {ol.Feature} feature - * @return {boolean} `true` if the feature is "valid", in the sense that it is - * also a candidate for insertion into the Rtree, otherwise `false`. + * @param {string} featureKey Unique identifier for the feature. + * @param {ol.Feature} feature The feature. + * @return {boolean} The feature is "valid", in the sense that it is also a + * candidate for insertion into the Rtree. * @private */ ol.source.Vector.prototype.addToIndex_ = function(featureKey, feature) { @@ -72123,7 +56526,7 @@ ol.source.Vector.prototype.bindFeaturesCollection_ = function(collection) { goog.asserts.assert(!this.featuresCollection_, 'bindFeaturesCollection can only be called once'); var modifyingCollection = false; - goog.events.listen(this, ol.source.VectorEventType.ADDFEATURE, + ol.events.listen(this, ol.source.VectorEventType.ADDFEATURE, function(evt) { if (!modifyingCollection) { modifyingCollection = true; @@ -72131,7 +56534,7 @@ ol.source.Vector.prototype.bindFeaturesCollection_ = function(collection) { modifyingCollection = false; } }); - goog.events.listen(this, ol.source.VectorEventType.REMOVEFEATURE, + ol.events.listen(this, ol.source.VectorEventType.REMOVEFEATURE, function(evt) { if (!modifyingCollection) { modifyingCollection = true; @@ -72139,7 +56542,7 @@ ol.source.Vector.prototype.bindFeaturesCollection_ = function(collection) { modifyingCollection = false; } }); - goog.events.listen(collection, ol.CollectionEventType.ADD, + ol.events.listen(collection, ol.CollectionEventType.ADD, function(evt) { if (!modifyingCollection) { var feature = evt.element; @@ -72148,8 +56551,8 @@ ol.source.Vector.prototype.bindFeaturesCollection_ = function(collection) { this.addFeature(feature); modifyingCollection = false; } - }, false, this); - goog.events.listen(collection, ol.CollectionEventType.REMOVE, + }, this); + ol.events.listen(collection, ol.CollectionEventType.REMOVE, function(evt) { if (!modifyingCollection) { var feature = evt.element; @@ -72158,7 +56561,7 @@ ol.source.Vector.prototype.bindFeaturesCollection_ = function(collection) { this.removeFeature(feature); modifyingCollection = false; } - }, false, this); + }, this); this.featuresCollection_ = collection; }; @@ -72172,7 +56575,7 @@ ol.source.Vector.prototype.clear = function(opt_fast) { if (opt_fast) { for (var featureId in this.featureChangeKeys_) { var keys = this.featureChangeKeys_[featureId]; - keys.forEach(goog.events.unlistenByKey); + keys.forEach(ol.events.unlistenByKey); } if (!this.featuresCollection_) { this.featureChangeKeys_ = {}; @@ -72180,20 +56583,21 @@ ol.source.Vector.prototype.clear = function(opt_fast) { this.undefIdIndex_ = {}; } } else { - var rmFeatureInternal = this.removeFeatureInternal; if (this.featuresRtree_) { - this.featuresRtree_.forEach(rmFeatureInternal, this); - goog.object.forEach(this.nullGeometryFeatures_, rmFeatureInternal, this); + this.featuresRtree_.forEach(this.removeFeatureInternal, this); + for (var id in this.nullGeometryFeatures_) { + this.removeFeatureInternal(this.nullGeometryFeatures_[id]); + } } } if (this.featuresCollection_) { this.featuresCollection_.clear(); } - goog.asserts.assert(goog.object.isEmpty(this.featureChangeKeys_), + goog.asserts.assert(ol.object.isEmpty(this.featureChangeKeys_), 'featureChangeKeys is an empty object now'); - goog.asserts.assert(goog.object.isEmpty(this.idIndex_), + goog.asserts.assert(ol.object.isEmpty(this.idIndex_), 'idIndex is an empty object now'); - goog.asserts.assert(goog.object.isEmpty(this.undefIdIndex_), + goog.asserts.assert(ol.object.isEmpty(this.undefIdIndex_), 'undefIdIndex is an empty object now'); if (this.featuresRtree_) { @@ -72242,8 +56646,7 @@ ol.source.Vector.prototype.forEachFeature = function(callback, opt_this) { * @return {S|undefined} The return value from the last call to the callback. * @template T,S */ -ol.source.Vector.prototype.forEachFeatureAtCoordinateDirect = - function(coordinate, callback, opt_this) { +ol.source.Vector.prototype.forEachFeatureAtCoordinateDirect = function(coordinate, callback, opt_this) { var extent = [coordinate[0], coordinate[1], coordinate[0], coordinate[1]]; return this.forEachFeatureInExtent(extent, function(feature) { var geometry = feature.getGeometry(); @@ -72278,8 +56681,7 @@ ol.source.Vector.prototype.forEachFeatureAtCoordinateDirect = * @template T,S * @api */ -ol.source.Vector.prototype.forEachFeatureInExtent = - function(extent, callback, opt_this) { +ol.source.Vector.prototype.forEachFeatureInExtent = function(extent, callback, opt_this) { if (this.featuresRtree_) { return this.featuresRtree_.forEachInExtent(extent, callback, opt_this); } else if (this.featuresCollection_) { @@ -72305,12 +56707,11 @@ ol.source.Vector.prototype.forEachFeatureInExtent = * @template T,S * @api */ -ol.source.Vector.prototype.forEachFeatureIntersectingExtent = - function(extent, callback, opt_this) { +ol.source.Vector.prototype.forEachFeatureIntersectingExtent = function(extent, callback, opt_this) { return this.forEachFeatureInExtent(extent, /** * @param {ol.Feature} feature Feature. - * @return {S|undefined} + * @return {S|undefined} The return value from the last call to the callback. * @template S */ function(feature) { @@ -72331,7 +56732,7 @@ ol.source.Vector.prototype.forEachFeatureIntersectingExtent = * Get the features collection associated with this source. Will be `null` * unless the source was configured with `useSpatialIndex` set to `false`, or * with an {@link ol.Collection} as `features`. - * @return {ol.Collection.<ol.Feature>} + * @return {ol.Collection.<ol.Feature>} The collection of features. * @api */ ol.source.Vector.prototype.getFeaturesCollection = function() { @@ -72350,9 +56751,9 @@ ol.source.Vector.prototype.getFeatures = function() { features = this.featuresCollection_.getArray(); } else if (this.featuresRtree_) { features = this.featuresRtree_.getAll(); - if (!goog.object.isEmpty(this.nullGeometryFeatures_)) { - goog.array.extend( - features, goog.object.getValues(this.nullGeometryFeatures_)); + if (!ol.object.isEmpty(this.nullGeometryFeatures_)) { + ol.array.extend( + features, ol.object.getValues(this.nullGeometryFeatures_)); } } goog.asserts.assert(features !== undefined, @@ -72400,11 +56801,13 @@ ol.source.Vector.prototype.getFeaturesInExtent = function(extent) { * This method is not available when the source is configured with * `useSpatialIndex` set to `false`. * @param {ol.Coordinate} coordinate Coordinate. + * @param {function(ol.Feature):boolean=} opt_filter Feature filter function. + * The filter function will receive one argument, the {@link ol.Feature feature} + * and it should return a boolean value. By default, no filtering is made. * @return {ol.Feature} Closest feature. * @api stable */ -ol.source.Vector.prototype.getClosestFeatureToCoordinate = - function(coordinate) { +ol.source.Vector.prototype.getClosestFeatureToCoordinate = function(coordinate, opt_filter) { // Find the closest feature using branch and bound. We start searching an // infinite extent, and find the distance from the first feature found. This // becomes the closest feature. We then compute a smaller extent which any @@ -72421,28 +56824,31 @@ ol.source.Vector.prototype.getClosestFeatureToCoordinate = goog.asserts.assert(this.featuresRtree_, 'getClosestFeatureToCoordinate does not work with useSpatialIndex set ' + 'to false'); + var filter = opt_filter ? opt_filter : ol.functions.TRUE; this.featuresRtree_.forEachInExtent(extent, /** * @param {ol.Feature} feature Feature. */ function(feature) { - var geometry = feature.getGeometry(); - goog.asserts.assert(geometry, - 'feature geometry is defined and not null'); - var previousMinSquaredDistance = minSquaredDistance; - minSquaredDistance = geometry.closestPointXY( - x, y, closestPoint, minSquaredDistance); - if (minSquaredDistance < previousMinSquaredDistance) { - closestFeature = feature; - // This is sneaky. Reduce the extent that it is currently being - // searched while the R-Tree traversal using this same extent object - // is still in progress. This is safe because the new extent is - // strictly contained by the old extent. - var minDistance = Math.sqrt(minSquaredDistance); - extent[0] = x - minDistance; - extent[1] = y - minDistance; - extent[2] = x + minDistance; - extent[3] = y + minDistance; + if (filter(feature)) { + var geometry = feature.getGeometry(); + goog.asserts.assert(geometry, + 'feature geometry is defined and not null'); + var previousMinSquaredDistance = minSquaredDistance; + minSquaredDistance = geometry.closestPointXY( + x, y, closestPoint, minSquaredDistance); + if (minSquaredDistance < previousMinSquaredDistance) { + closestFeature = feature; + // This is sneaky. Reduce the extent that it is currently being + // searched while the R-Tree traversal using this same extent object + // is still in progress. This is safe because the new extent is + // strictly contained by the old extent. + var minDistance = Math.sqrt(minSquaredDistance); + extent[0] = x - minDistance; + extent[1] = y - minDistance; + extent[2] = x + minDistance; + extent[3] = y + minDistance; + } } }); return closestFeature; @@ -72480,7 +56886,29 @@ ol.source.Vector.prototype.getFeatureById = function(id) { /** - * @param {goog.events.Event} event Event. + * Get the format associated with this source. + * + * @return {ol.format.Feature|undefined} The feature format. + * @api + */ +ol.source.Vector.prototype.getFormat = function() { + return this.format_; +}; + + +/** + * Get the url associated with this source. + * + * @return {string|ol.FeatureUrlFunction|undefined} The url. + * @api + */ +ol.source.Vector.prototype.getUrl = function() { + return this.url_; +}; + + +/** + * @param {ol.events.Event} event Event. * @private */ ol.source.Vector.prototype.handleFeatureChange_ = function(event) { @@ -72544,7 +56972,7 @@ ol.source.Vector.prototype.handleFeatureChange_ = function(event) { */ ol.source.Vector.prototype.isEmpty = function() { return this.featuresRtree_.isEmpty() && - goog.object.isEmpty(this.nullGeometryFeatures_); + ol.object.isEmpty(this.nullGeometryFeatures_); }; @@ -72606,7 +57034,7 @@ ol.source.Vector.prototype.removeFeatureInternal = function(feature) { var featureKey = goog.getUid(feature).toString(); goog.asserts.assert(featureKey in this.featureChangeKeys_, 'featureKey exists in featureChangeKeys'); - this.featureChangeKeys_[featureKey].forEach(goog.events.unlistenByKey); + this.featureChangeKeys_[featureKey].forEach(ol.events.unlistenByKey); delete this.featureChangeKeys_[featureKey]; var id = feature.getId(); if (id !== undefined) { @@ -72639,14 +57067,13 @@ ol.source.Vector.prototype.removeFromIdIndex_ = function(feature) { }; - /** * @classdesc * Events emitted by {@link ol.source.Vector} instances are instances of this * type. * * @constructor - * @extends {goog.events.Event} + * @extends {ol.events.Event} * @implements {oli.source.VectorEvent} * @param {string} type Type. * @param {ol.Feature=} opt_feature Feature. @@ -72663,13 +57090,13 @@ ol.source.VectorEvent = function(type, opt_feature) { this.feature = opt_feature; }; -goog.inherits(ol.source.VectorEvent, goog.events.Event); +goog.inherits(ol.source.VectorEvent, ol.events.Event); goog.provide('ol.source.ImageVector'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('goog.vec.Mat4'); goog.require('ol.dom'); goog.require('ol.extent'); @@ -72681,7 +57108,6 @@ goog.require('ol.style.Style'); goog.require('ol.vec.Mat4'); - /** * @classdesc * An image source whose images are canvas elements into which vector features @@ -72733,7 +57159,7 @@ ol.source.ImageVector = function(options) { goog.base(this, { attributions: options.attributions, - canvasFunction: goog.bind(this.canvasFunctionInternal_, this), + canvasFunction: this.canvasFunctionInternal_.bind(this), logo: options.logo, projection: options.projection, ratio: options.ratio, @@ -72757,8 +57183,8 @@ ol.source.ImageVector = function(options) { this.setStyle(options.style); - goog.events.listen(this.source_, goog.events.EventType.CHANGE, - this.handleSourceChange_, undefined, this); + ol.events.listen(this.source_, ol.events.EventType.CHANGE, + this.handleSourceChange_, this); }; goog.inherits(ol.source.ImageVector, ol.source.ImageCanvas); @@ -72773,8 +57199,7 @@ goog.inherits(ol.source.ImageVector, ol.source.ImageCanvas); * @return {HTMLCanvasElement} Canvas element. * @private */ -ol.source.ImageVector.prototype.canvasFunctionInternal_ = - function(extent, resolution, pixelRatio, size, projection) { +ol.source.ImageVector.prototype.canvasFunctionInternal_ = function(extent, resolution, pixelRatio, size, projection) { var replayGroup = new ol.render.canvas.ReplayGroup( ol.renderer.vector.getTolerance(resolution, pixelRatio), extent, @@ -72884,8 +57309,7 @@ ol.source.ImageVector.prototype.getStyleFunction = function() { * @return {!goog.vec.Mat4.Number} Transform. * @private */ -ol.source.ImageVector.prototype.getTransform_ = - function(center, resolution, pixelRatio, size) { +ol.source.ImageVector.prototype.getTransform_ = function(center, resolution, pixelRatio, size) { return ol.vec.Mat4.makeTransform2D(this.transform_, size[0] / 2, size[1] / 2, pixelRatio / resolution, -pixelRatio / resolution, @@ -72896,11 +57320,10 @@ ol.source.ImageVector.prototype.getTransform_ = /** * Handle changes in image style state. - * @param {goog.events.Event} event Image style change event. + * @param {ol.events.Event} event Image style change event. * @private */ -ol.source.ImageVector.prototype.handleImageChange_ = - function(event) { +ol.source.ImageVector.prototype.handleImageChange_ = function(event) { this.changed(); }; @@ -72923,8 +57346,7 @@ ol.source.ImageVector.prototype.handleSourceChange_ = function() { * @return {boolean} `true` if an image is loading. * @private */ -ol.source.ImageVector.prototype.renderFeature_ = - function(feature, resolution, pixelRatio, replayGroup) { +ol.source.ImageVector.prototype.renderFeature_ = function(feature, resolution, pixelRatio, replayGroup) { var styles; var styleFunction = feature.getStyleFunction(); if (styleFunction) { @@ -72936,6 +57358,9 @@ ol.source.ImageVector.prototype.renderFeature_ = return false; } var i, ii, loading = false; + if (!Array.isArray(styles)) { + styles = [styles]; + } for (i = 0, ii = styles.length; i < ii; ++i) { loading = ol.renderer.vector.renderFeature( replayGroup, feature, styles[i], @@ -72967,8 +57392,8 @@ ol.source.ImageVector.prototype.setStyle = function(style) { goog.provide('ol.renderer.canvas.ImageLayer'); goog.require('goog.asserts'); -goog.require('goog.functions'); goog.require('goog.vec.Mat4'); +goog.require('ol.functions'); goog.require('ol.ImageBase'); goog.require('ol.ViewHint'); goog.require('ol.dom'); @@ -72980,7 +57405,6 @@ goog.require('ol.source.ImageVector'); goog.require('ol.vec.Mat4'); - /** * @constructor * @extends {ol.renderer.canvas.Layer} @@ -73021,8 +57445,7 @@ goog.inherits(ol.renderer.canvas.ImageLayer, ol.renderer.canvas.Layer); /** * @inheritDoc */ -ol.renderer.canvas.ImageLayer.prototype.forEachFeatureAtCoordinate = - function(coordinate, frameState, callback, thisArg) { +ol.renderer.canvas.ImageLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, callback, thisArg) { var layer = this.getLayer(); var source = layer.getSource(); var resolution = frameState.viewState.resolution; @@ -73043,8 +57466,7 @@ ol.renderer.canvas.ImageLayer.prototype.forEachFeatureAtCoordinate = /** * @inheritDoc */ -ol.renderer.canvas.ImageLayer.prototype.forEachLayerAtPixel = - function(pixel, frameState, callback, thisArg) { +ol.renderer.canvas.ImageLayer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) { if (!this.getImage()) { return undefined; } @@ -73056,7 +57478,7 @@ ol.renderer.canvas.ImageLayer.prototype.forEachLayerAtPixel = ol.vec.Mat4.multVec2( frameState.pixelToCoordinateMatrix, coordinate, coordinate); var hasFeature = this.forEachFeatureAtCoordinate( - coordinate, frameState, goog.functions.TRUE, this); + coordinate, frameState, ol.functions.TRUE, this); if (hasFeature) { return callback.call(thisArg, this.getLayer()); @@ -73110,14 +57532,12 @@ ol.renderer.canvas.ImageLayer.prototype.getImageTransform = function() { /** * @inheritDoc */ -ol.renderer.canvas.ImageLayer.prototype.prepareFrame = - function(frameState, layerState) { +ol.renderer.canvas.ImageLayer.prototype.prepareFrame = function(frameState, layerState) { var pixelRatio = frameState.pixelRatio; var viewState = frameState.viewState; var viewCenter = viewState.center; var viewResolution = viewState.resolution; - var viewRotation = viewState.rotation; var image; var imageLayer = this.getLayer(); @@ -73165,7 +57585,7 @@ ol.renderer.canvas.ImageLayer.prototype.prepareFrame = pixelRatio * frameState.size[0] / 2, pixelRatio * frameState.size[1] / 2, scale, scale, - viewRotation, + 0, imagePixelRatio * (imageExtent[0] - viewCenter[0]) / imageResolution, imagePixelRatio * (viewCenter[1] - imageExtent[3]) / imageResolution); this.imageTransformInv_ = null; @@ -73173,62 +57593,59 @@ ol.renderer.canvas.ImageLayer.prototype.prepareFrame = this.updateLogos(frameState, imageSource); } - return true; + return !!this.image_; }; // FIXME find correct globalCompositeOperation -// FIXME optimize :-) goog.provide('ol.renderer.canvas.TileLayer'); goog.require('goog.asserts'); goog.require('goog.vec.Mat4'); -goog.require('ol.Size'); goog.require('ol.TileRange'); goog.require('ol.TileState'); goog.require('ol.array'); goog.require('ol.dom'); goog.require('ol.extent'); -goog.require('ol.layer.Tile'); +goog.require('ol.render.EventType'); goog.require('ol.renderer.canvas.Layer'); goog.require('ol.size'); -goog.require('ol.tilecoord'); +goog.require('ol.source.Tile'); goog.require('ol.vec.Mat4'); - /** * @constructor * @extends {ol.renderer.canvas.Layer} - * @param {ol.layer.Tile} tileLayer Tile layer. + * @param {ol.layer.Tile|ol.layer.VectorTile} tileLayer Tile layer. */ ol.renderer.canvas.TileLayer = function(tileLayer) { goog.base(this, tileLayer); /** - * @private - * @type {HTMLCanvasElement} + * @protected + * @type {CanvasRenderingContext2D} */ - this.canvas_ = null; + this.context = ol.dom.createCanvasContext2D(); /** - * @private - * @type {ol.Size} + * @protected + * @type {Array.<ol.Tile|undefined>} */ - this.canvasSize_ = null; + this.renderedTiles = null; /** - * @private - * @type {boolean} + * @protected + * @type {ol.Extent} */ - this.canvasTooBig_ = false; + this.tmpExtent = ol.extent.createEmpty(); /** * @private - * @type {CanvasRenderingContext2D} + * @type {ol.TileCoord} */ - this.context_ = null; + this.tmpTileCoord_ = [0, 0, 0]; /** * @private @@ -73237,46 +57654,10 @@ ol.renderer.canvas.TileLayer = function(tileLayer) { this.imageTransform_ = goog.vec.Mat4.createNumber(); /** - * @private - * @type {?goog.vec.Mat4.Number} - */ - this.imageTransformInv_ = null; - - /** - * @private - * @type {number} - */ - this.renderedCanvasZ_ = NaN; - - /** - * @private - * @type {number} - */ - this.renderedTileWidth_ = NaN; - - /** - * @private + * @protected * @type {number} */ - this.renderedTileHeight_ = NaN; - - /** - * @private - * @type {ol.TileRange} - */ - this.renderedCanvasTileRange_ = null; - - /** - * @private - * @type {Array.<ol.Tile|undefined>} - */ - this.renderedTiles_ = null; - - /** - * @private - * @type {ol.Size} - */ - this.tmpSize_ = [0, 0]; + this.zDirection = 0; }; goog.inherits(ol.renderer.canvas.TileLayer, ol.renderer.canvas.Layer); @@ -73285,105 +57666,32 @@ goog.inherits(ol.renderer.canvas.TileLayer, ol.renderer.canvas.Layer); /** * @inheritDoc */ -ol.renderer.canvas.TileLayer.prototype.getImage = function() { - return this.canvas_; -}; - - -/** - * @inheritDoc - */ -ol.renderer.canvas.TileLayer.prototype.getImageTransform = function() { - return this.imageTransform_; +ol.renderer.canvas.TileLayer.prototype.composeFrame = function( + frameState, layerState, context) { + var transform = this.getTransform(frameState, 0); + this.dispatchPreComposeEvent(context, frameState, transform); + this.renderTileImages(context, frameState, layerState); + this.dispatchPostComposeEvent(context, frameState, transform); }; /** * @inheritDoc */ -ol.renderer.canvas.TileLayer.prototype.prepareFrame = - function(frameState, layerState) { - - // - // Warning! You're entering a dangerous zone! - // - // The canvas tile layer renderering is highly optimized, hence - // the complexity of this function. For best performance we try - // to minimize the number of pixels to update on the canvas. This - // includes: - // - // - Only drawing pixels that will be visible. - // - Not re-drawing pixels/tiles that are already correct. - // - Minimizing calls to clearRect. - // - Never shrink the canvas. Just make it bigger when necessary. - // Re-sizing the canvas also clears it, which further means - // re-creating it (expensive). - // - // The various steps performed by this functions: - // - // - Create a canvas element if none has been created yet. - // - // - Make the canvas bigger if it's too small. Note that we never shrink - // the canvas, we just make it bigger when necessary, when rotating for - // example. Note also that the canvas always contains a whole number - // of tiles. - // - // - Invalidate the canvas tile range (renderedCanvasTileRange_ = null) - // if (1) the canvas has been enlarged, or (2) the zoom level changes, - // or (3) the canvas tile range doesn't contain the required tile - // range. This canvas tile range invalidation thing is related to - // an optimization where we attempt to redraw as few pixels as - // possible on each prepareFrame call. - // - // - If the canvas tile range has been invalidated we reset - // renderedCanvasTileRange_ and reset the renderedTiles_ array. - // The renderedTiles_ array is the structure used to determine - // the canvas pixels that need not be redrawn from one prepareFrame - // call to another. It records while tile has been rendered at - // which position in the canvas. - // - // - We then determine the tiles to draw on the canvas. Tiles for - // the target resolution may not be loaded yet. In that case we - // use low-resolution/interim tiles if loaded already. And, if - // for a non-yet-loaded tile we haven't found a corresponding - // low-resolution tile we indicate that the pixels for that - // tile must be cleared on the canvas. Note: determining the - // interim tiles is based on tile extents instead of tile - // coords, this is to be able to handler irregular tile grids. - // - // - We're now ready to render. We start by calling clearRect - // for the tiles that aren't loaded yet and are not fully covered - // by a low-resolution tile (if they're loaded, we'll draw them; - // if they're fully covered by a low-resolution tile then there's - // no need to clear). We then render the tiles "back to front", - // i.e. starting with the low-resolution tiles. - // - // - After rendering some bookkeeping is performed (updateUsedTiles, - // etc.). manageTilePyramid is what enqueue tiles in the tile - // queue for loading. - // - // - The last step involves updating the image transform matrix, - // which will be used by the map renderer for the final - // composition and positioning. - // +ol.renderer.canvas.TileLayer.prototype.prepareFrame = function( + frameState, layerState) { var pixelRatio = frameState.pixelRatio; var viewState = frameState.viewState; var projection = viewState.projection; var tileLayer = this.getLayer(); - goog.asserts.assertInstanceof(tileLayer, ol.layer.Tile, - 'layer is an instance of ol.layer.Tile'); var tileSource = tileLayer.getSource(); + goog.asserts.assertInstanceof(tileSource, ol.source.Tile, + 'source is an ol.source.Tile'); var tileGrid = tileSource.getTileGridForProjection(projection); - var tileGutter = tileSource.getGutter(); - var z = tileGrid.getZForResolution(viewState.resolution); - var tilePixelSize = - tileSource.getTilePixelSize(z, frameState.pixelRatio, projection); - var tilePixelRatio = tilePixelSize[0] / - ol.size.toSize(tileGrid.getTileSize(z), this.tmpSize_)[0]; + var z = tileGrid.getZForResolution(viewState.resolution, this.zDirection); var tileResolution = tileGrid.getResolution(z); - var tilePixelResolution = tileResolution / tilePixelRatio; var center = viewState.center; var extent; if (tileResolution == viewState.resolution) { @@ -73405,87 +57713,11 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = var tileRange = tileGrid.getTileRangeForExtentAndResolution( extent, tileResolution); - var canvasWidth = tilePixelSize[0] * tileRange.getWidth(); - var canvasHeight = tilePixelSize[1] * tileRange.getHeight(); - - var canvas, context; - if (!this.canvas_) { - goog.asserts.assert(!this.canvasSize_, - 'canvasSize is null (because canvas is null)'); - goog.asserts.assert(!this.context_, - 'context is null (because canvas is null)'); - goog.asserts.assert(!this.renderedCanvasTileRange_, - 'renderedCanvasTileRange is null (because canvas is null)'); - context = ol.dom.createCanvasContext2D(canvasWidth, canvasHeight); - this.canvas_ = context.canvas; - this.canvasSize_ = [canvasWidth, canvasHeight]; - this.context_ = context; - this.canvasTooBig_ = - !ol.renderer.canvas.Layer.testCanvasSize(this.canvasSize_); - } else { - goog.asserts.assert(this.canvasSize_, - 'non-null canvasSize (because canvas is not null)'); - goog.asserts.assert(this.context_, - 'non-null context (because canvas is not null)'); - canvas = this.canvas_; - context = this.context_; - if (this.canvasSize_[0] < canvasWidth || - this.canvasSize_[1] < canvasHeight || - this.renderedTileWidth_ !== tilePixelSize[0] || - this.renderedTileHeight_ !== tilePixelSize[1] || - (this.canvasTooBig_ && (this.canvasSize_[0] > canvasWidth || - this.canvasSize_[1] > canvasHeight))) { - // Canvas is too small or tileSize has changed, resize it. - // We never shrink the canvas, unless - // we know that the current canvas size exceeds the maximum size - canvas.width = canvasWidth; - canvas.height = canvasHeight; - this.canvasSize_ = [canvasWidth, canvasHeight]; - this.canvasTooBig_ = - !ol.renderer.canvas.Layer.testCanvasSize(this.canvasSize_); - this.renderedCanvasTileRange_ = null; - } else { - canvasWidth = this.canvasSize_[0]; - canvasHeight = this.canvasSize_[1]; - if (z != this.renderedCanvasZ_ || - !this.renderedCanvasTileRange_.containsTileRange(tileRange)) { - this.renderedCanvasTileRange_ = null; - } - } - } - - var canvasTileRange, canvasTileRangeWidth, minX, minY; - if (!this.renderedCanvasTileRange_) { - canvasTileRangeWidth = canvasWidth / tilePixelSize[0]; - var canvasTileRangeHeight = canvasHeight / tilePixelSize[1]; - minX = tileRange.minX - - Math.floor((canvasTileRangeWidth - tileRange.getWidth()) / 2); - minY = tileRange.minY - - Math.floor((canvasTileRangeHeight - tileRange.getHeight()) / 2); - this.renderedCanvasZ_ = z; - this.renderedTileWidth_ = tilePixelSize[0]; - this.renderedTileHeight_ = tilePixelSize[1]; - this.renderedCanvasTileRange_ = new ol.TileRange( - minX, minX + canvasTileRangeWidth - 1, - minY, minY + canvasTileRangeHeight - 1); - this.renderedTiles_ = - new Array(canvasTileRangeWidth * canvasTileRangeHeight); - canvasTileRange = this.renderedCanvasTileRange_; - } else { - canvasTileRange = this.renderedCanvasTileRange_; - canvasTileRangeWidth = canvasTileRange.getWidth(); - } - - goog.asserts.assert(canvasTileRange.containsTileRange(tileRange), - 'tileRange is contained in canvasTileRange'); - /** * @type {Object.<number, Object.<string, ol.Tile>>} */ var tilesToDrawByZ = {}; tilesToDrawByZ[z] = {}; - /** @type {Array.<ol.Tile>} */ - var tilesToClear = []; var findLoadedTiles = this.createLoadedTileFinder( tileSource, projection, tilesToDrawByZ); @@ -73514,15 +57746,12 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = } goog.asserts.assert(tile); if (drawableTile(tile)) { - tilesToDrawByZ[z][ol.tilecoord.toString(tile.tileCoord)] = tile; + tilesToDrawByZ[z][tile.tileCoord.toString()] = tile; continue; } fullyLoaded = tileGrid.forEachTileCoordParentTileRange( tile.tileCoord, findLoadedTiles, null, tmpTileRange, tmpExtent); if (!fullyLoaded) { - // FIXME we do not need to clear the tile if it is fully covered by its - // children - tilesToClear.push(tile); childTileRange = tileGrid.getTileCoordChildTileRange( tile.tileCoord, tmpTileRange, tmpExtent); if (childTileRange) { @@ -73533,86 +57762,22 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = } } - var i, ii; - for (i = 0, ii = tilesToClear.length; i < ii; ++i) { - tile = tilesToClear[i]; - x = tilePixelSize[0] * (tile.tileCoord[1] - canvasTileRange.minX); - y = tilePixelSize[1] * (canvasTileRange.maxY - tile.tileCoord[2]); - context.clearRect(x, y, tilePixelSize[0], tilePixelSize[1]); - } - /** @type {Array.<number>} */ var zs = Object.keys(tilesToDrawByZ).map(Number); zs.sort(ol.array.numberSafeCompareFunction); - var opaque = tileSource.getOpaque(); - var origin = ol.extent.getTopLeft(tileGrid.getTileCoordExtent( - [z, canvasTileRange.minX, canvasTileRange.maxY], - tmpExtent)); - var currentZ, index, scale, tileCoordKey, tileExtent, tileState, tilesToDraw; - var ix, iy, interimTileRange, maxX, maxY; - var height, width; + var renderables = []; + var i, ii, currentZ, tileCoordKey, tilesToDraw; for (i = 0, ii = zs.length; i < ii; ++i) { currentZ = zs[i]; - tilePixelSize = - tileSource.getTilePixelSize(currentZ, pixelRatio, projection); tilesToDraw = tilesToDrawByZ[currentZ]; - if (currentZ == z) { - for (tileCoordKey in tilesToDraw) { - tile = tilesToDraw[tileCoordKey]; - index = - (tile.tileCoord[2] - canvasTileRange.minY) * canvasTileRangeWidth + - (tile.tileCoord[1] - canvasTileRange.minX); - if (this.renderedTiles_[index] != tile) { - x = tilePixelSize[0] * (tile.tileCoord[1] - canvasTileRange.minX); - y = tilePixelSize[1] * (canvasTileRange.maxY - tile.tileCoord[2]); - tileState = tile.getState(); - if (tileState == ol.TileState.EMPTY || - (tileState == ol.TileState.ERROR && !useInterimTilesOnError) || - !opaque) { - context.clearRect(x, y, tilePixelSize[0], tilePixelSize[1]); - } - if (tileState == ol.TileState.LOADED) { - context.drawImage(tile.getImage(), - tileGutter, tileGutter, tilePixelSize[0], tilePixelSize[1], - x, y, tilePixelSize[0], tilePixelSize[1]); - } - this.renderedTiles_[index] = tile; - } - } - } else { - scale = tileGrid.getResolution(currentZ) / tileResolution; - for (tileCoordKey in tilesToDraw) { - tile = tilesToDraw[tileCoordKey]; - tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord, tmpExtent); - x = (tileExtent[0] - origin[0]) / tilePixelResolution; - y = (origin[1] - tileExtent[3]) / tilePixelResolution; - width = scale * tilePixelSize[0]; - height = scale * tilePixelSize[1]; - tileState = tile.getState(); - if (tileState == ol.TileState.EMPTY || !opaque) { - context.clearRect(x, y, width, height); - } - if (tileState == ol.TileState.LOADED) { - context.drawImage(tile.getImage(), - tileGutter, tileGutter, tilePixelSize[0], tilePixelSize[1], - x, y, width, height); - } - interimTileRange = - tileGrid.getTileRangeForExtentAndZ(tileExtent, z, tmpTileRange); - minX = Math.max(interimTileRange.minX, canvasTileRange.minX); - maxX = Math.min(interimTileRange.maxX, canvasTileRange.maxX); - minY = Math.max(interimTileRange.minY, canvasTileRange.minY); - maxY = Math.min(interimTileRange.maxY, canvasTileRange.maxY); - for (ix = minX; ix <= maxX; ++ix) { - for (iy = minY; iy <= maxY; ++iy) { - index = (iy - canvasTileRange.minY) * canvasTileRangeWidth + - (ix - canvasTileRange.minX); - this.renderedTiles_[index] = undefined; - } - } + for (tileCoordKey in tilesToDraw) { + tile = tilesToDraw[tileCoordKey]; + if (tile.getState() == ol.TileState.LOADED) { + renderables.push(tile); } } } + this.renderedTiles = renderables; this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange); this.manageTilePyramid(frameState, tileSource, tileGrid, pixelRatio, @@ -73620,16 +57785,6 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = this.scheduleExpireCache(frameState, tileSource); this.updateLogos(frameState, tileSource); - ol.vec.Mat4.makeTransform2D(this.imageTransform_, - pixelRatio * frameState.size[0] / 2, - pixelRatio * frameState.size[1] / 2, - pixelRatio * tilePixelResolution / viewState.resolution, - pixelRatio * tilePixelResolution / viewState.resolution, - viewState.rotation, - (origin[0] - center[0]) / tilePixelResolution, - (center[1] - origin[1]) / tilePixelResolution); - this.imageTransformInv_ = null; - return true; }; @@ -73637,22 +57792,16 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = /** * @inheritDoc */ -ol.renderer.canvas.TileLayer.prototype.forEachLayerAtPixel = - function(pixel, frameState, callback, thisArg) { - if (!this.context_) { - return undefined; - } - - if (!this.imageTransformInv_) { - this.imageTransformInv_ = goog.vec.Mat4.createNumber(); - goog.vec.Mat4.invert(this.imageTransform_, this.imageTransformInv_); - } +ol.renderer.canvas.TileLayer.prototype.forEachLayerAtPixel = function( + pixel, frameState, callback, thisArg) { + var canvas = this.context.canvas; + var size = frameState.size; + canvas.width = size[0]; + canvas.height = size[1]; + this.composeFrame(frameState, this.getLayer().getLayerState(), this.context); - var pixelOnCanvas = - this.getPixelOnCanvas(pixel, this.imageTransformInv_); - - var imageData = this.context_.getImageData( - pixelOnCanvas[0], pixelOnCanvas[1], 1, 1).data; + var imageData = this.context.getImageData( + pixel[0], pixel[1], 1, 1).data; if (imageData[3] > 0) { return callback.call(thisArg, this.getLayer()); @@ -73661,22 +57810,156 @@ ol.renderer.canvas.TileLayer.prototype.forEachLayerAtPixel = } }; + +/** + * @param {CanvasRenderingContext2D} context Context. + * @param {olx.FrameState} frameState Frame state. + * @param {ol.LayerState} layerState Layer state. + * @protected + */ +ol.renderer.canvas.TileLayer.prototype.renderTileImages = function(context, frameState, layerState) { + var pixelRatio = frameState.pixelRatio; + var viewState = frameState.viewState; + var center = viewState.center; + var projection = viewState.projection; + var resolution = viewState.resolution; + var rotation = viewState.rotation; + var size = frameState.size; + var offsetX = Math.round(pixelRatio * size[0] / 2); + var offsetY = Math.round(pixelRatio * size[1] / 2); + var pixelScale = pixelRatio / resolution; + var layer = this.getLayer(); + var source = layer.getSource(); + goog.asserts.assertInstanceof(source, ol.source.Tile, + 'source is an ol.source.Tile'); + var tileGutter = source.getGutter(projection); + var tileGrid = source.getTileGridForProjection(projection); + + var hasRenderListeners = layer.hasListener(ol.render.EventType.RENDER); + var renderContext = context; + var drawOffsetX, drawOffsetY, drawScale, drawSize; + if (rotation || hasRenderListeners) { + renderContext = this.context; + var renderCanvas = renderContext.canvas; + var drawZ = tileGrid.getZForResolution(resolution); + var drawTileSize = source.getTilePixelSize(drawZ, pixelRatio, projection); + var tileSize = ol.size.toSize(tileGrid.getTileSize(drawZ)); + drawScale = drawTileSize[0] / tileSize[0]; + var width = context.canvas.width * drawScale; + var height = context.canvas.height * drawScale; + // Make sure the canvas is big enough for all possible rotation angles + drawSize = Math.round(Math.sqrt(width * width + height * height)); + if (renderCanvas.width != drawSize) { + renderCanvas.width = renderCanvas.height = drawSize; + } else { + renderContext.clearRect(0, 0, drawSize, drawSize); + } + drawOffsetX = (drawSize - width) / 2 / drawScale; + drawOffsetY = (drawSize - height) / 2 / drawScale; + pixelScale *= drawScale; + offsetX = Math.round(drawScale * (offsetX + drawOffsetX)) + offsetY = Math.round(drawScale * (offsetY + drawOffsetY)); + } + // for performance reasons, context.save / context.restore is not used + // to save and restore the transformation matrix and the opacity. + // see http://jsperf.com/context-save-restore-versus-variable + var alpha = renderContext.globalAlpha; + renderContext.globalAlpha = layerState.opacity; + + var tilesToDraw = this.renderedTiles; + + var pixelExtents; + var opaque = source.getOpaque(projection) && layerState.opacity == 1; + if (!opaque) { + tilesToDraw.reverse(); + pixelExtents = []; + } + for (var i = 0, ii = tilesToDraw.length; i < ii; ++i) { + var tile = tilesToDraw[i]; + var tileCoord = tile.getTileCoord(); + var tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent); + var currentZ = tileCoord[0]; + // Calculate all insert points by tile widths from a common origin to avoid + // gaps caused by rounding + var origin = ol.extent.getBottomLeft(tileGrid.getTileCoordExtent( + tileGrid.getTileCoordForCoordAndZ(center, currentZ, this.tmpTileCoord_))); + var w = Math.round(ol.extent.getWidth(tileExtent) * pixelScale); + var h = Math.round(ol.extent.getHeight(tileExtent) * pixelScale); + var left = Math.round((tileExtent[0] - origin[0]) * pixelScale / w) * w + + offsetX + Math.round((origin[0] - center[0]) * pixelScale); + var top = Math.round((origin[1] - tileExtent[3]) * pixelScale / h) * h + + offsetY + Math.round((center[1] - origin[1]) * pixelScale); + if (!opaque) { + var pixelExtent = [left, top, left + w, top + h]; + // Create a clip mask for regions in this low resolution tile that are + // already filled by a higher resolution tile + renderContext.save(); + for (var j = 0, jj = pixelExtents.length; j < jj; ++j) { + var clipExtent = pixelExtents[j]; + if (ol.extent.intersects(pixelExtent, clipExtent)) { + renderContext.beginPath(); + // counter-clockwise (outer ring) for current tile + renderContext.moveTo(pixelExtent[0], pixelExtent[1]); + renderContext.lineTo(pixelExtent[0], pixelExtent[3]); + renderContext.lineTo(pixelExtent[2], pixelExtent[3]); + renderContext.lineTo(pixelExtent[2], pixelExtent[1]); + // clockwise (inner ring) for higher resolution tile + renderContext.moveTo(clipExtent[0], clipExtent[1]); + renderContext.lineTo(clipExtent[2], clipExtent[1]); + renderContext.lineTo(clipExtent[2], clipExtent[3]); + renderContext.lineTo(clipExtent[0], clipExtent[3]); + renderContext.closePath(); + renderContext.clip(); + } + } + pixelExtents.push(pixelExtent); + } + var tilePixelSize = source.getTilePixelSize(currentZ, pixelRatio, projection); + renderContext.drawImage(tile.getImage(), tileGutter, tileGutter, + tilePixelSize[0], tilePixelSize[1], left, top, w, h); + if (!opaque) { + renderContext.restore(); + } + } + + if (hasRenderListeners) { + var dX = drawOffsetX - offsetX / drawScale + offsetX; + var dY = drawOffsetY - offsetY / drawScale + offsetY; + var imageTransform = ol.vec.Mat4.makeTransform2D(this.imageTransform_, + drawSize / 2 - dX, drawSize / 2 - dY, pixelScale, -pixelScale, + -rotation, -center[0] + dX / pixelScale, -center[1] - dY / pixelScale); + this.dispatchRenderEvent(renderContext, frameState, imageTransform); + } + if (rotation || hasRenderListeners) { + context.drawImage(renderContext.canvas, -Math.round(drawOffsetX), + -Math.round(drawOffsetY), drawSize / drawScale, drawSize / drawScale); + } + renderContext.globalAlpha = alpha; +}; + + +/** + * @function + * @return {ol.layer.Tile|ol.layer.VectorTile} + */ +ol.renderer.canvas.TileLayer.prototype.getLayer; + goog.provide('ol.renderer.canvas.VectorLayer'); goog.require('goog.asserts'); -goog.require('goog.events'); +goog.require('ol.events'); goog.require('ol.ViewHint'); goog.require('ol.dom'); goog.require('ol.extent'); goog.require('ol.layer.Vector'); goog.require('ol.render.EventType'); +goog.require('ol.render.canvas'); goog.require('ol.render.canvas.ReplayGroup'); goog.require('ol.renderer.canvas.Layer'); goog.require('ol.renderer.vector'); goog.require('ol.source.Vector'); - /** * @constructor * @extends {ol.renderer.canvas.Layer} @@ -73735,8 +58018,7 @@ goog.inherits(ol.renderer.canvas.VectorLayer, ol.renderer.canvas.Layer); /** * @inheritDoc */ -ol.renderer.canvas.VectorLayer.prototype.composeFrame = - function(frameState, layerState, context) { +ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, layerState, context) { var extent = frameState.extent; var pixelRatio = frameState.pixelRatio; @@ -73771,6 +58053,10 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = var alpha = replayContext.globalAlpha; replayContext.globalAlpha = layerState.opacity; + var width = frameState.size[0] * pixelRatio; + var height = frameState.size[1] * pixelRatio; + ol.render.canvas.rotateAtOffset(replayContext, -rotation, + width / 2, height / 2); replayGroup.replay(replayContext, pixelRatio, transform, rotation, skippedFeatureUids); if (vectorSource.getWrapX() && projection.canWrapX() && @@ -73800,6 +58086,8 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = // restore original transform for render and compose events transform = this.getTransform(frameState, 0); } + ol.render.canvas.rotateAtOffset(replayContext, rotation, + width / 2, height / 2); if (replayContext != context) { this.dispatchRenderEvent(replayContext, frameState, transform); @@ -73816,19 +58104,17 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = /** * @inheritDoc */ -ol.renderer.canvas.VectorLayer.prototype.forEachFeatureAtCoordinate = - function(coordinate, frameState, callback, thisArg) { +ol.renderer.canvas.VectorLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, callback, thisArg) { if (!this.replayGroup_) { return undefined; } else { var resolution = frameState.viewState.resolution; var rotation = frameState.viewState.rotation; var layer = this.getLayer(); - var layerState = frameState.layerStates[goog.getUid(layer)]; /** @type {Object.<string, boolean>} */ var features = {}; return this.replayGroup_.forEachFeatureAtCoordinate(coordinate, resolution, - rotation, layerState.managed ? frameState.skippedFeatureUids : {}, + rotation, {}, /** * @param {ol.Feature|ol.render.Feature} feature Feature. * @return {?} Callback result. @@ -73847,11 +58133,10 @@ ol.renderer.canvas.VectorLayer.prototype.forEachFeatureAtCoordinate = /** * Handle changes in image style state. - * @param {goog.events.Event} event Image style change event. + * @param {ol.events.Event} event Image style change event. * @private */ -ol.renderer.canvas.VectorLayer.prototype.handleStyleImageChange_ = - function(event) { +ol.renderer.canvas.VectorLayer.prototype.handleStyleImageChange_ = function(event) { this.renderIfReadyAndVisible(); }; @@ -73859,8 +58144,7 @@ ol.renderer.canvas.VectorLayer.prototype.handleStyleImageChange_ = /** * @inheritDoc */ -ol.renderer.canvas.VectorLayer.prototype.prepareFrame = - function(frameState, layerState) { +ol.renderer.canvas.VectorLayer.prototype.prepareFrame = function(frameState, layerState) { var vectorLayer = /** @type {ol.layer.Vector} */ (this.getLayer()); goog.asserts.assertInstanceof(vectorLayer, ol.layer.Vector, @@ -73919,8 +58203,6 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame = return true; } - // FIXME dispose of old replayGroup in post render - goog.dispose(this.replayGroup_); this.replayGroup_ = null; this.dirty_ = false; @@ -73930,12 +58212,11 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame = ol.renderer.vector.getTolerance(resolution, pixelRatio), extent, resolution, vectorLayer.getRenderBuffer()); vectorSource.loadFeatures(extent, resolution, projection); - var renderFeature = - /** - * @param {ol.Feature} feature Feature. - * @this {ol.renderer.canvas.VectorLayer} - */ - function(feature) { + /** + * @param {ol.Feature} feature Feature. + * @this {ol.renderer.canvas.VectorLayer} + */ + var renderFeature = function(feature) { var styles; var styleFunction = feature.getStyleFunction(); if (styleFunction) { @@ -73988,13 +58269,12 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame = * @param {ol.render.canvas.ReplayGroup} replayGroup Replay group. * @return {boolean} `true` if an image is loading. */ -ol.renderer.canvas.VectorLayer.prototype.renderFeature = - function(feature, resolution, pixelRatio, styles, replayGroup) { +ol.renderer.canvas.VectorLayer.prototype.renderFeature = function(feature, resolution, pixelRatio, styles, replayGroup) { if (!styles) { return false; } var loading = false; - if (goog.isArray(styles)) { + if (Array.isArray(styles)) { for (var i = 0, ii = styles.length; i < ii; ++i) { loading = ol.renderer.vector.renderFeature( replayGroup, feature, styles[i], @@ -74011,39 +58291,13 @@ ol.renderer.canvas.VectorLayer.prototype.renderFeature = }; goog.provide('ol.TileUrlFunction'); -goog.provide('ol.TileUrlFunctionType'); goog.require('goog.asserts'); -goog.require('goog.math'); -goog.require('ol.TileCoord'); +goog.require('ol.math'); goog.require('ol.tilecoord'); /** - * {@link ol.source.Tile} sources use a function of this type to get the url - * that provides a tile for a given tile coordinate. - * - * This function takes an {@link ol.TileCoord} for the tile coordinate, a - * `{number}` representing the pixel ratio and an {@link ol.proj.Projection} for - * the projection as arguments and returns a `{string}` representing the tile - * URL, or undefined if no tile should be requested for the passed tile - * coordinate. - * - * @typedef {function(ol.TileCoord, number, - * ol.proj.Projection): (string|undefined)} - * @api - */ -ol.TileUrlFunctionType; - - -/** - * @typedef {function(ol.TileCoord, ol.proj.Projection, ol.TileCoord=): - * ol.TileCoord} - */ -ol.TileCoordTransformType; - - -/** * @param {string} template Template. * @param {ol.tilegrid.TileGrid} tileGrid Tile grid. * @return {ol.TileUrlFunctionType} Tile URL function. @@ -74121,7 +58375,7 @@ ol.TileUrlFunction.createFromTileUrlFunctions = function(tileUrlFunctions) { return undefined; } else { var h = ol.tilecoord.hash(tileCoord); - var index = goog.math.modulo(h, tileUrlFunctions.length); + var index = ol.math.modulo(h, tileUrlFunctions.length); return tileUrlFunctions[index](tileCoord, pixelRatio, projection); } }); @@ -74134,8 +58388,7 @@ ol.TileUrlFunction.createFromTileUrlFunctions = function(tileUrlFunctions) { * @param {ol.proj.Projection} projection Projection. * @return {string|undefined} Tile URL. */ -ol.TileUrlFunction.nullTileUrlFunction = - function(tileCoord, pixelRatio, projection) { +ol.TileUrlFunction.nullTileUrlFunction = function(tileCoord, pixelRatio, projection) { return undefined; }; @@ -74162,43 +58415,21 @@ ol.TileUrlFunction.expandUrl = function(url) { goog.provide('ol.source.UrlTile'); -goog.require('goog.events'); -goog.require('ol.TileLoadFunctionType'); +goog.require('ol.events'); goog.require('ol.TileState'); goog.require('ol.TileUrlFunction'); -goog.require('ol.TileUrlFunctionType'); -goog.require('ol.proj'); goog.require('ol.source.Tile'); goog.require('ol.source.TileEvent'); /** - * @typedef {{attributions: (Array.<ol.Attribution>|undefined), - * extent: (ol.Extent|undefined), - * logo: (string|olx.LogoOptions|undefined), - * opaque: (boolean|undefined), - * projection: ol.proj.ProjectionLike, - * state: (ol.source.State|string|undefined), - * tileGrid: (ol.tilegrid.TileGrid|undefined), - * tileLoadFunction: ol.TileLoadFunctionType, - * tilePixelRatio: (number|undefined), - * tileUrlFunction: (ol.TileUrlFunctionType|undefined), - * url: (string|undefined), - * urls: (Array.<string>|undefined), - * wrapX: (boolean|undefined)}} - */ -ol.source.UrlTileOptions; - - - -/** * @classdesc * Base class for sources providing tiles divided into a tile grid over http. * * @constructor * @fires ol.source.TileEvent * @extends {ol.source.Tile} - * @param {ol.source.UrlTileOptions} options Image tile options. + * @param {ol.SourceUrlTileOptions} options Image tile options. */ ol.source.UrlTile = function(options) { @@ -74209,8 +58440,7 @@ ol.source.UrlTile = function(options) { logo: options.logo, opaque: options.opaque, projection: options.projection, - state: options.state ? - /** @type {ol.source.State} */ (options.state) : undefined, + state: options.state, tileGrid: options.tileGrid, tilePixelRatio: options.tilePixelRatio, wrapX: options.wrapX @@ -74226,8 +58456,8 @@ ol.source.UrlTile = function(options) { * @protected * @type {ol.TileUrlFunctionType} */ - this.tileUrlFunction = options.tileUrlFunction ? - options.tileUrlFunction : + this.tileUrlFunction = this.fixedTileUrlFunction ? + this.fixedTileUrlFunction.bind(this) : ol.TileUrlFunction.nullTileUrlFunction; /** @@ -74237,11 +58467,7 @@ ol.source.UrlTile = function(options) { this.urls = null; if (options.urls) { - if (options.tileUrlFunction) { - this.urls = options.urls; - } else { - this.setUrls(options.urls); - } + this.setUrls(options.urls); } else if (options.url) { this.setUrl(options.url); } @@ -74254,6 +58480,12 @@ goog.inherits(ol.source.UrlTile, ol.source.Tile); /** + * @type {ol.TileUrlFunctionType|undefined} + * @protected + */ +ol.source.UrlTile.prototype.fixedTileUrlFunction; + +/** * Return the tile load function of the source. * @return {ol.TileLoadFunctionType} TileLoadFunction * @api @@ -74287,7 +58519,7 @@ ol.source.UrlTile.prototype.getUrls = function() { /** * Handle tile change events. - * @param {goog.events.Event} event Event. + * @param {ol.events.Event} event Event. * @protected */ ol.source.UrlTile.prototype.handleTileChange = function(event) { @@ -74305,6 +58537,8 @@ ol.source.UrlTile.prototype.handleTileChange = function(event) { this.dispatchEvent( new ol.source.TileEvent(ol.source.TileEventType.TILELOADERROR, tile)); break; + default: + // pass } }; @@ -74324,15 +58558,16 @@ ol.source.UrlTile.prototype.setTileLoadFunction = function(tileLoadFunction) { /** * Set the tile URL function of the source. * @param {ol.TileUrlFunctionType} tileUrlFunction Tile URL function. + * @param {string=} opt_key Optional new tile key for the source. * @api */ -ol.source.UrlTile.prototype.setTileUrlFunction = function(tileUrlFunction) { - // FIXME It should be possible to be more intelligent and avoid clearing the - // FIXME cache. The tile URL function would need to be incorporated into the - // FIXME cache key somehow. - this.tileCache.clear(); +ol.source.UrlTile.prototype.setTileUrlFunction = function(tileUrlFunction, opt_key) { this.tileUrlFunction = tileUrlFunction; - this.changed(); + if (typeof opt_key !== 'undefined') { + this.setKey(opt_key); + } else { + this.changed(); + } }; @@ -74342,9 +58577,10 @@ ol.source.UrlTile.prototype.setTileUrlFunction = function(tileUrlFunction) { * @api stable */ ol.source.UrlTile.prototype.setUrl = function(url) { - this.setTileUrlFunction(ol.TileUrlFunction.createFromTemplates( - ol.TileUrlFunction.expandUrl(url), this.tileGrid)); - this.urls = [url]; + var urls = this.urls = ol.TileUrlFunction.expandUrl(url); + this.setTileUrlFunction(this.fixedTileUrlFunction ? + this.fixedTileUrlFunction.bind(this) : + ol.TileUrlFunction.createFromTemplates(urls, this.tileGrid), url); }; @@ -74354,9 +58590,11 @@ ol.source.UrlTile.prototype.setUrl = function(url) { * @api stable */ ol.source.UrlTile.prototype.setUrls = function(urls) { - this.setTileUrlFunction(ol.TileUrlFunction.createFromTemplates( - urls, this.tileGrid)); this.urls = urls; + var key = urls.join('\n'); + this.setTileUrlFunction(this.fixedTileUrlFunction ? + this.fixedTileUrlFunction.bind(this) : + ol.TileUrlFunction.createFromTemplates(urls, this.tileGrid), key); }; @@ -74372,16 +58610,15 @@ ol.source.UrlTile.prototype.useTile = function(z, x, y) { goog.provide('ol.source.VectorTile'); -goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); goog.require('ol.TileState'); goog.require('ol.VectorTile'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol.featureloader'); +goog.require('ol.size'); goog.require('ol.source.UrlTile'); - /** * @classdesc * Class for layer sources providing vector data divided into a tile grid, to be @@ -74402,13 +58639,12 @@ ol.source.VectorTile = function(options) { goog.base(this, { attributions: options.attributions, - cacheSize: ol.DEFAULT_TILE_CACHE_HIGH_WATER_MARK / 16, + cacheSize: options.cacheSize !== undefined ? options.cacheSize : 128, extent: options.extent, logo: options.logo, - opaque: options.opaque, + opaque: false, projection: options.projection, - state: options.state ? - /** @type {ol.source.State} */ (options.state) : undefined, + state: options.state, tileGrid: options.tileGrid, tileLoadFunction: options.tileLoadFunction ? options.tileLoadFunction : ol.source.VectorTile.defaultTileLoadFunction, @@ -74428,7 +58664,7 @@ ol.source.VectorTile = function(options) { /** * @protected * @type {function(new: ol.VectorTile, ol.TileCoord, ol.TileState, string, - * ol.format.Feature, ol.TileLoadFunctionType, ol.proj.Projection)} + * ol.format.Feature, ol.TileLoadFunctionType)} */ this.tileClass = options.tileClass ? options.tileClass : ol.VectorTile; @@ -74439,13 +58675,11 @@ goog.inherits(ol.source.VectorTile, ol.source.UrlTile); /** * @inheritDoc */ -ol.source.VectorTile.prototype.getTile = - function(z, x, y, pixelRatio, projection) { +ol.source.VectorTile.prototype.getTile = function(z, x, y, pixelRatio, projection) { var tileCoordKey = this.getKeyZXY(z, x, y); if (this.tileCache.containsKey(tileCoordKey)) { return /** @type {!ol.Tile} */ (this.tileCache.get(tileCoordKey)); } else { - goog.asserts.assert(projection, 'argument projection is truthy'); var tileCoord = [z, x, y]; var urlTileCoord = this.getTileCoordForTileUrlFunction( tileCoord, projection); @@ -74455,9 +58689,9 @@ ol.source.VectorTile.prototype.getTile = tileCoord, tileUrl !== undefined ? ol.TileState.IDLE : ol.TileState.EMPTY, tileUrl !== undefined ? tileUrl : '', - this.format_, this.tileLoadFunction, projection); - goog.events.listen(tile, goog.events.EventType.CHANGE, - this.handleTileChange, false, this); + this.format_, this.tileLoadFunction); + ol.events.listen(tile, ol.events.EventType.CHANGE, + this.handleTileChange, this); this.tileCache.set(tileCoordKey, tile); return tile; @@ -74466,6 +58700,15 @@ ol.source.VectorTile.prototype.getTile = /** + * @inheritDoc + */ +ol.source.VectorTile.prototype.getTilePixelSize = function(z, pixelRatio, projection) { + var tileSize = ol.size.toSize(this.tileGrid.getTileSize(z)); + return [tileSize[0] * pixelRatio, tileSize[1] * pixelRatio]; +}; + + +/** * @param {ol.VectorTile} vectorTile Vector tile. * @param {string} url URL. */ @@ -74476,32 +58719,48 @@ ol.source.VectorTile.defaultTileLoadFunction = function(vectorTile, url) { goog.provide('ol.renderer.canvas.VectorTileLayer'); goog.require('goog.asserts'); -goog.require('goog.events'); +goog.require('ol.events'); goog.require('goog.vec.Mat4'); goog.require('ol.Feature'); -goog.require('ol.TileRange'); -goog.require('ol.TileState'); goog.require('ol.VectorTile'); -goog.require('ol.ViewHint'); goog.require('ol.array'); -goog.require('ol.dom'); goog.require('ol.extent'); goog.require('ol.layer.VectorTile'); +goog.require('ol.proj'); goog.require('ol.proj.Units'); goog.require('ol.render.EventType'); +goog.require('ol.render.canvas'); goog.require('ol.render.canvas.ReplayGroup'); -goog.require('ol.renderer.canvas.Layer'); +goog.require('ol.renderer.canvas.TileLayer'); goog.require('ol.renderer.vector'); goog.require('ol.size'); goog.require('ol.source.VectorTile'); -goog.require('ol.tilecoord'); goog.require('ol.vec.Mat4'); +/** + * @const + * @type {!Object.<string, Array.<ol.render.ReplayType>>} + */ +ol.renderer.canvas.IMAGE_REPLAYS = { + 'image': ol.render.REPLAY_ORDER, + 'hybrid': [ol.render.ReplayType.POLYGON, ol.render.ReplayType.LINE_STRING] +}; + + +/** + * @const + * @type {!Object.<string, Array.<ol.render.ReplayType>>} + */ +ol.renderer.canvas.VECTOR_REPLAYS = { + 'hybrid': [ol.render.ReplayType.IMAGE, ol.render.ReplayType.TEXT], + 'vector': ol.render.REPLAY_ORDER +}; + /** * @constructor - * @extends {ol.renderer.canvas.Layer} + * @extends {ol.renderer.canvas.TileLayer} * @param {ol.layer.VectorTile} layer VectorTile layer. */ ol.renderer.canvas.VectorTileLayer = function(layer) { @@ -74510,73 +58769,75 @@ ol.renderer.canvas.VectorTileLayer = function(layer) { /** * @private - * @type {CanvasRenderingContext2D} - */ - this.context_ = ol.dom.createCanvasContext2D(); - - /** - * @private * @type {boolean} */ this.dirty_ = false; /** * @private - * @type {Array.<ol.VectorTile>} - */ - this.renderedTiles_ = []; - - /** - * @private - * @type {ol.Extent} - */ - this.tmpExtent_ = ol.extent.createEmpty(); - - /** - * @private - * @type {ol.Size} - */ - this.tmpSize_ = [NaN, NaN]; - - /** - * @private * @type {!goog.vec.Mat4.Number} */ this.tmpTransform_ = goog.vec.Mat4.createNumber(); + // Use lower resolution for pure vector rendering. Closest resolution otherwise. + this.zDirection = + layer.getRenderMode() == ol.layer.VectorTileRenderType.VECTOR ? 1 : 0; + }; -goog.inherits(ol.renderer.canvas.VectorTileLayer, ol.renderer.canvas.Layer); +goog.inherits(ol.renderer.canvas.VectorTileLayer, ol.renderer.canvas.TileLayer); /** * @inheritDoc */ -ol.renderer.canvas.VectorTileLayer.prototype.composeFrame = - function(frameState, layerState, context) { +ol.renderer.canvas.VectorTileLayer.prototype.composeFrame = function( + frameState, layerState, context) { + var transform = this.getTransform(frameState, 0); + this.dispatchPreComposeEvent(context, frameState, transform); + var renderMode = this.getLayer().getRenderMode(); + if (renderMode !== ol.layer.VectorTileRenderType.VECTOR) { + this.renderTileImages(context, frameState, layerState); + } + if (renderMode !== ol.layer.VectorTileRenderType.IMAGE) { + this.renderTileReplays_(context, frameState, layerState); + } + this.dispatchPostComposeEvent(context, frameState, transform); +}; + + +/** + * @param {CanvasRenderingContext2D} context Context. + * @param {olx.FrameState} frameState Frame state. + * @param {ol.LayerState} layerState Layer state. + * @private + */ +ol.renderer.canvas.VectorTileLayer.prototype.renderTileReplays_ = function( + context, frameState, layerState) { + var layer = this.getLayer(); + var replays = ol.renderer.canvas.VECTOR_REPLAYS[layer.getRenderMode()]; var pixelRatio = frameState.pixelRatio; var skippedFeatureUids = layerState.managed ? frameState.skippedFeatureUids : {}; var viewState = frameState.viewState; var center = viewState.center; - var projection = viewState.projection; var resolution = viewState.resolution; var rotation = viewState.rotation; - var layer = this.getLayer(); + var size = frameState.size; + var pixelScale = pixelRatio / resolution; var source = layer.getSource(); goog.asserts.assertInstanceof(source, ol.source.VectorTile, 'Source is an ol.source.VectorTile'); + var tilePixelRatio = source.getTilePixelRatio(pixelRatio); var transform = this.getTransform(frameState, 0); - this.dispatchPreComposeEvent(context, frameState, transform); - var replayContext; if (layer.hasListener(ol.render.EventType.RENDER)) { // resize and clear - this.context_.canvas.width = context.canvas.width; - this.context_.canvas.height = context.canvas.height; - replayContext = this.context_; + this.context.canvas.width = context.canvas.width; + this.context.canvas.height = context.canvas.height; + replayContext = this.context; } else { replayContext = context; } @@ -74586,55 +58847,58 @@ ol.renderer.canvas.VectorTileLayer.prototype.composeFrame = var alpha = replayContext.globalAlpha; replayContext.globalAlpha = layerState.opacity; - var tilesToDraw = this.renderedTiles_; + var tilesToDraw = this.renderedTiles; var tileGrid = source.getTileGrid(); - var currentZ, i, ii, origin, tile, tileSize; - var tilePixelRatio, tilePixelResolution, tilePixelSize, tileResolution; + var currentZ, i, ii, offsetX, offsetY, origin, pixelSpace, replayState; + var tile, tileExtent, tilePixelResolution, tileResolution, tileTransform; for (i = 0, ii = tilesToDraw.length; i < ii; ++i) { tile = tilesToDraw[i]; + replayState = tile.getReplayState(); + tileExtent = tileGrid.getTileCoordExtent( + tile.getTileCoord(), this.tmpExtent); currentZ = tile.getTileCoord()[0]; - tileSize = tileGrid.getTileSize(currentZ); - tilePixelSize = source.getTilePixelSize(currentZ, pixelRatio, projection); - tilePixelRatio = tilePixelSize[0] / - ol.size.toSize(tileSize, this.tmpSize_)[0]; + pixelSpace = tile.getProjection().getUnits() == ol.proj.Units.TILE_PIXELS; tileResolution = tileGrid.getResolution(currentZ); tilePixelResolution = tileResolution / tilePixelRatio; - if (tile.getProjection().getUnits() == ol.proj.Units.TILE_PIXELS) { - origin = ol.extent.getTopLeft(tileGrid.getTileCoordExtent( - tile.getTileCoord(), this.tmpExtent_)); - transform = ol.vec.Mat4.makeTransform2D(this.tmpTransform_, - pixelRatio * frameState.size[0] / 2, - pixelRatio * frameState.size[1] / 2, - pixelRatio * tilePixelResolution / resolution, - pixelRatio * tilePixelResolution / resolution, - viewState.rotation, + offsetX = Math.round(pixelRatio * size[0] / 2); + offsetY = Math.round(pixelRatio * size[1] / 2); + + if (pixelSpace) { + origin = ol.extent.getTopLeft(tileExtent); + tileTransform = ol.vec.Mat4.makeTransform2D(this.tmpTransform_, + offsetX, offsetY, + pixelScale * tilePixelResolution, + pixelScale * tilePixelResolution, + rotation, (origin[0] - center[0]) / tilePixelResolution, (center[1] - origin[1]) / tilePixelResolution); + } else { + tileTransform = transform; } - tile.getReplayState().replayGroup.replay(replayContext, pixelRatio, - transform, rotation, skippedFeatureUids); + ol.render.canvas.rotateAtOffset(replayContext, -rotation, offsetX, offsetY); + replayState.replayGroup.replay(replayContext, pixelRatio, + tileTransform, rotation, skippedFeatureUids, replays); + ol.render.canvas.rotateAtOffset(replayContext, rotation, offsetX, offsetY); } - transform = this.getTransform(frameState, 0); - if (replayContext != context) { this.dispatchRenderEvent(replayContext, frameState, transform); context.drawImage(replayContext.canvas, 0, 0); } replayContext.globalAlpha = alpha; - - this.dispatchPostComposeEvent(context, frameState, transform); }; /** * @param {ol.VectorTile} tile Tile. - * @param {ol.layer.VectorTile} layer Vector tile layer. - * @param {number} pixelRatio Pixel ratio. + * @param {olx.FrameState} frameState Frame state. */ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup = function(tile, - layer, pixelRatio) { + frameState) { + var layer = this.getLayer(); + var pixelRatio = frameState.pixelRatio; + var projection = frameState.viewState.projection; var revision = layer.getRevision(); var renderOrder = layer.getRenderOrder() || null; @@ -74644,8 +58908,6 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup = function(tile, return; } - // FIXME dispose of old replayGroup in post render - goog.dispose(replayState.replayGroup); replayState.replayGroup = null; replayState.dirty = false; @@ -74654,17 +58916,22 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup = function(tile, 'Source is an ol.source.VectorTile'); var tileGrid = source.getTileGrid(); var tileCoord = tile.getTileCoord(); - var pixelSpace = tile.getProjection().getUnits() == ol.proj.Units.TILE_PIXELS; - var extent; + var tileProjection = tile.getProjection(); + var pixelSpace = tileProjection.getUnits() == ol.proj.Units.TILE_PIXELS; + var resolution = tileGrid.getResolution(tileCoord[0]); + var extent, reproject, tileResolution; if (pixelSpace) { - var tilePixelSize = source.getTilePixelSize(tileCoord[0], pixelRatio, - tile.getProjection()); - extent = [0, 0, tilePixelSize[0], tilePixelSize[1]]; + var tilePixelRatio = tileResolution = source.getTilePixelRatio(pixelRatio); + var tileSize = ol.size.toSize(tileGrid.getTileSize(tileCoord[0])); + extent = [0, 0, tileSize[0] * tilePixelRatio, tileSize[1] * tilePixelRatio]; } else { + tileResolution = resolution; extent = tileGrid.getTileCoordExtent(tileCoord); + if (!ol.proj.equivalent(projection, tileProjection)) { + reproject = true; + tile.setProjection(projection); + } } - var resolution = tileGrid.getResolution(tileCoord[0]); - var tileResolution = pixelSpace ? source.getTilePixelRatio() : resolution; replayState.dirty = false; var replayGroup = new ol.render.canvas.ReplayGroup(0, extent, tileResolution, layer.getRenderBuffer()); @@ -74688,7 +58955,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup = function(tile, } } if (styles) { - if (!goog.isArray(styles)) { + if (!Array.isArray(styles)) { styles = [styles]; } var dirty = this.renderFeature(feature, squaredTolerance, styles, @@ -74702,29 +58969,36 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup = function(tile, if (renderOrder && renderOrder !== replayState.renderedRenderOrder) { features.sort(renderOrder); } - features.forEach(renderFeature, this); + var feature; + for (var i = 0, ii = features.length; i < ii; ++i) { + feature = features[i]; + if (reproject) { + feature.getGeometry().transform(tileProjection, projection); + } + renderFeature.call(this, feature); + } replayGroup.finish(); replayState.renderedRevision = revision; replayState.renderedRenderOrder = renderOrder; replayState.replayGroup = replayGroup; + replayState.resolution = NaN; }; /** * @inheritDoc */ -ol.renderer.canvas.VectorTileLayer.prototype.forEachFeatureAtCoordinate = - function(coordinate, frameState, callback, thisArg) { +ol.renderer.canvas.VectorTileLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, callback, thisArg) { + var pixelRatio = frameState.pixelRatio; var resolution = frameState.viewState.resolution; var rotation = frameState.viewState.rotation; var layer = this.getLayer(); - var layerState = frameState.layerStates[goog.getUid(layer)]; /** @type {Object.<string, boolean>} */ var features = {}; - var replayables = this.renderedTiles_; + var replayables = this.renderedTiles; var source = layer.getSource(); goog.asserts.assertInstanceof(source, ol.source.VectorTile, 'Source is an ol.source.VectorTile'); @@ -74736,13 +59010,13 @@ ol.renderer.canvas.VectorTileLayer.prototype.forEachFeatureAtCoordinate = tile = replayables[i]; tileCoord = tile.getTileCoord(); tileExtent = source.getTileGrid().getTileCoordExtent(tileCoord, - this.tmpExtent_); + this.tmpExtent); if (!ol.extent.containsCoordinate(tileExtent, coordinate)) { continue; } if (tile.getProjection().getUnits() === ol.proj.Units.TILE_PIXELS) { origin = ol.extent.getTopLeft(tileExtent); - tilePixelRatio = source.getTilePixelRatio(); + tilePixelRatio = source.getTilePixelRatio(pixelRatio); tileResolution = tileGrid.getResolution(tileCoord[0]) / tilePixelRatio; tileSpaceCoordinate = [ (coordinate[0] - origin[0]) / tileResolution, @@ -74754,8 +59028,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.forEachFeatureAtCoordinate = } replayGroup = tile.getReplayState().replayGroup; found = found || replayGroup.forEachFeatureAtCoordinate( - tileSpaceCoordinate, resolution, rotation, - layerState.managed ? frameState.skippedFeatureUids : {}, + tileSpaceCoordinate, resolution, rotation, {}, /** * @param {ol.Feature|ol.render.Feature} feature Feature. * @return {?} Callback result. @@ -74775,11 +59048,10 @@ ol.renderer.canvas.VectorTileLayer.prototype.forEachFeatureAtCoordinate = /** * Handle changes in image style state. - * @param {goog.events.Event} event Image style change event. + * @param {ol.events.Event} event Image style change event. * @private */ -ol.renderer.canvas.VectorTileLayer.prototype.handleStyleImageChange_ = - function(event) { +ol.renderer.canvas.VectorTileLayer.prototype.handleStyleImageChange_ = function(event) { this.renderIfReadyAndVisible(); }; @@ -74787,118 +59059,18 @@ ol.renderer.canvas.VectorTileLayer.prototype.handleStyleImageChange_ = /** * @inheritDoc */ -ol.renderer.canvas.VectorTileLayer.prototype.prepareFrame = - function(frameState, layerState) { - var layer = /** @type {ol.layer.Vector} */ (this.getLayer()); - goog.asserts.assertInstanceof(layer, ol.layer.VectorTile, - 'layer is an instance of ol.layer.VectorTile'); - var source = layer.getSource(); - goog.asserts.assertInstanceof(source, ol.source.VectorTile, - 'Source is an ol.source.VectorTile'); - - this.updateAttributions( - frameState.attributions, source.getAttributions()); - this.updateLogos(frameState, source); - - var animating = frameState.viewHints[ol.ViewHint.ANIMATING]; - var interacting = frameState.viewHints[ol.ViewHint.INTERACTING]; - var updateWhileAnimating = layer.getUpdateWhileAnimating(); - var updateWhileInteracting = layer.getUpdateWhileInteracting(); - - if (!this.dirty_ && (!updateWhileAnimating && animating) || - (!updateWhileInteracting && interacting)) { - return true; - } - - var extent = frameState.extent; - if (layerState.extent) { - extent = ol.extent.getIntersection(extent, layerState.extent); - } - if (ol.extent.isEmpty(extent)) { - // Return false to prevent the rendering of the layer. - return false; - } - - var viewState = frameState.viewState; - var projection = viewState.projection; - var resolution = viewState.resolution; - var pixelRatio = frameState.pixelRatio; - - var tileGrid = source.getTileGrid(); - var resolutions = tileGrid.getResolutions(); - var z = resolutions.length - 1; - while (z > 0 && resolutions[z] < resolution) { - --z; - } - var tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z); - this.updateUsedTiles(frameState.usedTiles, source, z, tileRange); - this.manageTilePyramid(frameState, source, tileGrid, pixelRatio, - projection, extent, z, layer.getPreload()); - this.scheduleExpireCache(frameState, source); - - /** - * @type {Object.<number, Object.<string, ol.VectorTile>>} - */ - var tilesToDrawByZ = {}; - tilesToDrawByZ[z] = {}; - - var findLoadedTiles = this.createLoadedTileFinder(source, projection, - tilesToDrawByZ); - - var useInterimTilesOnError = layer.getUseInterimTilesOnError(); - - var tmpExtent = this.tmpExtent_; - var tmpTileRange = new ol.TileRange(0, 0, 0, 0); - var childTileRange, fullyLoaded, tile, tileState, x, y; - for (x = tileRange.minX; x <= tileRange.maxX; ++x) { - for (y = tileRange.minY; y <= tileRange.maxY; ++y) { - - tile = source.getTile(z, x, y, pixelRatio, projection); - goog.asserts.assertInstanceof(tile, ol.VectorTile, - 'Tile is an ol.VectorTile'); - tileState = tile.getState(); - if (tileState == ol.TileState.LOADED || - tileState == ol.TileState.EMPTY || - (tileState == ol.TileState.ERROR && !useInterimTilesOnError)) { - tilesToDrawByZ[z][ol.tilecoord.toString(tile.tileCoord)] = tile; - continue; - } - - fullyLoaded = tileGrid.forEachTileCoordParentTileRange( - tile.tileCoord, findLoadedTiles, null, tmpTileRange, tmpExtent); - if (!fullyLoaded) { - childTileRange = tileGrid.getTileCoordChildTileRange( - tile.tileCoord, tmpTileRange, tmpExtent); - if (childTileRange) { - findLoadedTiles(z + 1, childTileRange); - } - } - - } - } - - this.dirty_ = false; - - /** @type {Array.<number>} */ - var zs = Object.keys(tilesToDrawByZ).map(Number); - zs.sort(ol.array.numberSafeCompareFunction); - var replayables = []; - var i, ii, currentZ, tileCoordKey, tilesToDraw; - for (i = 0, ii = zs.length; i < ii; ++i) { - currentZ = zs[i]; - tilesToDraw = tilesToDrawByZ[currentZ]; - for (tileCoordKey in tilesToDraw) { - tile = tilesToDraw[tileCoordKey]; - if (tile.getState() == ol.TileState.LOADED) { - replayables.push(tile); - this.createReplayGroup(tile, layer, pixelRatio); - } +ol.renderer.canvas.VectorTileLayer.prototype.prepareFrame = function(frameState, layerState) { + var prepared = goog.base(this, 'prepareFrame', frameState, layerState); + if (prepared) { + var skippedFeatures = Object.keys(frameState.skippedFeatureUids_ || {}); + for (var i = 0, ii = this.renderedTiles.length; i < ii; ++i) { + var tile = this.renderedTiles[i]; + goog.asserts.assertInstanceof(tile, ol.VectorTile, 'got an ol.VectorTile'); + this.createReplayGroup(tile, frameState); + this.renderTileImage_(tile, frameState, layerState, skippedFeatures); } } - - this.renderedTiles_ = replayables; - - return true; + return prepared; }; @@ -74910,13 +59082,12 @@ ol.renderer.canvas.VectorTileLayer.prototype.prepareFrame = * @param {ol.render.canvas.ReplayGroup} replayGroup Replay group. * @return {boolean} `true` if an image is loading. */ -ol.renderer.canvas.VectorTileLayer.prototype.renderFeature = - function(feature, squaredTolerance, styles, replayGroup) { +ol.renderer.canvas.VectorTileLayer.prototype.renderFeature = function(feature, squaredTolerance, styles, replayGroup) { if (!styles) { return false; } var loading = false; - if (goog.isArray(styles)) { + if (Array.isArray(styles)) { for (var i = 0, ii = styles.length; i < ii; ++i) { loading = ol.renderer.vector.renderFeature( replayGroup, feature, styles[i], squaredTolerance, @@ -74930,17 +59101,81 @@ ol.renderer.canvas.VectorTileLayer.prototype.renderFeature = return loading; }; + +/** + * @param {ol.VectorTile} tile Tile. + * @param {olx.FrameState} frameState Frame state. + * @param {ol.LayerState} layerState Layer state. + * @param {Array.<string>} skippedFeatures Skipped features. + * @private + */ +ol.renderer.canvas.VectorTileLayer.prototype.renderTileImage_ = function( + tile, frameState, layerState, skippedFeatures) { + var layer = this.getLayer(); + var replays = ol.renderer.canvas.IMAGE_REPLAYS[layer.getRenderMode()]; + if (!replays) { + // do not create an image in 'vector' mode + return; + } + var pixelRatio = frameState.pixelRatio; + var replayState = tile.getReplayState(); + var revision = layer.getRevision(); + if (!ol.array.equals(replayState.skippedFeatures, skippedFeatures) || + replayState.renderedTileRevision !== revision) { + replayState.skippedFeatures = skippedFeatures; + replayState.renderedTileRevision = revision; + var tileContext = tile.getContext(); + var source = layer.getSource(); + var tileGrid = source.getTileGrid(); + var currentZ = tile.getTileCoord()[0]; + var resolution = tileGrid.getResolution(currentZ); + var tileSize = ol.size.toSize(tileGrid.getTileSize(currentZ)); + var tileResolution = tileGrid.getResolution(currentZ); + var resolutionRatio = tileResolution / resolution; + var width = tileSize[0] * pixelRatio * resolutionRatio; + var height = tileSize[1] * pixelRatio * resolutionRatio; + tileContext.canvas.width = width / resolutionRatio + 0.5; + tileContext.canvas.height = height / resolutionRatio + 0.5; + tileContext.scale(1 / resolutionRatio, 1 / resolutionRatio); + tileContext.translate(width / 2, height / 2); + var pixelSpace = tile.getProjection().getUnits() == ol.proj.Units.TILE_PIXELS; + var pixelScale = pixelRatio / resolution; + var tilePixelRatio = source.getTilePixelRatio(pixelRatio); + var tilePixelResolution = tileResolution / tilePixelRatio; + var tileExtent = tileGrid.getTileCoordExtent( + tile.getTileCoord(), this.tmpExtent); + var tileTransform; + if (pixelSpace) { + tileTransform = ol.vec.Mat4.makeTransform2D(this.tmpTransform_, + 0, 0, + pixelScale * tilePixelResolution, pixelScale * tilePixelResolution, + 0, + -tileSize[0] * tilePixelRatio / 2, -tileSize[1] * tilePixelRatio / 2); + } else { + var tileCenter = ol.extent.getCenter(tileExtent); + tileTransform = ol.vec.Mat4.makeTransform2D(this.tmpTransform_, + 0, 0, + pixelScale, -pixelScale, + 0, + -tileCenter[0], -tileCenter[1]); + } + + replayState.replayGroup.replay(tileContext, pixelRatio, + tileTransform, 0, frameState.skippedFeatureUids || {}, replays); + } +} + // FIXME offset panning goog.provide('ol.renderer.canvas.Map'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom'); goog.require('goog.style'); goog.require('goog.vec.Mat4'); goog.require('ol'); goog.require('ol.RendererType'); +goog.require('ol.array'); goog.require('ol.css'); goog.require('ol.dom'); goog.require('ol.layer.Image'); @@ -74950,6 +59185,7 @@ goog.require('ol.layer.Vector'); goog.require('ol.layer.VectorTile'); goog.require('ol.render.Event'); goog.require('ol.render.EventType'); +goog.require('ol.render.canvas'); goog.require('ol.render.canvas.Immediate'); goog.require('ol.renderer.Map'); goog.require('ol.renderer.canvas.ImageLayer'); @@ -74961,7 +59197,6 @@ goog.require('ol.source.State'); goog.require('ol.vec.Mat4'); - /** * @constructor * @extends {ol.renderer.Map} @@ -75029,8 +59264,7 @@ ol.renderer.canvas.Map.prototype.createLayerRenderer = function(layer) { * @param {olx.FrameState} frameState Frame state. * @private */ -ol.renderer.canvas.Map.prototype.dispatchComposeEvent_ = - function(type, frameState) { +ol.renderer.canvas.Map.prototype.dispatchComposeEvent_ = function(type, frameState) { var map = this.getMap(); var context = this.context_; if (map.hasListener(type)) { @@ -75046,8 +59280,6 @@ ol.renderer.canvas.Map.prototype.dispatchComposeEvent_ = var composeEvent = new ol.render.Event(type, map, vectorContext, frameState, context, null); map.dispatchEvent(composeEvent); - - vectorContext.flush(); } }; @@ -75091,21 +59323,26 @@ ol.renderer.canvas.Map.prototype.renderFrame = function(frameState) { } var context = this.context_; - var width = frameState.size[0] * frameState.pixelRatio; - var height = frameState.size[1] * frameState.pixelRatio; + var pixelRatio = frameState.pixelRatio; + var width = Math.round(frameState.size[0] * pixelRatio); + var height = Math.round(frameState.size[1] * pixelRatio); if (this.canvas_.width != width || this.canvas_.height != height) { this.canvas_.width = width; this.canvas_.height = height; } else { - context.clearRect(0, 0, this.canvas_.width, this.canvas_.height); + context.clearRect(0, 0, width, height); } + var rotation = frameState.viewState.rotation; + this.calculateMatrices2D(frameState); this.dispatchComposeEvent_(ol.render.EventType.PRECOMPOSE, frameState); var layerStatesArray = frameState.layerStatesArray; - goog.array.stableSort(layerStatesArray, ol.renderer.Map.sortByZIndex); + ol.array.stableSort(layerStatesArray, ol.renderer.Map.sortByZIndex); + + ol.render.canvas.rotateAtOffset(context, rotation, width / 2, height / 2); var viewResolution = frameState.viewState.resolution; var i, ii, layer, layerRenderer, layerState; @@ -75124,6 +59361,8 @@ ol.renderer.canvas.Map.prototype.renderFrame = function(frameState) { } } + ol.render.canvas.rotateAtOffset(context, -rotation, width / 2, height / 2); + this.dispatchComposeEvent_( ol.render.EventType.POSTCOMPOSE, frameState); @@ -75143,7 +59382,6 @@ goog.require('ol.layer.Layer'); goog.require('ol.renderer.Layer'); - /** * @constructor * @extends {ol.renderer.Layer} @@ -75172,7 +59410,7 @@ ol.renderer.dom.Layer.prototype.clearFrame = ol.nullFunction; /** * @param {olx.FrameState} frameState Frame state. - * @param {ol.layer.LayerState} layerState Layer state. + * @param {ol.LayerState} layerState Layer state. */ ol.renderer.dom.Layer.prototype.composeFrame = ol.nullFunction; @@ -75187,7 +59425,7 @@ ol.renderer.dom.Layer.prototype.getTarget = function() { /** * @param {olx.FrameState} frameState Frame state. - * @param {ol.layer.LayerState} layerState Layer state. + * @param {ol.LayerState} layerState Layer state. * @return {boolean} whether composeFrame should be called. */ ol.renderer.dom.Layer.prototype.prepareFrame = goog.abstractMethod; @@ -75207,7 +59445,6 @@ goog.require('ol.renderer.dom.Layer'); goog.require('ol.vec.Mat4'); - /** * @constructor * @extends {ol.renderer.dom.Layer} @@ -75239,8 +59476,7 @@ goog.inherits(ol.renderer.dom.ImageLayer, ol.renderer.dom.Layer); /** * @inheritDoc */ -ol.renderer.dom.ImageLayer.prototype.forEachFeatureAtCoordinate = - function(coordinate, frameState, callback, thisArg) { +ol.renderer.dom.ImageLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, callback, thisArg) { var layer = this.getLayer(); var source = layer.getSource(); var resolution = frameState.viewState.resolution; @@ -75270,8 +59506,7 @@ ol.renderer.dom.ImageLayer.prototype.clearFrame = function() { /** * @inheritDoc */ -ol.renderer.dom.ImageLayer.prototype.prepareFrame = - function(frameState, layerState) { +ol.renderer.dom.ImageLayer.prototype.prepareFrame = function(frameState, layerState) { var viewState = frameState.viewState; var viewCenter = viewState.center; @@ -75364,8 +59599,6 @@ goog.require('goog.dom'); goog.require('goog.style'); goog.require('goog.vec.Mat4'); goog.require('ol'); -goog.require('ol.Coordinate'); -goog.require('ol.TileCoord'); goog.require('ol.TileRange'); goog.require('ol.TileState'); goog.require('ol.ViewHint'); @@ -75375,12 +59608,10 @@ goog.require('ol.extent'); goog.require('ol.layer.Tile'); goog.require('ol.renderer.dom.Layer'); goog.require('ol.size'); -goog.require('ol.tilecoord'); goog.require('ol.tilegrid.TileGrid'); goog.require('ol.vec.Mat4'); - /** * @constructor * @extends {ol.renderer.dom.Layer} @@ -75433,8 +59664,7 @@ ol.renderer.dom.TileLayer.prototype.clearFrame = function() { /** * @inheritDoc */ -ol.renderer.dom.TileLayer.prototype.prepareFrame = - function(frameState, layerState) { +ol.renderer.dom.TileLayer.prototype.prepareFrame = function(frameState, layerState) { if (!layerState.visible) { if (this.renderedVisible_) { @@ -75453,7 +59683,7 @@ ol.renderer.dom.TileLayer.prototype.prepareFrame = 'layer is an instance of ol.layer.Tile'); var tileSource = tileLayer.getSource(); var tileGrid = tileSource.getTileGridForProjection(projection); - var tileGutter = tileSource.getGutter(); + var tileGutter = tileSource.getGutter(projection); var z = tileGrid.getZForResolution(viewState.resolution); var tileResolution = tileGrid.getResolution(z); var center = viewState.center; @@ -75498,7 +59728,7 @@ ol.renderer.dom.TileLayer.prototype.prepareFrame = goog.asserts.assert(tile); tileState = tile.getState(); if (tileState == ol.TileState.LOADED) { - tilesToDrawByZ[z][ol.tilecoord.toString(tile.tileCoord)] = tile; + tilesToDrawByZ[z][tile.tileCoord.toString()] = tile; continue; } else if (tileState == ol.TileState.EMPTY || (tileState == ol.TileState.ERROR && @@ -75621,7 +59851,6 @@ ol.renderer.dom.TileLayer.prototype.prepareFrame = }; - /** * @constructor * @private @@ -75701,7 +59930,7 @@ ol.renderer.dom.TileLayerZ_.prototype.addTile = function(tile, tileGutter) { var tileCoordY = tileCoord[2]; goog.asserts.assert(tileCoordZ == this.tileCoordOrigin_[0], 'tileCoordZ matches z of tileCoordOrigin'); - var tileCoordKey = ol.tilecoord.toString(tileCoord); + var tileCoordKey = tileCoord.toString(); if (tileCoordKey in this.tiles_) { return; } @@ -75777,8 +60006,7 @@ ol.renderer.dom.TileLayerZ_.prototype.getResolution = function() { * @param {ol.Extent} extent Extent. * @param {ol.TileRange=} opt_tileRange Temporary ol.TileRange object. */ -ol.renderer.dom.TileLayerZ_.prototype.removeTilesOutsideExtent = - function(extent, opt_tileRange) { +ol.renderer.dom.TileLayerZ_.prototype.removeTilesOutsideExtent = function(extent, opt_tileRange) { var tileRange = this.tileGrid_.getTileRangeForExtentAndZ( extent, this.tileCoordOrigin_[0], opt_tileRange); /** @type {Array.<ol.Tile>} */ @@ -75793,7 +60021,7 @@ ol.renderer.dom.TileLayerZ_.prototype.removeTilesOutsideExtent = var i, ii; for (i = 0, ii = tilesToRemove.length; i < ii; ++i) { tile = tilesToRemove[i]; - tileCoordKey = ol.tilecoord.toString(tile.tileCoord); + tileCoordKey = tile.tileCoord.toString(); goog.dom.removeNode(tile.getImage(this)); delete this.tiles_[tileCoordKey]; } @@ -75813,7 +60041,7 @@ ol.renderer.dom.TileLayerZ_.prototype.setTransform = function(transform) { goog.provide('ol.renderer.dom.VectorLayer'); goog.require('goog.asserts'); -goog.require('goog.events'); +goog.require('ol.events'); goog.require('goog.vec.Mat4'); goog.require('ol.ViewHint'); goog.require('ol.dom'); @@ -75828,7 +60056,6 @@ goog.require('ol.renderer.vector'); goog.require('ol.vec.Mat4'); - /** * @constructor * @extends {ol.renderer.dom.Layer} @@ -75906,8 +60133,18 @@ goog.inherits(ol.renderer.dom.VectorLayer, ol.renderer.dom.Layer); /** * @inheritDoc */ -ol.renderer.dom.VectorLayer.prototype.composeFrame = - function(frameState, layerState) { +ol.renderer.dom.VectorLayer.prototype.clearFrame = function() { + // Clear the canvas + var canvas = this.context_.canvas; + canvas.width = canvas.width; + this.renderedRevision_ = 0; +}; + + +/** + * @inheritDoc + */ +ol.renderer.dom.VectorLayer.prototype.composeFrame = function(frameState, layerState) { var vectorLayer = /** @type {ol.layer.Vector} */ (this.getLayer()); goog.asserts.assertInstanceof(vectorLayer, ol.layer.Vector, @@ -75968,8 +60205,7 @@ ol.renderer.dom.VectorLayer.prototype.composeFrame = * @param {goog.vec.Mat4.Number} transform Transform. * @private */ -ol.renderer.dom.VectorLayer.prototype.dispatchEvent_ = - function(type, frameState, transform) { +ol.renderer.dom.VectorLayer.prototype.dispatchEvent_ = function(type, frameState, transform) { var context = this.context_; var layer = this.getLayer(); if (layer.hasListener(type)) { @@ -75979,7 +60215,6 @@ ol.renderer.dom.VectorLayer.prototype.dispatchEvent_ = var event = new ol.render.Event(type, layer, render, frameState, context, null); layer.dispatchEvent(event); - render.flush(); } }; @@ -75987,19 +60222,17 @@ ol.renderer.dom.VectorLayer.prototype.dispatchEvent_ = /** * @inheritDoc */ -ol.renderer.dom.VectorLayer.prototype.forEachFeatureAtCoordinate = - function(coordinate, frameState, callback, thisArg) { +ol.renderer.dom.VectorLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, callback, thisArg) { if (!this.replayGroup_) { return undefined; } else { var resolution = frameState.viewState.resolution; var rotation = frameState.viewState.rotation; var layer = this.getLayer(); - var layerState = frameState.layerStates[goog.getUid(layer)]; /** @type {Object.<string, boolean>} */ var features = {}; return this.replayGroup_.forEachFeatureAtCoordinate(coordinate, resolution, - rotation, layerState.managed ? frameState.skippedFeatureUids : {}, + rotation, {}, /** * @param {ol.Feature|ol.render.Feature} feature Feature. * @return {?} Callback result. @@ -76018,11 +60251,10 @@ ol.renderer.dom.VectorLayer.prototype.forEachFeatureAtCoordinate = /** * Handle changes in image style state. - * @param {goog.events.Event} event Image style change event. + * @param {ol.events.Event} event Image style change event. * @private */ -ol.renderer.dom.VectorLayer.prototype.handleStyleImageChange_ = - function(event) { +ol.renderer.dom.VectorLayer.prototype.handleStyleImageChange_ = function(event) { this.renderIfReadyAndVisible(); }; @@ -76030,8 +60262,7 @@ ol.renderer.dom.VectorLayer.prototype.handleStyleImageChange_ = /** * @inheritDoc */ -ol.renderer.dom.VectorLayer.prototype.prepareFrame = - function(frameState, layerState) { +ol.renderer.dom.VectorLayer.prototype.prepareFrame = function(frameState, layerState) { var vectorLayer = /** @type {ol.layer.Vector} */ (this.getLayer()); goog.asserts.assertInstanceof(vectorLayer, ol.layer.Vector, @@ -76076,8 +60307,6 @@ ol.renderer.dom.VectorLayer.prototype.prepareFrame = return true; } - // FIXME dispose of old replayGroup in post render - goog.dispose(this.replayGroup_); this.replayGroup_ = null; this.dirty_ = false; @@ -76087,12 +60316,11 @@ ol.renderer.dom.VectorLayer.prototype.prepareFrame = ol.renderer.vector.getTolerance(resolution, pixelRatio), extent, resolution, vectorLayer.getRenderBuffer()); vectorSource.loadFeatures(extent, resolution, projection); - var renderFeature = - /** - * @param {ol.Feature} feature Feature. - * @this {ol.renderer.dom.VectorLayer} - */ - function(feature) { + /** + * @param {ol.Feature} feature Feature. + * @this {ol.renderer.dom.VectorLayer} + */ + var renderFeature = function(feature) { var styles; var styleFunction = feature.getStyleFunction(); if (styleFunction) { @@ -76145,13 +60373,12 @@ ol.renderer.dom.VectorLayer.prototype.prepareFrame = * @param {ol.render.canvas.ReplayGroup} replayGroup Replay group. * @return {boolean} `true` if an image is loading. */ -ol.renderer.dom.VectorLayer.prototype.renderFeature = - function(feature, resolution, pixelRatio, styles, replayGroup) { +ol.renderer.dom.VectorLayer.prototype.renderFeature = function(feature, resolution, pixelRatio, styles, replayGroup) { if (!styles) { return false; } var loading = false; - if (goog.isArray(styles)) { + if (Array.isArray(styles)) { for (var i = 0, ii = styles.length; i < ii; ++i) { loading = ol.renderer.vector.renderFeature( replayGroup, feature, styles[i], @@ -76169,16 +60396,16 @@ ol.renderer.dom.VectorLayer.prototype.renderFeature = goog.provide('ol.renderer.dom.Map'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom'); -goog.require('goog.events'); -goog.require('goog.events.Event'); -goog.require('goog.events.EventType'); +goog.require('ol.events'); +goog.require('ol.events.Event'); +goog.require('ol.events.EventType'); goog.require('goog.style'); goog.require('goog.vec.Mat4'); goog.require('ol'); goog.require('ol.RendererType'); +goog.require('ol.array'); goog.require('ol.css'); goog.require('ol.dom'); goog.require('ol.layer.Image'); @@ -76197,7 +60424,6 @@ goog.require('ol.source.State'); goog.require('ol.vec.Mat4'); - /** * @constructor * @extends {ol.renderer.Map} @@ -76238,8 +60464,8 @@ ol.renderer.dom.Map = function(container, map) { style.height = '100%'; // prevent the img context menu on mobile devices - goog.events.listen(this.layersPane_, goog.events.EventType.TOUCHSTART, - goog.events.Event.preventDefault); + ol.events.listen(this.layersPane_, ol.events.EventType.TOUCHSTART, + ol.events.Event.preventDefault); goog.dom.insertChildAt(container, this.layersPane_, 0); @@ -76286,8 +60512,7 @@ ol.renderer.dom.Map.prototype.createLayerRenderer = function(layer) { * @param {olx.FrameState} frameState Frame state. * @private */ -ol.renderer.dom.Map.prototype.dispatchComposeEvent_ = - function(type, frameState) { +ol.renderer.dom.Map.prototype.dispatchComposeEvent_ = function(type, frameState) { var map = this.getMap(); if (map.hasListener(type)) { var extent = frameState.extent; @@ -76309,7 +60534,6 @@ ol.renderer.dom.Map.prototype.dispatchComposeEvent_ = var composeEvent = new ol.render.Event(type, map, vectorContext, frameState, context, null); map.dispatchEvent(composeEvent); - vectorContext.flush(); } }; @@ -76347,7 +60571,7 @@ ol.renderer.dom.Map.prototype.renderFrame = function(frameState) { this.dispatchComposeEvent_(ol.render.EventType.PRECOMPOSE, frameState); var layerStatesArray = frameState.layerStatesArray; - goog.array.stableSort(layerStatesArray, ol.renderer.Map.sortByZIndex); + ol.array.stableSort(layerStatesArray, ol.renderer.Map.sortByZIndex); var viewResolution = frameState.viewState.resolution; var i, ii, layer, layerRenderer, layerState; @@ -78592,12 +62816,11 @@ goog.provide('ol.webgl.Shader'); goog.provide('ol.webgl.Vertex'); goog.provide('ol.webgl.shader'); -goog.require('goog.functions'); goog.require('goog.webgl'); +goog.require('ol.functions'); goog.require('ol.webgl'); - /** * @constructor * @param {string} source Source. @@ -78631,8 +62854,7 @@ ol.webgl.Shader.prototype.getSource = function() { /** * @return {boolean} Is animated? */ -ol.webgl.Shader.prototype.isAnimated = goog.functions.FALSE; - +ol.webgl.Shader.prototype.isAnimated = ol.functions.FALSE; /** @@ -78655,7 +62877,6 @@ ol.webgl.shader.Fragment.prototype.getType = function() { }; - /** * @constructor * @extends {ol.webgl.Shader} @@ -78684,7 +62905,6 @@ goog.provide('ol.render.webgl.imagereplay.shader.DefaultVertex'); goog.require('ol.webgl.shader'); - /** * @constructor * @extends {ol.webgl.shader.Fragment} @@ -78720,7 +62940,6 @@ ol.render.webgl.imagereplay.shader.DefaultFragment.SOURCE = goog.DEBUG ? ol.render.webgl.imagereplay.shader.DefaultFragment.OPTIMIZED_SOURCE; - /** * @constructor * @extends {ol.webgl.shader.Vertex} @@ -78756,7 +62975,6 @@ ol.render.webgl.imagereplay.shader.DefaultVertex.SOURCE = goog.DEBUG ? ol.render.webgl.imagereplay.shader.DefaultVertex.OPTIMIZED_SOURCE; - /** * @constructor * @param {WebGLRenderingContext} gl GL. @@ -78842,7 +63060,6 @@ ol.webgl.BufferUsage = { }; - /** * @constructor * @param {Array.<number>=} opt_arr Array. @@ -78885,29 +63102,21 @@ ol.webgl.Buffer.prototype.getUsage = function() { goog.provide('ol.webgl.Context'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.log'); -goog.require('goog.object'); goog.require('ol'); +goog.require('ol.Disposable'); goog.require('ol.array'); +goog.require('ol.events'); +goog.require('ol.object'); goog.require('ol.webgl.Buffer'); goog.require('ol.webgl.WebGLContextEventType'); /** - * @typedef {{buf: ol.webgl.Buffer, - * buffer: WebGLBuffer}} - */ -ol.webgl.BufferCacheEntry; - - - -/** * @classdesc * A WebGL context for accessing low-level WebGL capabilities. * * @constructor - * @extends {goog.events.EventTarget} + * @extends {ol.Disposable} * @param {HTMLCanvasElement} canvas Canvas. * @param {WebGLRenderingContext} gl GL. */ @@ -78927,13 +63136,13 @@ ol.webgl.Context = function(canvas, gl) { /** * @private - * @type {Object.<number, ol.webgl.BufferCacheEntry>} + * @type {Object.<string, ol.WebglBufferCacheEntry>} */ this.bufferCache_ = {}; /** * @private - * @type {Object.<number, WebGLShader>} + * @type {Object.<string, WebGLShader>} */ this.shaderCache_ = {}; @@ -78980,12 +63189,13 @@ ol.webgl.Context = function(canvas, gl) { 'Failed to get extension "OES_element_index_uint"'); } - goog.events.listen(this.canvas_, ol.webgl.WebGLContextEventType.LOST, - this.handleWebGLContextLost, false, this); - goog.events.listen(this.canvas_, ol.webgl.WebGLContextEventType.RESTORED, - this.handleWebGLContextRestored, false, this); + ol.events.listen(this.canvas_, ol.webgl.WebGLContextEventType.LOST, + this.handleWebGLContextLost, this); + ol.events.listen(this.canvas_, ol.webgl.WebGLContextEventType.RESTORED, + this.handleWebGLContextRestored, this); }; +goog.inherits(ol.webgl.Context, ol.Disposable); /** @@ -78998,7 +63208,7 @@ ol.webgl.Context = function(canvas, gl) { ol.webgl.Context.prototype.bindBuffer = function(target, buf) { var gl = this.getGL(); var arr = buf.getArray(); - var bufferKey = goog.getUid(buf); + var bufferKey = String(goog.getUid(buf)); if (bufferKey in this.bufferCache_) { var bufferCacheEntry = this.bufferCache_[bufferKey]; gl.bindBuffer(target, bufferCacheEntry.buffer); @@ -79031,7 +63241,7 @@ ol.webgl.Context.prototype.bindBuffer = function(target, buf) { */ ol.webgl.Context.prototype.deleteBuffer = function(buf) { var gl = this.getGL(); - var bufferKey = goog.getUid(buf); + var bufferKey = String(goog.getUid(buf)); goog.asserts.assert(bufferKey in this.bufferCache_, 'attempted to delete uncached buffer'); var bufferCacheEntry = this.bufferCache_[bufferKey]; @@ -79046,17 +63256,19 @@ ol.webgl.Context.prototype.deleteBuffer = function(buf) { * @inheritDoc */ ol.webgl.Context.prototype.disposeInternal = function() { + ol.events.unlistenAll(this.canvas_); var gl = this.getGL(); if (!gl.isContextLost()) { - goog.object.forEach(this.bufferCache_, function(bufferCacheEntry) { - gl.deleteBuffer(bufferCacheEntry.buffer); - }); - goog.object.forEach(this.programCache_, function(program) { - gl.deleteProgram(program); - }); - goog.object.forEach(this.shaderCache_, function(shader) { - gl.deleteShader(shader); - }); + var key; + for (key in this.bufferCache_) { + gl.deleteBuffer(this.bufferCache_[key].buffer); + } + for (key in this.programCache_) { + gl.deleteProgram(this.programCache_[key]); + } + for (key in this.shaderCache_) { + gl.deleteShader(this.shaderCache_[key]); + } // delete objects for hit-detection gl.deleteFramebuffer(this.hitDetectionFramebuffer_); gl.deleteRenderbuffer(this.hitDetectionRenderbuffer_); @@ -79102,7 +63314,7 @@ ol.webgl.Context.prototype.getHitDetectionFramebuffer = function() { * @return {WebGLShader} Shader. */ ol.webgl.Context.prototype.getShader = function(shaderObject) { - var shaderKey = goog.getUid(shaderObject); + var shaderKey = String(goog.getUid(shaderObject)); if (shaderKey in this.shaderCache_) { return this.shaderCache_[shaderKey]; } else { @@ -79110,16 +63322,10 @@ ol.webgl.Context.prototype.getShader = function(shaderObject) { var shader = gl.createShader(shaderObject.getType()); gl.shaderSource(shader, shaderObject.getSource()); gl.compileShader(shader); - if (goog.DEBUG) { - if (!gl.getShaderParameter(shader, goog.webgl.COMPILE_STATUS) && - !gl.isContextLost()) { - goog.log.error(this.logger_, gl.getShaderInfoLog(shader)); - } - } goog.asserts.assert( gl.getShaderParameter(shader, goog.webgl.COMPILE_STATUS) || gl.isContextLost(), - 'illegal state, shader not compiled or context lost'); + gl.getShaderInfoLog(shader) || 'illegal state, shader not compiled or context lost'); this.shaderCache_[shaderKey] = shader; return shader; } @@ -79146,16 +63352,10 @@ ol.webgl.Context.prototype.getProgram = function( gl.attachShader(program, this.getShader(fragmentShaderObject)); gl.attachShader(program, this.getShader(vertexShaderObject)); gl.linkProgram(program); - if (goog.DEBUG) { - if (!gl.getProgramParameter(program, goog.webgl.LINK_STATUS) && - !gl.isContextLost()) { - goog.log.error(this.logger_, gl.getProgramInfoLog(program)); - } - } goog.asserts.assert( gl.getProgramParameter(program, goog.webgl.LINK_STATUS) || gl.isContextLost(), - 'illegal state, shader not linked or context lost'); + gl.getProgramInfoLog(program) || 'illegal state, shader not linked or context lost'); this.programCache_[programKey] = program; return program; } @@ -79166,9 +63366,9 @@ ol.webgl.Context.prototype.getProgram = function( * FIXME empy description for jsdoc */ ol.webgl.Context.prototype.handleWebGLContextLost = function() { - goog.object.clear(this.bufferCache_); - goog.object.clear(this.shaderCache_); - goog.object.clear(this.programCache_); + ol.object.clear(this.bufferCache_); + ol.object.clear(this.shaderCache_); + ol.object.clear(this.programCache_); this.currentProgram_ = null; this.hitDetectionFramebuffer_ = null; this.hitDetectionTexture_ = null; @@ -79230,17 +63430,10 @@ ol.webgl.Context.prototype.useProgram = function(program) { /** - * @private - * @type {goog.log.Logger} - */ -ol.webgl.Context.prototype.logger_ = goog.log.getLogger('ol.webgl.Context'); - - -/** * @param {WebGLRenderingContext} gl WebGL rendering context. * @param {number=} opt_wrapS wrapS. * @param {number=} opt_wrapT wrapT. - * @return {WebGLTexture} + * @return {WebGLTexture} The texture. * @private */ ol.webgl.Context.createTexture_ = function(gl, opt_wrapS, opt_wrapT) { @@ -79268,7 +63461,7 @@ ol.webgl.Context.createTexture_ = function(gl, opt_wrapS, opt_wrapT) { * @param {number} height Height. * @param {number=} opt_wrapS wrapS. * @param {number=} opt_wrapT wrapT. - * @return {WebGLTexture} + * @return {WebGLTexture} The texture. */ ol.webgl.Context.createEmptyTexture = function( gl, width, height, opt_wrapS, opt_wrapT) { @@ -79286,7 +63479,7 @@ ol.webgl.Context.createEmptyTexture = function( * @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image. * @param {number=} opt_wrapS wrapS. * @param {number=} opt_wrapT wrapT. - * @return {WebGLTexture} + * @return {WebGLTexture} The texture. */ ol.webgl.Context.createTexture = function(gl, image, opt_wrapS, opt_wrapT) { var texture = ol.webgl.Context.createTexture_(gl, opt_wrapS, opt_wrapT); @@ -79300,10 +63493,9 @@ goog.provide('ol.render.webgl.ImageReplay'); goog.provide('ol.render.webgl.ReplayGroup'); goog.require('goog.asserts'); -goog.require('goog.functions'); -goog.require('goog.object'); goog.require('goog.vec.Mat4'); goog.require('ol.extent'); +goog.require('ol.object'); goog.require('ol.render.IReplayGroup'); goog.require('ol.render.VectorContext'); goog.require('ol.render.webgl.imagereplay.shader.Default'); @@ -79315,7 +63507,6 @@ goog.require('ol.webgl.Buffer'); goog.require('ol.webgl.Context'); - /** * @constructor * @extends {ol.render.VectorContext} @@ -79496,7 +63687,7 @@ ol.render.webgl.ImageReplay = function(tolerance, maxExtent) { /** * Start index per feature (the feature). - * @type {Array.<ol.Feature>} + * @type {Array.<ol.Feature|ol.render.Feature>} * @private */ this.startIndicesFeature_ = []; @@ -79514,8 +63705,7 @@ goog.inherits(ol.render.webgl.ImageReplay, ol.render.VectorContext); * @param {ol.webgl.Context} context WebGL context. * @return {function()} Delete resources function. */ -ol.render.webgl.ImageReplay.prototype.getDeleteResourcesFunction = - function(context) { +ol.render.webgl.ImageReplay.prototype.getDeleteResourcesFunction = function(context) { // We only delete our stuff here. The shaders and the program may // be used by other ImageReplay instances (for other layers). And // they will be deleted when disposing of the ol.webgl.Context @@ -79546,12 +63736,6 @@ ol.render.webgl.ImageReplay.prototype.getDeleteResourcesFunction = /** - * @inheritDoc - */ -ol.render.webgl.ImageReplay.prototype.drawAsync = goog.abstractMethod; - - -/** * @param {Array.<number>} flatCoordinates Flat coordinates. * @param {number} offset Offset. * @param {number} end End. @@ -79559,8 +63743,7 @@ ol.render.webgl.ImageReplay.prototype.drawAsync = goog.abstractMethod; * @return {number} My end. * @private */ -ol.render.webgl.ImageReplay.prototype.drawCoordinates_ = - function(flatCoordinates, offset, end, stride) { +ol.render.webgl.ImageReplay.prototype.drawCoordinates_ = function(flatCoordinates, offset, end, stride) { goog.asserts.assert(this.anchorX_ !== undefined, 'anchorX is defined'); goog.asserts.assert(this.anchorY_ !== undefined, 'anchorY is defined'); goog.asserts.assert(this.height_ !== undefined, 'height is defined'); @@ -79671,8 +63854,7 @@ ol.render.webgl.ImageReplay.prototype.drawCoordinates_ = /** * @inheritDoc */ -ol.render.webgl.ImageReplay.prototype.drawMultiPointGeometry = - function(multiPointGeometry, feature) { +ol.render.webgl.ImageReplay.prototype.drawMultiPoint = function(multiPointGeometry, feature) { this.startIndices_.push(this.indices_.length); this.startIndicesFeature_.push(feature); var flatCoordinates = multiPointGeometry.getFlatCoordinates(); @@ -79685,8 +63867,7 @@ ol.render.webgl.ImageReplay.prototype.drawMultiPointGeometry = /** * @inheritDoc */ -ol.render.webgl.ImageReplay.prototype.drawPointGeometry = - function(pointGeometry, feature) { +ol.render.webgl.ImageReplay.prototype.drawPoint = function(pointGeometry, feature) { this.startIndices_.push(this.indices_.length); this.startIndicesFeature_.push(feature); var flatCoordinates = pointGeometry.getFlatCoordinates(); @@ -79765,8 +63946,7 @@ ol.render.webgl.ImageReplay.prototype.finish = function(context) { * @param {Object.<string, WebGLTexture>} texturePerImage Texture cache. * @param {WebGLRenderingContext} gl Gl. */ -ol.render.webgl.ImageReplay.prototype.createTextures_ = - function(textures, images, texturePerImage, gl) { +ol.render.webgl.ImageReplay.prototype.createTextures_ = function(textures, images, texturePerImage, gl) { goog.asserts.assert(textures.length === 0, 'upon creation, textures is empty'); @@ -79798,7 +63978,7 @@ ol.render.webgl.ImageReplay.prototype.createTextures_ = * @param {number} opacity Global opacity. * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features * to skip. - * @param {function(ol.Feature): T|undefined} featureCallback Feature callback. + * @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback. * @param {boolean} oneByOne Draw features one-by-one for the hit-detecion. * @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting * this extent are checked. @@ -79917,15 +64097,14 @@ ol.render.webgl.ImageReplay.prototype.replay = function(context, * @param {Array.<WebGLTexture>} textures Textures. * @param {Array.<number>} groupIndices Texture group indices. */ -ol.render.webgl.ImageReplay.prototype.drawReplay_ = - function(gl, context, skippedFeaturesHash, textures, groupIndices) { +ol.render.webgl.ImageReplay.prototype.drawReplay_ = function(gl, context, skippedFeaturesHash, textures, groupIndices) { goog.asserts.assert(textures.length === groupIndices.length, 'number of textures and groupIndeces match'); var elementType = context.hasOESElementIndexUint ? goog.webgl.UNSIGNED_INT : goog.webgl.UNSIGNED_SHORT; var elementSize = context.hasOESElementIndexUint ? 4 : 2; - if (!goog.object.isEmpty(skippedFeaturesHash)) { + if (!ol.object.isEmpty(skippedFeaturesHash)) { this.drawReplaySkipping_( gl, skippedFeaturesHash, textures, groupIndices, elementType, elementSize); @@ -79968,8 +64147,7 @@ ol.render.webgl.ImageReplay.prototype.drawReplay_ = * @param {number} elementType Element type. * @param {number} elementSize Element Size. */ -ol.render.webgl.ImageReplay.prototype.drawReplaySkipping_ = - function(gl, skippedFeaturesHash, textures, groupIndices, +ol.render.webgl.ImageReplay.prototype.drawReplaySkipping_ = function(gl, skippedFeaturesHash, textures, groupIndices, elementType, elementSize) { var featureIndex = 0; @@ -80035,15 +64213,14 @@ ol.render.webgl.ImageReplay.prototype.drawElements_ = function( * @param {ol.webgl.Context} context Context. * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features * to skip. - * @param {function(ol.Feature): T|undefined} featureCallback Feature callback. + * @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback. * @param {boolean} oneByOne Draw features one-by-one for the hit-detecion. * @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting * this extent are checked. * @return {T|undefined} Callback result. * @template T */ -ol.render.webgl.ImageReplay.prototype.drawHitDetectionReplay_ = - function(gl, context, skippedFeaturesHash, featureCallback, oneByOne, +ol.render.webgl.ImageReplay.prototype.drawHitDetectionReplay_ = function(gl, context, skippedFeaturesHash, featureCallback, oneByOne, opt_hitExtent) { if (!oneByOne) { // draw all hit-detection features in "once" (by texture group) @@ -80063,12 +64240,11 @@ ol.render.webgl.ImageReplay.prototype.drawHitDetectionReplay_ = * @param {ol.webgl.Context} context Context. * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features * to skip. - * @param {function(ol.Feature): T|undefined} featureCallback Feature callback. + * @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback. * @return {T|undefined} Callback result. * @template T */ -ol.render.webgl.ImageReplay.prototype.drawHitDetectionReplayAll_ = - function(gl, context, skippedFeaturesHash, featureCallback) { +ol.render.webgl.ImageReplay.prototype.drawHitDetectionReplayAll_ = function(gl, context, skippedFeaturesHash, featureCallback) { gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); this.drawReplay_(gl, context, skippedFeaturesHash, this.hitDetectionTextures_, this.hitDetectionGroupIndices_); @@ -80088,14 +64264,13 @@ ol.render.webgl.ImageReplay.prototype.drawHitDetectionReplayAll_ = * @param {ol.webgl.Context} context Context. * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features * to skip. - * @param {function(ol.Feature): T|undefined} featureCallback Feature callback. + * @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback. * @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting * this extent are checked. * @return {T|undefined} Callback result. * @template T */ -ol.render.webgl.ImageReplay.prototype.drawHitDetectionReplayOneByOne_ = - function(gl, context, skippedFeaturesHash, featureCallback, +ol.render.webgl.ImageReplay.prototype.drawHitDetectionReplayOneByOne_ = function(gl, context, skippedFeaturesHash, featureCallback, opt_hitExtent) { goog.asserts.assert(this.hitDetectionTextures_.length === this.hitDetectionGroupIndices_.length, @@ -80219,7 +64394,6 @@ ol.render.webgl.ImageReplay.prototype.setImageStyle = function(imageStyle) { }; - /** * @constructor * @implements {ol.render.IReplayGroup} @@ -80263,15 +64437,21 @@ ol.render.webgl.ReplayGroup = function( * @param {ol.webgl.Context} context WebGL context. * @return {function()} Delete resources function. */ -ol.render.webgl.ReplayGroup.prototype.getDeleteResourcesFunction = - function(context) { +ol.render.webgl.ReplayGroup.prototype.getDeleteResourcesFunction = function(context) { var functions = []; var replayKey; for (replayKey in this.replays_) { functions.push( this.replays_[replayKey].getDeleteResourcesFunction(context)); } - return goog.functions.sequence.apply(null, functions); + return function() { + var length = functions.length; + var result; + for (var i = 0; i < length; i++) { + result = functions[i].apply(this, arguments); + } + return result; + }; }; @@ -80289,8 +64469,7 @@ ol.render.webgl.ReplayGroup.prototype.finish = function(context) { /** * @inheritDoc */ -ol.render.webgl.ReplayGroup.prototype.getReplay = - function(zIndex, replayType) { +ol.render.webgl.ReplayGroup.prototype.getReplay = function(zIndex, replayType) { var replay = this.replays_[replayType]; if (replay === undefined) { var constructor = ol.render.webgl.BATCH_CONSTRUCTORS_[replayType]; @@ -80308,7 +64487,7 @@ ol.render.webgl.ReplayGroup.prototype.getReplay = * @inheritDoc */ ol.render.webgl.ReplayGroup.prototype.isEmpty = function() { - return goog.object.isEmpty(this.replays_); + return ol.object.isEmpty(this.replays_); }; @@ -80350,7 +64529,7 @@ ol.render.webgl.ReplayGroup.prototype.replay = function(context, * @param {number} opacity Global opacity. * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features * to skip. - * @param {function(ol.Feature): T|undefined} featureCallback Feature callback. + * @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback. * @param {boolean} oneByOne Draw features one-by-one for the hit-detecion. * @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting * this extent are checked. @@ -80387,7 +64566,7 @@ ol.render.webgl.ReplayGroup.prototype.replayHitDetection_ = function(context, * @param {number} opacity Global opacity. * @param {Object.<string, boolean>} skippedFeaturesHash Ids of features * to skip. - * @param {function(ol.Feature): T|undefined} callback Feature callback. + * @param {function((ol.Feature|ol.render.Feature)): T|undefined} callback Feature callback. * @return {T|undefined} Callback result. * @template T */ @@ -80416,7 +64595,7 @@ ol.render.webgl.ReplayGroup.prototype.forEachFeatureAtCoordinate = function( coordinate, resolution, rotation, ol.render.webgl.HIT_DETECTION_SIZE_, pixelRatio, opacity, skippedFeaturesHash, /** - * @param {ol.Feature} feature Feature. + * @param {ol.Feature|ol.render.Feature} feature Feature. * @return {?} Callback result. */ function(feature) { @@ -80457,7 +64636,7 @@ ol.render.webgl.ReplayGroup.prototype.hasFeatureAtCoordinate = function( coordinate, resolution, rotation, ol.render.webgl.HIT_DETECTION_SIZE_, pixelRatio, opacity, skippedFeaturesHash, /** - * @param {ol.Feature} feature Feature. + * @param {ol.Feature|ol.render.Feature} feature Feature. * @return {boolean} Is there a feature? */ function(feature) { @@ -80490,14 +64669,14 @@ ol.render.webgl.BATCH_CONSTRUCTORS_ = { ol.render.webgl.HIT_DETECTION_SIZE_ = [1, 1]; goog.provide('ol.render.webgl.Immediate'); -goog.require('ol.array'); +goog.require('goog.asserts'); goog.require('ol.extent'); +goog.require('ol.geom.GeometryType'); goog.require('ol.render.VectorContext'); goog.require('ol.render.webgl.ImageReplay'); goog.require('ol.render.webgl.ReplayGroup'); - /** * @constructor * @extends {ol.render.VectorContext} @@ -80510,8 +64689,7 @@ goog.require('ol.render.webgl.ReplayGroup'); * @param {number} pixelRatio Pixel ratio. * @struct */ -ol.render.webgl.Immediate = function(context, - center, resolution, rotation, size, extent, pixelRatio) { +ol.render.webgl.Immediate = function(context, center, resolution, rotation, size, extent, pixelRatio) { goog.base(this); /** @@ -80555,58 +64733,44 @@ ol.render.webgl.Immediate = function(context, */ this.imageStyle_ = null; - /** - * @private - * @type {!Object.<string, - * Array.<function(ol.render.webgl.Immediate)>>} - */ - this.callbacksByZIndex_ = {}; }; goog.inherits(ol.render.webgl.Immediate, ol.render.VectorContext); /** - * FIXME: empty description for jsdoc - */ -ol.render.webgl.Immediate.prototype.flush = function() { - /** @type {Array.<number>} */ - var zs = Object.keys(this.callbacksByZIndex_).map(Number); - zs.sort(ol.array.numberSafeCompareFunction); - var i, ii, callbacks, j, jj; - for (i = 0, ii = zs.length; i < ii; ++i) { - callbacks = this.callbacksByZIndex_[zs[i].toString()]; - for (j = 0, jj = callbacks.length; j < jj; ++j) { - callbacks[j](this); - } - } -}; - - -/** - * Register a function to be called for rendering at a given zIndex. The - * function will be called asynchronously. The callback will receive a - * reference to {@link ol.render.canvas.Immediate} context for drawing. - * @param {number} zIndex Z index. - * @param {function(ol.render.webgl.Immediate)} callback Callback. + * Set the rendering style. Note that since this is an immediate rendering API, + * any `zIndex` on the provided style will be ignored. + * + * @param {ol.style.Style} style The rendering style. * @api */ -ol.render.webgl.Immediate.prototype.drawAsync = function(zIndex, callback) { - var zIndexKey = zIndex.toString(); - var callbacks = this.callbacksByZIndex_[zIndexKey]; - if (callbacks !== undefined) { - callbacks.push(callback); - } else { - this.callbacksByZIndex_[zIndexKey] = [callback]; - } +ol.render.webgl.Immediate.prototype.setStyle = function(style) { + this.setImageStyle(style.getImage()); }; /** - * @inheritDoc + * Render a geometry into the canvas. Call + * {@link ol.render.webgl.Immediate#setStyle} first to set the rendering style. + * + * @param {ol.geom.Geometry|ol.render.Feature} geometry The geometry to render. * @api */ -ol.render.webgl.Immediate.prototype.drawCircleGeometry = - function(circleGeometry, data) { +ol.render.webgl.Immediate.prototype.drawGeometry = function(geometry) { + var type = geometry.getType(); + switch (type) { + case ol.geom.GeometryType.POINT: + this.drawPoint(/** @type {ol.geom.Point} */ (geometry), null); + break; + case ol.geom.GeometryType.MULTI_POINT: + this.drawMultiPoint(/** @type {ol.geom.MultiPoint} */ (geometry), null); + break; + case ol.geom.GeometryType.GEOMETRY_COLLECTION: + this.drawGeometryCollection(/** @type {ol.geom.GeometryCollection} */ (geometry), null); + break; + default: + goog.asserts.fail('Unsupported geometry type: ' + type); + } }; @@ -80620,59 +64784,34 @@ ol.render.webgl.Immediate.prototype.drawFeature = function(feature, style) { !ol.extent.intersects(this.extent_, geometry.getExtent())) { return; } - var zIndex = style.getZIndex(); - if (zIndex === undefined) { - zIndex = 0; - } - this.drawAsync(zIndex, function(render) { - render.setFillStrokeStyle(style.getFill(), style.getStroke()); - render.setImageStyle(style.getImage()); - render.setTextStyle(style.getText()); - var type = geometry.getType(); - var renderGeometry = ol.render.webgl.Immediate.GEOMETRY_RENDERERS_[type]; - // Do not assert since all kinds of geometries are not handled yet. - // In spite, render what we support. - if (renderGeometry) { - renderGeometry.call(render, geometry, null); - } - }); + this.setStyle(style); + goog.asserts.assert(geometry, 'geometry must be truthy'); + this.drawGeometry(geometry); }; /** * @inheritDoc - * @api */ -ol.render.webgl.Immediate.prototype.drawGeometryCollectionGeometry = - function(geometryCollectionGeometry, data) { - var geometries = geometryCollectionGeometry.getGeometriesArray(); - var renderers = ol.render.webgl.Immediate.GEOMETRY_RENDERERS_; +ol.render.webgl.Immediate.prototype.drawGeometryCollection = function(geometry, data) { + var geometries = geometry.getGeometriesArray(); var i, ii; for (i = 0, ii = geometries.length; i < ii; ++i) { - var geometry = geometries[i]; - var geometryRenderer = renderers[geometry.getType()]; - // Do not assert since all kinds of geometries are not handled yet. - // In order to support hierarchies, delegate instead what we can to - // valid renderers. - if (geometryRenderer) { - geometryRenderer.call(this, geometry, data); - } + this.drawGeometry(geometries[i]); } }; /** * @inheritDoc - * @api */ -ol.render.webgl.Immediate.prototype.drawPointGeometry = - function(pointGeometry, data) { +ol.render.webgl.Immediate.prototype.drawPoint = function(geometry, data) { var context = this.context_; var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_); var replay = /** @type {ol.render.webgl.ImageReplay} */ ( replayGroup.getReplay(0, ol.render.ReplayType.IMAGE)); replay.setImageStyle(this.imageStyle_); - replay.drawPointGeometry(pointGeometry, data); + replay.drawPoint(geometry, data); replay.finish(context); // default colors var opacity = 1; @@ -80688,34 +64827,14 @@ ol.render.webgl.Immediate.prototype.drawPointGeometry = /** * @inheritDoc - * @api - */ -ol.render.webgl.Immediate.prototype.drawLineStringGeometry = - function(lineStringGeometry, data) { -}; - - -/** - * @inheritDoc - * @api - */ -ol.render.webgl.Immediate.prototype.drawMultiLineStringGeometry = - function(multiLineStringGeometry, data) { -}; - - -/** - * @inheritDoc - * @api */ -ol.render.webgl.Immediate.prototype.drawMultiPointGeometry = - function(multiPointGeometry, data) { +ol.render.webgl.Immediate.prototype.drawMultiPoint = function(geometry, data) { var context = this.context_; var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_); var replay = /** @type {ol.render.webgl.ImageReplay} */ ( replayGroup.getReplay(0, ol.render.ReplayType.IMAGE)); replay.setImageStyle(this.imageStyle_); - replay.drawMultiPointGeometry(multiPointGeometry, data); + replay.drawMultiPoint(geometry, data); replay.finish(context); var opacity = 1; var skippedFeatures = {}; @@ -80730,71 +64849,11 @@ ol.render.webgl.Immediate.prototype.drawMultiPointGeometry = /** * @inheritDoc - * @api - */ -ol.render.webgl.Immediate.prototype.drawMultiPolygonGeometry = - function(multiPolygonGeometry, data) { -}; - - -/** - * @inheritDoc - * @api - */ -ol.render.webgl.Immediate.prototype.drawPolygonGeometry = - function(polygonGeometry, data) { -}; - - -/** - * @inheritDoc - * @api - */ -ol.render.webgl.Immediate.prototype.drawText = - function(flatCoordinates, offset, end, stride, geometry, data) { -}; - - -/** - * @inheritDoc - * @api - */ -ol.render.webgl.Immediate.prototype.setFillStrokeStyle = - function(fillStyle, strokeStyle) { -}; - - -/** - * @inheritDoc - * @api */ ol.render.webgl.Immediate.prototype.setImageStyle = function(imageStyle) { this.imageStyle_ = imageStyle; }; - -/** - * @inheritDoc - * @api - */ -ol.render.webgl.Immediate.prototype.setTextStyle = function(textStyle) { -}; - - -/** - * @const - * @private - * @type {Object.<ol.geom.GeometryType, - * function(this: ol.render.webgl.Immediate, - * (ol.geom.Geometry|ol.render.Feature), Object)>} - */ -ol.render.webgl.Immediate.GEOMETRY_RENDERERS_ = { - 'Point': ol.render.webgl.Immediate.prototype.drawPointGeometry, - 'MultiPoint': ol.render.webgl.Immediate.prototype.drawMultiPointGeometry, - 'GeometryCollection': - ol.render.webgl.Immediate.prototype.drawGeometryCollectionGeometry -}; - // This file is automatically generated, do not edit goog.provide('ol.renderer.webgl.map.shader.Default'); goog.provide('ol.renderer.webgl.map.shader.Default.Locations'); @@ -80804,7 +64863,6 @@ goog.provide('ol.renderer.webgl.map.shader.DefaultVertex'); goog.require('ol.webgl.shader'); - /** * @constructor * @extends {ol.webgl.shader.Fragment} @@ -80840,7 +64898,6 @@ ol.renderer.webgl.map.shader.DefaultFragment.SOURCE = goog.DEBUG ? ol.renderer.webgl.map.shader.DefaultFragment.OPTIMIZED_SOURCE; - /** * @constructor * @extends {ol.webgl.shader.Vertex} @@ -80876,7 +64933,6 @@ ol.renderer.webgl.map.shader.DefaultVertex.SOURCE = goog.DEBUG ? ol.renderer.webgl.map.shader.DefaultVertex.OPTIMIZED_SOURCE; - /** * @constructor * @param {WebGLRenderingContext} gl GL. @@ -80939,7 +64995,6 @@ goog.require('ol.webgl.Buffer'); goog.require('ol.webgl.Context'); - /** * @constructor * @extends {ol.renderer.Layer} @@ -81012,27 +65067,27 @@ goog.inherits(ol.renderer.webgl.Layer, ol.renderer.Layer); * @param {number} framebufferDimension Framebuffer dimension. * @protected */ -ol.renderer.webgl.Layer.prototype.bindFramebuffer = - function(frameState, framebufferDimension) { +ol.renderer.webgl.Layer.prototype.bindFramebuffer = function(frameState, framebufferDimension) { var gl = this.mapRenderer.getGL(); if (this.framebufferDimension === undefined || this.framebufferDimension != framebufferDimension) { + /** + * @param {WebGLRenderingContext} gl GL. + * @param {WebGLFramebuffer} framebuffer Framebuffer. + * @param {WebGLTexture} texture Texture. + */ + var postRenderFunction = function(gl, framebuffer, texture) { + if (!gl.isContextLost()) { + gl.deleteFramebuffer(framebuffer); + gl.deleteTexture(texture); + } + }.bind(null, gl, this.framebuffer, this.texture); frameState.postRenderFunctions.push( - goog.partial( - /** - * @param {WebGLRenderingContext} gl GL. - * @param {WebGLFramebuffer} framebuffer Framebuffer. - * @param {WebGLTexture} texture Texture. - */ - function(gl, framebuffer, texture) { - if (!gl.isContextLost()) { - gl.deleteFramebuffer(framebuffer); - gl.deleteTexture(texture); - } - }, gl, this.framebuffer, this.texture)); + /** @type {ol.PostRenderFunction} */ (postRenderFunction) + ); var texture = ol.webgl.Context.createEmptyTexture( gl, framebufferDimension, framebufferDimension); @@ -81055,11 +65110,10 @@ ol.renderer.webgl.Layer.prototype.bindFramebuffer = /** * @param {olx.FrameState} frameState Frame state. - * @param {ol.layer.LayerState} layerState Layer state. + * @param {ol.LayerState} layerState Layer state. * @param {ol.webgl.Context} context Context. */ -ol.renderer.webgl.Layer.prototype.composeFrame = - function(frameState, layerState, context) { +ol.renderer.webgl.Layer.prototype.composeFrame = function(frameState, layerState, context) { this.dispatchComposeEvent_( ol.render.EventType.PRECOMPOSE, context, frameState); @@ -81113,8 +65167,7 @@ ol.renderer.webgl.Layer.prototype.composeFrame = * @param {olx.FrameState} frameState Frame state. * @private */ -ol.renderer.webgl.Layer.prototype.dispatchComposeEvent_ = - function(type, context, frameState) { +ol.renderer.webgl.Layer.prototype.dispatchComposeEvent_ = function(type, context, frameState) { var layer = this.getLayer(); if (layer.hasListener(type)) { var viewState = frameState.viewState; @@ -81170,7 +65223,7 @@ ol.renderer.webgl.Layer.prototype.handleWebGLContextLost = function() { /** * @param {olx.FrameState} frameState Frame state. - * @param {ol.layer.LayerState} layerState Layer state. + * @param {ol.LayerState} layerState Layer state. * @param {ol.webgl.Context} context Context. * @return {boolean} whether composeFrame should be called. */ @@ -81179,15 +65232,13 @@ ol.renderer.webgl.Layer.prototype.prepareFrame = goog.abstractMethod; goog.provide('ol.renderer.webgl.ImageLayer'); goog.require('goog.asserts'); -goog.require('goog.functions'); goog.require('goog.vec.Mat4'); goog.require('goog.webgl'); -goog.require('ol.Coordinate'); -goog.require('ol.Extent'); goog.require('ol.ImageBase'); goog.require('ol.ViewHint'); goog.require('ol.dom'); goog.require('ol.extent'); +goog.require('ol.functions'); goog.require('ol.layer.Image'); goog.require('ol.proj'); goog.require('ol.renderer.webgl.Layer'); @@ -81196,7 +65247,6 @@ goog.require('ol.vec.Mat4'); goog.require('ol.webgl.Context'); - /** * @constructor * @extends {ol.renderer.webgl.Layer} @@ -81252,8 +65302,7 @@ ol.renderer.webgl.ImageLayer.prototype.createTexture_ = function(image) { /** * @inheritDoc */ -ol.renderer.webgl.ImageLayer.prototype.forEachFeatureAtCoordinate = - function(coordinate, frameState, callback, thisArg) { +ol.renderer.webgl.ImageLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, callback, thisArg) { var layer = this.getLayer(); var source = layer.getSource(); var resolution = frameState.viewState.resolution; @@ -81275,8 +65324,7 @@ ol.renderer.webgl.ImageLayer.prototype.forEachFeatureAtCoordinate = /** * @inheritDoc */ -ol.renderer.webgl.ImageLayer.prototype.prepareFrame = - function(frameState, layerState, context) { +ol.renderer.webgl.ImageLayer.prototype.prepareFrame = function(frameState, layerState, context) { var gl = this.mapRenderer.getGL(); @@ -81319,17 +65367,18 @@ ol.renderer.webgl.ImageLayer.prototype.prepareFrame = image = image_; texture = this.createTexture_(image_); if (this.texture) { + /** + * @param {WebGLRenderingContext} gl GL. + * @param {WebGLTexture} texture Texture. + */ + var postRenderFunction = function(gl, texture) { + if (!gl.isContextLost()) { + gl.deleteTexture(texture); + } + }.bind(null, gl, this.texture); frameState.postRenderFunctions.push( - goog.partial( - /** - * @param {WebGLRenderingContext} gl GL. - * @param {WebGLTexture} texture Texture. - */ - function(gl, texture) { - if (!gl.isContextLost()) { - gl.deleteTexture(texture); - } - }, gl, this.texture)); + /** @type {ol.PostRenderFunction} */ (postRenderFunction) + ); } } } @@ -81372,8 +65421,7 @@ ol.renderer.webgl.ImageLayer.prototype.prepareFrame = * @param {ol.Extent} imageExtent Image extent. * @private */ -ol.renderer.webgl.ImageLayer.prototype.updateProjectionMatrix_ = - function(canvasWidth, canvasHeight, pixelRatio, +ol.renderer.webgl.ImageLayer.prototype.updateProjectionMatrix_ = function(canvasWidth, canvasHeight, pixelRatio, viewCenter, viewResolution, viewRotation, imageExtent) { var canvasExtentWidth = canvasWidth * viewResolution; @@ -81401,10 +65449,9 @@ ol.renderer.webgl.ImageLayer.prototype.updateProjectionMatrix_ = /** * @inheritDoc */ -ol.renderer.webgl.ImageLayer.prototype.hasFeatureAtCoordinate = - function(coordinate, frameState) { +ol.renderer.webgl.ImageLayer.prototype.hasFeatureAtCoordinate = function(coordinate, frameState) { var hasFeature = this.forEachFeatureAtCoordinate( - coordinate, frameState, goog.functions.TRUE, this); + coordinate, frameState, ol.functions.TRUE, this); return hasFeature !== undefined; }; @@ -81412,8 +65459,7 @@ ol.renderer.webgl.ImageLayer.prototype.hasFeatureAtCoordinate = /** * @inheritDoc */ -ol.renderer.webgl.ImageLayer.prototype.forEachLayerAtPixel = - function(pixel, frameState, callback, thisArg) { +ol.renderer.webgl.ImageLayer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) { if (!this.image_ || !this.image_.getImage()) { return undefined; } @@ -81425,7 +65471,7 @@ ol.renderer.webgl.ImageLayer.prototype.forEachLayerAtPixel = ol.vec.Mat4.multVec2( frameState.pixelToCoordinateMatrix, coordinate, coordinate); var hasFeature = this.forEachFeatureAtCoordinate( - coordinate, frameState, goog.functions.TRUE, this); + coordinate, frameState, ol.functions.TRUE, this); if (hasFeature) { return callback.call(thisArg, this.getLayer()); @@ -81472,13 +65518,12 @@ ol.renderer.webgl.ImageLayer.prototype.forEachLayerAtPixel = /** * The transformation matrix to get the pixel on the image for a * pixel on the map. - * @param {ol.Size} mapSize - * @param {ol.Size} imageSize - * @return {goog.vec.Mat4.Number} + * @param {ol.Size} mapSize The map size. + * @param {ol.Size} imageSize The image size. + * @return {goog.vec.Mat4.Number} The transformation matrix. * @private */ -ol.renderer.webgl.ImageLayer.prototype.getHitTransformationMatrix_ = - function(mapSize, imageSize) { +ol.renderer.webgl.ImageLayer.prototype.getHitTransformationMatrix_ = function(mapSize, imageSize) { // the first matrix takes a map pixel, flips the y-axis and scales to // a range between -1 ... 1 var mapCoordMatrix = goog.vec.Mat4.createNumber(); @@ -81519,7 +65564,6 @@ goog.provide('ol.renderer.webgl.tilelayer.shader.Vertex'); goog.require('ol.webgl.shader'); - /** * @constructor * @extends {ol.webgl.shader.Fragment} @@ -81555,7 +65599,6 @@ ol.renderer.webgl.tilelayer.shader.Fragment.SOURCE = goog.DEBUG ? ol.renderer.webgl.tilelayer.shader.Fragment.OPTIMIZED_SOURCE; - /** * @constructor * @extends {ol.webgl.shader.Vertex} @@ -81591,7 +65634,6 @@ ol.renderer.webgl.tilelayer.shader.Vertex.SOURCE = goog.DEBUG ? ol.renderer.webgl.tilelayer.shader.Vertex.OPTIMIZED_SOURCE; - /** * @constructor * @param {WebGLRenderingContext} gl GL. @@ -81645,12 +65687,10 @@ goog.require('ol.renderer.webgl.tilelayer.shader.Fragment'); goog.require('ol.renderer.webgl.tilelayer.shader.Locations'); goog.require('ol.renderer.webgl.tilelayer.shader.Vertex'); goog.require('ol.size'); -goog.require('ol.tilecoord'); goog.require('ol.vec.Mat4'); goog.require('ol.webgl.Buffer'); - /** * @constructor * @extends {ol.renderer.webgl.Layer} @@ -81740,8 +65780,7 @@ ol.renderer.webgl.TileLayer.prototype.disposeInternal = function() { * lookup. * @protected */ -ol.renderer.webgl.TileLayer.prototype.createLoadedTileFinder = - function(source, projection, tiles) { +ol.renderer.webgl.TileLayer.prototype.createLoadedTileFinder = function(source, projection, tiles) { var mapRenderer = this.mapRenderer; return ( @@ -81751,17 +65790,17 @@ ol.renderer.webgl.TileLayer.prototype.createLoadedTileFinder = * @return {boolean} The tile range is fully loaded. */ function(zoom, tileRange) { - return source.forEachLoadedTile(projection, zoom, - tileRange, function(tile) { - var loaded = mapRenderer.isTileTextureLoaded(tile); - if (loaded) { - if (!tiles[zoom]) { - tiles[zoom] = {}; - } - tiles[zoom][tile.tileCoord.toString()] = tile; - } - return loaded; - }); + function callback(tile) { + var loaded = mapRenderer.isTileTextureLoaded(tile); + if (loaded) { + if (!tiles[zoom]) { + tiles[zoom] = {}; + } + tiles[zoom][tile.tileCoord.toString()] = tile; + } + return loaded; + } + return source.forEachLoadedTile(projection, zoom, tileRange, callback); }); }; @@ -81778,8 +65817,7 @@ ol.renderer.webgl.TileLayer.prototype.handleWebGLContextLost = function() { /** * @inheritDoc */ -ol.renderer.webgl.TileLayer.prototype.prepareFrame = - function(frameState, layerState, context) { +ol.renderer.webgl.TileLayer.prototype.prepareFrame = function(frameState, layerState, context) { var mapRenderer = this.mapRenderer; var gl = context.getGL(); @@ -81800,7 +65838,7 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame = var pixelRatio = tilePixelSize[0] / ol.size.toSize(tileGrid.getTileSize(z), this.tmpSize_)[0]; var tilePixelResolution = tileResolution / pixelRatio; - var tileGutter = tileSource.getGutter(); + var tileGutter = tileSource.getGutter(projection); var center = viewState.center; var extent; @@ -81898,7 +65936,7 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame = tileState = tile.getState(); if (tileState == ol.TileState.LOADED) { if (mapRenderer.isTileTextureLoaded(tile)) { - tilesToDrawByZ[z][ol.tilecoord.toString(tile.tileCoord)] = tile; + tilesToDrawByZ[z][tile.tileCoord.toString()] = tile; continue; } } else if (tileState == ol.TileState.EMPTY || @@ -82013,8 +66051,7 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame = /** * @inheritDoc */ -ol.renderer.webgl.TileLayer.prototype.forEachLayerAtPixel = - function(pixel, frameState, callback, thisArg) { +ol.renderer.webgl.TileLayer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) { if (!this.framebuffer) { return undefined; } @@ -82046,7 +66083,7 @@ ol.renderer.webgl.TileLayer.prototype.forEachLayerAtPixel = goog.provide('ol.renderer.webgl.VectorLayer'); goog.require('goog.asserts'); -goog.require('goog.events'); +goog.require('ol.events'); goog.require('ol.ViewHint'); goog.require('ol.extent'); goog.require('ol.layer.Vector'); @@ -82056,7 +66093,6 @@ goog.require('ol.renderer.webgl.Layer'); goog.require('ol.vec.Mat4'); - /** * @constructor * @extends {ol.renderer.webgl.Layer} @@ -82106,7 +66142,7 @@ ol.renderer.webgl.VectorLayer = function(mapRenderer, vectorLayer) { /** * The last layer state. * @private - * @type {?ol.layer.LayerState} + * @type {?ol.LayerState} */ this.layerState_ = null; @@ -82117,8 +66153,7 @@ goog.inherits(ol.renderer.webgl.VectorLayer, ol.renderer.webgl.Layer); /** * @inheritDoc */ -ol.renderer.webgl.VectorLayer.prototype.composeFrame = - function(frameState, layerState, context) { +ol.renderer.webgl.VectorLayer.prototype.composeFrame = function(frameState, layerState, context) { this.layerState_ = layerState; var viewState = frameState.viewState; var replayGroup = this.replayGroup_; @@ -82149,8 +66184,7 @@ ol.renderer.webgl.VectorLayer.prototype.disposeInternal = function() { /** * @inheritDoc */ -ol.renderer.webgl.VectorLayer.prototype.forEachFeatureAtCoordinate = - function(coordinate, frameState, callback, thisArg) { +ol.renderer.webgl.VectorLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, callback, thisArg) { if (!this.replayGroup_ || !this.layerState_) { return undefined; } else { @@ -82163,9 +66197,9 @@ ol.renderer.webgl.VectorLayer.prototype.forEachFeatureAtCoordinate = return this.replayGroup_.forEachFeatureAtCoordinate(coordinate, context, viewState.center, viewState.resolution, viewState.rotation, frameState.size, frameState.pixelRatio, layerState.opacity, - layerState.managed ? frameState.skippedFeatureUids : {}, + {}, /** - * @param {ol.Feature} feature Feature. + * @param {ol.Feature|ol.render.Feature} feature Feature. * @return {?} Callback result. */ function(feature) { @@ -82183,8 +66217,7 @@ ol.renderer.webgl.VectorLayer.prototype.forEachFeatureAtCoordinate = /** * @inheritDoc */ -ol.renderer.webgl.VectorLayer.prototype.hasFeatureAtCoordinate = - function(coordinate, frameState) { +ol.renderer.webgl.VectorLayer.prototype.hasFeatureAtCoordinate = function(coordinate, frameState) { if (!this.replayGroup_ || !this.layerState_) { return false; } else { @@ -82202,8 +66235,7 @@ ol.renderer.webgl.VectorLayer.prototype.hasFeatureAtCoordinate = /** * @inheritDoc */ -ol.renderer.webgl.VectorLayer.prototype.forEachLayerAtPixel = - function(pixel, frameState, callback, thisArg) { +ol.renderer.webgl.VectorLayer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) { var coordinate = pixel.slice(); ol.vec.Mat4.multVec2( frameState.pixelToCoordinateMatrix, coordinate, coordinate); @@ -82219,11 +66251,10 @@ ol.renderer.webgl.VectorLayer.prototype.forEachLayerAtPixel = /** * Handle changes in image style state. - * @param {goog.events.Event} event Image style change event. + * @param {ol.events.Event} event Image style change event. * @private */ -ol.renderer.webgl.VectorLayer.prototype.handleStyleImageChange_ = - function(event) { +ol.renderer.webgl.VectorLayer.prototype.handleStyleImageChange_ = function(event) { this.renderIfReadyAndVisible(); }; @@ -82231,8 +66262,7 @@ ol.renderer.webgl.VectorLayer.prototype.handleStyleImageChange_ = /** * @inheritDoc */ -ol.renderer.webgl.VectorLayer.prototype.prepareFrame = - function(frameState, layerState, context) { +ol.renderer.webgl.VectorLayer.prototype.prepareFrame = function(frameState, layerState, context) { var vectorLayer = /** @type {ol.layer.Vector} */ (this.getLayer()); goog.asserts.assertInstanceof(vectorLayer, ol.layer.Vector, @@ -82288,12 +66318,11 @@ ol.renderer.webgl.VectorLayer.prototype.prepareFrame = ol.renderer.vector.getTolerance(resolution, pixelRatio), extent, vectorLayer.getRenderBuffer()); vectorSource.loadFeatures(extent, resolution, projection); - var renderFeature = - /** - * @param {ol.Feature} feature Feature. - * @this {ol.renderer.webgl.VectorLayer} - */ - function(feature) { + /** + * @param {ol.Feature} feature Feature. + * @this {ol.renderer.webgl.VectorLayer} + */ + var renderFeature = function(feature) { var styles; var styleFunction = feature.getStyleFunction(); if (styleFunction) { @@ -82346,13 +66375,12 @@ ol.renderer.webgl.VectorLayer.prototype.prepareFrame = * @param {ol.render.webgl.ReplayGroup} replayGroup Replay group. * @return {boolean} `true` if an image is loading. */ -ol.renderer.webgl.VectorLayer.prototype.renderFeature = - function(feature, resolution, pixelRatio, styles, replayGroup) { +ol.renderer.webgl.VectorLayer.prototype.renderFeature = function(feature, resolution, pixelRatio, styles, replayGroup) { if (!styles) { return false; } var loading = false; - if (goog.isArray(styles)) { + if (Array.isArray(styles)) { for (var i = 0, ii = styles.length; i < ii; ++i) { loading = ol.renderer.vector.renderFeature( replayGroup, feature, styles[i], @@ -82372,20 +66400,17 @@ ol.renderer.webgl.VectorLayer.prototype.renderFeature = goog.provide('ol.renderer.webgl.Map'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom'); -goog.require('goog.events'); -goog.require('goog.events.Event'); -goog.require('goog.log'); -goog.require('goog.log.Logger'); -goog.require('goog.object'); goog.require('goog.style'); goog.require('goog.webgl'); goog.require('ol'); goog.require('ol.RendererType'); +goog.require('ol.array'); goog.require('ol.css'); goog.require('ol.dom'); +goog.require('ol.events'); +goog.require('ol.events.Event'); goog.require('ol.layer.Image'); goog.require('ol.layer.Layer'); goog.require('ol.layer.Tile'); @@ -82407,13 +66432,6 @@ goog.require('ol.webgl.WebGLContextEventType'); /** - * @typedef {{magFilter: number, minFilter: number, texture: WebGLTexture}} - */ -ol.renderer.webgl.TextureCacheEntry; - - - -/** * @constructor * @extends {ol.renderer.Map} * @param {Element} container Container. @@ -82477,14 +66495,14 @@ ol.renderer.webgl.Map = function(container, map) { */ this.context_ = new ol.webgl.Context(this.canvas_, this.gl_); - goog.events.listen(this.canvas_, ol.webgl.WebGLContextEventType.LOST, - this.handleWebGLContextLost, false, this); - goog.events.listen(this.canvas_, ol.webgl.WebGLContextEventType.RESTORED, - this.handleWebGLContextRestored, false, this); + ol.events.listen(this.canvas_, ol.webgl.WebGLContextEventType.LOST, + this.handleWebGLContextLost, this); + ol.events.listen(this.canvas_, ol.webgl.WebGLContextEventType.RESTORED, + this.handleWebGLContextRestored, this); /** * @private - * @type {ol.structs.LRUCache.<ol.renderer.webgl.TextureCacheEntry|null>} + * @type {ol.structs.LRUCache.<ol.WebglTextureCacheEntry|null>} */ this.textureCache_ = new ol.structs.LRUCache(); @@ -82499,20 +66517,19 @@ ol.renderer.webgl.Map = function(container, map) { * @type {ol.structs.PriorityQueue.<Array>} */ this.tileTextureQueue_ = new ol.structs.PriorityQueue( - goog.bind( - /** - * @param {Array.<*>} element Element. - * @return {number} Priority. - * @this {ol.renderer.webgl.Map} - */ - function(element) { - var tileCenter = /** @type {ol.Coordinate} */ (element[1]); - var tileResolution = /** @type {number} */ (element[2]); - var deltaX = tileCenter[0] - this.focus_[0]; - var deltaY = tileCenter[1] - this.focus_[1]; - return 65536 * Math.log(tileResolution) + - Math.sqrt(deltaX * deltaX + deltaY * deltaY) / tileResolution; - }, this), + /** + * @param {Array.<*>} element Element. + * @return {number} Priority. + * @this {ol.renderer.webgl.Map} + */ + (function(element) { + var tileCenter = /** @type {ol.Coordinate} */ (element[1]); + var tileResolution = /** @type {number} */ (element[2]); + var deltaX = tileCenter[0] - this.focus_[0]; + var deltaY = tileCenter[1] - this.focus_[1]; + return 65536 * Math.log(tileResolution) + + Math.sqrt(deltaX * deltaX + deltaY * deltaY) / tileResolution; + }).bind(this), /** * @param {Array.<*>} element Element. * @return {string} Key. @@ -82521,11 +66538,14 @@ ol.renderer.webgl.Map = function(container, map) { return /** @type {ol.Tile} */ (element[0]).getKey(); }); - /** - * @private - * @type {ol.PostRenderFunction} - */ - this.loadNextTileTexture_ = goog.bind( + + /** + * @param {ol.Map} map Map. + * @param {?olx.FrameState} frameState Frame state. + * @return {boolean} false. + * @this {ol.renderer.webgl.Map} + */ + this.loadNextTileTexture_ = function(map, frameState) { if (!this.tileTextureQueue_.isEmpty()) { this.tileTextureQueue_.reprioritize(); @@ -82536,7 +66556,9 @@ ol.renderer.webgl.Map = function(container, map) { this.bindTileTexture( tile, tileSize, tileGutter, goog.webgl.LINEAR, goog.webgl.LINEAR); } - }, this); + return false; + }.bind(this); + /** * @private @@ -82557,8 +66579,7 @@ goog.inherits(ol.renderer.webgl.Map, ol.renderer.Map); * @param {number} magFilter Mag filter. * @param {number} minFilter Min filter. */ -ol.renderer.webgl.Map.prototype.bindTileTexture = - function(tile, tileSize, tileGutter, magFilter, minFilter) { +ol.renderer.webgl.Map.prototype.bindTileTexture = function(tile, tileSize, tileGutter, magFilter, minFilter) { var gl = this.getGL(); var tileKey = tile.getKey(); if (this.textureCache_.containsKey(tileKey)) { @@ -82640,8 +66661,7 @@ ol.renderer.webgl.Map.prototype.createLayerRenderer = function(layer) { * @param {olx.FrameState} frameState Frame state. * @private */ -ol.renderer.webgl.Map.prototype.dispatchComposeEvent_ = - function(type, frameState) { +ol.renderer.webgl.Map.prototype.dispatchComposeEvent_ = function(type, frameState) { var map = this.getMap(); if (map.hasListener(type)) { var context = this.context_; @@ -82660,8 +66680,6 @@ ol.renderer.webgl.Map.prototype.dispatchComposeEvent_ = var composeEvent = new ol.render.Event(type, map, vectorContext, frameState, null, context); map.dispatchEvent(composeEvent); - - vectorContext.flush(); } }; @@ -82674,7 +66692,7 @@ ol.renderer.webgl.Map.prototype.disposeInternal = function() { if (!gl.isContextLost()) { this.textureCache_.forEach( /** - * @param {?ol.renderer.webgl.TextureCacheEntry} textureCacheEntry + * @param {?ol.WebglTextureCacheEntry} textureCacheEntry * Texture cache entry. */ function(textureCacheEntry) { @@ -82683,7 +66701,7 @@ ol.renderer.webgl.Map.prototype.disposeInternal = function() { } }); } - goog.dispose(this.context_); + this.context_.dispose(); goog.base(this, 'disposeInternal'); }; @@ -82714,7 +66732,7 @@ ol.renderer.webgl.Map.prototype.expireCache_ = function(map, frameState) { /** - * @return {ol.webgl.Context} + * @return {ol.webgl.Context} The context. */ ol.renderer.webgl.Map.prototype.getContext = function() { return this.context_; @@ -82746,24 +66764,19 @@ ol.renderer.webgl.Map.prototype.getType = function() { /** - * @param {goog.events.Event} event Event. + * @param {ol.events.Event} event Event. * @protected */ ol.renderer.webgl.Map.prototype.handleWebGLContextLost = function(event) { event.preventDefault(); this.textureCache_.clear(); this.textureCacheFrameMarkerCount_ = 0; - goog.object.forEach(this.getLayerRenderers(), - /** - * @param {ol.renderer.Layer} layerRenderer Layer renderer. - * @param {string} key Key. - * @param {Object.<string, ol.renderer.Layer>} object Object. - */ - function(layerRenderer, key, object) { - goog.asserts.assertInstanceof(layerRenderer, ol.renderer.webgl.Layer, - 'renderer is an instance of ol.renderer.webgl.Layer'); - layerRenderer.handleWebGLContextLost(); - }); + + var renderers = this.getLayerRenderers(); + for (var id in renderers) { + var renderer = /** @type {ol.renderer.webgl.Layer} */ (renderers[id]); + renderer.handleWebGLContextLost(); + } }; @@ -82802,14 +66815,6 @@ ol.renderer.webgl.Map.prototype.isTileTextureLoaded = function(tile) { /** - * @private - * @type {goog.log.Logger} - */ -ol.renderer.webgl.Map.prototype.logger_ = - goog.log.getLogger('ol.renderer.webgl.Map'); - - -/** * @inheritDoc */ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) { @@ -82836,10 +66841,10 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) { this.dispatchComposeEvent_(ol.render.EventType.PRECOMPOSE, frameState); - /** @type {Array.<ol.layer.LayerState>} */ + /** @type {Array.<ol.LayerState>} */ var layerStatesToDraw = []; var layerStatesArray = frameState.layerStatesArray; - goog.array.stableSort(layerStatesArray, ol.renderer.Map.sortByZIndex); + ol.array.stableSort(layerStatesArray, ol.renderer.Map.sortByZIndex); var viewResolution = frameState.viewState.resolution; var i, ii, layerRenderer, layerState; @@ -82887,7 +66892,9 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) { if (this.textureCache_.getCount() - this.textureCacheFrameMarkerCount_ > ol.WEBGL_TEXTURE_CACHE_HIGH_WATER_MARK) { - frameState.postRenderFunctions.push(goog.bind(this.expireCache_, this)); + frameState.postRenderFunctions.push( + /** @type {ol.PostRenderFunction} */ (this.expireCache_.bind(this)) + ); } if (!this.tileTextureQueue_.isEmpty()) { @@ -82906,8 +66913,7 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) { /** * @inheritDoc */ -ol.renderer.webgl.Map.prototype.forEachFeatureAtCoordinate = - function(coordinate, frameState, callback, thisArg, +ol.renderer.webgl.Map.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, callback, thisArg, layerFilter, thisArg2) { var result; @@ -82940,8 +66946,7 @@ ol.renderer.webgl.Map.prototype.forEachFeatureAtCoordinate = /** * @inheritDoc */ -ol.renderer.webgl.Map.prototype.hasFeatureAtCoordinate = - function(coordinate, frameState, layerFilter, thisArg) { +ol.renderer.webgl.Map.prototype.hasFeatureAtCoordinate = function(coordinate, frameState, layerFilter, thisArg) { var hasFeature = false; if (this.getGL().isContextLost()) { @@ -82973,8 +66978,7 @@ ol.renderer.webgl.Map.prototype.hasFeatureAtCoordinate = /** * @inheritDoc */ -ol.renderer.webgl.Map.prototype.forEachLayerAtPixel = - function(pixel, frameState, callback, thisArg, +ol.renderer.webgl.Map.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg, layerFilter, thisArg2) { if (this.getGL().isContextLost()) { return false; @@ -83009,26 +67013,9 @@ ol.renderer.webgl.Map.prototype.forEachLayerAtPixel = goog.provide('ol.Map'); goog.provide('ol.MapProperty'); -goog.require('goog.array'); goog.require('goog.asserts'); -goog.require('goog.async.AnimationDelay'); goog.require('goog.async.nextTick'); -goog.require('goog.debug.Console'); goog.require('goog.dom'); -goog.require('goog.dom.ViewportSizeMonitor'); -goog.require('goog.dom.classlist'); -goog.require('goog.events'); -goog.require('goog.events.BrowserEvent'); -goog.require('goog.events.Event'); -goog.require('goog.events.EventType'); -goog.require('goog.events.KeyHandler'); -goog.require('goog.events.KeyHandler.EventType'); -goog.require('goog.events.MouseWheelHandler'); -goog.require('goog.events.MouseWheelHandler.EventType'); -goog.require('goog.functions'); -goog.require('goog.log'); -goog.require('goog.log.Level'); -goog.require('goog.object'); goog.require('goog.style'); goog.require('goog.vec.Mat4'); goog.require('ol.Collection'); @@ -83041,20 +67028,22 @@ goog.require('ol.MapEventType'); goog.require('ol.Object'); goog.require('ol.ObjectEvent'); goog.require('ol.ObjectEventType'); -goog.require('ol.Pixel'); -goog.require('ol.PostRenderFunction'); -goog.require('ol.PreRenderFunction'); goog.require('ol.RendererType'); -goog.require('ol.Size'); goog.require('ol.TileQueue'); goog.require('ol.View'); goog.require('ol.ViewHint'); +goog.require('ol.array'); goog.require('ol.control'); +goog.require('ol.events'); +goog.require('ol.events.Event'); +goog.require('ol.events.EventType'); goog.require('ol.extent'); +goog.require('ol.functions'); goog.require('ol.has'); goog.require('ol.interaction'); goog.require('ol.layer.Base'); goog.require('ol.layer.Group'); +goog.require('ol.object'); goog.require('ol.proj'); goog.require('ol.proj.common'); goog.require('ol.renderer.Map'); @@ -83063,7 +67052,6 @@ goog.require('ol.renderer.dom.Map'); goog.require('ol.renderer.webgl.Map'); goog.require('ol.size'); goog.require('ol.structs.PriorityQueue'); -goog.require('ol.tilecoord'); goog.require('ol.vec.Mat4'); @@ -83124,7 +67112,6 @@ ol.MapProperty = { }; - /** * @classdesc * The map is the core component of OpenLayers. For a map to render, a view, @@ -83211,11 +67198,17 @@ ol.Map = function(options) { /** * @private - * @type {goog.async.AnimationDelay} + * @type {number|undefined} + */ + this.animationDelayKey_; + + /** + * @private */ - this.animationDelay_ = - new goog.async.AnimationDelay(this.renderFrame_, undefined, this); - this.registerDisposable(this.animationDelay_); + this.animationDelay_ = function() { + this.animationDelayKey_ = undefined; + this.renderFrame_.call(this, Date.now()); + }.bind(this); /** * @private @@ -83250,13 +67243,13 @@ ol.Map = function(options) { /** * @private - * @type {goog.events.Key} + * @type {?ol.events.Key} */ this.viewPropertyListenerKey_ = null; /** * @private - * @type {Array.<goog.events.Key>} + * @type {Array.<ol.events.Key>} */ this.layerGroupPropertyListenerKeys_ = null; @@ -83265,7 +67258,7 @@ ol.Map = function(options) { * @type {Element} */ this.viewport_ = document.createElement('DIV'); - this.viewport_.className = 'ol-viewport'; + this.viewport_.className = 'ol-viewport' + (ol.has.TOUCH ? ' ol-touch' : ''); this.viewport_.style.position = 'relative'; this.viewport_.style.overflow = 'hidden'; this.viewport_.style.width = '100%'; @@ -83273,13 +67266,10 @@ ol.Map = function(options) { // prevent page zoom on IE >= 10 browsers this.viewport_.style.msTouchAction = 'none'; this.viewport_.style.touchAction = 'none'; - if (ol.has.TOUCH) { - goog.dom.classlist.add(this.viewport_, 'ol-touch'); - } /** * @private - * @type {Element} + * @type {!Element} */ this.overlayContainer_ = document.createElement('DIV'); this.overlayContainer_.className = 'ol-overlaycontainer'; @@ -83287,26 +67277,35 @@ ol.Map = function(options) { /** * @private - * @type {Element} + * @type {!Element} */ this.overlayContainerStopEvent_ = document.createElement('DIV'); this.overlayContainerStopEvent_.className = 'ol-overlaycontainer-stopevent'; - goog.events.listen(this.overlayContainerStopEvent_, [ - goog.events.EventType.CLICK, - goog.events.EventType.DBLCLICK, - goog.events.EventType.MOUSEDOWN, - goog.events.EventType.TOUCHSTART, - goog.events.EventType.MSPOINTERDOWN, + var overlayEvents = [ + ol.events.EventType.CLICK, + ol.events.EventType.DBLCLICK, + ol.events.EventType.MOUSEDOWN, + ol.events.EventType.TOUCHSTART, + ol.events.EventType.MSPOINTERDOWN, ol.MapBrowserEvent.EventType.POINTERDOWN, - goog.userAgent.GECKO ? 'DOMMouseScroll' : 'mousewheel' - ], goog.events.Event.stopPropagation); + ol.events.EventType.MOUSEWHEEL, + ol.events.EventType.WHEEL + ]; + for (var i = 0, ii = overlayEvents.length; i < ii; ++i) { + ol.events.listen(this.overlayContainerStopEvent_, overlayEvents[i], + ol.events.Event.stopPropagation); + } this.viewport_.appendChild(this.overlayContainerStopEvent_); - var mapBrowserEventHandler = new ol.MapBrowserEventHandler(this); - goog.events.listen(mapBrowserEventHandler, - goog.object.getValues(ol.MapBrowserEvent.EventType), - this.handleMapBrowserEvent, false, this); - this.registerDisposable(mapBrowserEventHandler); + /** + * @private + * @type {ol.MapBrowserEventHandler} + */ + this.mapBrowserEventHandler_ = new ol.MapBrowserEventHandler(this); + for (var key in ol.MapBrowserEvent.EventType) { + ol.events.listen(this.mapBrowserEventHandler_, ol.MapBrowserEvent.EventType[key], + this.handleMapBrowserEvent, this); + } /** * @private @@ -83316,18 +67315,14 @@ ol.Map = function(options) { /** * @private - * @type {goog.events.KeyHandler} + * @type {Array.<ol.events.Key>} */ - this.keyHandler_ = new goog.events.KeyHandler(); - goog.events.listen(this.keyHandler_, goog.events.KeyHandler.EventType.KEY, - this.handleBrowserEvent, false, this); - this.registerDisposable(this.keyHandler_); + this.keyHandlerKeys_ = null; - var mouseWheelHandler = new goog.events.MouseWheelHandler(this.viewport_); - goog.events.listen(mouseWheelHandler, - goog.events.MouseWheelHandler.EventType.MOUSEWHEEL, - this.handleBrowserEvent, false, this); - this.registerDisposable(mouseWheelHandler); + ol.events.listen(this.viewport_, ol.events.EventType.WHEEL, + this.handleBrowserEvent, this); + ol.events.listen(this.viewport_, ol.events.EventType.MOUSEWHEEL, + this.handleBrowserEvent, this); /** * @type {ol.Collection.<ol.control.Control>} @@ -83358,22 +67353,13 @@ ol.Map = function(options) { * @type {ol.renderer.Map} * @private */ - this.renderer_ = - new optionsInternal.rendererConstructor(this.viewport_, this); - this.registerDisposable(this.renderer_); - - /** - * @type {goog.dom.ViewportSizeMonitor} - * @private - */ - this.viewportSizeMonitor_ = new goog.dom.ViewportSizeMonitor(); - this.registerDisposable(this.viewportSizeMonitor_); + this.renderer_ = new optionsInternal.rendererConstructor(this.viewport_, this); /** - * @type {goog.events.Key} + * @type {function(Event)|undefined} * @private */ - this.viewportResizeListenerKey_ = null; + this.handleResize_; /** * @private @@ -83398,8 +67384,8 @@ ol.Map = function(options) { * @type {ol.TileQueue} */ this.tileQueue_ = new ol.TileQueue( - goog.bind(this.getTilePriority, this), - goog.bind(this.handleTileChange_, this)); + this.getTilePriority.bind(this), + this.handleTileChange_.bind(this)); /** * Uids of features to skip at rendering time. @@ -83408,15 +67394,15 @@ ol.Map = function(options) { */ this.skippedFeatureUids_ = {}; - goog.events.listen( + ol.events.listen( this, ol.Object.getChangeEventType(ol.MapProperty.LAYERGROUP), - this.handleLayerGroupChanged_, false, this); - goog.events.listen(this, ol.Object.getChangeEventType(ol.MapProperty.VIEW), - this.handleViewChanged_, false, this); - goog.events.listen(this, ol.Object.getChangeEventType(ol.MapProperty.SIZE), - this.handleSizeChanged_, false, this); - goog.events.listen(this, ol.Object.getChangeEventType(ol.MapProperty.TARGET), - this.handleTargetChanged_, false, this); + this.handleLayerGroupChanged_, this); + ol.events.listen(this, ol.Object.getChangeEventType(ol.MapProperty.VIEW), + this.handleViewChanged_, this); + ol.events.listen(this, ol.Object.getChangeEventType(ol.MapProperty.SIZE), + this.handleSizeChanged_, this); + ol.events.listen(this, ol.Object.getChangeEventType(ol.MapProperty.TARGET), + this.handleTargetChanged_, this); // setProperties will trigger the rendering of the map if the map // is "defined" already. @@ -83431,21 +67417,21 @@ ol.Map = function(options) { control.setMap(this); }, this); - goog.events.listen(this.controls_, ol.CollectionEventType.ADD, + ol.events.listen(this.controls_, ol.CollectionEventType.ADD, /** * @param {ol.CollectionEvent} event Collection event. */ function(event) { event.element.setMap(this); - }, false, this); + }, this); - goog.events.listen(this.controls_, ol.CollectionEventType.REMOVE, + ol.events.listen(this.controls_, ol.CollectionEventType.REMOVE, /** * @param {ol.CollectionEvent} event Collection event. */ function(event) { event.element.setMap(null); - }, false, this); + }, this); this.interactions_.forEach( /** @@ -83456,33 +67442,33 @@ ol.Map = function(options) { interaction.setMap(this); }, this); - goog.events.listen(this.interactions_, ol.CollectionEventType.ADD, + ol.events.listen(this.interactions_, ol.CollectionEventType.ADD, /** * @param {ol.CollectionEvent} event Collection event. */ function(event) { event.element.setMap(this); - }, false, this); + }, this); - goog.events.listen(this.interactions_, ol.CollectionEventType.REMOVE, + ol.events.listen(this.interactions_, ol.CollectionEventType.REMOVE, /** * @param {ol.CollectionEvent} event Collection event. */ function(event) { event.element.setMap(null); - }, false, this); + }, this); this.overlays_.forEach(this.addOverlayInternal_, this); - goog.events.listen(this.overlays_, ol.CollectionEventType.ADD, + ol.events.listen(this.overlays_, ol.CollectionEventType.ADD, /** * @param {ol.CollectionEvent} event Collection event. */ function(event) { this.addOverlayInternal_(/** @type {ol.Overlay} */ (event.element)); - }, false, this); + }, this); - goog.events.listen(this.overlays_, ol.CollectionEventType.REMOVE, + ol.events.listen(this.overlays_, ol.CollectionEventType.REMOVE, /** * @param {ol.CollectionEvent} event Collection event. */ @@ -83492,7 +67478,7 @@ ol.Map = function(options) { delete this.overlayIdIndex_[id.toString()]; } event.element.setMap(null); - }, false, this); + }, this); }; goog.inherits(ol.Map, ol.Object); @@ -83580,7 +67566,7 @@ ol.Map.prototype.beforeRender = function(var_args) { * @return {boolean} Whether the preRenderFunction has been found and removed. */ ol.Map.prototype.removePreRenderFunction = function(preRenderFunction) { - return goog.array.remove(this.preRenderFunctions_, preRenderFunction); + return ol.array.remove(this.preRenderFunctions_, preRenderFunction); }; @@ -83589,7 +67575,22 @@ ol.Map.prototype.removePreRenderFunction = function(preRenderFunction) { * @inheritDoc */ ol.Map.prototype.disposeInternal = function() { - goog.dom.removeNode(this.viewport_); + this.mapBrowserEventHandler_.dispose(); + this.renderer_.dispose(); + ol.events.unlisten(this.viewport_, ol.events.EventType.WHEEL, + this.handleBrowserEvent, this); + ol.events.unlisten(this.viewport_, ol.events.EventType.MOUSEWHEEL, + this.handleBrowserEvent, this); + if (this.handleResize_ !== undefined) { + ol.global.removeEventListener(ol.events.EventType.RESIZE, + this.handleResize_, false); + this.handleResize_ = undefined; + } + if (this.animationDelayKey_) { + ol.global.cancelAnimationFrame(this.animationDelayKey_); + this.animationDelayKey_ = undefined; + } + this.setTarget(null); goog.base(this, 'disposeInternal'); }; @@ -83620,15 +67621,14 @@ ol.Map.prototype.disposeInternal = function() { * @template S,T,U * @api stable */ -ol.Map.prototype.forEachFeatureAtPixel = - function(pixel, callback, opt_this, opt_layerFilter, opt_this2) { +ol.Map.prototype.forEachFeatureAtPixel = function(pixel, callback, opt_this, opt_layerFilter, opt_this2) { if (!this.frameState_) { return; } var coordinate = this.getCoordinateFromPixel(pixel); var thisArg = opt_this !== undefined ? opt_this : null; var layerFilter = opt_layerFilter !== undefined ? - opt_layerFilter : goog.functions.TRUE; + opt_layerFilter : ol.functions.TRUE; var thisArg2 = opt_this2 !== undefined ? opt_this2 : null; return this.renderer_.forEachFeatureAtCoordinate( coordinate, this.frameState_, callback, thisArg, @@ -83658,14 +67658,13 @@ ol.Map.prototype.forEachFeatureAtPixel = * @template S,T,U * @api stable */ -ol.Map.prototype.forEachLayerAtPixel = - function(pixel, callback, opt_this, opt_layerFilter, opt_this2) { +ol.Map.prototype.forEachLayerAtPixel = function(pixel, callback, opt_this, opt_layerFilter, opt_this2) { if (!this.frameState_) { return; } var thisArg = opt_this !== undefined ? opt_this : null; var layerFilter = opt_layerFilter !== undefined ? - opt_layerFilter : goog.functions.TRUE; + opt_layerFilter : ol.functions.TRUE; var thisArg2 = opt_this2 !== undefined ? opt_this2 : null; return this.renderer_.forEachLayerAtPixel( pixel, this.frameState_, callback, thisArg, @@ -83688,14 +67687,13 @@ ol.Map.prototype.forEachLayerAtPixel = * @template U * @api */ -ol.Map.prototype.hasFeatureAtPixel = - function(pixel, opt_layerFilter, opt_this) { +ol.Map.prototype.hasFeatureAtPixel = function(pixel, opt_layerFilter, opt_this) { if (!this.frameState_) { return false; } var coordinate = this.getCoordinateFromPixel(pixel); var layerFilter = opt_layerFilter !== undefined ? - opt_layerFilter : goog.functions.TRUE; + opt_layerFilter : ol.functions.TRUE; var thisArg = opt_this !== undefined ? opt_this : null; return this.renderer_.hasFeatureAtCoordinate( coordinate, this.frameState_, layerFilter, thisArg); @@ -83720,8 +67718,12 @@ ol.Map.prototype.getEventCoordinate = function(event) { * @api stable */ ol.Map.prototype.getEventPixel = function(event) { - var eventPosition = goog.style.getRelativePosition(event, this.viewport_); - return [eventPosition.x, eventPosition.y]; + var viewportPosition = this.viewport_.getBoundingClientRect(); + var eventPosition = event.changedTouches ? event.changedTouches[0] : event; + return [ + eventPosition.clientX - viewportPosition.left, + eventPosition.clientY - viewportPosition.top + ]; }; @@ -83907,7 +67909,7 @@ ol.Map.prototype.getViewport = function() { * this container will let mousedown and touchstart events through to the map, * so clicks and gestures on an overlay will trigger {@link ol.MapBrowserEvent} * events. - * @return {Element} The map's overlay container. + * @return {!Element} The map's overlay container. */ ol.Map.prototype.getOverlayContainer = function() { return this.overlayContainer_; @@ -83919,7 +67921,7 @@ ol.Map.prototype.getOverlayContainer = function() { * event propagation. Elements added to this container won't let mousedown and * touchstart events through to the map, so clicks and gestures on an overlay * don't trigger any {@link ol.MapBrowserEvent}. - * @return {Element} The map's overlay container that stops events. + * @return {!Element} The map's overlay container that stops events. */ ol.Map.prototype.getOverlayContainerStopEvent = function() { return this.overlayContainerStopEvent_; @@ -83933,15 +67935,14 @@ ol.Map.prototype.getOverlayContainerStopEvent = function() { * @param {number} tileResolution Tile resolution. * @return {number} Tile priority. */ -ol.Map.prototype.getTilePriority = - function(tile, tileSourceKey, tileCenter, tileResolution) { +ol.Map.prototype.getTilePriority = function(tile, tileSourceKey, tileCenter, tileResolution) { // Filter out tiles at higher zoom levels than the current zoom level, or that // are outside the visible extent. var frameState = this.frameState_; if (!frameState || !(tileSourceKey in frameState.wantedTiles)) { return ol.structs.PriorityQueue.DROP; } - var coordKey = ol.tilecoord.toString(tile.tileCoord); + var coordKey = tile.tileCoord.toString(); if (!frameState.wantedTiles[tileSourceKey][coordKey]) { return ol.structs.PriorityQueue.DROP; } @@ -83959,7 +67960,7 @@ ol.Map.prototype.getTilePriority = /** - * @param {goog.events.BrowserEvent} browserEvent Browser event. + * @param {Event} browserEvent Browser event. * @param {string=} opt_type Type. */ ol.Map.prototype.handleBrowserEvent = function(browserEvent, opt_type) { @@ -84020,7 +68021,6 @@ ol.Map.prototype.handlePostRender = function() { if (!tileQueue.isEmpty()) { var maxTotalLoading = 16; var maxNewLoads = maxTotalLoading; - var tileSourceCount = 0; if (frameState) { var hints = frameState.viewHints; if (hints[ol.ViewHint.ANIMATING]) { @@ -84031,10 +68031,7 @@ ol.Map.prototype.handlePostRender = function() { maxTotalLoading = this.loadTilesWhileInteracting_ ? 8 : 0; maxNewLoads = 2; } - tileSourceCount = goog.object.getCount(frameState.wantedTiles); } - maxTotalLoading *= tileSourceCount; - maxNewLoads *= tileSourceCount; if (tileQueue.getTilesLoading() < maxTotalLoading) { tileQueue.reprioritize(); // FIXME only call if view has changed tileQueue.loadMoreTiles(maxTotalLoading, maxNewLoads); @@ -84067,27 +68064,43 @@ ol.Map.prototype.handleTargetChanged_ = function() { // If it's not now an Element we remove the viewport from the DOM. // If it's an Element we append the viewport element to it. - var targetElement = this.getTargetElement(); + var targetElement; + if (this.getTarget()) { + targetElement = this.getTargetElement(); + goog.asserts.assert(targetElement !== null, + 'expects a non-null value for targetElement'); + } - this.keyHandler_.detach(); + if (this.keyHandlerKeys_) { + for (var i = 0, ii = this.keyHandlerKeys_.length; i < ii; ++i) { + ol.events.unlistenByKey(this.keyHandlerKeys_[i]); + } + this.keyHandlerKeys_ = null; + } if (!targetElement) { goog.dom.removeNode(this.viewport_); - if (this.viewportResizeListenerKey_) { - goog.events.unlistenByKey(this.viewportResizeListenerKey_); - this.viewportResizeListenerKey_ = null; + if (this.handleResize_ !== undefined) { + ol.global.removeEventListener(ol.events.EventType.RESIZE, + this.handleResize_, false); + this.handleResize_ = undefined; } } else { targetElement.appendChild(this.viewport_); var keyboardEventTarget = !this.keyboardEventTarget_ ? targetElement : this.keyboardEventTarget_; - this.keyHandler_.attach(keyboardEventTarget); + this.keyHandlerKeys_ = [ + ol.events.listen(keyboardEventTarget, ol.events.EventType.KEYDOWN, + this.handleBrowserEvent, this), + ol.events.listen(keyboardEventTarget, ol.events.EventType.KEYPRESS, + this.handleBrowserEvent, this) + ]; - if (!this.viewportResizeListenerKey_) { - this.viewportResizeListenerKey_ = goog.events.listen( - this.viewportSizeMonitor_, goog.events.EventType.RESIZE, - this.updateSize, false, this); + if (!this.handleResize_) { + this.handleResize_ = this.updateSize.bind(this); + ol.global.addEventListener(ol.events.EventType.RESIZE, + this.handleResize_, false); } } @@ -84118,25 +68131,25 @@ ol.Map.prototype.handleViewPropertyChanged_ = function() { */ ol.Map.prototype.handleViewChanged_ = function() { if (this.viewPropertyListenerKey_) { - goog.events.unlistenByKey(this.viewPropertyListenerKey_); + ol.events.unlistenByKey(this.viewPropertyListenerKey_); this.viewPropertyListenerKey_ = null; } var view = this.getView(); if (view) { - this.viewPropertyListenerKey_ = goog.events.listen( + this.viewPropertyListenerKey_ = ol.events.listen( view, ol.ObjectEventType.PROPERTYCHANGE, - this.handleViewPropertyChanged_, false, this); + this.handleViewPropertyChanged_, this); } this.render(); }; /** - * @param {goog.events.Event} event Event. + * @param {ol.events.Event} event Event. * @private */ ol.Map.prototype.handleLayerGroupMemberChanged_ = function(event) { - goog.asserts.assertInstanceof(event, goog.events.Event, + goog.asserts.assertInstanceof(event, ol.events.Event, 'event should be an Event'); this.render(); }; @@ -84158,18 +68171,18 @@ ol.Map.prototype.handleLayerGroupPropertyChanged_ = function(event) { */ ol.Map.prototype.handleLayerGroupChanged_ = function() { if (this.layerGroupPropertyListenerKeys_) { - this.layerGroupPropertyListenerKeys_.forEach(goog.events.unlistenByKey); + this.layerGroupPropertyListenerKeys_.forEach(ol.events.unlistenByKey); this.layerGroupPropertyListenerKeys_ = null; } var layerGroup = this.getLayerGroup(); if (layerGroup) { this.layerGroupPropertyListenerKeys_ = [ - goog.events.listen( + ol.events.listen( layerGroup, ol.ObjectEventType.PROPERTYCHANGE, - this.handleLayerGroupPropertyChanged_, false, this), - goog.events.listen( - layerGroup, goog.events.EventType.CHANGE, - this.handleLayerGroupMemberChanged_, false, this) + this.handleLayerGroupPropertyChanged_, this), + ol.events.listen( + layerGroup, ol.events.EventType.CHANGE, + this.handleLayerGroupMemberChanged_, this) ]; } this.render(); @@ -84177,31 +68190,6 @@ ol.Map.prototype.handleLayerGroupChanged_ = function() { /** - * Returns `true` if the map is defined, `false` otherwise. The map is defined - * if it is contained in `document`, visible, has non-zero height and width, and - * has a defined view. - * @return {boolean} Is defined. - */ -ol.Map.prototype.isDef = function() { - if (!goog.dom.contains(document, this.viewport_)) { - return false; - } - if (!goog.style.isElementShown(this.viewport_)) { - return false; - } - var size = this.getSize(); - if (!size || size[0] <= 0 || size[1] <= 0) { - return false; - } - var view = this.getView(); - if (!view || !view.isDef()) { - return false; - } - return true; -}; - - -/** * @return {boolean} Is rendered. */ ol.Map.prototype.isRendered = function() { @@ -84214,7 +68202,10 @@ ol.Map.prototype.isRendered = function() { * @api stable */ ol.Map.prototype.renderSync = function() { - this.animationDelay_.fire(); + if (this.animationDelayKey_) { + ol.global.cancelAnimationFrame(this.animationDelayKey_); + } + this.animationDelay_(); }; @@ -84223,8 +68214,9 @@ ol.Map.prototype.renderSync = function() { * @api stable */ ol.Map.prototype.render = function() { - if (!this.animationDelay_.isActive()) { - this.animationDelay_.start(); + if (this.animationDelayKey_ === undefined) { + this.animationDelayKey_ = ol.global.requestAnimationFrame( + this.animationDelay_); } }; @@ -84295,11 +68287,11 @@ ol.Map.prototype.renderFrame_ = function(time) { var size = this.getSize(); var view = this.getView(); + var extent = ol.extent.createEmpty(); /** @type {?olx.FrameState} */ var frameState = null; - if (size !== undefined && ol.size.hasArea(size) && - view && view.isDef()) { - var viewHints = view.getHints(); + if (size !== undefined && ol.size.hasArea(size) && view && view.isDef()) { + var viewHints = view.getHints(this.frameState_ ? this.frameState_.viewHints : undefined); var layerStatesArray = this.getLayerGroup().getLayerStatesArray(); var layerStates = {}; for (i = 0, ii = layerStatesArray.length; i < ii; ++i) { @@ -84310,12 +68302,12 @@ ol.Map.prototype.renderFrame_ = function(time) { animate: false, attributions: {}, coordinateToPixelMatrix: this.coordinateToPixelMatrix_, - extent: null, + extent: extent, focus: !this.focus_ ? viewState.center : this.focus_, index: this.frameIndex_++, layerStates: layerStates, layerStatesArray: layerStatesArray, - logos: goog.object.clone(this.logos_), + logos: ol.object.assign({}, this.logos_), pixelRatio: this.pixelRatio_, pixelToCoordinateMatrix: this.pixelToCoordinateMatrix_, postRenderFunctions: [], @@ -84342,7 +68334,7 @@ ol.Map.prototype.renderFrame_ = function(time) { preRenderFunctions.length = n; frameState.extent = ol.extent.getForViewAndSize(viewState.center, - viewState.resolution, viewState.rotation, frameState.size); + viewState.resolution, viewState.rotation, frameState.size, extent); } this.frameState_ = frameState; @@ -84459,19 +68451,6 @@ ol.Map.prototype.unskipFeature = function(feature) { /** - * @typedef {{controls: ol.Collection.<ol.control.Control>, - * interactions: ol.Collection.<ol.interaction.Interaction>, - * keyboardEventTarget: (Element|Document), - * logos: Object.<string, string>, - * overlays: ol.Collection.<ol.Overlay>, - * rendererConstructor: - * function(new: ol.renderer.Map, Element, ol.Map), - * values: Object.<string, *>}} - */ -ol.MapOptionsInternal; - - -/** * @param {olx.MapOptions} options Map options. * @return {ol.MapOptionsInternal} Internal map options. */ @@ -84484,7 +68463,7 @@ ol.Map.createOptionsInternal = function(options) { if (options.keyboardEventTarget !== undefined) { // cannot use goog.dom.getElement because its argument cannot be // of type Document - keyboardEventTarget = goog.isString(options.keyboardEventTarget) ? + keyboardEventTarget = typeof options.keyboardEventTarget === 'string' ? document.getElementById(options.keyboardEventTarget) : options.keyboardEventTarget; } @@ -84496,12 +68475,14 @@ ol.Map.createOptionsInternal = function(options) { var logos = {}; if (options.logo === undefined || - (goog.isBoolean(options.logo) && options.logo)) { + (typeof options.logo === 'boolean' && options.logo)) { logos[ol.OL3_LOGO_URL] = ol.OL3_URL; } else { var logo = options.logo; - if (goog.isString(logo)) { + if (typeof logo === 'string') { logos[logo] = ''; + } else if (logo instanceof HTMLElement) { + logos[goog.getUid(logo).toString()] = logo; } else if (goog.isObject(logo)) { goog.asserts.assertString(logo.href, 'logo.href should be a string'); goog.asserts.assertString(logo.src, 'logo.src should be a string'); @@ -84528,9 +68509,9 @@ ol.Map.createOptionsInternal = function(options) { */ var rendererTypes; if (options.renderer !== undefined) { - if (goog.isArray(options.renderer)) { + if (Array.isArray(options.renderer)) { rendererTypes = options.renderer; - } else if (goog.isString(options.renderer)) { + } else if (typeof options.renderer === 'string') { rendererTypes = [options.renderer]; } else { goog.asserts.fail('Incorrect format for renderer option'); @@ -84563,7 +68544,7 @@ ol.Map.createOptionsInternal = function(options) { var controls; if (options.controls !== undefined) { - if (goog.isArray(options.controls)) { + if (Array.isArray(options.controls)) { controls = new ol.Collection(options.controls.slice()); } else { goog.asserts.assertInstanceof(options.controls, ol.Collection, @@ -84576,7 +68557,7 @@ ol.Map.createOptionsInternal = function(options) { var interactions; if (options.interactions !== undefined) { - if (goog.isArray(options.interactions)) { + if (Array.isArray(options.interactions)) { interactions = new ol.Collection(options.interactions.slice()); } else { goog.asserts.assertInstanceof(options.interactions, ol.Collection, @@ -84589,7 +68570,7 @@ ol.Map.createOptionsInternal = function(options) { var overlays; if (options.overlays !== undefined) { - if (goog.isArray(options.overlays)) { + if (Array.isArray(options.overlays)) { overlays = new ol.Collection(options.overlays.slice()); } else { goog.asserts.assertInstanceof(options.overlays, ol.Collection, @@ -84615,24 +68596,14 @@ ol.Map.createOptionsInternal = function(options) { ol.proj.common.add(); - -if (goog.DEBUG) { - (function() { - goog.debug.Console.autoInstall(); - var logger = goog.log.getLogger('ol'); - logger.setLevel(goog.log.Level.FINEST); - })(); -} - goog.provide('ol.Overlay'); goog.provide('ol.OverlayPositioning'); goog.provide('ol.OverlayProperty'); goog.require('goog.asserts'); goog.require('goog.dom'); -goog.require('goog.events'); +goog.require('ol.events'); goog.require('goog.style'); -goog.require('ol.Coordinate'); goog.require('ol.Map'); goog.require('ol.MapEventType'); goog.require('ol.Object'); @@ -84673,7 +68644,6 @@ ol.OverlayPositioning = { }; - /** * @classdesc * An element to be displayed over the map and attached to a single map @@ -84764,29 +68734,29 @@ ol.Overlay = function(options) { /** * @private - * @type {goog.events.Key} + * @type {?ol.events.Key} */ this.mapPostrenderListenerKey_ = null; - goog.events.listen( + ol.events.listen( this, ol.Object.getChangeEventType(ol.OverlayProperty.ELEMENT), - this.handleElementChanged, false, this); + this.handleElementChanged, this); - goog.events.listen( + ol.events.listen( this, ol.Object.getChangeEventType(ol.OverlayProperty.MAP), - this.handleMapChanged, false, this); + this.handleMapChanged, this); - goog.events.listen( + ol.events.listen( this, ol.Object.getChangeEventType(ol.OverlayProperty.OFFSET), - this.handleOffsetChanged, false, this); + this.handleOffsetChanged, this); - goog.events.listen( + ol.events.listen( this, ol.Object.getChangeEventType(ol.OverlayProperty.POSITION), - this.handlePositionChanged, false, this); + this.handlePositionChanged, this); - goog.events.listen( + ol.events.listen( this, ol.Object.getChangeEventType(ol.OverlayProperty.POSITIONING), - this.handlePositioningChanged, false, this); + this.handlePositioningChanged, this); if (options.element !== undefined) { this.setElement(options.element); @@ -84896,19 +68866,18 @@ ol.Overlay.prototype.handleElementChanged = function() { ol.Overlay.prototype.handleMapChanged = function() { if (this.mapPostrenderListenerKey_) { goog.dom.removeNode(this.element_); - goog.events.unlistenByKey(this.mapPostrenderListenerKey_); + ol.events.unlistenByKey(this.mapPostrenderListenerKey_); this.mapPostrenderListenerKey_ = null; } var map = this.getMap(); if (map) { - this.mapPostrenderListenerKey_ = goog.events.listen(map, - ol.MapEventType.POSTRENDER, this.render, false, this); + this.mapPostrenderListenerKey_ = ol.events.listen(map, + ol.MapEventType.POSTRENDER, this.render, this); this.updatePixelPosition(); var container = this.stopEvent_ ? map.getOverlayContainerStopEvent() : map.getOverlayContainer(); if (this.insertFirst_) { - goog.dom.insertChildAt(/** @type {!Element} */ ( - container), this.element_, 0); + goog.dom.insertChildAt(container, this.element_, 0); } else { container.appendChild(this.element_); } @@ -85063,7 +69032,7 @@ ol.Overlay.prototype.panIntoView_ = function() { * Get the extent of an element relative to the document * @param {Element|undefined} element The element. * @param {ol.Size|undefined} size The size of the element. - * @return {ol.Extent} + * @return {ol.Extent} The extent. * @private */ ol.Overlay.prototype.getRect_ = function(element, size) { @@ -85094,7 +69063,7 @@ ol.Overlay.prototype.setPositioning = function(positioning) { /** * Modify the visibility of the element. - * @param {boolean} visible + * @param {boolean} visible Element visibility. * @protected */ ol.Overlay.prototype.setVisible = function(visible) { @@ -85124,8 +69093,8 @@ ol.Overlay.prototype.updatePixelPosition = function() { /** - * @param {ol.Pixel} pixel - * @param {ol.Size|undefined} mapSize + * @param {ol.Pixel} pixel The pixel location. + * @param {ol.Size|undefined} mapSize The map size. * @protected */ ol.Overlay.prototype.updateRenderedPosition = function(pixel, mapSize) { @@ -85133,7 +69102,7 @@ ol.Overlay.prototype.updateRenderedPosition = function(pixel, mapSize) { goog.asserts.assert(mapSize !== undefined, 'mapSize should be defined'); var style = this.element_.style; var offset = this.getOffset(); - goog.asserts.assert(goog.isArray(offset), 'offset should be an array'); + goog.asserts.assert(Array.isArray(offset), 'offset should be an array'); var positioning = this.getPositioning(); goog.asserts.assert(positioning !== undefined, @@ -85197,11 +69166,8 @@ goog.provide('ol.control.OverviewMap'); goog.require('goog.asserts'); goog.require('goog.dom'); -goog.require('goog.dom.classlist'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.math.Size'); -goog.require('goog.style'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol'); goog.require('ol.Collection'); goog.require('ol.Map'); @@ -85218,7 +69184,6 @@ goog.require('ol.css'); goog.require('ol.extent'); - /** * Create a new control with a map acting as an overview map for an other * defined map. @@ -85248,27 +69213,27 @@ ol.control.OverviewMap = function(opt_options) { this.collapsed_ = false; } - var className = options.className ? options.className : 'ol-overviewmap'; + var className = options.className !== undefined ? options.className : 'ol-overviewmap'; - var tipLabel = options.tipLabel ? options.tipLabel : 'Overview map'; + var tipLabel = options.tipLabel !== undefined ? options.tipLabel : 'Overview map'; - var collapseLabel = options.collapseLabel ? options.collapseLabel : '\u00AB'; + var collapseLabel = options.collapseLabel !== undefined ? options.collapseLabel : '\u00AB'; /** * @private * @type {Node} */ - this.collapseLabel_ = goog.isString(collapseLabel) ? + this.collapseLabel_ = typeof collapseLabel === 'string' ? goog.dom.createDom('SPAN', {}, collapseLabel) : collapseLabel; - var label = options.label ? options.label : '\u00BB'; + var label = options.label !== undefined ? options.label : '\u00BB'; /** * @private * @type {Node} */ - this.label_ = goog.isString(label) ? + this.label_ = typeof label === 'string' ? goog.dom.createDom('SPAN', {}, label) : label; @@ -85279,10 +69244,11 @@ ol.control.OverviewMap = function(opt_options) { 'title': tipLabel }, activeLabel); - goog.events.listen(button, goog.events.EventType.CLICK, - this.handleClick_, false, this); + ol.events.listen(button, ol.events.EventType.CLICK, + this.handleClick_, this); - var ovmapDiv = goog.dom.createDom('DIV', 'ol-overviewmap-map'); + var ovmapDiv = document.createElement('DIV'); + ovmapDiv.className = 'ol-overviewmap-map'; /** * @type {ol.Map} @@ -85306,7 +69272,9 @@ ol.control.OverviewMap = function(opt_options) { }, this); } - var box = goog.dom.createDom('DIV', 'ol-overviewmap-box'); + var box = document.createElement('DIV'); + box.className = 'ol-overviewmap-box'; + box.style.boxSizing = 'border-box'; /** * @type {ol.Overlay} @@ -85355,9 +69323,9 @@ ol.control.OverviewMap.prototype.setMap = function(map) { goog.base(this, 'setMap', map); if (map) { - this.listenerKeys.push(goog.events.listen( + this.listenerKeys.push(ol.events.listen( map, ol.ObjectEventType.PROPERTYCHANGE, - this.handleMapPropertyChange_, false, this)); + this.handleMapPropertyChange_, this)); // TODO: to really support map switching, this would need to be reworked if (this.ovmap_.getLayers().getLength() === 0) { @@ -85399,9 +69367,9 @@ ol.control.OverviewMap.prototype.handleMapPropertyChange_ = function(event) { * @private */ ol.control.OverviewMap.prototype.bindView_ = function(view) { - goog.events.listen(view, + ol.events.listen(view, ol.Object.getChangeEventType(ol.ViewProperty.ROTATION), - this.handleRotationChanged_, false, this); + this.handleRotationChanged_, this); }; @@ -85411,9 +69379,9 @@ ol.control.OverviewMap.prototype.bindView_ = function(view) { * @private */ ol.control.OverviewMap.prototype.unbindView_ = function(view) { - goog.events.unlisten(view, + ol.events.unlisten(view, ol.Object.getChangeEventType(ol.ViewProperty.ROTATION), - this.handleRotationChanged_, false, this); + this.handleRotationChanged_, this); }; @@ -85477,17 +69445,17 @@ ol.control.OverviewMap.prototype.validateExtent_ = function() { ovmap.getPixelFromCoordinate(ol.extent.getTopLeft(extent)); var bottomRightPixel = ovmap.getPixelFromCoordinate(ol.extent.getBottomRight(extent)); - var boxSize = new goog.math.Size( - Math.abs(topLeftPixel[0] - bottomRightPixel[0]), - Math.abs(topLeftPixel[1] - bottomRightPixel[1])); + + var boxWidth = Math.abs(topLeftPixel[0] - bottomRightPixel[0]); + var boxHeight = Math.abs(topLeftPixel[1] - bottomRightPixel[1]); var ovmapWidth = ovmapSize[0]; var ovmapHeight = ovmapSize[1]; - if (boxSize.width < ovmapWidth * ol.OVERVIEWMAP_MIN_RATIO || - boxSize.height < ovmapHeight * ol.OVERVIEWMAP_MIN_RATIO || - boxSize.width > ovmapWidth * ol.OVERVIEWMAP_MAX_RATIO || - boxSize.height > ovmapHeight * ol.OVERVIEWMAP_MAX_RATIO) { + if (boxWidth < ovmapWidth * ol.OVERVIEWMAP_MIN_RATIO || + boxHeight < ovmapHeight * ol.OVERVIEWMAP_MIN_RATIO || + boxWidth > ovmapWidth * ol.OVERVIEWMAP_MAX_RATIO || + boxHeight > ovmapHeight * ol.OVERVIEWMAP_MAX_RATIO) { this.resetExtent_(); } else if (!ol.extent.containsExtent(ovextent, extent)) { this.recenter_(); @@ -85591,10 +69559,8 @@ ol.control.OverviewMap.prototype.updateBox_ = function() { // set box size calculated from map extent size and overview map resolution if (box) { - var boxWidth = Math.abs((bottomLeft[0] - topRight[0]) / ovresolution); - var boxHeight = Math.abs((topRight[1] - bottomLeft[1]) / ovresolution); - goog.style.setBorderBoxSize(box, new goog.math.Size( - boxWidth, boxHeight)); + box.style.width = Math.abs((bottomLeft[0] - topRight[0]) / ovresolution) + 'px'; + box.style.height = Math.abs((topRight[1] - bottomLeft[1]) / ovresolution) + 'px'; } }; @@ -85628,7 +69594,7 @@ ol.control.OverviewMap.prototype.calculateCoordinateRotate_ = function( /** - * @param {goog.events.BrowserEvent} event The event to handle + * @param {Event} event The event to handle * @private */ ol.control.OverviewMap.prototype.handleClick_ = function(event) { @@ -85641,7 +69607,7 @@ ol.control.OverviewMap.prototype.handleClick_ = function(event) { * @private */ ol.control.OverviewMap.prototype.handleToggle_ = function() { - goog.dom.classlist.toggle(this.element, 'ol-collapsed'); + this.element.classList.toggle('ol-collapsed'); if (this.collapsed_) { goog.dom.replaceNode(this.collapseLabel_, this.label_); } else { @@ -85655,11 +69621,11 @@ ol.control.OverviewMap.prototype.handleToggle_ = function() { if (!this.collapsed_ && !ovmap.isRendered()) { ovmap.updateSize(); this.resetExtent_(); - goog.events.listenOnce(ovmap, ol.MapEventType.POSTRENDER, + ol.events.listenOnce(ovmap, ol.MapEventType.POSTRENDER, function(event) { this.updateBox_(); }, - false, this); + this); } }; @@ -85684,7 +69650,7 @@ ol.control.OverviewMap.prototype.setCollapsible = function(collapsible) { return; } this.collapsible_ = collapsible; - goog.dom.classlist.toggle(this.element, 'ol-uncollapsible'); + this.element.classList.toggle('ol-uncollapsible'); if (!collapsible && this.collapsed_) { this.handleToggle_(); } @@ -85730,19 +69696,14 @@ goog.provide('ol.control.ScaleLineProperty'); goog.provide('ol.control.ScaleLineUnits'); goog.require('goog.asserts'); -goog.require('goog.dom'); -goog.require('goog.events'); +goog.require('ol.events'); goog.require('goog.style'); goog.require('ol'); goog.require('ol.Object'); -goog.require('ol.TransformFunction'); goog.require('ol.control.Control'); goog.require('ol.css'); -goog.require('ol.math'); -goog.require('ol.proj'); goog.require('ol.proj.METERS_PER_UNIT'); goog.require('ol.proj.Units'); -goog.require('ol.sphere.NORMAL'); /** @@ -85768,7 +69729,6 @@ ol.control.ScaleLineUnits = { }; - /** * @classdesc * A control displaying rough x-axis distances, calculated for the center of the @@ -85787,21 +69747,22 @@ ol.control.ScaleLine = function(opt_options) { var options = opt_options ? opt_options : {}; - var className = options.className ? options.className : 'ol-scale-line'; + var className = options.className !== undefined ? options.className : 'ol-scale-line'; /** * @private * @type {Element} */ - this.innerElement_ = goog.dom.createDom('DIV', - className + '-inner'); + this.innerElement_ = document.createElement('DIV'); + this.innerElement_.className = className + '-inner'; /** * @private * @type {Element} */ - this.element_ = goog.dom.createDom('DIV', - className + ' ' + ol.css.CLASS_UNSELECTABLE, this.innerElement_); + this.element_ = document.createElement('DIV'); + this.element_.className = className + ' ' + ol.css.CLASS_UNSELECTABLE; + this.element_.appendChild(this.innerElement_); /** * @private @@ -85833,12 +69794,6 @@ ol.control.ScaleLine = function(opt_options) { */ this.renderedHTML_ = ''; - /** - * @private - * @type {?ol.TransformFunction} - */ - this.toEPSG4326_ = null; - var render = options.render ? options.render : ol.control.ScaleLine.render; goog.base(this, { @@ -85847,9 +69802,9 @@ ol.control.ScaleLine = function(opt_options) { target: options.target }); - goog.events.listen( + ol.events.listen( this, ol.Object.getChangeEventType(ol.control.ScaleLineProperty.UNITS), - this.handleUnitsChanged_, false, this); + this.handleUnitsChanged_, this); this.setUnits(/** @type {ol.control.ScaleLineUnits} */ (options.units) || ol.control.ScaleLineUnits.METRIC); @@ -85930,61 +69885,21 @@ ol.control.ScaleLine.prototype.updateElement_ = function() { var center = viewState.center; var projection = viewState.projection; + var metersPerUnit = projection.getMetersPerUnit(); var pointResolution = - projection.getPointResolution(viewState.resolution, center); - var projectionUnits = projection.getUnits(); - - var cosLatitude; - var units = this.getUnits(); - if (projectionUnits == ol.proj.Units.DEGREES && - (units == ol.control.ScaleLineUnits.METRIC || - units == ol.control.ScaleLineUnits.IMPERIAL || - units == ol.control.ScaleLineUnits.US || - units == ol.control.ScaleLineUnits.NAUTICAL)) { - - // Convert pointResolution from degrees to meters - this.toEPSG4326_ = null; - cosLatitude = Math.cos(ol.math.toRadians(center[1])); - pointResolution *= Math.PI * cosLatitude * ol.sphere.NORMAL.radius / 180; - projectionUnits = ol.proj.Units.METERS; - - } else if (projectionUnits != ol.proj.Units.DEGREES && - units == ol.control.ScaleLineUnits.DEGREES) { - - // Convert pointResolution from other units to degrees - if (!this.toEPSG4326_) { - this.toEPSG4326_ = ol.proj.getTransformFromProjections( - projection, ol.proj.get('EPSG:4326')); - } - cosLatitude = Math.cos(ol.math.toRadians(this.toEPSG4326_(center)[1])); - var radius = ol.sphere.NORMAL.radius; - goog.asserts.assert(ol.proj.METERS_PER_UNIT[projectionUnits], - 'Meters per unit should be defined for the projection unit'); - radius /= ol.proj.METERS_PER_UNIT[projectionUnits]; - pointResolution *= 180 / (Math.PI * cosLatitude * radius); - projectionUnits = ol.proj.Units.DEGREES; - - } else { - this.toEPSG4326_ = null; - } - - goog.asserts.assert( - ((units == ol.control.ScaleLineUnits.METRIC || - units == ol.control.ScaleLineUnits.IMPERIAL || - units == ol.control.ScaleLineUnits.US || - units == ol.control.ScaleLineUnits.NAUTICAL) && - projectionUnits == ol.proj.Units.METERS) || - (units == ol.control.ScaleLineUnits.DEGREES && - projectionUnits == ol.proj.Units.DEGREES), - 'Scale line units and projection units should match'); + projection.getPointResolution(viewState.resolution, center) * + metersPerUnit; var nominalCount = this.minWidth_ * pointResolution; var suffix = ''; + var units = this.getUnits(); if (units == ol.control.ScaleLineUnits.DEGREES) { - if (nominalCount < 1 / 60) { + var metersPerDegree = ol.proj.METERS_PER_UNIT[ol.proj.Units.DEGREES]; + pointResolution /= metersPerDegree; + if (nominalCount < metersPerDegree / 60) { suffix = '\u2033'; // seconds pointResolution *= 3600; - } else if (nominalCount < 1) { + } else if (nominalCount < metersPerDegree) { suffix = '\u2032'; // minutes pointResolution *= 60; } else { @@ -86033,7 +69948,7 @@ ol.control.ScaleLine.prototype.updateElement_ = function() { Math.log(this.minWidth_ * pointResolution) / Math.log(10)); var count, width; while (true) { - count = ol.control.ScaleLine.LEADING_DIGITS[i % 3] * + count = ol.control.ScaleLine.LEADING_DIGITS[((i % 3) + 3) % 3] * Math.pow(10, Math.floor(i / 3)); width = Math.round(count / pointResolution); if (isNaN(width)) { @@ -86064,1481 +69979,17 @@ ol.control.ScaleLine.prototype.updateElement_ = function() { }; -// Copyright 2005 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Class to create objects which want to handle multiple events - * and have their listeners easily cleaned up via a dispose method. - * - * Example: - * <pre> - * function Something() { - * Something.base(this); - * - * ... set up object ... - * - * // Add event listeners - * this.listen(this.starEl, goog.events.EventType.CLICK, this.handleStar); - * this.listen(this.headerEl, goog.events.EventType.CLICK, this.expand); - * this.listen(this.collapseEl, goog.events.EventType.CLICK, this.collapse); - * this.listen(this.infoEl, goog.events.EventType.MOUSEOVER, this.showHover); - * this.listen(this.infoEl, goog.events.EventType.MOUSEOUT, this.hideHover); - * } - * goog.inherits(Something, goog.events.EventHandler); - * - * Something.prototype.disposeInternal = function() { - * Something.base(this, 'disposeInternal'); - * goog.dom.removeNode(this.container); - * }; - * - * - * // Then elsewhere: - * - * var activeSomething = null; - * function openSomething() { - * activeSomething = new Something(); - * } - * - * function closeSomething() { - * if (activeSomething) { - * activeSomething.dispose(); // Remove event listeners - * activeSomething = null; - * } - * } - * </pre> - * - */ - -goog.provide('goog.events.EventHandler'); - -goog.require('goog.Disposable'); -goog.require('goog.events'); -goog.require('goog.object'); - -goog.forwardDeclare('goog.events.EventWrapper'); - - - -/** - * Super class for objects that want to easily manage a number of event - * listeners. It allows a short cut to listen and also provides a quick way - * to remove all events listeners belonging to this object. - * @param {SCOPE=} opt_scope Object in whose scope to call the listeners. - * @constructor - * @extends {goog.Disposable} - * @template SCOPE - */ -goog.events.EventHandler = function(opt_scope) { - goog.Disposable.call(this); - // TODO(mknichel): Rename this to this.scope_ and fix the classes in google3 - // that access this private variable. :( - this.handler_ = opt_scope; - - /** - * Keys for events that are being listened to. - * @type {!Object<!goog.events.Key>} - * @private - */ - this.keys_ = {}; -}; -goog.inherits(goog.events.EventHandler, goog.Disposable); - - -/** - * Utility array used to unify the cases of listening for an array of types - * and listening for a single event, without using recursion or allocating - * an array each time. - * @type {!Array<string>} - * @const - * @private - */ -goog.events.EventHandler.typeArray_ = []; - - -/** - * Listen to an event on a Listenable. If the function is omitted then the - * EventHandler's handleEvent method will be used. - * @param {goog.events.ListenableType} src Event source. - * @param {string|Array<string>| - * !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>} - * type Event type to listen for or array of event types. - * @param {function(this:SCOPE, EVENTOBJ):?|{handleEvent:function(?):?}|null=} - * opt_fn Optional callback function to be used as the listener or an object - * with handleEvent function. - * @param {boolean=} opt_capture Optional whether to use capture phase. - * @return {!goog.events.EventHandler<SCOPE>} This object, allowing for - * chaining of calls. - * @template EVENTOBJ - */ -goog.events.EventHandler.prototype.listen = function( - src, type, opt_fn, opt_capture) { - return this.listen_(src, type, opt_fn, opt_capture); -}; - - -/** - * Listen to an event on a Listenable. If the function is omitted then the - * EventHandler's handleEvent method will be used. - * @param {goog.events.ListenableType} src Event source. - * @param {string|Array<string>| - * !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>} - * type Event type to listen for or array of event types. - * @param {function(this:T, EVENTOBJ):?|{handleEvent:function(this:T, ?):?}| - * null|undefined} fn Optional callback function to be used as the - * listener or an object with handleEvent function. - * @param {boolean|undefined} capture Optional whether to use capture phase. - * @param {T} scope Object in whose scope to call the listener. - * @return {!goog.events.EventHandler<SCOPE>} This object, allowing for - * chaining of calls. - * @template T,EVENTOBJ - */ -goog.events.EventHandler.prototype.listenWithScope = function( - src, type, fn, capture, scope) { - // TODO(mknichel): Deprecate this function. - return this.listen_(src, type, fn, capture, scope); -}; - - -/** - * Listen to an event on a Listenable. If the function is omitted then the - * EventHandler's handleEvent method will be used. - * @param {goog.events.ListenableType} src Event source. - * @param {string|Array<string>| - * !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>} - * type Event type to listen for or array of event types. - * @param {function(EVENTOBJ):?|{handleEvent:function(?):?}|null=} opt_fn - * Optional callback function to be used as the listener or an object with - * handleEvent function. - * @param {boolean=} opt_capture Optional whether to use capture phase. - * @param {Object=} opt_scope Object in whose scope to call the listener. - * @return {!goog.events.EventHandler<SCOPE>} This object, allowing for - * chaining of calls. - * @template EVENTOBJ - * @private - */ -goog.events.EventHandler.prototype.listen_ = function(src, type, opt_fn, - opt_capture, - opt_scope) { - if (!goog.isArray(type)) { - if (type) { - goog.events.EventHandler.typeArray_[0] = type.toString(); - } - type = goog.events.EventHandler.typeArray_; - } - for (var i = 0; i < type.length; i++) { - var listenerObj = goog.events.listen( - src, type[i], opt_fn || this.handleEvent, - opt_capture || false, - opt_scope || this.handler_ || this); - - if (!listenerObj) { - // When goog.events.listen run on OFF_AND_FAIL or OFF_AND_SILENT - // (goog.events.CaptureSimulationMode) in IE8-, it will return null - // value. - return this; - } - - var key = listenerObj.key; - this.keys_[key] = listenerObj; - } - - return this; -}; - - -/** - * Listen to an event on a Listenable. If the function is omitted, then the - * EventHandler's handleEvent method will be used. After the event has fired the - * event listener is removed from the target. If an array of event types is - * provided, each event type will be listened to once. - * @param {goog.events.ListenableType} src Event source. - * @param {string|Array<string>| - * !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>} - * type Event type to listen for or array of event types. - * @param {function(this:SCOPE, EVENTOBJ):?|{handleEvent:function(?):?}|null=} opt_fn - * Optional callback function to be used as the listener or an object with - * handleEvent function. - * @param {boolean=} opt_capture Optional whether to use capture phase. - * @return {!goog.events.EventHandler<SCOPE>} This object, allowing for - * chaining of calls. - * @template EVENTOBJ - */ -goog.events.EventHandler.prototype.listenOnce = function( - src, type, opt_fn, opt_capture) { - return this.listenOnce_(src, type, opt_fn, opt_capture); -}; - - -/** - * Listen to an event on a Listenable. If the function is omitted, then the - * EventHandler's handleEvent method will be used. After the event has fired the - * event listener is removed from the target. If an array of event types is - * provided, each event type will be listened to once. - * @param {goog.events.ListenableType} src Event source. - * @param {string|Array<string>| - * !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>} - * type Event type to listen for or array of event types. - * @param {function(this:T, EVENTOBJ):?|{handleEvent:function(this:T, ?):?}| - * null|undefined} fn Optional callback function to be used as the - * listener or an object with handleEvent function. - * @param {boolean|undefined} capture Optional whether to use capture phase. - * @param {T} scope Object in whose scope to call the listener. - * @return {!goog.events.EventHandler<SCOPE>} This object, allowing for - * chaining of calls. - * @template T,EVENTOBJ - */ -goog.events.EventHandler.prototype.listenOnceWithScope = function( - src, type, fn, capture, scope) { - // TODO(mknichel): Deprecate this function. - return this.listenOnce_(src, type, fn, capture, scope); -}; - - -/** - * Listen to an event on a Listenable. If the function is omitted, then the - * EventHandler's handleEvent method will be used. After the event has fired - * the event listener is removed from the target. If an array of event types is - * provided, each event type will be listened to once. - * @param {goog.events.ListenableType} src Event source. - * @param {string|Array<string>| - * !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>} - * type Event type to listen for or array of event types. - * @param {function(EVENTOBJ):?|{handleEvent:function(?):?}|null=} opt_fn - * Optional callback function to be used as the listener or an object with - * handleEvent function. - * @param {boolean=} opt_capture Optional whether to use capture phase. - * @param {Object=} opt_scope Object in whose scope to call the listener. - * @return {!goog.events.EventHandler<SCOPE>} This object, allowing for - * chaining of calls. - * @template EVENTOBJ - * @private - */ -goog.events.EventHandler.prototype.listenOnce_ = function( - src, type, opt_fn, opt_capture, opt_scope) { - if (goog.isArray(type)) { - for (var i = 0; i < type.length; i++) { - this.listenOnce_(src, type[i], opt_fn, opt_capture, opt_scope); - } - } else { - var listenerObj = goog.events.listenOnce( - src, type, opt_fn || this.handleEvent, opt_capture, - opt_scope || this.handler_ || this); - if (!listenerObj) { - // When goog.events.listen run on OFF_AND_FAIL or OFF_AND_SILENT - // (goog.events.CaptureSimulationMode) in IE8-, it will return null - // value. - return this; - } - - var key = listenerObj.key; - this.keys_[key] = listenerObj; - } - - return this; -}; - - -/** - * Adds an event listener with a specific event wrapper on a DOM Node or an - * object that has implemented {@link goog.events.EventTarget}. A listener can - * only be added once to an object. - * - * @param {EventTarget|goog.events.EventTarget} src The node to listen to - * events on. - * @param {goog.events.EventWrapper} wrapper Event wrapper to use. - * @param {function(this:SCOPE, ?):?|{handleEvent:function(?):?}|null} listener - * Callback method, or an object with a handleEvent function. - * @param {boolean=} opt_capt Whether to fire in capture phase (defaults to - * false). - * @return {!goog.events.EventHandler<SCOPE>} This object, allowing for - * chaining of calls. - */ -goog.events.EventHandler.prototype.listenWithWrapper = function( - src, wrapper, listener, opt_capt) { - // TODO(mknichel): Remove the opt_scope from this function and then - // templatize it. - return this.listenWithWrapper_(src, wrapper, listener, opt_capt); -}; - - -/** - * Adds an event listener with a specific event wrapper on a DOM Node or an - * object that has implemented {@link goog.events.EventTarget}. A listener can - * only be added once to an object. - * - * @param {EventTarget|goog.events.EventTarget} src The node to listen to - * events on. - * @param {goog.events.EventWrapper} wrapper Event wrapper to use. - * @param {function(this:T, ?):?|{handleEvent:function(this:T, ?):?}|null} - * listener Optional callback function to be used as the - * listener or an object with handleEvent function. - * @param {boolean|undefined} capture Optional whether to use capture phase. - * @param {T} scope Object in whose scope to call the listener. - * @return {!goog.events.EventHandler<SCOPE>} This object, allowing for - * chaining of calls. - * @template T - */ -goog.events.EventHandler.prototype.listenWithWrapperAndScope = function( - src, wrapper, listener, capture, scope) { - // TODO(mknichel): Deprecate this function. - return this.listenWithWrapper_(src, wrapper, listener, capture, scope); -}; - - -/** - * Adds an event listener with a specific event wrapper on a DOM Node or an - * object that has implemented {@link goog.events.EventTarget}. A listener can - * only be added once to an object. - * - * @param {EventTarget|goog.events.EventTarget} src The node to listen to - * events on. - * @param {goog.events.EventWrapper} wrapper Event wrapper to use. - * @param {function(?):?|{handleEvent:function(?):?}|null} listener Callback - * method, or an object with a handleEvent function. - * @param {boolean=} opt_capt Whether to fire in capture phase (defaults to - * false). - * @param {Object=} opt_scope Element in whose scope to call the listener. - * @return {!goog.events.EventHandler<SCOPE>} This object, allowing for - * chaining of calls. - * @private - */ -goog.events.EventHandler.prototype.listenWithWrapper_ = function( - src, wrapper, listener, opt_capt, opt_scope) { - wrapper.listen(src, listener, opt_capt, opt_scope || this.handler_ || this, - this); - return this; -}; - - -/** - * @return {number} Number of listeners registered by this handler. - */ -goog.events.EventHandler.prototype.getListenerCount = function() { - var count = 0; - for (var key in this.keys_) { - if (Object.prototype.hasOwnProperty.call(this.keys_, key)) { - count++; - } - } - return count; -}; - - -/** - * Unlistens on an event. - * @param {goog.events.ListenableType} src Event source. - * @param {string|Array<string>| - * !goog.events.EventId<EVENTOBJ>|!Array<!goog.events.EventId<EVENTOBJ>>} - * type Event type or array of event types to unlisten to. - * @param {function(EVENTOBJ):?|{handleEvent:function(?):?}|null=} opt_fn - * Optional callback function to be used as the listener or an object with - * handleEvent function. - * @param {boolean=} opt_capture Optional whether to use capture phase. - * @param {Object=} opt_scope Object in whose scope to call the listener. - * @return {!goog.events.EventHandler} This object, allowing for chaining of - * calls. - * @template EVENTOBJ - */ -goog.events.EventHandler.prototype.unlisten = function(src, type, opt_fn, - opt_capture, - opt_scope) { - if (goog.isArray(type)) { - for (var i = 0; i < type.length; i++) { - this.unlisten(src, type[i], opt_fn, opt_capture, opt_scope); - } - } else { - var listener = goog.events.getListener(src, type, - opt_fn || this.handleEvent, - opt_capture, opt_scope || this.handler_ || this); - - if (listener) { - goog.events.unlistenByKey(listener); - delete this.keys_[listener.key]; - } - } - - return this; -}; - - -/** - * Removes an event listener which was added with listenWithWrapper(). - * - * @param {EventTarget|goog.events.EventTarget} src The target to stop - * listening to events on. - * @param {goog.events.EventWrapper} wrapper Event wrapper to use. - * @param {function(?):?|{handleEvent:function(?):?}|null} listener The - * listener function to remove. - * @param {boolean=} opt_capt In DOM-compliant browsers, this determines - * whether the listener is fired during the capture or bubble phase of the - * event. - * @param {Object=} opt_scope Element in whose scope to call the listener. - * @return {!goog.events.EventHandler} This object, allowing for chaining of - * calls. - */ -goog.events.EventHandler.prototype.unlistenWithWrapper = function(src, wrapper, - listener, opt_capt, opt_scope) { - wrapper.unlisten(src, listener, opt_capt, - opt_scope || this.handler_ || this, this); - return this; -}; - - -/** - * Unlistens to all events. - */ -goog.events.EventHandler.prototype.removeAll = function() { - goog.object.forEach(this.keys_, function(listenerObj, key) { - if (this.keys_.hasOwnProperty(key)) { - goog.events.unlistenByKey(listenerObj); - } - }, this); - - this.keys_ = {}; -}; - - -/** - * Disposes of this EventHandler and removes all listeners that it registered. - * @override - * @protected - */ -goog.events.EventHandler.prototype.disposeInternal = function() { - goog.events.EventHandler.superClass_.disposeInternal.call(this); - this.removeAll(); -}; - - -/** - * Default event handler - * @param {goog.events.Event} e Event object. - */ -goog.events.EventHandler.prototype.handleEvent = function(e) { - throw Error('EventHandler.handleEvent not implemented'); -}; - -// Copyright 2012 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Bidi utility functions. - * - */ - -goog.provide('goog.style.bidi'); - -goog.require('goog.dom'); -goog.require('goog.style'); -goog.require('goog.userAgent'); - - -/** - * Returns the normalized scrollLeft position for a scrolled element. - * @param {Element} element The scrolled element. - * @return {number} The number of pixels the element is scrolled. 0 indicates - * that the element is not scrolled at all (which, in general, is the - * left-most position in ltr and the right-most position in rtl). - */ -goog.style.bidi.getScrollLeft = function(element) { - var isRtl = goog.style.isRightToLeft(element); - if (isRtl && goog.userAgent.GECKO) { - // ScrollLeft starts at 0 and then goes negative as the element is scrolled - // towards the left. - return -element.scrollLeft; - } else if (isRtl && - !(goog.userAgent.IE && goog.userAgent.isVersionOrHigher('8'))) { - // ScrollLeft starts at the maximum positive value and decreases towards - // 0 as the element is scrolled towards the left. However, for overflow - // visible, there is no scrollLeft and the value always stays correctly at 0 - var overflowX = goog.style.getComputedOverflowX(element); - if (overflowX == 'visible') { - return element.scrollLeft; - } else { - return element.scrollWidth - element.clientWidth - element.scrollLeft; - } - } - // ScrollLeft behavior is identical in rtl and ltr, it starts at 0 and - // increases as the element is scrolled away from the start. - return element.scrollLeft; -}; - - -/** - * Returns the "offsetStart" of an element, analagous to offsetLeft but - * normalized for right-to-left environments and various browser - * inconsistencies. This value returned can always be passed to setScrollOffset - * to scroll to an element's left edge in a left-to-right offsetParent or - * right edge in a right-to-left offsetParent. - * - * For example, here offsetStart is 10px in an LTR environment and 5px in RTL: - * - * <pre> - * | xxxxxxxxxx | - * ^^^^^^^^^^ ^^^^ ^^^^^ - * 10px elem 5px - * </pre> - * - * If an element is positioned before the start of its offsetParent, the - * startOffset may be negative. This can be used with setScrollOffset to - * reliably scroll to an element: - * - * <pre> - * var scrollOffset = goog.style.bidi.getOffsetStart(element); - * goog.style.bidi.setScrollOffset(element.offsetParent, scrollOffset); - * </pre> - * - * @see setScrollOffset - * - * @param {Element} element The element for which we need to determine the - * offsetStart position. - * @return {number} The offsetStart for that element. - */ -goog.style.bidi.getOffsetStart = function(element) { - element = /** @type {!HTMLElement} */ (element); - var offsetLeftForReal = element.offsetLeft; - - // The element might not have an offsetParent. - // For example, the node might not be attached to the DOM tree, - // and position:fixed children do not have an offset parent. - // Just try to do the best we can with what we have. - var bestParent = element.offsetParent; - - if (!bestParent && goog.style.getComputedPosition(element) == 'fixed') { - bestParent = goog.dom.getOwnerDocument(element).documentElement; - } - - // Just give up in this case. - if (!bestParent) { - return offsetLeftForReal; - } - - if (goog.userAgent.GECKO) { - // When calculating an element's offsetLeft, Firefox erroneously subtracts - // the border width from the actual distance. So we need to add it back. - var borderWidths = goog.style.getBorderBox(bestParent); - offsetLeftForReal += borderWidths.left; - } else if (goog.userAgent.isDocumentModeOrHigher(8) && - !goog.userAgent.isDocumentModeOrHigher(9)) { - // When calculating an element's offsetLeft, IE8/9-Standards Mode - // erroneously adds the border width to the actual distance. So we need to - // subtract it. - var borderWidths = goog.style.getBorderBox(bestParent); - offsetLeftForReal -= borderWidths.left; - } - - if (goog.style.isRightToLeft(bestParent)) { - // Right edge of the element relative to the left edge of its parent. - var elementRightOffset = offsetLeftForReal + element.offsetWidth; - - // Distance from the parent's right edge to the element's right edge. - return bestParent.clientWidth - elementRightOffset; - } - - return offsetLeftForReal; -}; - - -/** - * Sets the element's scrollLeft attribute so it is correctly scrolled by - * offsetStart pixels. This takes into account whether the element is RTL and - * the nuances of different browsers. To scroll to the "beginning" of an - * element use getOffsetStart to obtain the element's offsetStart value and then - * pass the value to setScrollOffset. - * @see getOffsetStart - * @param {Element} element The element to set scrollLeft on. - * @param {number} offsetStart The number of pixels to scroll the element. - * If this value is < 0, 0 is used. - */ -goog.style.bidi.setScrollOffset = function(element, offsetStart) { - offsetStart = Math.max(offsetStart, 0); - // In LTR and in "mirrored" browser RTL (such as IE), we set scrollLeft to - // the number of pixels to scroll. - // Otherwise, in RTL, we need to account for different browser behavior. - if (!goog.style.isRightToLeft(element)) { - element.scrollLeft = offsetStart; - } else if (goog.userAgent.GECKO) { - // Negative scroll-left positions in RTL. - element.scrollLeft = -offsetStart; - } else if (!(goog.userAgent.IE && goog.userAgent.isVersionOrHigher('8'))) { - // Take the current scrollLeft value and move to the right by the - // offsetStart to get to the left edge of the element, and then by - // the clientWidth of the element to get to the right edge. - element.scrollLeft = - element.scrollWidth - offsetStart - element.clientWidth; - } else { - element.scrollLeft = offsetStart; - } -}; - - -/** - * Sets the element's left style attribute in LTR or right style attribute in - * RTL. Also clears the left attribute in RTL and the right attribute in LTR. - * @param {Element} elem The element to position. - * @param {number} left The left position in LTR; will be set as right in RTL. - * @param {?number} top The top position. If null only the left/right is set. - * @param {boolean} isRtl Whether we are in RTL mode. - */ -goog.style.bidi.setPosition = function(elem, left, top, isRtl) { - if (!goog.isNull(top)) { - elem.style.top = top + 'px'; - } - if (isRtl) { - elem.style.right = left + 'px'; - elem.style.left = ''; - } else { - elem.style.left = left + 'px'; - elem.style.right = ''; - } -}; - -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Drag Utilities. - * - * Provides extensible functionality for drag & drop behaviour. - * - * @see ../demos/drag.html - * @see ../demos/dragger.html - */ - - -goog.provide('goog.fx.DragEvent'); -goog.provide('goog.fx.Dragger'); -goog.provide('goog.fx.Dragger.EventType'); - -goog.require('goog.dom'); -goog.require('goog.dom.TagName'); -goog.require('goog.events'); -goog.require('goog.events.Event'); -goog.require('goog.events.EventHandler'); -goog.require('goog.events.EventTarget'); -goog.require('goog.events.EventType'); -goog.require('goog.math.Coordinate'); -goog.require('goog.math.Rect'); -goog.require('goog.style'); -goog.require('goog.style.bidi'); -goog.require('goog.userAgent'); - - - -/** - * A class that allows mouse or touch-based dragging (moving) of an element - * - * @param {Element} target The element that will be dragged. - * @param {Element=} opt_handle An optional handle to control the drag, if null - * the target is used. - * @param {goog.math.Rect=} opt_limits Object containing left, top, width, - * and height. - * - * @extends {goog.events.EventTarget} - * @constructor - * @struct - */ -goog.fx.Dragger = function(target, opt_handle, opt_limits) { - goog.fx.Dragger.base(this, 'constructor'); - - /** - * Reference to drag target element. - * @type {?Element} - */ - this.target = target; - - /** - * Reference to the handler that initiates the drag. - * @type {?Element} - */ - this.handle = opt_handle || target; - - /** - * Object representing the limits of the drag region. - * @type {goog.math.Rect} - */ - this.limits = opt_limits || new goog.math.Rect(NaN, NaN, NaN, NaN); - - /** - * Reference to a document object to use for the events. - * @private {Document} - */ - this.document_ = goog.dom.getOwnerDocument(target); - - /** @private {!goog.events.EventHandler} */ - this.eventHandler_ = new goog.events.EventHandler(this); - this.registerDisposable(this.eventHandler_); - - /** - * Whether the element is rendered right-to-left. We initialize this lazily. - * @private {boolean|undefined}} - */ - this.rightToLeft_; - - /** - * Current x position of mouse or touch relative to viewport. - * @type {number} - */ - this.clientX = 0; - - /** - * Current y position of mouse or touch relative to viewport. - * @type {number} - */ - this.clientY = 0; - - /** - * Current x position of mouse or touch relative to screen. Deprecated because - * it doesn't take into affect zoom level or pixel density. - * @type {number} - * @deprecated Consider switching to clientX instead. - */ - this.screenX = 0; - - /** - * Current y position of mouse or touch relative to screen. Deprecated because - * it doesn't take into affect zoom level or pixel density. - * @type {number} - * @deprecated Consider switching to clientY instead. - */ - this.screenY = 0; - - /** - * The x position where the first mousedown or touchstart occurred. - * @type {number} - */ - this.startX = 0; - - /** - * The y position where the first mousedown or touchstart occurred. - * @type {number} - */ - this.startY = 0; - - /** - * Current x position of drag relative to target's parent. - * @type {number} - */ - this.deltaX = 0; - - /** - * Current y position of drag relative to target's parent. - * @type {number} - */ - this.deltaY = 0; - - /** - * The current page scroll value. - * @type {?goog.math.Coordinate} - */ - this.pageScroll; - - /** - * Whether dragging is currently enabled. - * @private {boolean} - */ - this.enabled_ = true; - - /** - * Whether object is currently being dragged. - * @private {boolean} - */ - this.dragging_ = false; - - /** - * Whether mousedown should be default prevented. - * @private {boolean} - **/ - this.preventMouseDown_ = true; - - /** - * The amount of distance, in pixels, after which a mousedown or touchstart is - * considered a drag. - * @private {number} - */ - this.hysteresisDistanceSquared_ = 0; - - /** - * The SCROLL event target used to make drag element follow scrolling. - * @private {?EventTarget} - */ - this.scrollTarget_; - - /** - * Whether IE drag events cancelling is on. - * @private {boolean} - */ - this.ieDragStartCancellingOn_ = false; - - /** - * Whether the dragger implements the changes described in http://b/6324964, - * making it truly RTL. This is a temporary flag to allow clients to - * transition to the new behavior at their convenience. At some point it will - * be the default. - * @private {boolean} - */ - this.useRightPositioningForRtl_ = false; - - // Add listener. Do not use the event handler here since the event handler is - // used for listeners added and removed during the drag operation. - goog.events.listen(this.handle, - [goog.events.EventType.TOUCHSTART, goog.events.EventType.MOUSEDOWN], - this.startDrag, false, this); -}; -goog.inherits(goog.fx.Dragger, goog.events.EventTarget); -// Dragger is meant to be extended, but defines most properties on its -// prototype, thus making it unsuitable for sealing. -goog.tagUnsealableClass(goog.fx.Dragger); - - -/** - * Whether setCapture is supported by the browser. - * @type {boolean} - * @private - */ -goog.fx.Dragger.HAS_SET_CAPTURE_ = - // IE and Gecko after 1.9.3 has setCapture - // WebKit does not yet: https://bugs.webkit.org/show_bug.cgi?id=27330 - goog.userAgent.IE || - goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.9.3'); - - -/** - * Creates copy of node being dragged. This is a utility function to be used - * wherever it is inappropriate for the original source to follow the mouse - * cursor itself. - * - * @param {Element} sourceEl Element to copy. - * @return {!Element} The clone of {@code sourceEl}. - */ -goog.fx.Dragger.cloneNode = function(sourceEl) { - var clonedEl = /** @type {Element} */ (sourceEl.cloneNode(true)), - origTexts = sourceEl.getElementsByTagName(goog.dom.TagName.TEXTAREA), - dragTexts = clonedEl.getElementsByTagName(goog.dom.TagName.TEXTAREA); - // Cloning does not copy the current value of textarea elements, so correct - // this manually. - for (var i = 0; i < origTexts.length; i++) { - dragTexts[i].value = origTexts[i].value; - } - switch (sourceEl.tagName) { - case goog.dom.TagName.TR: - return goog.dom.createDom(goog.dom.TagName.TABLE, null, - goog.dom.createDom(goog.dom.TagName.TBODY, - null, clonedEl)); - case goog.dom.TagName.TD: - case goog.dom.TagName.TH: - return goog.dom.createDom( - goog.dom.TagName.TABLE, null, goog.dom.createDom( - goog.dom.TagName.TBODY, null, goog.dom.createDom( - goog.dom.TagName.TR, null, clonedEl))); - case goog.dom.TagName.TEXTAREA: - clonedEl.value = sourceEl.value; - default: - return clonedEl; - } -}; - - -/** - * Constants for event names. - * @enum {string} - */ -goog.fx.Dragger.EventType = { - // The drag action was canceled before the START event. Possible reasons: - // disabled dragger, dragging with the right mouse button or releasing the - // button before reaching the hysteresis distance. - EARLY_CANCEL: 'earlycancel', - START: 'start', - BEFOREDRAG: 'beforedrag', - DRAG: 'drag', - END: 'end' -}; - - -/** - * Turns on/off true RTL behavior. This should be called immediately after - * construction. This is a temporary flag to allow clients to transition - * to the new component at their convenience. At some point true will be the - * default. - * @param {boolean} useRightPositioningForRtl True if "right" should be used for - * positioning, false if "left" should be used for positioning. - */ -goog.fx.Dragger.prototype.enableRightPositioningForRtl = - function(useRightPositioningForRtl) { - this.useRightPositioningForRtl_ = useRightPositioningForRtl; -}; - - -/** - * Returns the event handler, intended for subclass use. - * @return {!goog.events.EventHandler<T>} The event handler. - * @this {T} - * @template T - */ -goog.fx.Dragger.prototype.getHandler = function() { - // TODO(user): templated "this" values currently result in "this" being - // "unknown" in the body of the function. - var self = /** @type {goog.fx.Dragger} */ (this); - return self.eventHandler_; -}; - - -/** - * Sets (or reset) the Drag limits after a Dragger is created. - * @param {goog.math.Rect?} limits Object containing left, top, width, - * height for new Dragger limits. If target is right-to-left and - * enableRightPositioningForRtl(true) is called, then rect is interpreted as - * right, top, width, and height. - */ -goog.fx.Dragger.prototype.setLimits = function(limits) { - this.limits = limits || new goog.math.Rect(NaN, NaN, NaN, NaN); -}; - - -/** - * Sets the distance the user has to drag the element before a drag operation is - * started. - * @param {number} distance The number of pixels after which a mousedown and - * move is considered a drag. - */ -goog.fx.Dragger.prototype.setHysteresis = function(distance) { - this.hysteresisDistanceSquared_ = Math.pow(distance, 2); -}; - - -/** - * Gets the distance the user has to drag the element before a drag operation is - * started. - * @return {number} distance The number of pixels after which a mousedown and - * move is considered a drag. - */ -goog.fx.Dragger.prototype.getHysteresis = function() { - return Math.sqrt(this.hysteresisDistanceSquared_); -}; - - -/** - * Sets the SCROLL event target to make drag element follow scrolling. - * - * @param {EventTarget} scrollTarget The event target that dispatches SCROLL - * events. - */ -goog.fx.Dragger.prototype.setScrollTarget = function(scrollTarget) { - this.scrollTarget_ = scrollTarget; -}; - - -/** - * Enables cancelling of built-in IE drag events. - * @param {boolean} cancelIeDragStart Whether to enable cancelling of IE - * dragstart event. - */ -goog.fx.Dragger.prototype.setCancelIeDragStart = function(cancelIeDragStart) { - this.ieDragStartCancellingOn_ = cancelIeDragStart; -}; - - -/** - * @return {boolean} Whether the dragger is enabled. - */ -goog.fx.Dragger.prototype.getEnabled = function() { - return this.enabled_; -}; - - -/** - * Set whether dragger is enabled - * @param {boolean} enabled Whether dragger is enabled. - */ -goog.fx.Dragger.prototype.setEnabled = function(enabled) { - this.enabled_ = enabled; -}; - - -/** - * Set whether mousedown should be default prevented. - * @param {boolean} preventMouseDown Whether mousedown should be default - * prevented. - */ -goog.fx.Dragger.prototype.setPreventMouseDown = function(preventMouseDown) { - this.preventMouseDown_ = preventMouseDown; -}; - - -/** @override */ -goog.fx.Dragger.prototype.disposeInternal = function() { - goog.fx.Dragger.superClass_.disposeInternal.call(this); - goog.events.unlisten(this.handle, - [goog.events.EventType.TOUCHSTART, goog.events.EventType.MOUSEDOWN], - this.startDrag, false, this); - this.cleanUpAfterDragging_(); - - this.target = null; - this.handle = null; -}; - - -/** - * Whether the DOM element being manipulated is rendered right-to-left. - * @return {boolean} True if the DOM element is rendered right-to-left, false - * otherwise. - * @private - */ -goog.fx.Dragger.prototype.isRightToLeft_ = function() { - if (!goog.isDef(this.rightToLeft_)) { - this.rightToLeft_ = goog.style.isRightToLeft(this.target); - } - return this.rightToLeft_; -}; - - -/** - * Event handler that is used to start the drag - * @param {goog.events.BrowserEvent} e Event object. - */ -goog.fx.Dragger.prototype.startDrag = function(e) { - var isMouseDown = e.type == goog.events.EventType.MOUSEDOWN; - - // Dragger.startDrag() can be called by AbstractDragDrop with a mousemove - // event and IE does not report pressed mouse buttons on mousemove. Also, - // it does not make sense to check for the button if the user is already - // dragging. - - if (this.enabled_ && !this.dragging_ && - (!isMouseDown || e.isMouseActionButton())) { - if (this.hysteresisDistanceSquared_ == 0) { - if (this.fireDragStart_(e)) { - this.dragging_ = true; - if (this.preventMouseDown_) { - e.preventDefault(); - } - } else { - // If the start drag is cancelled, don't setup for a drag. - return; - } - } else if (this.preventMouseDown_) { - // Need to preventDefault for hysteresis to prevent page getting selected. - e.preventDefault(); - } - this.setupDragHandlers(); - - this.clientX = this.startX = e.clientX; - this.clientY = this.startY = e.clientY; - this.screenX = e.screenX; - this.screenY = e.screenY; - this.computeInitialPosition(); - this.pageScroll = goog.dom.getDomHelper(this.document_).getDocumentScroll(); - } else { - this.dispatchEvent(goog.fx.Dragger.EventType.EARLY_CANCEL); - } -}; - - -/** - * Sets up event handlers when dragging starts. - * @protected - */ -goog.fx.Dragger.prototype.setupDragHandlers = function() { - var doc = this.document_; - var docEl = doc.documentElement; - // Use bubbling when we have setCapture since we got reports that IE has - // problems with the capturing events in combination with setCapture. - var useCapture = !goog.fx.Dragger.HAS_SET_CAPTURE_; - - this.eventHandler_.listen(doc, - [goog.events.EventType.TOUCHMOVE, goog.events.EventType.MOUSEMOVE], - this.handleMove_, useCapture); - this.eventHandler_.listen(doc, - [goog.events.EventType.TOUCHEND, goog.events.EventType.MOUSEUP], - this.endDrag, useCapture); - - if (goog.fx.Dragger.HAS_SET_CAPTURE_) { - docEl.setCapture(false); - this.eventHandler_.listen(docEl, - goog.events.EventType.LOSECAPTURE, - this.endDrag); - } else { - // Make sure we stop the dragging if the window loses focus. - // Don't use capture in this listener because we only want to end the drag - // if the actual window loses focus. Since blur events do not bubble we use - // a bubbling listener on the window. - this.eventHandler_.listen(goog.dom.getWindow(doc), - goog.events.EventType.BLUR, - this.endDrag); - } - - if (goog.userAgent.IE && this.ieDragStartCancellingOn_) { - // Cancel IE's 'ondragstart' event. - this.eventHandler_.listen(doc, goog.events.EventType.DRAGSTART, - goog.events.Event.preventDefault); - } - - if (this.scrollTarget_) { - this.eventHandler_.listen(this.scrollTarget_, goog.events.EventType.SCROLL, - this.onScroll_, useCapture); - } -}; - - -/** - * Fires a goog.fx.Dragger.EventType.START event. - * @param {goog.events.BrowserEvent} e Browser event that triggered the drag. - * @return {boolean} False iff preventDefault was called on the DragEvent. - * @private - */ -goog.fx.Dragger.prototype.fireDragStart_ = function(e) { - return this.dispatchEvent(new goog.fx.DragEvent( - goog.fx.Dragger.EventType.START, this, e.clientX, e.clientY, e)); -}; - - -/** - * Unregisters the event handlers that are only active during dragging, and - * releases mouse capture. - * @private - */ -goog.fx.Dragger.prototype.cleanUpAfterDragging_ = function() { - this.eventHandler_.removeAll(); - if (goog.fx.Dragger.HAS_SET_CAPTURE_) { - this.document_.releaseCapture(); - } -}; - - -/** - * Event handler that is used to end the drag. - * @param {goog.events.BrowserEvent} e Event object. - * @param {boolean=} opt_dragCanceled Whether the drag has been canceled. - */ -goog.fx.Dragger.prototype.endDrag = function(e, opt_dragCanceled) { - this.cleanUpAfterDragging_(); - - if (this.dragging_) { - this.dragging_ = false; - - var x = this.limitX(this.deltaX); - var y = this.limitY(this.deltaY); - var dragCanceled = opt_dragCanceled || - e.type == goog.events.EventType.TOUCHCANCEL; - this.dispatchEvent(new goog.fx.DragEvent( - goog.fx.Dragger.EventType.END, this, e.clientX, e.clientY, e, x, y, - dragCanceled)); - } else { - this.dispatchEvent(goog.fx.Dragger.EventType.EARLY_CANCEL); - } -}; - - -/** - * Event handler that is used to end the drag by cancelling it. - * @param {goog.events.BrowserEvent} e Event object. - */ -goog.fx.Dragger.prototype.endDragCancel = function(e) { - this.endDrag(e, true); -}; - - -/** - * Event handler that is used on mouse / touch move to update the drag - * @param {goog.events.BrowserEvent} e Event object. - * @private - */ -goog.fx.Dragger.prototype.handleMove_ = function(e) { - if (this.enabled_) { - // dx in right-to-left cases is relative to the right. - var sign = this.useRightPositioningForRtl_ && - this.isRightToLeft_() ? -1 : 1; - var dx = sign * (e.clientX - this.clientX); - var dy = e.clientY - this.clientY; - this.clientX = e.clientX; - this.clientY = e.clientY; - this.screenX = e.screenX; - this.screenY = e.screenY; - - if (!this.dragging_) { - var diffX = this.startX - this.clientX; - var diffY = this.startY - this.clientY; - var distance = diffX * diffX + diffY * diffY; - if (distance > this.hysteresisDistanceSquared_) { - if (this.fireDragStart_(e)) { - this.dragging_ = true; - } else { - // DragListGroup disposes of the dragger if BEFOREDRAGSTART is - // canceled. - if (!this.isDisposed()) { - this.endDrag(e); - } - return; - } - } - } - - var pos = this.calculatePosition_(dx, dy); - var x = pos.x; - var y = pos.y; - - if (this.dragging_) { - - var rv = this.dispatchEvent(new goog.fx.DragEvent( - goog.fx.Dragger.EventType.BEFOREDRAG, this, e.clientX, e.clientY, - e, x, y)); - - // Only do the defaultAction and dispatch drag event if predrag didn't - // prevent default - if (rv) { - this.doDrag(e, x, y, false); - e.preventDefault(); - } - } - } -}; - - -/** - * Calculates the drag position. - * - * @param {number} dx The horizontal movement delta. - * @param {number} dy The vertical movement delta. - * @return {!goog.math.Coordinate} The newly calculated drag element position. - * @private - */ -goog.fx.Dragger.prototype.calculatePosition_ = function(dx, dy) { - // Update the position for any change in body scrolling - var pageScroll = goog.dom.getDomHelper(this.document_).getDocumentScroll(); - dx += pageScroll.x - this.pageScroll.x; - dy += pageScroll.y - this.pageScroll.y; - this.pageScroll = pageScroll; - - this.deltaX += dx; - this.deltaY += dy; - - var x = this.limitX(this.deltaX); - var y = this.limitY(this.deltaY); - return new goog.math.Coordinate(x, y); -}; - - -/** - * Event handler for scroll target scrolling. - * @param {goog.events.BrowserEvent} e The event. - * @private - */ -goog.fx.Dragger.prototype.onScroll_ = function(e) { - var pos = this.calculatePosition_(0, 0); - e.clientX = this.clientX; - e.clientY = this.clientY; - this.doDrag(e, pos.x, pos.y, true); -}; - - -/** - * @param {goog.events.BrowserEvent} e The closure object - * representing the browser event that caused a drag event. - * @param {number} x The new horizontal position for the drag element. - * @param {number} y The new vertical position for the drag element. - * @param {boolean} dragFromScroll Whether dragging was caused by scrolling - * the associated scroll target. - * @protected - */ -goog.fx.Dragger.prototype.doDrag = function(e, x, y, dragFromScroll) { - this.defaultAction(x, y); - this.dispatchEvent(new goog.fx.DragEvent( - goog.fx.Dragger.EventType.DRAG, this, e.clientX, e.clientY, e, x, y)); -}; - - -/** - * Returns the 'real' x after limits are applied (allows for some - * limits to be undefined). - * @param {number} x X-coordinate to limit. - * @return {number} The 'real' X-coordinate after limits are applied. - */ -goog.fx.Dragger.prototype.limitX = function(x) { - var rect = this.limits; - var left = !isNaN(rect.left) ? rect.left : null; - var width = !isNaN(rect.width) ? rect.width : 0; - var maxX = left != null ? left + width : Infinity; - var minX = left != null ? left : -Infinity; - return Math.min(maxX, Math.max(minX, x)); -}; - - -/** - * Returns the 'real' y after limits are applied (allows for some - * limits to be undefined). - * @param {number} y Y-coordinate to limit. - * @return {number} The 'real' Y-coordinate after limits are applied. - */ -goog.fx.Dragger.prototype.limitY = function(y) { - var rect = this.limits; - var top = !isNaN(rect.top) ? rect.top : null; - var height = !isNaN(rect.height) ? rect.height : 0; - var maxY = top != null ? top + height : Infinity; - var minY = top != null ? top : -Infinity; - return Math.min(maxY, Math.max(minY, y)); -}; - - -/** - * Overridable function for computing the initial position of the target - * before dragging begins. - * @protected - */ -goog.fx.Dragger.prototype.computeInitialPosition = function() { - this.deltaX = this.useRightPositioningForRtl_ ? - goog.style.bidi.getOffsetStart(this.target) : - /** @type {!HTMLElement} */ (this.target).offsetLeft; - this.deltaY = /** @type {!HTMLElement} */ (this.target).offsetTop; -}; - - -/** - * Overridable function for handling the default action of the drag behaviour. - * Normally this is simply moving the element to x,y though in some cases it - * might be used to resize the layer. This is basically a shortcut to - * implementing a default ondrag event handler. - * @param {number} x X-coordinate for target element. In right-to-left, x this - * is the number of pixels the target should be moved to from the right. - * @param {number} y Y-coordinate for target element. - */ -goog.fx.Dragger.prototype.defaultAction = function(x, y) { - if (this.useRightPositioningForRtl_ && this.isRightToLeft_()) { - this.target.style.right = x + 'px'; - } else { - this.target.style.left = x + 'px'; - } - this.target.style.top = y + 'px'; -}; - - -/** - * @return {boolean} Whether the dragger is currently in the midst of a drag. - */ -goog.fx.Dragger.prototype.isDragging = function() { - return this.dragging_; -}; - - - -/** - * Object representing a drag event - * @param {string} type Event type. - * @param {goog.fx.Dragger} dragobj Drag object initiating event. - * @param {number} clientX X-coordinate relative to the viewport. - * @param {number} clientY Y-coordinate relative to the viewport. - * @param {goog.events.BrowserEvent} browserEvent The closure object - * representing the browser event that caused this drag event. - * @param {number=} opt_actX Optional actual x for drag if it has been limited. - * @param {number=} opt_actY Optional actual y for drag if it has been limited. - * @param {boolean=} opt_dragCanceled Whether the drag has been canceled. - * @constructor - * @struct - * @extends {goog.events.Event} - */ -goog.fx.DragEvent = function(type, dragobj, clientX, clientY, browserEvent, - opt_actX, opt_actY, opt_dragCanceled) { - goog.events.Event.call(this, type); - - /** - * X-coordinate relative to the viewport - * @type {number} - */ - this.clientX = clientX; - - /** - * Y-coordinate relative to the viewport - * @type {number} - */ - this.clientY = clientY; - - /** - * The closure object representing the browser event that caused this drag - * event. - * @type {goog.events.BrowserEvent} - */ - this.browserEvent = browserEvent; - - /** - * The real x-position of the drag if it has been limited - * @type {number} - */ - this.left = goog.isDef(opt_actX) ? opt_actX : dragobj.deltaX; - - /** - * The real y-position of the drag if it has been limited - * @type {number} - */ - this.top = goog.isDef(opt_actY) ? opt_actY : dragobj.deltaY; - - /** - * Reference to the drag object for this event - * @type {goog.fx.Dragger} - */ - this.dragger = dragobj; - - /** - * Whether drag was canceled with this event. Used to differentiate between - * a legitimate drag END that can result in an action and a drag END which is - * a result of a drag cancelation. For now it can happen 1) with drag END - * event on FireFox when user drags the mouse out of the window, 2) with - * drag END event on IE7 which is generated on MOUSEMOVE event when user - * moves the mouse into the document after the mouse button has been - * released, 3) when TOUCHCANCEL is raised instead of TOUCHEND (on touch - * events). - * @type {boolean} - */ - this.dragCanceled = !!opt_dragCanceled; -}; -goog.inherits(goog.fx.DragEvent, goog.events.Event); - // FIXME should possibly show tooltip when dragging? goog.provide('ol.control.ZoomSlider'); goog.require('goog.asserts'); goog.require('goog.dom'); -goog.require('goog.events'); -goog.require('goog.events.Event'); -goog.require('goog.events.EventType'); -goog.require('goog.fx.DragEvent'); -goog.require('goog.fx.Dragger'); -goog.require('goog.fx.Dragger.EventType'); -goog.require('goog.math.Rect'); goog.require('goog.style'); -goog.require('ol.Size'); +goog.require('ol.events'); +goog.require('ol.events.Event'); +goog.require('ol.events.EventType'); +goog.require('ol.pointer.PointerEventHandler'); goog.require('ol.ViewHint'); goog.require('ol.animation'); goog.require('ol.control.Control'); @@ -87547,7 +69998,6 @@ goog.require('ol.easing'); goog.require('ol.math'); - /** * @classdesc * A slider type of control for zooming. @@ -87583,6 +70033,42 @@ ol.control.ZoomSlider = function(opt_options) { this.direction_ = ol.control.ZoomSlider.direction.VERTICAL; /** + * @type {boolean} + * @private + */ + this.dragging_; + + /** + * @type {!Array.<ol.events.Key>} + * @private + */ + this.dragListenerKeys_ = []; + + /** + * @type {number} + * @private + */ + this.heightLimit_ = 0; + + /** + * @type {number} + * @private + */ + this.widthLimit_ = 0; + + /** + * @type {number|undefined} + * @private + */ + this.previousX_; + + /** + * @type {number|undefined} + * @private + */ + this.previousY_; + + /** * The calculated thumb size (border box plus margins). Set when initSlider_ * is called. * @type {ol.Size} @@ -87598,12 +70084,12 @@ ol.control.ZoomSlider = function(opt_options) { this.sliderInitialized_ = false; /** - * @private * @type {number} + * @private */ this.duration_ = options.duration !== undefined ? options.duration : 200; - var className = options.className ? options.className : 'ol-zoomslider'; + var className = options.className !== undefined ? options.className : 'ol-zoomslider'; var thumbElement = goog.dom.createDom('BUTTON', { 'type': 'button', 'class': className + '-thumb ' + ol.css.CLASS_UNSELECTABLE @@ -87613,23 +70099,22 @@ ol.control.ZoomSlider = function(opt_options) { thumbElement); /** - * @type {goog.fx.Dragger} + * @type {ol.pointer.PointerEventHandler} * @private */ - this.dragger_ = new goog.fx.Dragger(thumbElement); - this.registerDisposable(this.dragger_); + this.dragger_ = new ol.pointer.PointerEventHandler(containerElement); - goog.events.listen(this.dragger_, goog.fx.Dragger.EventType.START, - this.handleDraggerStart_, false, this); - goog.events.listen(this.dragger_, goog.fx.Dragger.EventType.DRAG, - this.handleDraggerDrag_, false, this); - goog.events.listen(this.dragger_, goog.fx.Dragger.EventType.END, - this.handleDraggerEnd_, false, this); + ol.events.listen(this.dragger_, ol.pointer.EventType.POINTERDOWN, + this.handleDraggerStart_, this); + ol.events.listen(this.dragger_, ol.pointer.EventType.POINTERMOVE, + this.handleDraggerDrag_, this); + ol.events.listen(this.dragger_, ol.pointer.EventType.POINTERUP, + this.handleDraggerEnd_, this); - goog.events.listen(containerElement, goog.events.EventType.CLICK, - this.handleContainerClick_, false, this); - goog.events.listen(thumbElement, goog.events.EventType.CLICK, - goog.events.Event.stopPropagation); + ol.events.listen(containerElement, ol.events.EventType.CLICK, + this.handleContainerClick_, this); + ol.events.listen(thumbElement, ol.events.EventType.CLICK, + ol.events.Event.stopPropagation); var render = options.render ? options.render : ol.control.ZoomSlider.render; @@ -87642,6 +70127,15 @@ goog.inherits(ol.control.ZoomSlider, ol.control.Control); /** + * @inheritDoc + */ +ol.control.ZoomSlider.prototype.disposeInternal = function() { + this.dragger_.dispose(); + goog.base(this, 'disposeInternal'); +}; + + +/** * The enum for available directions. * * @enum {number} @@ -87674,7 +70168,7 @@ ol.control.ZoomSlider.prototype.initSlider_ = function() { var container = this.element; var containerSize = goog.style.getSize(container); - var thumb = goog.dom.getFirstElementChild(container); + var thumb = container.firstElementChild; var thumbMargins = goog.style.getMarginBox(thumb); var thumbBorderBoxSize = goog.style.getBorderBoxSize(thumb); var thumbWidth = thumbBorderBoxSize.width + @@ -87683,18 +70177,13 @@ ol.control.ZoomSlider.prototype.initSlider_ = function() { thumbMargins.top + thumbMargins.bottom; this.thumbSize_ = [thumbWidth, thumbHeight]; - var width = containerSize.width - thumbWidth; - var height = containerSize.height - thumbHeight; - - var limits; if (containerSize.width > containerSize.height) { this.direction_ = ol.control.ZoomSlider.direction.HORIZONTAL; - limits = new goog.math.Rect(0, 0, width, 0); + this.widthLimit_ = containerSize.width - thumbWidth; } else { this.direction_ = ol.control.ZoomSlider.direction.VERTICAL; - limits = new goog.math.Rect(0, 0, 0, height); + this.heightLimit_ = containerSize.height - thumbHeight; } - this.dragger_.setLimits(limits); this.sliderInitialized_ = true; }; @@ -87723,10 +70212,10 @@ ol.control.ZoomSlider.render = function(mapEvent) { /** - * @param {goog.events.BrowserEvent} browserEvent The browser event to handle. + * @param {Event} event The browser event to handle. * @private */ -ol.control.ZoomSlider.prototype.handleContainerClick_ = function(browserEvent) { +ol.control.ZoomSlider.prototype.handleContainerClick_ = function(event) { var map = this.getMap(); var view = map.getView(); var currentResolution = view.getResolution(); @@ -87738,8 +70227,8 @@ ol.control.ZoomSlider.prototype.handleContainerClick_ = function(browserEvent) { easing: ol.easing.easeOut })); var relativePosition = this.getRelativePosition_( - browserEvent.offsetX - this.thumbSize_[0] / 2, - browserEvent.offsetY - this.thumbSize_[1] / 2); + event.offsetX - this.thumbSize_[0] / 2, + event.offsetY - this.thumbSize_[1] / 2); var resolution = this.getResolutionForPosition_(relativePosition); view.setResolution(view.constrainResolution(resolution)); }; @@ -87747,45 +70236,79 @@ ol.control.ZoomSlider.prototype.handleContainerClick_ = function(browserEvent) { /** * Handle dragger start events. - * @param {goog.fx.DragEvent} event The drag event. + * @param {ol.pointer.PointerEvent} event The drag event. * @private */ ol.control.ZoomSlider.prototype.handleDraggerStart_ = function(event) { - this.getMap().getView().setHint(ol.ViewHint.INTERACTING, 1); + if (!this.dragging_ && + event.originalEvent.target === this.element.firstElementChild) { + this.getMap().getView().setHint(ol.ViewHint.INTERACTING, 1); + this.previousX_ = event.clientX; + this.previousY_ = event.clientY; + this.dragging_ = true; + + if (this.dragListenerKeys_.length === 0) { + var drag = this.handleDraggerDrag_; + var end = this.handleDraggerEnd_; + this.dragListenerKeys_.push( + ol.events.listen(document, ol.events.EventType.MOUSEMOVE, drag, this), + ol.events.listen(document, ol.events.EventType.TOUCHMOVE, drag, this), + ol.events.listen(document, ol.pointer.EventType.POINTERMOVE, drag, this), + ol.events.listen(document, ol.events.EventType.MOUSEUP, end, this), + ol.events.listen(document, ol.events.EventType.TOUCHEND, end, this), + ol.events.listen(document, ol.pointer.EventType.POINTERUP, end, this) + ); + } + } }; /** * Handle dragger drag events. * - * @param {goog.fx.DragEvent} event The drag event. + * @param {ol.pointer.PointerEvent|Event} event The drag event. * @private */ ol.control.ZoomSlider.prototype.handleDraggerDrag_ = function(event) { - var relativePosition = this.getRelativePosition_(event.left, event.top); - this.currentResolution_ = this.getResolutionForPosition_(relativePosition); - this.getMap().getView().setResolution(this.currentResolution_); + if (this.dragging_) { + var element = this.element.firstElementChild; + var deltaX = event.clientX - this.previousX_ + parseInt(element.style.left, 10); + var deltaY = event.clientY - this.previousY_ + parseInt(element.style.top, 10); + var relativePosition = this.getRelativePosition_(deltaX, deltaY); + this.currentResolution_ = this.getResolutionForPosition_(relativePosition); + this.getMap().getView().setResolution(this.currentResolution_); + this.setThumbPosition_(this.currentResolution_); + this.previousX_ = event.clientX; + this.previousY_ = event.clientY; + } }; /** * Handle dragger end events. - * @param {goog.fx.DragEvent} event The drag event. + * @param {ol.pointer.PointerEvent|Event} event The drag event. * @private */ ol.control.ZoomSlider.prototype.handleDraggerEnd_ = function(event) { - var map = this.getMap(); - var view = map.getView(); - view.setHint(ol.ViewHint.INTERACTING, -1); - goog.asserts.assert(this.currentResolution_, - 'this.currentResolution_ should be defined'); - map.beforeRender(ol.animation.zoom({ - resolution: this.currentResolution_, - duration: this.duration_, - easing: ol.easing.easeOut - })); - var resolution = view.constrainResolution(this.currentResolution_); - view.setResolution(resolution); + if (this.dragging_) { + var map = this.getMap(); + var view = map.getView(); + view.setHint(ol.ViewHint.INTERACTING, -1); + goog.asserts.assert(this.currentResolution_, + 'this.currentResolution_ should be defined'); + map.beforeRender(ol.animation.zoom({ + resolution: this.currentResolution_, + duration: this.duration_, + easing: ol.easing.easeOut + })); + var resolution = view.constrainResolution(this.currentResolution_); + view.setResolution(resolution); + this.dragging_ = false; + this.previousX_ = undefined; + this.previousY_ = undefined; + this.dragListenerKeys_.forEach(ol.events.unlistenByKey); + this.dragListenerKeys_.length = 0; + } }; @@ -87797,15 +70320,12 @@ ol.control.ZoomSlider.prototype.handleDraggerEnd_ = function(event) { */ ol.control.ZoomSlider.prototype.setThumbPosition_ = function(res) { var position = this.getPositionForResolution_(res); - var dragger = this.dragger_; - var thumb = goog.dom.getFirstElementChild(this.element); + var thumb = this.element.firstElementChild; if (this.direction_ == ol.control.ZoomSlider.direction.HORIZONTAL) { - var left = dragger.limits.left + dragger.limits.width * position; - goog.style.setPosition(thumb, left); + thumb.style.left = this.widthLimit_ * position + 'px'; } else { - var top = dragger.limits.top + dragger.limits.height * position; - goog.style.setPosition(thumb, dragger.limits.left, top); + thumb.style.top = this.heightLimit_ * position + 'px'; } }; @@ -87821,12 +70341,11 @@ ol.control.ZoomSlider.prototype.setThumbPosition_ = function(res) { * @private */ ol.control.ZoomSlider.prototype.getRelativePosition_ = function(x, y) { - var draggerLimits = this.dragger_.limits; var amount; if (this.direction_ === ol.control.ZoomSlider.direction.HORIZONTAL) { - amount = (x - draggerLimits.left) / draggerLimits.width; + amount = x / this.widthLimit_; } else { - amount = (y - draggerLimits.top) / draggerLimits.height; + amount = y / this.heightLimit_; } return ol.math.clamp(amount, 0, 1); }; @@ -87864,13 +70383,12 @@ goog.provide('ol.control.ZoomToExtent'); goog.require('goog.asserts'); goog.require('goog.dom'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol.control.Control'); goog.require('ol.css'); - /** * @classdesc * A button control which, when pressed, changes the map view to a specific @@ -87890,19 +70408,19 @@ ol.control.ZoomToExtent = function(opt_options) { */ this.extent_ = options.extent ? options.extent : null; - var className = options.className ? options.className : + var className = options.className !== undefined ? options.className : 'ol-zoom-extent'; - var label = options.label ? options.label : 'E'; - var tipLabel = options.tipLabel ? + var label = options.label !== undefined ? options.label : 'E'; + var tipLabel = options.tipLabel !== undefined ? options.tipLabel : 'Fit to extent'; var button = goog.dom.createDom('BUTTON', { 'type': 'button', 'title': tipLabel }, label); - goog.events.listen(button, goog.events.EventType.CLICK, - this.handleClick_, false, this); + ol.events.listen(button, ol.events.EventType.CLICK, + this.handleClick_, this); var cssClasses = className + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' + ol.css.CLASS_CONTROL; @@ -87917,7 +70435,7 @@ goog.inherits(ol.control.ZoomToExtent, ol.control.Control); /** - * @param {goog.events.BrowserEvent} event The event to handle + * @param {Event} event The event to handle * @private */ ol.control.ZoomToExtent.prototype.handleClick_ = function(event) { @@ -87932,8 +70450,7 @@ ol.control.ZoomToExtent.prototype.handleClick_ = function(event) { ol.control.ZoomToExtent.prototype.handleZoomToExtent_ = function() { var map = this.getMap(); var view = map.getView(); - var extent = !this.extent_ ? - view.getProjection().getExtent() : this.extent_; + var extent = !this.extent_ ? view.getProjection().getExtent() : this.extent_; var size = map.getSize(); goog.asserts.assert(size, 'size should be defined'); view.fit(extent, size); @@ -87942,7 +70459,7 @@ ol.control.ZoomToExtent.prototype.handleZoomToExtent_ = function() { goog.provide('ol.DeviceOrientation'); goog.provide('ol.DeviceOrientationProperty'); -goog.require('goog.events'); +goog.require('ol.events'); goog.require('ol'); goog.require('ol.Object'); goog.require('ol.has'); @@ -87961,7 +70478,6 @@ ol.DeviceOrientationProperty = { }; - /** * @classdesc * The ol.DeviceOrientation class provides access to information from @@ -88007,11 +70523,11 @@ ol.DeviceOrientationProperty = { * equivalent properties in ol.DeviceOrientation are in radians for consistency * with all other uses of angles throughout OpenLayers. * - * @see http://www.w3.org/TR/orientation-event/ - * * To get notified of device orientation changes, register a listener for the * generic `change` event on your `ol.DeviceOrientation` instance. * + * @see {@link http://www.w3.org/TR/orientation-event/} + * * @constructor * @extends {ol.Object} * @param {olx.DeviceOrientationOptions=} opt_options Options. @@ -88025,13 +70541,13 @@ ol.DeviceOrientation = function(opt_options) { /** * @private - * @type {goog.events.Key} + * @type {?ol.events.Key} */ this.listenerKey_ = null; - goog.events.listen(this, + ol.events.listen(this, ol.Object.getChangeEventType(ol.DeviceOrientationProperty.TRACKING), - this.handleTrackingChanged_, false, this); + this.handleTrackingChanged_, this); this.setTracking(options.tracking !== undefined ? options.tracking : false); @@ -88050,16 +70566,15 @@ ol.DeviceOrientation.prototype.disposeInternal = function() { /** * @private - * @param {goog.events.BrowserEvent} browserEvent Event. + * @param {Event} originalEvent Event. */ -ol.DeviceOrientation.prototype.orientationChange_ = function(browserEvent) { - var event = /** @type {DeviceOrientationEvent} */ - (browserEvent.getBrowserEvent()); +ol.DeviceOrientation.prototype.orientationChange_ = function(originalEvent) { + var event = /** @type {DeviceOrientationEvent} */ (originalEvent); if (event.alpha !== null) { var alpha = ol.math.toRadians(event.alpha); this.set(ol.DeviceOrientationProperty.ALPHA, alpha); // event.absolute is undefined in iOS. - if (goog.isBoolean(event.absolute) && event.absolute) { + if (typeof event.absolute === 'boolean' && event.absolute) { this.set(ol.DeviceOrientationProperty.HEADING, alpha); } else if (goog.isNumber(event.webkitCompassHeading) && event.webkitCompassAccuracy != -1) { @@ -88150,10 +70665,10 @@ ol.DeviceOrientation.prototype.handleTrackingChanged_ = function() { if (ol.has.DEVICE_ORIENTATION) { var tracking = this.getTracking(); if (tracking && !this.listenerKey_) { - this.listenerKey_ = goog.events.listen(goog.global, 'deviceorientation', - this.orientationChange_, false, this); - } else if (!tracking && this.listenerKey_) { - goog.events.unlistenByKey(this.listenerKey_); + this.listenerKey_ = ol.events.listen(ol.global, 'deviceorientation', + this.orientationChange_, this); + } else if (!tracking && this.listenerKey_ !== null) { + ol.events.unlistenByKey(this.listenerKey_); this.listenerKey_ = null; } } @@ -88177,7 +70692,6 @@ goog.require('ol.geom.Geometry'); goog.require('ol.proj'); - /** * @classdesc * Abstract base class; normally only used for creating subclasses and not @@ -88245,6 +70759,9 @@ ol.format.Feature.prototype.adaptOptions = function(options) { options.dataProjection : this.defaultDataProjection, rightHanded: options.rightHanded }; + if (options.decimals) { + updatedOptions.decimals = options.decimals; + } } return updatedOptions; }; @@ -88339,34 +70856,56 @@ ol.format.Feature.transformWithOptions = function( ol.proj.get(opt_options.featureProjection) : null; var dataProjection = opt_options ? ol.proj.get(opt_options.dataProjection) : null; + /** + * @type {ol.geom.Geometry|ol.Extent} + */ + var transformed; if (featureProjection && dataProjection && !ol.proj.equivalent(featureProjection, dataProjection)) { if (geometry instanceof ol.geom.Geometry) { - return (write ? geometry.clone() : geometry).transform( + transformed = (write ? geometry.clone() : geometry).transform( write ? featureProjection : dataProjection, write ? dataProjection : featureProjection); } else { // FIXME this is necessary because ol.format.GML treats extents // as geometries - return ol.proj.transformExtent( + transformed = ol.proj.transformExtent( write ? geometry.slice() : geometry, write ? featureProjection : dataProjection, write ? dataProjection : featureProjection); } } else { - return geometry; + transformed = geometry; } + if (write && opt_options && opt_options.decimals) { + var power = Math.pow(10, opt_options.decimals); + // if decimals option on write, round each coordinate appropriately + /** + * @param {Array.<number>} coordinates Coordinates. + * @return {Array.<number>} Transformed coordinates. + */ + var transform = function(coordinates) { + for (var i = 0, ii = coordinates.length; i < ii; ++i) { + coordinates[i] = Math.round(coordinates[i] * power) / power; + } + return coordinates; + }; + if (Array.isArray(transformed)) { + transform(transformed); + } else { + transformed.applyTransform(transform); + } + } + return transformed; }; goog.provide('ol.format.JSONFeature'); goog.require('goog.asserts'); -goog.require('goog.json'); goog.require('ol.format.Feature'); goog.require('ol.format.FormatType'); - /** * @classdesc * Abstract base class; normally only used for creating subclasses and not @@ -88390,9 +70929,9 @@ goog.inherits(ol.format.JSONFeature, ol.format.Feature); ol.format.JSONFeature.prototype.getObject_ = function(source) { if (goog.isObject(source)) { return source; - } else if (goog.isString(source)) { - var object = goog.json.parse(source); - return object ? object : null; + } else if (typeof source === 'string') { + var object = JSON.parse(source); + return object ? /** @type {Object} */ (object) : null; } else { goog.asserts.fail(); return null; @@ -88482,7 +71021,7 @@ ol.format.JSONFeature.prototype.readProjectionFromObject = goog.abstractMethod; * @inheritDoc */ ol.format.JSONFeature.prototype.writeFeature = function(feature, opt_options) { - return goog.json.serialize(this.writeFeatureObject(feature, opt_options)); + return JSON.stringify(this.writeFeatureObject(feature, opt_options)); }; @@ -88497,9 +71036,8 @@ ol.format.JSONFeature.prototype.writeFeatureObject = goog.abstractMethod; /** * @inheritDoc */ -ol.format.JSONFeature.prototype.writeFeatures = function( - features, opt_options) { - return goog.json.serialize(this.writeFeaturesObject(features, opt_options)); +ol.format.JSONFeature.prototype.writeFeatures = function(features, opt_options) { + return JSON.stringify(this.writeFeaturesObject(features, opt_options)); }; @@ -88514,9 +71052,8 @@ ol.format.JSONFeature.prototype.writeFeaturesObject = goog.abstractMethod; /** * @inheritDoc */ -ol.format.JSONFeature.prototype.writeGeometry = function( - geometry, opt_options) { - return goog.json.serialize(this.writeGeometryObject(geometry, opt_options)); +ol.format.JSONFeature.prototype.writeGeometry = function(geometry, opt_options) { + return JSON.stringify(this.writeGeometryObject(geometry, opt_options)); }; @@ -88529,9 +71066,9 @@ ol.format.JSONFeature.prototype.writeGeometryObject = goog.abstractMethod; goog.provide('ol.geom.flat.interpolate'); -goog.require('goog.array'); goog.require('goog.asserts'); -goog.require('goog.math'); +goog.require('ol.array'); +goog.require('ol.math'); /** @@ -88543,8 +71080,8 @@ goog.require('goog.math'); * @param {Array.<number>=} opt_dest Destination. * @return {Array.<number>} Destination. */ -ol.geom.flat.interpolate.lineString = - function(flatCoordinates, offset, end, stride, fraction, opt_dest) { +ol.geom.flat.interpolate.lineString = function(flatCoordinates, offset, end, stride, fraction, opt_dest) { + // FIXME does not work when vertices are repeated // FIXME interpolate extra dimensions goog.asserts.assert(0 <= fraction && fraction <= 1, 'fraction should be in between 0 and 1'); @@ -88576,14 +71113,14 @@ ol.geom.flat.interpolate.lineString = y1 = y2; } var target = fraction * length; - var index = goog.array.binarySearch(cumulativeLengths, target); + var index = ol.array.binarySearch(cumulativeLengths, target); if (index < 0) { var t = (target - cumulativeLengths[-index - 2]) / (cumulativeLengths[-index - 1] - cumulativeLengths[-index - 2]); var o = offset + (-index - 2) * stride; - pointX = goog.math.lerp( + pointX = ol.math.lerp( flatCoordinates[o], flatCoordinates[o + stride], t); - pointY = goog.math.lerp( + pointY = ol.math.lerp( flatCoordinates[o + 1], flatCoordinates[o + stride + 1], t); } else { pointX = flatCoordinates[offset + index * stride]; @@ -88609,8 +71146,7 @@ ol.geom.flat.interpolate.lineString = * @param {boolean} extrapolate Extrapolate. * @return {ol.Coordinate} Coordinate. */ -ol.geom.flat.lineStringCoordinateAtM = - function(flatCoordinates, offset, end, stride, m, extrapolate) { +ol.geom.flat.lineStringCoordinateAtM = function(flatCoordinates, offset, end, stride, m, extrapolate) { if (end == offset) { return null; } @@ -88657,7 +71193,7 @@ ol.geom.flat.lineStringCoordinateAtM = coordinate = []; var i; for (i = 0; i < stride - 1; ++i) { - coordinate.push(goog.math.lerp(flatCoordinates[(lo - 1) * stride + i], + coordinate.push(ol.math.lerp(flatCoordinates[(lo - 1) * stride + i], flatCoordinates[lo * stride + i], t)); } coordinate.push(m); @@ -88731,8 +71267,7 @@ goog.provide('ol.geom.flat.length'); * @param {number} stride Stride. * @return {number} Length. */ -ol.geom.flat.length.lineString = - function(flatCoordinates, offset, end, stride) { +ol.geom.flat.length.lineString = function(flatCoordinates, offset, end, stride) { var x1 = flatCoordinates[offset]; var y1 = flatCoordinates[offset + 1]; var length = 0; @@ -88755,8 +71290,7 @@ ol.geom.flat.length.lineString = * @param {number} stride Stride. * @return {number} Perimeter. */ -ol.geom.flat.length.linearRing = - function(flatCoordinates, offset, end, stride) { +ol.geom.flat.length.linearRing = function(flatCoordinates, offset, end, stride) { var perimeter = ol.geom.flat.length.lineString(flatCoordinates, offset, end, stride); var dx = flatCoordinates[end - stride] - flatCoordinates[offset]; @@ -88767,9 +71301,9 @@ ol.geom.flat.length.linearRing = goog.provide('ol.geom.LineString'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('ol'); +goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.geom.GeometryLayout'); goog.require('ol.geom.GeometryType'); @@ -88784,7 +71318,6 @@ goog.require('ol.geom.flat.segments'); goog.require('ol.geom.flat.simplify'); - /** * @classdesc * Linestring geometry. @@ -88840,7 +71373,7 @@ ol.geom.LineString.prototype.appendCoordinate = function(coordinate) { if (!this.flatCoordinates) { this.flatCoordinates = coordinate.slice(); } else { - goog.array.extend(this.flatCoordinates, coordinate); + ol.array.extend(this.flatCoordinates, coordinate); } this.changed(); }; @@ -88861,8 +71394,7 @@ ol.geom.LineString.prototype.clone = function() { /** * @inheritDoc */ -ol.geom.LineString.prototype.closestPointXY = - function(x, y, closestPoint, minSquaredDistance) { +ol.geom.LineString.prototype.closestPointXY = function(x, y, closestPoint, minSquaredDistance) { if (minSquaredDistance < ol.extent.closestSquaredDistanceXY(this.getExtent(), x, y)) { return minSquaredDistance; @@ -88934,6 +71466,23 @@ ol.geom.LineString.prototype.getCoordinates = function() { /** + * Return the coordinate at the provided fraction along the linestring. + * The `fraction` is a number between 0 and 1, where 0 is the start of the + * linestring and 1 is the end. + * @param {number} fraction Fraction. + * @param {ol.Coordinate=} opt_dest Optional coordinate whose values will + * be modified. If not provided, a new coordinate will be returned. + * @return {ol.Coordinate} Coordinate of the interpolated point. + * @api + */ +ol.geom.LineString.prototype.getCoordinateAt = function(fraction, opt_dest) { + return ol.geom.flat.interpolate.lineString( + this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, + fraction, opt_dest); +}; + + +/** * Return the length of the linestring on projected plane. * @return {number} Length (on projected plane). * @api stable @@ -88949,9 +71498,7 @@ ol.geom.LineString.prototype.getLength = function() { */ ol.geom.LineString.prototype.getFlatMidpoint = function() { if (this.flatMidpointRevision_ != this.getRevision()) { - this.flatMidpoint_ = ol.geom.flat.interpolate.lineString( - this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, - 0.5, this.flatMidpoint_); + this.flatMidpoint_ = this.getCoordinateAt(0.5, this.flatMidpoint_); this.flatMidpointRevision_ = this.getRevision(); } return this.flatMidpoint_; @@ -88961,8 +71508,7 @@ ol.geom.LineString.prototype.getFlatMidpoint = function() { /** * @inheritDoc */ -ol.geom.LineString.prototype.getSimplifiedGeometryInternal = - function(squaredTolerance) { +ol.geom.LineString.prototype.getSimplifiedGeometryInternal = function(squaredTolerance) { var simplifiedFlatCoordinates = []; simplifiedFlatCoordinates.length = ol.geom.flat.simplify.douglasPeucker( this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, @@ -89000,8 +71546,7 @@ ol.geom.LineString.prototype.intersectsExtent = function(extent) { * @param {ol.geom.GeometryLayout=} opt_layout Layout. * @api stable */ -ol.geom.LineString.prototype.setCoordinates = - function(coordinates, opt_layout) { +ol.geom.LineString.prototype.setCoordinates = function(coordinates, opt_layout) { if (!coordinates) { this.setFlatCoordinates(ol.geom.GeometryLayout.XY, null); } else { @@ -89020,17 +71565,16 @@ ol.geom.LineString.prototype.setCoordinates = * @param {ol.geom.GeometryLayout} layout Layout. * @param {Array.<number>} flatCoordinates Flat coordinates. */ -ol.geom.LineString.prototype.setFlatCoordinates = - function(layout, flatCoordinates) { +ol.geom.LineString.prototype.setFlatCoordinates = function(layout, flatCoordinates) { this.setFlatCoordinatesInternal(layout, flatCoordinates); this.changed(); }; goog.provide('ol.geom.MultiLineString'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('ol'); +goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.geom.GeometryLayout'); goog.require('ol.geom.GeometryType'); @@ -89044,7 +71588,6 @@ goog.require('ol.geom.flat.intersectsextent'); goog.require('ol.geom.flat.simplify'); - /** * @classdesc * Multi-linestring geometry. @@ -89094,7 +71637,7 @@ ol.geom.MultiLineString.prototype.appendLineString = function(lineString) { if (!this.flatCoordinates) { this.flatCoordinates = lineString.getFlatCoordinates().slice(); } else { - goog.array.extend( + ol.array.extend( this.flatCoordinates, lineString.getFlatCoordinates().slice()); } this.ends_.push(this.flatCoordinates.length); @@ -89118,8 +71661,7 @@ ol.geom.MultiLineString.prototype.clone = function() { /** * @inheritDoc */ -ol.geom.MultiLineString.prototype.closestPointXY = - function(x, y, closestPoint, minSquaredDistance) { +ol.geom.MultiLineString.prototype.closestPointXY = function(x, y, closestPoint, minSquaredDistance) { if (minSquaredDistance < ol.extent.closestSquaredDistanceXY(this.getExtent(), x, y)) { return minSquaredDistance; @@ -89157,8 +71699,7 @@ ol.geom.MultiLineString.prototype.closestPointXY = * @return {ol.Coordinate} Coordinate. * @api stable */ -ol.geom.MultiLineString.prototype.getCoordinateAtM = - function(m, opt_extrapolate, opt_interpolate) { +ol.geom.MultiLineString.prototype.getCoordinateAtM = function(m, opt_extrapolate, opt_interpolate) { if ((this.layout != ol.geom.GeometryLayout.XYM && this.layout != ol.geom.GeometryLayout.XYZM) || this.flatCoordinates.length === 0) { @@ -89247,7 +71788,7 @@ ol.geom.MultiLineString.prototype.getFlatMidpoints = function() { var end = ends[i]; var midpoint = ol.geom.flat.interpolate.lineString( flatCoordinates, offset, end, stride, 0.5); - goog.array.extend(midpoints, midpoint); + ol.array.extend(midpoints, midpoint); offset = end; } return midpoints; @@ -89257,8 +71798,7 @@ ol.geom.MultiLineString.prototype.getFlatMidpoints = function() { /** * @inheritDoc */ -ol.geom.MultiLineString.prototype.getSimplifiedGeometryInternal = - function(squaredTolerance) { +ol.geom.MultiLineString.prototype.getSimplifiedGeometryInternal = function(squaredTolerance) { var simplifiedFlatCoordinates = []; var simplifiedEnds = []; simplifiedFlatCoordinates.length = ol.geom.flat.simplify.douglasPeuckers( @@ -89296,8 +71836,7 @@ ol.geom.MultiLineString.prototype.intersectsExtent = function(extent) { * @param {ol.geom.GeometryLayout=} opt_layout Layout. * @api stable */ -ol.geom.MultiLineString.prototype.setCoordinates = - function(coordinates, opt_layout) { +ol.geom.MultiLineString.prototype.setCoordinates = function(coordinates, opt_layout) { if (!coordinates) { this.setFlatCoordinates(ol.geom.GeometryLayout.XY, null, this.ends_); } else { @@ -89318,8 +71857,7 @@ ol.geom.MultiLineString.prototype.setCoordinates = * @param {Array.<number>} flatCoordinates Flat coordinates. * @param {Array.<number>} ends Ends. */ -ol.geom.MultiLineString.prototype.setFlatCoordinates = - function(layout, flatCoordinates, ends) { +ol.geom.MultiLineString.prototype.setFlatCoordinates = function(layout, flatCoordinates, ends) { if (!flatCoordinates) { goog.asserts.assert(ends && ends.length === 0, 'ends must be truthy and ends.length should be 0'); @@ -89353,7 +71891,7 @@ ol.geom.MultiLineString.prototype.setLineStrings = function(lineStrings) { goog.asserts.assert(lineString.getLayout() == layout, 'layout of lineString should match layout'); } - goog.array.extend(flatCoordinates, lineString.getFlatCoordinates()); + ol.array.extend(flatCoordinates, lineString.getFlatCoordinates()); ends.push(flatCoordinates.length); } this.setFlatCoordinates(layout, flatCoordinates, ends); @@ -89361,8 +71899,8 @@ ol.geom.MultiLineString.prototype.setLineStrings = function(lineStrings) { goog.provide('ol.geom.MultiPoint'); -goog.require('goog.array'); goog.require('goog.asserts'); +goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.geom.GeometryLayout'); goog.require('ol.geom.GeometryType'); @@ -89373,7 +71911,6 @@ goog.require('ol.geom.flat.inflate'); goog.require('ol.math'); - /** * @classdesc * Multi-point geometry. @@ -89402,7 +71939,7 @@ ol.geom.MultiPoint.prototype.appendPoint = function(point) { if (!this.flatCoordinates) { this.flatCoordinates = point.getFlatCoordinates().slice(); } else { - goog.array.extend(this.flatCoordinates, point.getFlatCoordinates()); + ol.array.extend(this.flatCoordinates, point.getFlatCoordinates()); } this.changed(); }; @@ -89423,8 +71960,7 @@ ol.geom.MultiPoint.prototype.clone = function() { /** * @inheritDoc */ -ol.geom.MultiPoint.prototype.closestPointXY = - function(x, y, closestPoint, minSquaredDistance) { +ol.geom.MultiPoint.prototype.closestPointXY = function(x, y, closestPoint, minSquaredDistance) { if (minSquaredDistance < ol.extent.closestSquaredDistanceXY(this.getExtent(), x, y)) { return minSquaredDistance; @@ -89534,8 +72070,7 @@ ol.geom.MultiPoint.prototype.intersectsExtent = function(extent) { * @param {ol.geom.GeometryLayout=} opt_layout Layout. * @api stable */ -ol.geom.MultiPoint.prototype.setCoordinates = - function(coordinates, opt_layout) { +ol.geom.MultiPoint.prototype.setCoordinates = function(coordinates, opt_layout) { if (!coordinates) { this.setFlatCoordinates(ol.geom.GeometryLayout.XY, null); } else { @@ -89554,8 +72089,7 @@ ol.geom.MultiPoint.prototype.setCoordinates = * @param {ol.geom.GeometryLayout} layout Layout. * @param {Array.<number>} flatCoordinates Flat coordinates. */ -ol.geom.MultiPoint.prototype.setFlatCoordinates = - function(layout, flatCoordinates) { +ol.geom.MultiPoint.prototype.setFlatCoordinates = function(layout, flatCoordinates) { this.setFlatCoordinatesInternal(layout, flatCoordinates); this.changed(); }; @@ -89572,8 +72106,7 @@ goog.require('ol.extent'); * @param {number} stride Stride. * @return {Array.<number>} Flat centers. */ -ol.geom.flat.center.linearRingss = - function(flatCoordinates, offset, endss, stride) { +ol.geom.flat.center.linearRingss = function(flatCoordinates, offset, endss, stride) { var flatCenters = []; var i, ii; var extent = ol.extent.createEmpty(); @@ -89589,10 +72122,9 @@ ol.geom.flat.center.linearRingss = goog.provide('ol.geom.MultiPolygon'); -goog.require('goog.array'); goog.require('goog.asserts'); -goog.require('goog.object'); goog.require('ol'); +goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.geom.GeometryLayout'); goog.require('ol.geom.GeometryType'); @@ -89611,7 +72143,6 @@ goog.require('ol.geom.flat.orient'); goog.require('ol.geom.flat.simplify'); - /** * @classdesc * Multi-polygon geometry. @@ -89690,7 +72221,7 @@ ol.geom.MultiPolygon.prototype.appendPolygon = function(polygon) { this.endss_.push(); } else { var offset = this.flatCoordinates.length; - goog.array.extend(this.flatCoordinates, polygon.getFlatCoordinates()); + ol.array.extend(this.flatCoordinates, polygon.getFlatCoordinates()); ends = polygon.getEnds().slice(); var i, ii; for (i = 0, ii = ends.length; i < ii; ++i) { @@ -89709,8 +72240,13 @@ ol.geom.MultiPolygon.prototype.appendPolygon = function(polygon) { */ ol.geom.MultiPolygon.prototype.clone = function() { var multiPolygon = new ol.geom.MultiPolygon(null); - var newEndss = /** @type {Array.<Array.<number>>} */ - (goog.object.unsafeClone(this.endss_)); + + var len = this.endss_.length; + var newEndss = new Array(len); + for (var i = 0; i < len; ++i) { + newEndss[i] = this.endss_[i].slice(); + } + multiPolygon.setFlatCoordinates( this.layout, this.flatCoordinates.slice(), newEndss); return multiPolygon; @@ -89720,8 +72256,7 @@ ol.geom.MultiPolygon.prototype.clone = function() { /** * @inheritDoc */ -ol.geom.MultiPolygon.prototype.closestPointXY = - function(x, y, closestPoint, minSquaredDistance) { +ol.geom.MultiPolygon.prototype.closestPointXY = function(x, y, closestPoint, minSquaredDistance) { if (minSquaredDistance < ol.extent.closestSquaredDistanceXY(this.getExtent(), x, y)) { return minSquaredDistance; @@ -89846,8 +72381,7 @@ ol.geom.MultiPolygon.prototype.getOrientedFlatCoordinates = function() { /** * @inheritDoc */ -ol.geom.MultiPolygon.prototype.getSimplifiedGeometryInternal = - function(squaredTolerance) { +ol.geom.MultiPolygon.prototype.getSimplifiedGeometryInternal = function(squaredTolerance) { var simplifiedFlatCoordinates = []; var simplifiedEndss = []; simplifiedFlatCoordinates.length = ol.geom.flat.simplify.quantizess( @@ -89950,8 +72484,7 @@ ol.geom.MultiPolygon.prototype.intersectsExtent = function(extent) { * @param {ol.geom.GeometryLayout=} opt_layout Layout. * @api stable */ -ol.geom.MultiPolygon.prototype.setCoordinates = - function(coordinates, opt_layout) { +ol.geom.MultiPolygon.prototype.setCoordinates = function(coordinates, opt_layout) { if (!coordinates) { this.setFlatCoordinates(ol.geom.GeometryLayout.XY, null, this.endss_); } else { @@ -89978,8 +72511,7 @@ ol.geom.MultiPolygon.prototype.setCoordinates = * @param {Array.<number>} flatCoordinates Flat coordinates. * @param {Array.<Array.<number>>} endss Endss. */ -ol.geom.MultiPolygon.prototype.setFlatCoordinates = - function(layout, flatCoordinates, endss) { +ol.geom.MultiPolygon.prototype.setFlatCoordinates = function(layout, flatCoordinates, endss) { goog.asserts.assert(endss, 'endss must be truthy'); if (!flatCoordinates || flatCoordinates.length === 0) { goog.asserts.assert(endss.length === 0, 'the length of endss should be 0'); @@ -90018,7 +72550,7 @@ ol.geom.MultiPolygon.prototype.setPolygons = function(polygons) { for (j = 0, jj = ends.length; j < jj; ++j) { ends[j] += offset; } - goog.array.extend(flatCoordinates, polygon.getFlatCoordinates()); + ol.array.extend(flatCoordinates, polygon.getFlatCoordinates()); endss.push(ends); } this.setFlatCoordinates(layout, flatCoordinates, endss); @@ -90026,10 +72558,9 @@ ol.geom.MultiPolygon.prototype.setPolygons = function(polygons) { goog.provide('ol.format.EsriJSON'); -goog.require('goog.array'); goog.require('goog.asserts'); -goog.require('goog.object'); goog.require('ol.Feature'); +goog.require('ol.array'); goog.require('ol.extent'); goog.require('ol.format.Feature'); goog.require('ol.format.JSONFeature'); @@ -90043,10 +72574,10 @@ goog.require('ol.geom.MultiPolygon'); goog.require('ol.geom.Point'); goog.require('ol.geom.Polygon'); goog.require('ol.geom.flat.orient'); +goog.require('ol.object'); goog.require('ol.proj'); - /** * @classdesc * Feature format for reading and writing data in the EsriJSON format. @@ -90097,7 +72628,7 @@ ol.format.EsriJSON.readGeometry_ = function(object, opt_options) { } else if (object.rings) { var layout = ol.format.EsriJSON.getGeometryLayout_(object); var rings = ol.format.EsriJSON.convertRings_(object.rings, layout); - object = /** @type {EsriJSONGeometry} */(goog.object.clone(object)); + object = /** @type {EsriJSONGeometry} */(ol.object.assign({}, object)); if (rings.length === 1) { type = ol.geom.GeometryType.POLYGON; object.rings = rings[0]; @@ -90131,7 +72662,7 @@ ol.format.EsriJSON.convertRings_ = function(rings, layout) { var holes = []; var i, ii; for (i = 0, ii = rings.length; i < ii; ++i) { - var flatRing = goog.array.flatten(rings[i]); + var flatRing = ol.array.flatten(rings[i]); // is this ring an outer ring? is it clockwise? var clockwise = ol.geom.flat.orient.linearRingIsClockwise(flatRing, 0, flatRing.length, layout.length); @@ -90197,7 +72728,7 @@ ol.format.EsriJSON.readPointGeometry_ = function(object) { * @return {ol.geom.Geometry} LineString. */ ol.format.EsriJSON.readLineStringGeometry_ = function(object) { - goog.asserts.assert(goog.isArray(object.paths), + goog.asserts.assert(Array.isArray(object.paths), 'object.paths should be an array'); goog.asserts.assert(object.paths.length === 1, 'object.paths array length should be 1'); @@ -90212,7 +72743,7 @@ ol.format.EsriJSON.readLineStringGeometry_ = function(object) { * @return {ol.geom.Geometry} MultiLineString. */ ol.format.EsriJSON.readMultiLineStringGeometry_ = function(object) { - goog.asserts.assert(goog.isArray(object.paths), + goog.asserts.assert(Array.isArray(object.paths), 'object.paths should be an array'); goog.asserts.assert(object.paths.length > 1, 'object.paths array length should be more than 1'); @@ -90379,8 +72910,7 @@ ol.format.EsriJSON.writePolygonGeometry_ = function(geometry, opt_options) { * @private * @return {EsriJSONPolyline} EsriJSON geometry. */ -ol.format.EsriJSON.writeMultiLineStringGeometry_ = - function(geometry, opt_options) { +ol.format.EsriJSON.writeMultiLineStringGeometry_ = function(geometry, opt_options) { goog.asserts.assertInstanceof(geometry, ol.geom.MultiLineString, 'geometry should be an ol.geom.MultiLineString'); var hasZM = ol.format.EsriJSON.getHasZM_(geometry); @@ -90679,7 +73209,7 @@ ol.format.EsriJSON.prototype.writeFeatureObject = function( } var properties = feature.getProperties(); delete properties[feature.getGeometryName()]; - if (!goog.object.isEmpty(properties)) { + if (!ol.object.isEmpty(properties)) { object['attributes'] = properties; } else { object['attributes'] = {}; @@ -90714,8 +73244,7 @@ ol.format.EsriJSON.prototype.writeFeatures; * @return {Object} EsriJSON Object. * @api */ -ol.format.EsriJSON.prototype.writeFeaturesObject = - function(features, opt_options) { +ol.format.EsriJSON.prototype.writeFeaturesObject = function(features, opt_options) { opt_options = this.adaptOptions(opt_options); var objects = []; var i, ii; @@ -90729,13 +73258,12 @@ ol.format.EsriJSON.prototype.writeFeaturesObject = goog.provide('ol.geom.GeometryCollection'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.object'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol.extent'); goog.require('ol.geom.Geometry'); goog.require('ol.geom.GeometryType'); - +goog.require('ol.object'); /** @@ -90786,9 +73314,9 @@ ol.geom.GeometryCollection.prototype.unlistenGeometriesChange_ = function() { return; } for (i = 0, ii = this.geometries_.length; i < ii; ++i) { - goog.events.unlisten( - this.geometries_[i], goog.events.EventType.CHANGE, - this.changed, false, this); + ol.events.unlisten( + this.geometries_[i], ol.events.EventType.CHANGE, + this.changed, this); } }; @@ -90802,9 +73330,9 @@ ol.geom.GeometryCollection.prototype.listenGeometriesChange_ = function() { return; } for (i = 0, ii = this.geometries_.length; i < ii; ++i) { - goog.events.listen( - this.geometries_[i], goog.events.EventType.CHANGE, - this.changed, false, this); + ol.events.listen( + this.geometries_[i], ol.events.EventType.CHANGE, + this.changed, this); } }; @@ -90824,8 +73352,7 @@ ol.geom.GeometryCollection.prototype.clone = function() { /** * @inheritDoc */ -ol.geom.GeometryCollection.prototype.closestPointXY = - function(x, y, closestPoint, minSquaredDistance) { +ol.geom.GeometryCollection.prototype.closestPointXY = function(x, y, closestPoint, minSquaredDistance) { if (minSquaredDistance < ol.extent.closestSquaredDistanceXY(this.getExtent(), x, y)) { return minSquaredDistance; @@ -90889,10 +73416,9 @@ ol.geom.GeometryCollection.prototype.getGeometriesArray = function() { /** * @inheritDoc */ -ol.geom.GeometryCollection.prototype.getSimplifiedGeometry = - function(squaredTolerance) { +ol.geom.GeometryCollection.prototype.getSimplifiedGeometry = function(squaredTolerance) { if (this.simplifiedGeometryRevision != this.getRevision()) { - goog.object.clear(this.simplifiedGeometryCache); + ol.object.clear(this.simplifiedGeometryCache); this.simplifiedGeometryMaxMinSquaredTolerance = 0; this.simplifiedGeometryRevision = this.getRevision(); } @@ -90964,6 +73490,19 @@ ol.geom.GeometryCollection.prototype.isEmpty = function() { /** + * @inheritDoc + * @api + */ +ol.geom.GeometryCollection.prototype.rotate = function(angle, anchor) { + var geometries = this.geometries_; + for (var i = 0, ii = geometries.length; i < ii; ++i) { + geometries[i].rotate(angle, anchor); + } + this.changed(); +}; + + +/** * Set the geometries that make up this geometry collection. * @param {Array.<ol.geom.Geometry>} geometries Geometries. * @api stable @@ -91029,7 +73568,6 @@ ol.geom.GeometryCollection.prototype.disposeInternal = function() { goog.provide('ol.format.GeoJSON'); goog.require('goog.asserts'); -goog.require('goog.object'); goog.require('ol.Feature'); goog.require('ol.format.Feature'); goog.require('ol.format.JSONFeature'); @@ -91040,10 +73578,10 @@ goog.require('ol.geom.MultiPoint'); goog.require('ol.geom.MultiPolygon'); goog.require('ol.geom.Point'); goog.require('ol.geom.Polygon'); +goog.require('ol.object'); goog.require('ol.proj'); - /** * @classdesc * Feature format for reading and writing data in the GeoJSON format. @@ -91237,7 +73775,9 @@ ol.format.GeoJSON.writeGeometryCollectionGeometry_ = function( goog.asserts.assertInstanceof(geometry, ol.geom.GeometryCollection, 'geometry should be an ol.geom.GeometryCollection'); var geometries = geometry.getGeometriesArray().map(function(geometry) { - return ol.format.GeoJSON.writeGeometry_(geometry, opt_options); + var options = ol.object.assign({}, opt_options); + delete options.featureProjection; + return ol.format.GeoJSON.writeGeometry_(geometry, options); }); return /** @type {GeoJSONGeometryCollection} */ ({ type: 'GeometryCollection', @@ -91268,8 +73808,7 @@ ol.format.GeoJSON.writeLineStringGeometry_ = function(geometry, opt_options) { * @private * @return {GeoJSONGeometry} GeoJSON geometry. */ -ol.format.GeoJSON.writeMultiLineStringGeometry_ = - function(geometry, opt_options) { +ol.format.GeoJSON.writeMultiLineStringGeometry_ = function(geometry, opt_options) { goog.asserts.assertInstanceof(geometry, ol.geom.MultiLineString, 'geometry should be an ol.geom.MultiLineString'); return /** @type {GeoJSONGeometry} */ ({ @@ -91545,32 +74084,32 @@ ol.format.GeoJSON.prototype.writeFeature; * * @param {ol.Feature} feature Feature. * @param {olx.format.WriteOptions=} opt_options Write options. - * @return {Object} Object. + * @return {GeoJSONFeature} Object. * @api stable */ -ol.format.GeoJSON.prototype.writeFeatureObject = function( - feature, opt_options) { +ol.format.GeoJSON.prototype.writeFeatureObject = function(feature, opt_options) { opt_options = this.adaptOptions(opt_options); - var object = { + + var object = /** @type {GeoJSONFeature} */ ({ 'type': 'Feature' - }; + }); var id = feature.getId(); if (id !== undefined) { - object['id'] = id; + object.id = id; } var geometry = feature.getGeometry(); if (geometry) { - object['geometry'] = + object.geometry = ol.format.GeoJSON.writeGeometry_(geometry, opt_options); } else { - object['geometry'] = null; + object.geometry = null; } var properties = feature.getProperties(); delete properties[feature.getGeometryName()]; - if (!goog.object.isEmpty(properties)) { - object['properties'] = properties; + if (!ol.object.isEmpty(properties)) { + object.properties = properties; } else { - object['properties'] = null; + object.properties = null; } return object; }; @@ -91593,11 +74132,10 @@ ol.format.GeoJSON.prototype.writeFeatures; * * @param {Array.<ol.Feature>} features Features. * @param {olx.format.WriteOptions=} opt_options Write options. - * @return {Object} GeoJSON Object. + * @return {GeoJSONFeatureCollection} GeoJSON Object. * @api stable */ -ol.format.GeoJSON.prototype.writeFeaturesObject = - function(features, opt_options) { +ol.format.GeoJSON.prototype.writeFeaturesObject = function(features, opt_options) { opt_options = this.adaptOptions(opt_options); var objects = []; var i, ii; @@ -91639,17 +74177,15 @@ ol.format.GeoJSON.prototype.writeGeometryObject = function(geometry, goog.provide('ol.format.XMLFeature'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom.NodeType'); -goog.require('goog.dom.xml'); +goog.require('ol.array'); goog.require('ol.format.Feature'); goog.require('ol.format.FormatType'); goog.require('ol.proj'); goog.require('ol.xml'); - /** * @classdesc * Abstract base class; normally only used for creating subclasses and not @@ -91660,6 +74196,13 @@ goog.require('ol.xml'); * @extends {ol.format.Feature} */ ol.format.XMLFeature = function() { + + /** + * @type {XMLSerializer} + * @private + */ + this.xmlSerializer_ = new XMLSerializer(); + goog.base(this); }; goog.inherits(ol.format.XMLFeature, ol.format.Feature); @@ -91682,7 +74225,7 @@ ol.format.XMLFeature.prototype.readFeature = function(source, opt_options) { /** @type {Document} */ (source), opt_options); } else if (ol.xml.isNode(source)) { return this.readFeatureFromNode(/** @type {Node} */ (source), opt_options); - } else if (goog.isString(source)) { + } else if (typeof source === 'string') { var doc = ol.xml.parse(source); return this.readFeatureFromDocument(doc, opt_options); } else { @@ -91725,7 +74268,7 @@ ol.format.XMLFeature.prototype.readFeatures = function(source, opt_options) { /** @type {Document} */ (source), opt_options); } else if (ol.xml.isNode(source)) { return this.readFeaturesFromNode(/** @type {Node} */ (source), opt_options); - } else if (goog.isString(source)) { + } else if (typeof source === 'string') { var doc = ol.xml.parse(source); return this.readFeaturesFromDocument(doc, opt_options); } else { @@ -91748,7 +74291,7 @@ ol.format.XMLFeature.prototype.readFeaturesFromDocument = function( var n; for (n = doc.firstChild; n; n = n.nextSibling) { if (n.nodeType == goog.dom.NodeType.ELEMENT) { - goog.array.extend(features, this.readFeaturesFromNode(n, opt_options)); + ol.array.extend(features, this.readFeaturesFromNode(n, opt_options)); } } return features; @@ -91773,7 +74316,7 @@ ol.format.XMLFeature.prototype.readGeometry = function(source, opt_options) { /** @type {Document} */ (source), opt_options); } else if (ol.xml.isNode(source)) { return this.readGeometryFromNode(/** @type {Node} */ (source), opt_options); - } else if (goog.isString(source)) { + } else if (typeof source === 'string') { var doc = ol.xml.parse(source); return this.readGeometryFromDocument(doc, opt_options); } else { @@ -91809,7 +74352,7 @@ ol.format.XMLFeature.prototype.readProjection = function(source) { return this.readProjectionFromDocument(/** @type {Document} */ (source)); } else if (ol.xml.isNode(source)) { return this.readProjectionFromNode(/** @type {Node} */ (source)); - } else if (goog.isString(source)) { + } else if (typeof source === 'string') { var doc = ol.xml.parse(source); return this.readProjectionFromDocument(doc); } else { @@ -91846,7 +74389,7 @@ ol.format.XMLFeature.prototype.writeFeature = function(feature, opt_options) { var node = this.writeFeatureNode(feature, opt_options); goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); - return goog.dom.xml.serialize(/** @type {Element} */(node)); + return this.xmlSerializer_.serializeToString(node); }; @@ -91866,7 +74409,7 @@ ol.format.XMLFeature.prototype.writeFeatures = function(features, opt_options) { var node = this.writeFeaturesNode(features, opt_options); goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); - return goog.dom.xml.serialize(/** @type {Element} */(node)); + return this.xmlSerializer_.serializeToString(node); }; @@ -91885,7 +74428,7 @@ ol.format.XMLFeature.prototype.writeGeometry = function(geometry, opt_options) { var node = this.writeGeometryNode(geometry, opt_options); goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); - return goog.dom.xml.serialize(/** @type {Element} */(node)); + return this.xmlSerializer_.serializeToString(node); }; @@ -91901,11 +74444,9 @@ ol.format.XMLFeature.prototype.writeGeometryNode = goog.abstractMethod; // envelopes/extents, only geometries! goog.provide('ol.format.GMLBase'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom.NodeType'); -goog.require('goog.object'); -goog.require('goog.string'); +goog.require('ol.array'); goog.require('ol.Feature'); goog.require('ol.format.Feature'); goog.require('ol.format.XMLFeature'); @@ -91918,11 +74459,11 @@ goog.require('ol.geom.MultiPoint'); goog.require('ol.geom.MultiPolygon'); goog.require('ol.geom.Point'); goog.require('ol.geom.Polygon'); +goog.require('ol.object'); goog.require('ol.proj'); goog.require('ol.xml'); - /** * @classdesc * Abstract base class; normally only used for creating subclasses and not @@ -91989,15 +74530,30 @@ ol.format.GMLBase.GMLNS = 'http://www.opengis.net/gml'; /** + * A regular expression that matches if a string only contains whitespace + * characters. It will e.g. match `''`, `' '`, `'\n'` etc. The non-breaking + * space (0xa0) is explicitly included as IE doesn't include it in its + * definition of `\s`. + * + * Information from `goog.string.isEmptyOrWhitespace`: https://github.com/google/closure-library/blob/e877b1e/closure/goog/string/string.js#L156-L160 + * + * @const + * @type {RegExp} + * @private + */ +ol.format.GMLBase.ONLY_WHITESPACE_RE_ = /^[\s\xa0]*$/; + + +/** * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. - * @return {Array.<ol.Feature>} Features. + * @return {Array.<ol.Feature> | undefined} Features. */ ol.format.GMLBase.prototype.readFeaturesInternal = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); - var localName = ol.xml.getLocalName(node); - var features; + var localName = node.localName; + var features = null; if (localName == 'FeatureCollection') { if (node.namespaceURI === 'http://www.opengis.net/wfs') { features = ol.xml.pushParseAndPop([], @@ -92021,29 +74577,37 @@ ol.format.GMLBase.prototype.readFeaturesInternal = function(node, objectStack) { if (child.nodeType === 1) { var ft = child.nodeName.split(':').pop(); if (featureType.indexOf(ft) === -1) { - var key; - if (!goog.object.contains(featureNS, child.namespaceURI)) { - key = prefix + goog.object.getCount(featureNS); - featureNS[key] = child.namespaceURI; - } else { - key = goog.object.findKey(featureNS, function(value) { - return value === child.namespaceURI; - }); + var key = ''; + var count = 0; + var uri = child.namespaceURI; + for (var candidate in featureNS) { + if (featureNS[candidate] === uri) { + key = candidate; + break; + } + ++count; + } + if (!key) { + key = prefix + count; + featureNS[key] = uri; } featureType.push(key + ':' + ft); } } } - context['featureType'] = featureType; - context['featureNS'] = featureNS; + if (localName != 'featureMember') { + // recheck featureType for each featureMember + context['featureType'] = featureType; + context['featureNS'] = featureNS; + } } - if (goog.isString(featureNS)) { + if (typeof featureNS === 'string') { var ns = featureNS; featureNS = {}; featureNS[defaultPrefix] = ns; } var parsersNS = {}; - var featureTypes = goog.isArray(featureType) ? featureType : [featureType]; + var featureTypes = Array.isArray(featureType) ? featureType : [featureType]; for (var p in featureNS) { var parsers = {}; for (i = 0, ii = featureTypes.length; i < ii; ++i) { @@ -92058,9 +74622,13 @@ ol.format.GMLBase.prototype.readFeaturesInternal = function(node, objectStack) { } parsersNS[featureNS[p]] = parsers; } - features = ol.xml.pushParseAndPop([], parsersNS, node, objectStack); + if (localName == 'featureMember') { + features = ol.xml.pushParseAndPop(undefined, parsersNS, node, objectStack); + } else { + features = ol.xml.pushParseAndPop([], parsersNS, node, objectStack); + } } - if (!features) { + if (features === null) { features = []; } return features; @@ -92076,7 +74644,8 @@ ol.format.GMLBase.prototype.readGeometryElement = function(node, objectStack) { var context = objectStack[0]; goog.asserts.assert(goog.isObject(context), 'context should be an Object'); context['srsName'] = node.firstElementChild.getAttribute('srsName'); - var geometry = ol.xml.pushParseAndPop(/** @type {ol.geom.Geometry} */(null), + /** @type {ol.geom.Geometry} */ + var geometry = ol.xml.pushParseAndPop(null, this.GEOMETRY_PARSERS_, node, objectStack, this); if (geometry) { return /** @type {ol.geom.Geometry} */ ( @@ -92098,7 +74667,7 @@ ol.format.GMLBase.prototype.readFeatureElement = function(node, objectStack) { ol.xml.getAttributeNS(node, ol.format.GMLBase.GMLNS, 'id'); var values = {}, geometryName; for (n = node.firstElementChild; n; n = n.nextElementSibling) { - var localName = ol.xml.getLocalName(n); + var localName = n.localName; // Assume attribute elements have one child node and that the child // is a text or CDATA node (to be treated as text). // Otherwise assume it is a geometry node. @@ -92106,7 +74675,7 @@ ol.format.GMLBase.prototype.readFeatureElement = function(node, objectStack) { (n.childNodes.length === 1 && (n.firstChild.nodeType === 3 || n.firstChild.nodeType === 4))) { var value = ol.xml.getAllTextContent(n, false); - if (goog.string.isEmpty(value)) { + if (ol.format.GMLBase.ONLY_WHITESPACE_RE_.test(value)) { value = undefined; } values[localName] = value; @@ -92160,8 +74729,8 @@ ol.format.GMLBase.prototype.readMultiPoint = function(node, objectStack) { 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'MultiPoint', 'localName should be MultiPoint'); - var coordinates = ol.xml.pushParseAndPop( - /** @type {Array.<Array.<number>>} */ ([]), + /** @type {Array.<Array.<number>>} */ + var coordinates = ol.xml.pushParseAndPop([], this.MULTIPOINT_PARSERS_, node, objectStack, this); if (coordinates) { return new ol.geom.MultiPoint(coordinates); @@ -92181,8 +74750,8 @@ ol.format.GMLBase.prototype.readMultiLineString = function(node, objectStack) { 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'MultiLineString', 'localName should be MultiLineString'); - var lineStrings = ol.xml.pushParseAndPop( - /** @type {Array.<ol.geom.LineString>} */ ([]), + /** @type {Array.<ol.geom.LineString>} */ + var lineStrings = ol.xml.pushParseAndPop([], this.MULTILINESTRING_PARSERS_, node, objectStack, this); if (lineStrings) { var multiLineString = new ol.geom.MultiLineString(null); @@ -92204,8 +74773,8 @@ ol.format.GMLBase.prototype.readMultiPolygon = function(node, objectStack) { 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'MultiPolygon', 'localName should be MultiPolygon'); - var polygons = ol.xml.pushParseAndPop( - /** @type {Array.<ol.geom.Polygon>} */ ([]), + /** @type {Array.<ol.geom.Polygon>} */ + var polygons = ol.xml.pushParseAndPop([], this.MULTIPOLYGON_PARSERS_, node, objectStack, this); if (polygons) { var multiPolygon = new ol.geom.MultiPolygon(null); @@ -92238,8 +74807,7 @@ ol.format.GMLBase.prototype.pointMemberParser_ = function(node, objectStack) { * @param {Array.<*>} objectStack Object stack. * @private */ -ol.format.GMLBase.prototype.lineStringMemberParser_ = - function(node, objectStack) { +ol.format.GMLBase.prototype.lineStringMemberParser_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'lineStringMember' || @@ -92255,8 +74823,7 @@ ol.format.GMLBase.prototype.lineStringMemberParser_ = * @param {Array.<*>} objectStack Object stack. * @private */ -ol.format.GMLBase.prototype.polygonMemberParser_ = - function(node, objectStack) { +ol.format.GMLBase.prototype.polygonMemberParser_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'polygonMember' || @@ -92300,7 +74867,7 @@ ol.format.GMLBase.prototype.readFlatLinearRing_ = function(node, objectStack) { 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'LinearRing', 'localName should be LinearRing'); - var ring = ol.xml.pushParseAndPop(/** @type {Array.<number>} */(null), + var ring = ol.xml.pushParseAndPop(null, this.GEOMETRY_FLAT_COORDINATES_PARSERS_, node, objectStack, this); if (ring) { @@ -92343,8 +74910,8 @@ ol.format.GMLBase.prototype.readPolygon = function(node, objectStack) { 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'Polygon', 'localName should be Polygon'); - var flatLinearRings = ol.xml.pushParseAndPop( - /** @type {Array.<Array.<number>>} */ ([null]), + /** @type {Array.<Array.<number>>} */ + var flatLinearRings = ol.xml.pushParseAndPop([null], this.FLAT_LINEAR_RINGS_PARSERS_, node, objectStack, this); if (flatLinearRings && flatLinearRings[0]) { var polygon = new ol.geom.Polygon(null); @@ -92352,7 +74919,7 @@ ol.format.GMLBase.prototype.readPolygon = function(node, objectStack) { var ends = [flatCoordinates.length]; var i, ii; for (i = 1, ii = flatLinearRings.length; i < ii; ++i) { - goog.array.extend(flatCoordinates, flatLinearRings[i]); + ol.array.extend(flatCoordinates, flatLinearRings[i]); ends.push(flatCoordinates.length); } polygon.setFlatCoordinates( @@ -92370,119 +74937,116 @@ ol.format.GMLBase.prototype.readPolygon = function(node, objectStack) { * @private * @return {Array.<number>} Flat coordinates. */ -ol.format.GMLBase.prototype.readFlatCoordinatesFromNode_ = - function(node, objectStack) { +ol.format.GMLBase.prototype.readFlatCoordinatesFromNode_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); - return /** @type {Array.<number>} */ (ol.xml.pushParseAndPop( - null, + return ol.xml.pushParseAndPop(null, this.GEOMETRY_FLAT_COORDINATES_PARSERS_, node, - objectStack, this)); + objectStack, this); }; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GMLBase.prototype.MULTIPOINT_PARSERS_ = Object({ +ol.format.GMLBase.prototype.MULTIPOINT_PARSERS_ = { 'http://www.opengis.net/gml' : { 'pointMember': ol.xml.makeArrayPusher( ol.format.GMLBase.prototype.pointMemberParser_), 'pointMembers': ol.xml.makeArrayPusher( ol.format.GMLBase.prototype.pointMemberParser_) } -}); +}; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GMLBase.prototype.MULTILINESTRING_PARSERS_ = Object({ +ol.format.GMLBase.prototype.MULTILINESTRING_PARSERS_ = { 'http://www.opengis.net/gml' : { 'lineStringMember': ol.xml.makeArrayPusher( ol.format.GMLBase.prototype.lineStringMemberParser_), 'lineStringMembers': ol.xml.makeArrayPusher( ol.format.GMLBase.prototype.lineStringMemberParser_) } -}); +}; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GMLBase.prototype.MULTIPOLYGON_PARSERS_ = Object({ +ol.format.GMLBase.prototype.MULTIPOLYGON_PARSERS_ = { 'http://www.opengis.net/gml' : { 'polygonMember': ol.xml.makeArrayPusher( ol.format.GMLBase.prototype.polygonMemberParser_), 'polygonMembers': ol.xml.makeArrayPusher( ol.format.GMLBase.prototype.polygonMemberParser_) } -}); +}; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GMLBase.prototype.POINTMEMBER_PARSERS_ = Object({ +ol.format.GMLBase.prototype.POINTMEMBER_PARSERS_ = { 'http://www.opengis.net/gml' : { 'Point': ol.xml.makeArrayPusher( ol.format.GMLBase.prototype.readFlatCoordinatesFromNode_) } -}); +}; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GMLBase.prototype.LINESTRINGMEMBER_PARSERS_ = Object({ +ol.format.GMLBase.prototype.LINESTRINGMEMBER_PARSERS_ = { 'http://www.opengis.net/gml' : { 'LineString': ol.xml.makeArrayPusher( ol.format.GMLBase.prototype.readLineString) } -}); +}; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GMLBase.prototype.POLYGONMEMBER_PARSERS_ = Object({ +ol.format.GMLBase.prototype.POLYGONMEMBER_PARSERS_ = { 'http://www.opengis.net/gml' : { 'Polygon': ol.xml.makeArrayPusher( ol.format.GMLBase.prototype.readPolygon) } -}); +}; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @protected */ -ol.format.GMLBase.prototype.RING_PARSERS = Object({ +ol.format.GMLBase.prototype.RING_PARSERS = { 'http://www.opengis.net/gml' : { 'LinearRing': ol.xml.makeReplacer( ol.format.GMLBase.prototype.readFlatLinearRing_) } -}); +}; /** * @inheritDoc */ -ol.format.GMLBase.prototype.readGeometryFromNode = - function(node, opt_options) { +ol.format.GMLBase.prototype.readGeometryFromNode = function(node, opt_options) { var geometry = this.readGeometryElement(node, [this.getReadOptions(node, opt_options ? opt_options : {})]); return geometry ? geometry : null; @@ -92504,16 +75068,16 @@ ol.format.GMLBase.prototype.readFeatures; /** * @inheritDoc */ -ol.format.GMLBase.prototype.readFeaturesFromNode = - function(node, opt_options) { +ol.format.GMLBase.prototype.readFeaturesFromNode = function(node, opt_options) { var options = { featureType: this.featureType, featureNS: this.featureNS }; if (opt_options) { - goog.object.extend(options, this.getReadOptions(node, opt_options)); + ol.object.assign(options, this.getReadOptions(node, opt_options)); } - return this.readFeaturesInternal(node, [options]); + var features = this.readFeaturesInternal(node, [options]); + return features || []; }; @@ -92521,16 +75085,16 @@ ol.format.GMLBase.prototype.readFeaturesFromNode = * @inheritDoc */ ol.format.GMLBase.prototype.readProjectionFromNode = function(node) { - return ol.proj.get(this.srsName_ ? this.srsName_ : + return ol.proj.get(this.srsName ? this.srsName : node.firstElementChild.getAttribute('srsName')); }; goog.provide('ol.format.XSD'); goog.require('goog.asserts'); -goog.require('goog.string'); goog.require('ol'); goog.require('ol.xml'); +goog.require('ol.string'); /** @@ -92669,11 +75233,11 @@ ol.format.XSD.writeBooleanTextNode = function(node, bool) { ol.format.XSD.writeDateTimeTextNode = function(node, dateTime) { var date = new Date(dateTime * 1000); var string = date.getUTCFullYear() + '-' + - goog.string.padNumber(date.getUTCMonth() + 1, 2) + '-' + - goog.string.padNumber(date.getUTCDate(), 2) + 'T' + - goog.string.padNumber(date.getUTCHours(), 2) + ':' + - goog.string.padNumber(date.getUTCMinutes(), 2) + ':' + - goog.string.padNumber(date.getUTCSeconds(), 2) + 'Z'; + ol.string.padNumber(date.getUTCMonth() + 1, 2) + '-' + + ol.string.padNumber(date.getUTCDate(), 2) + 'T' + + ol.string.padNumber(date.getUTCHours(), 2) + ':' + + ol.string.padNumber(date.getUTCMinutes(), 2) + ':' + + ol.string.padNumber(date.getUTCSeconds(), 2) + 'Z'; node.appendChild(ol.xml.DOCUMENT.createTextNode(string)); }; @@ -92692,8 +75256,7 @@ ol.format.XSD.writeDecimalTextNode = function(node, decimal) { * @param {Node} node Node to append a TextNode with the decimal to. * @param {number} nonNegativeInteger Non negative integer. */ -ol.format.XSD.writeNonNegativeIntegerTextNode = - function(node, nonNegativeInteger) { +ol.format.XSD.writeNonNegativeIntegerTextNode = function(node, nonNegativeInteger) { goog.asserts.assert(nonNegativeInteger >= 0, 'value should be more than 0'); goog.asserts.assert(nonNegativeInteger == (nonNegativeInteger | 0), 'value should be an integer value'); @@ -92721,7 +75284,6 @@ goog.require('ol.proj'); goog.require('ol.xml'); - /** * @classdesc * Feature format for reading and writing data in the GML format, @@ -92818,8 +75380,8 @@ ol.format.GML2.prototype.readBox_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'Box', 'localName should be Box'); - var flatCoordinates = ol.xml.pushParseAndPop( - /** @type {Array.<number>} */ ([null]), + /** @type {Array.<number>} */ + var flatCoordinates = ol.xml.pushParseAndPop([null], this.BOX_PARSERS_, node, objectStack, this); return ol.extent.createOrUpdate(flatCoordinates[1][0], flatCoordinates[1][1], flatCoordinates[1][3], @@ -92832,19 +75394,18 @@ ol.format.GML2.prototype.readBox_ = function(node, objectStack) { * @param {Array.<*>} objectStack Object stack. * @private */ -ol.format.GML2.prototype.innerBoundaryIsParser_ = - function(node, objectStack) { +ol.format.GML2.prototype.innerBoundaryIsParser_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'innerBoundaryIs', 'localName should be innerBoundaryIs'); - var flatLinearRing = ol.xml.pushParseAndPop( - /** @type {Array.<number>|undefined} */ (undefined), + /** @type {Array.<number>|undefined} */ + var flatLinearRing = ol.xml.pushParseAndPop(undefined, this.RING_PARSERS, node, objectStack, this); if (flatLinearRing) { var flatLinearRings = /** @type {Array.<Array.<number>>} */ (objectStack[objectStack.length - 1]); - goog.asserts.assert(goog.isArray(flatLinearRings), + goog.asserts.assert(Array.isArray(flatLinearRings), 'flatLinearRings should be an array'); goog.asserts.assert(flatLinearRings.length > 0, 'flatLinearRings should have an array length larger than 0'); @@ -92858,19 +75419,18 @@ ol.format.GML2.prototype.innerBoundaryIsParser_ = * @param {Array.<*>} objectStack Object stack. * @private */ -ol.format.GML2.prototype.outerBoundaryIsParser_ = - function(node, objectStack) { +ol.format.GML2.prototype.outerBoundaryIsParser_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'outerBoundaryIs', 'localName should be outerBoundaryIs'); - var flatLinearRing = ol.xml.pushParseAndPop( - /** @type {Array.<number>|undefined} */ (undefined), + /** @type {Array.<number>|undefined} */ + var flatLinearRing = ol.xml.pushParseAndPop(undefined, this.RING_PARSERS, node, objectStack, this); if (flatLinearRing) { var flatLinearRings = /** @type {Array.<Array.<number>>} */ (objectStack[objectStack.length - 1]); - goog.asserts.assert(goog.isArray(flatLinearRings), + goog.asserts.assert(Array.isArray(flatLinearRings), 'flatLinearRings should be an array'); goog.asserts.assert(flatLinearRings.length > 0, 'flatLinearRings should have an array length larger than 0'); @@ -92881,49 +75441,49 @@ ol.format.GML2.prototype.outerBoundaryIsParser_ = /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GML2.prototype.GEOMETRY_FLAT_COORDINATES_PARSERS_ = Object({ +ol.format.GML2.prototype.GEOMETRY_FLAT_COORDINATES_PARSERS_ = { 'http://www.opengis.net/gml' : { 'coordinates': ol.xml.makeReplacer( ol.format.GML2.prototype.readFlatCoordinates_) } -}); +}; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GML2.prototype.FLAT_LINEAR_RINGS_PARSERS_ = Object({ +ol.format.GML2.prototype.FLAT_LINEAR_RINGS_PARSERS_ = { 'http://www.opengis.net/gml' : { 'innerBoundaryIs': ol.format.GML2.prototype.innerBoundaryIsParser_, 'outerBoundaryIs': ol.format.GML2.prototype.outerBoundaryIsParser_ } -}); +}; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GML2.prototype.BOX_PARSERS_ = Object({ +ol.format.GML2.prototype.BOX_PARSERS_ = { 'http://www.opengis.net/gml' : { 'coordinates': ol.xml.makeArrayPusher( ol.format.GML2.prototype.readFlatCoordinates_) } -}); +}; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GML2.prototype.GEOMETRY_PARSERS_ = Object({ +ol.format.GML2.prototype.GEOMETRY_PARSERS_ = { 'http://www.opengis.net/gml' : { 'Point': ol.xml.makeReplacer(ol.format.GMLBase.prototype.readPoint), 'MultiPoint': ol.xml.makeReplacer( @@ -92939,16 +75499,15 @@ ol.format.GML2.prototype.GEOMETRY_PARSERS_ = Object({ ol.format.GMLBase.prototype.readMultiPolygon), 'Box': ol.xml.makeReplacer(ol.format.GML2.prototype.readBox_) } -}); +}; goog.provide('ol.format.GML'); goog.provide('ol.format.GML3'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom.NodeType'); -goog.require('goog.object'); goog.require('ol'); +goog.require('ol.array'); goog.require('ol.Feature'); goog.require('ol.extent'); goog.require('ol.format.Feature'); @@ -92962,11 +75521,11 @@ goog.require('ol.geom.MultiLineString'); goog.require('ol.geom.MultiPolygon'); goog.require('ol.geom.Point'); goog.require('ol.geom.Polygon'); +goog.require('ol.object'); goog.require('ol.proj'); goog.require('ol.xml'); - /** * @classdesc * Feature format for reading and writing data in the GML format @@ -93042,8 +75601,8 @@ ol.format.GML3.prototype.readMultiCurve_ = function(node, objectStack) { 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'MultiCurve', 'localName should be MultiCurve'); - var lineStrings = ol.xml.pushParseAndPop( - /** @type {Array.<ol.geom.LineString>} */ ([]), + /** @type {Array.<ol.geom.LineString>} */ + var lineStrings = ol.xml.pushParseAndPop([], this.MULTICURVE_PARSERS_, node, objectStack, this); if (lineStrings) { var multiLineString = new ol.geom.MultiLineString(null); @@ -93066,8 +75625,8 @@ ol.format.GML3.prototype.readMultiSurface_ = function(node, objectStack) { 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'MultiSurface', 'localName should be MultiSurface'); - var polygons = ol.xml.pushParseAndPop( - /** @type {Array.<ol.geom.Polygon>} */ ([]), + /** @type {Array.<ol.geom.Polygon>} */ + var polygons = ol.xml.pushParseAndPop([], this.MULTISURFACE_PARSERS_, node, objectStack, this); if (polygons) { var multiPolygon = new ol.geom.MultiPolygon(null); @@ -93121,8 +75680,7 @@ ol.format.GML3.prototype.readPatch_ = function(node, objectStack) { 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'patches', 'localName should be patches'); - return ol.xml.pushParseAndPop( - /** @type {Array.<Array.<number>>} */ ([null]), + return ol.xml.pushParseAndPop([null], this.PATCHES_PARSERS_, node, objectStack, this); }; @@ -93138,8 +75696,7 @@ ol.format.GML3.prototype.readSegment_ = function(node, objectStack) { 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'segments', 'localName should be segments'); - return ol.xml.pushParseAndPop( - /** @type {Array.<number>} */ ([null]), + return ol.xml.pushParseAndPop([null], this.SEGMENTS_PARSERS_, node, objectStack, this); }; @@ -93155,8 +75712,7 @@ ol.format.GML3.prototype.readPolygonPatch_ = function(node, objectStack) { 'npde.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'PolygonPatch', 'localName should be PolygonPatch'); - return ol.xml.pushParseAndPop( - /** @type {Array.<Array.<number>>} */ ([null]), + return ol.xml.pushParseAndPop([null], this.FLAT_LINEAR_RINGS_PARSERS_, node, objectStack, this); }; @@ -93167,14 +75723,12 @@ ol.format.GML3.prototype.readPolygonPatch_ = function(node, objectStack) { * @private * @return {Array.<number>|undefined} flat coordinates. */ -ol.format.GML3.prototype.readLineStringSegment_ = - function(node, objectStack) { +ol.format.GML3.prototype.readLineStringSegment_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'LineStringSegment', 'localName should be LineStringSegment'); - return ol.xml.pushParseAndPop( - /** @type {Array.<number>} */ ([null]), + return ol.xml.pushParseAndPop([null], this.GEOMETRY_FLAT_COORDINATES_PARSERS_, node, objectStack, this); }; @@ -93190,13 +75744,13 @@ ol.format.GML3.prototype.interiorParser_ = function(node, objectStack) { 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'interior', 'localName should be interior'); - var flatLinearRing = ol.xml.pushParseAndPop( - /** @type {Array.<number>|undefined} */ (undefined), + /** @type {Array.<number>|undefined} */ + var flatLinearRing = ol.xml.pushParseAndPop(undefined, this.RING_PARSERS, node, objectStack, this); if (flatLinearRing) { var flatLinearRings = /** @type {Array.<Array.<number>>} */ (objectStack[objectStack.length - 1]); - goog.asserts.assert(goog.isArray(flatLinearRings), + goog.asserts.assert(Array.isArray(flatLinearRings), 'flatLinearRings should be an array'); goog.asserts.assert(flatLinearRings.length > 0, 'flatLinearRings should have an array length of 1 or more'); @@ -93215,13 +75769,13 @@ ol.format.GML3.prototype.exteriorParser_ = function(node, objectStack) { 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'exterior', 'localName should be exterior'); - var flatLinearRing = ol.xml.pushParseAndPop( - /** @type {Array.<number>|undefined} */ (undefined), + /** @type {Array.<number>|undefined} */ + var flatLinearRing = ol.xml.pushParseAndPop(undefined, this.RING_PARSERS, node, objectStack, this); if (flatLinearRing) { var flatLinearRings = /** @type {Array.<Array.<number>>} */ (objectStack[objectStack.length - 1]); - goog.asserts.assert(goog.isArray(flatLinearRings), + goog.asserts.assert(Array.isArray(flatLinearRings), 'flatLinearRings should be an array'); goog.asserts.assert(flatLinearRings.length > 0, 'flatLinearRings should have an array length of 1 or more'); @@ -93241,8 +75795,8 @@ ol.format.GML3.prototype.readSurface_ = function(node, objectStack) { 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'Surface', 'localName should be Surface'); - var flatLinearRings = ol.xml.pushParseAndPop( - /** @type {Array.<Array.<number>>} */ ([null]), + /** @type {Array.<Array.<number>>} */ + var flatLinearRings = ol.xml.pushParseAndPop([null], this.SURFACE_PARSERS_, node, objectStack, this); if (flatLinearRings && flatLinearRings[0]) { var polygon = new ol.geom.Polygon(null); @@ -93250,7 +75804,7 @@ ol.format.GML3.prototype.readSurface_ = function(node, objectStack) { var ends = [flatCoordinates.length]; var i, ii; for (i = 1, ii = flatLinearRings.length; i < ii; ++i) { - goog.array.extend(flatCoordinates, flatLinearRings[i]); + ol.array.extend(flatCoordinates, flatLinearRings[i]); ends.push(flatCoordinates.length); } polygon.setFlatCoordinates( @@ -93272,8 +75826,8 @@ ol.format.GML3.prototype.readCurve_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'Curve', 'localName should be Curve'); - var flatCoordinates = ol.xml.pushParseAndPop( - /** @type {Array.<number>} */ ([null]), + /** @type {Array.<number>} */ + var flatCoordinates = ol.xml.pushParseAndPop([null], this.CURVE_PARSERS_, node, objectStack, this); if (flatCoordinates) { var lineString = new ol.geom.LineString(null); @@ -93296,8 +75850,8 @@ ol.format.GML3.prototype.readEnvelope_ = function(node, objectStack) { 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'Envelope', 'localName should be Envelope'); - var flatCoordinates = ol.xml.pushParseAndPop( - /** @type {Array.<number>} */ ([null]), + /** @type {Array.<number>} */ + var flatCoordinates = ol.xml.pushParseAndPop([null], this.ENVELOPE_PARSERS_, node, objectStack, this); return ol.extent.createOrUpdate(flatCoordinates[1][0], flatCoordinates[1][1], flatCoordinates[2][0], @@ -93399,36 +75953,36 @@ ol.format.GML3.prototype.readFlatPosList_ = function(node, objectStack) { /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GML3.prototype.GEOMETRY_FLAT_COORDINATES_PARSERS_ = Object({ +ol.format.GML3.prototype.GEOMETRY_FLAT_COORDINATES_PARSERS_ = { 'http://www.opengis.net/gml' : { 'pos': ol.xml.makeReplacer(ol.format.GML3.prototype.readFlatPos_), 'posList': ol.xml.makeReplacer(ol.format.GML3.prototype.readFlatPosList_) } -}); +}; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GML3.prototype.FLAT_LINEAR_RINGS_PARSERS_ = Object({ +ol.format.GML3.prototype.FLAT_LINEAR_RINGS_PARSERS_ = { 'http://www.opengis.net/gml' : { 'interior': ol.format.GML3.prototype.interiorParser_, 'exterior': ol.format.GML3.prototype.exteriorParser_ } -}); +}; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GML3.prototype.GEOMETRY_PARSERS_ = Object({ +ol.format.GML3.prototype.GEOMETRY_PARSERS_ = { 'http://www.opengis.net/gml' : { 'Point': ol.xml.makeReplacer(ol.format.GMLBase.prototype.readPoint), 'MultiPoint': ol.xml.makeReplacer( @@ -93450,129 +76004,129 @@ ol.format.GML3.prototype.GEOMETRY_PARSERS_ = Object({ ol.format.GML3.prototype.readMultiCurve_), 'Envelope': ol.xml.makeReplacer(ol.format.GML3.prototype.readEnvelope_) } -}); +}; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GML3.prototype.MULTICURVE_PARSERS_ = Object({ +ol.format.GML3.prototype.MULTICURVE_PARSERS_ = { 'http://www.opengis.net/gml' : { 'curveMember': ol.xml.makeArrayPusher( ol.format.GML3.prototype.curveMemberParser_), 'curveMembers': ol.xml.makeArrayPusher( ol.format.GML3.prototype.curveMemberParser_) } -}); +}; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GML3.prototype.MULTISURFACE_PARSERS_ = Object({ +ol.format.GML3.prototype.MULTISURFACE_PARSERS_ = { 'http://www.opengis.net/gml' : { 'surfaceMember': ol.xml.makeArrayPusher( ol.format.GML3.prototype.surfaceMemberParser_), 'surfaceMembers': ol.xml.makeArrayPusher( ol.format.GML3.prototype.surfaceMemberParser_) } -}); +}; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GML3.prototype.CURVEMEMBER_PARSERS_ = Object({ +ol.format.GML3.prototype.CURVEMEMBER_PARSERS_ = { 'http://www.opengis.net/gml' : { 'LineString': ol.xml.makeArrayPusher( ol.format.GMLBase.prototype.readLineString), 'Curve': ol.xml.makeArrayPusher(ol.format.GML3.prototype.readCurve_) } -}); +}; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GML3.prototype.SURFACEMEMBER_PARSERS_ = Object({ +ol.format.GML3.prototype.SURFACEMEMBER_PARSERS_ = { 'http://www.opengis.net/gml' : { 'Polygon': ol.xml.makeArrayPusher(ol.format.GMLBase.prototype.readPolygon), 'Surface': ol.xml.makeArrayPusher(ol.format.GML3.prototype.readSurface_) } -}); +}; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GML3.prototype.SURFACE_PARSERS_ = Object({ +ol.format.GML3.prototype.SURFACE_PARSERS_ = { 'http://www.opengis.net/gml' : { 'patches': ol.xml.makeReplacer(ol.format.GML3.prototype.readPatch_) } -}); +}; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GML3.prototype.CURVE_PARSERS_ = Object({ +ol.format.GML3.prototype.CURVE_PARSERS_ = { 'http://www.opengis.net/gml' : { 'segments': ol.xml.makeReplacer(ol.format.GML3.prototype.readSegment_) } -}); +}; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GML3.prototype.ENVELOPE_PARSERS_ = Object({ +ol.format.GML3.prototype.ENVELOPE_PARSERS_ = { 'http://www.opengis.net/gml' : { 'lowerCorner': ol.xml.makeArrayPusher( ol.format.GML3.prototype.readFlatPosList_), 'upperCorner': ol.xml.makeArrayPusher( ol.format.GML3.prototype.readFlatPosList_) } -}); +}; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GML3.prototype.PATCHES_PARSERS_ = Object({ +ol.format.GML3.prototype.PATCHES_PARSERS_ = { 'http://www.opengis.net/gml' : { 'PolygonPatch': ol.xml.makeReplacer( ol.format.GML3.prototype.readPolygonPatch_) } -}); +}; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ -ol.format.GML3.prototype.SEGMENTS_PARSERS_ = Object({ +ol.format.GML3.prototype.SEGMENTS_PARSERS_ = { 'http://www.opengis.net/gml' : { 'LineStringSegment': ol.xml.makeReplacer( ol.format.GML3.prototype.readLineStringSegment_) } -}); +}; /** @@ -93604,7 +76158,7 @@ ol.format.GML3.prototype.writePos_ = function(node, value, objectStack) { /** * @param {Array.<number>} point Point geometry. * @param {string=} opt_srsName Optional srsName - * @return {string} + * @return {string} The coords string. * @private */ ol.format.GML3.prototype.getCoords_ = function(point, opt_srsName) { @@ -93661,7 +76215,7 @@ ol.format.GML3.prototype.writePoint_ = function(node, geometry, objectStack) { /** - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.GML3.ENVELOPE_SERIALIZERS_ = { @@ -93687,7 +76241,7 @@ ol.format.GML3.prototype.writeEnvelope = function(node, extent, objectStack) { } var keys = ['lowerCorner', 'upperCorner']; var values = [extent[0] + ' ' + extent[1], extent[2] + ' ' + extent[3]]; - ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */ + ol.xml.pushSerializeAndPop(/** @type {ol.XmlNodeStackItem} */ ({node: node}), ol.format.GML3.ENVELOPE_SERIALIZERS_, ol.xml.OBJECT_PROPERTY_NODE_FACTORY, values, @@ -93701,8 +76255,7 @@ ol.format.GML3.prototype.writeEnvelope = function(node, extent, objectStack) { * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML3.prototype.writeLinearRing_ = - function(node, geometry, objectStack) { +ol.format.GML3.prototype.writeLinearRing_ = function(node, geometry, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context), 'context should be an Object'); var srsName = context['srsName']; @@ -93722,8 +76275,7 @@ ol.format.GML3.prototype.writeLinearRing_ = * @return {Node} Node. * @private */ -ol.format.GML3.prototype.RING_NODE_FACTORY_ = - function(value, objectStack, opt_nodeName) { +ol.format.GML3.prototype.RING_NODE_FACTORY_ = function(value, objectStack, opt_nodeName) { var context = objectStack[objectStack.length - 1]; var parentNode = context.node; goog.asserts.assert(goog.isObject(context), 'context should be an Object'); @@ -93742,8 +76294,7 @@ ol.format.GML3.prototype.RING_NODE_FACTORY_ = * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML3.prototype.writeSurfaceOrPolygon_ = - function(node, geometry, objectStack) { +ol.format.GML3.prototype.writeSurfaceOrPolygon_ = function(node, geometry, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context), 'context should be an Object'); var srsName = context['srsName']; @@ -93772,8 +76323,7 @@ ol.format.GML3.prototype.writeSurfaceOrPolygon_ = * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML3.prototype.writeCurveOrLineString_ = - function(node, geometry, objectStack) { +ol.format.GML3.prototype.writeCurveOrLineString_ = function(node, geometry, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context), 'context should be an Object'); var srsName = context['srsName']; @@ -93800,8 +76350,7 @@ ol.format.GML3.prototype.writeCurveOrLineString_ = * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML3.prototype.writeMultiSurfaceOrPolygon_ = - function(node, geometry, objectStack) { +ol.format.GML3.prototype.writeMultiSurfaceOrPolygon_ = function(node, geometry, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context), 'context should be an Object'); var srsName = context['srsName']; @@ -93845,8 +76394,7 @@ ol.format.GML3.prototype.writeMultiPoint_ = function(node, geometry, * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML3.prototype.writeMultiCurveOrLineString_ = - function(node, geometry, objectStack) { +ol.format.GML3.prototype.writeMultiCurveOrLineString_ = function(node, geometry, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context), 'context should be an Object'); var srsName = context['srsName']; @@ -93881,8 +76429,7 @@ ol.format.GML3.prototype.writeRing_ = function(node, ring, objectStack) { * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML3.prototype.writeSurfaceOrPolygonMember_ = - function(node, polygon, objectStack) { +ol.format.GML3.prototype.writeSurfaceOrPolygonMember_ = function(node, polygon, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context), 'context should be an Object'); var child = this.GEOMETRY_NODE_FACTORY_( @@ -93900,8 +76447,7 @@ ol.format.GML3.prototype.writeSurfaceOrPolygonMember_ = * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML3.prototype.writePointMember_ = - function(node, point, objectStack) { +ol.format.GML3.prototype.writePointMember_ = function(node, point, objectStack) { var child = ol.xml.createElementNS(node.namespaceURI, 'Point'); node.appendChild(child); this.writePoint_(child, point, objectStack); @@ -93914,8 +76460,7 @@ ol.format.GML3.prototype.writePointMember_ = * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML3.prototype.writeLineStringOrCurveMember_ = - function(node, line, objectStack) { +ol.format.GML3.prototype.writeLineStringOrCurveMember_ = function(node, line, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context), 'context should be an Object'); var child = this.GEOMETRY_NODE_FACTORY_(line, objectStack); @@ -93932,8 +76477,7 @@ ol.format.GML3.prototype.writeLineStringOrCurveMember_ = * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML3.prototype.writeSurfacePatches_ = - function(node, polygon, objectStack) { +ol.format.GML3.prototype.writeSurfacePatches_ = function(node, polygon, objectStack) { var child = ol.xml.createElementNS(node.namespaceURI, 'PolygonPatch'); node.appendChild(child); this.writeSurfaceOrPolygon_(child, polygon, objectStack); @@ -93946,8 +76490,7 @@ ol.format.GML3.prototype.writeSurfacePatches_ = * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML3.prototype.writeCurveSegments_ = - function(node, line, objectStack) { +ol.format.GML3.prototype.writeCurveSegments_ = function(node, line, objectStack) { var child = ol.xml.createElementNS(node.namespaceURI, 'LineStringSegment'); node.appendChild(child); @@ -93960,14 +76503,13 @@ ol.format.GML3.prototype.writeCurveSegments_ = * @param {ol.geom.Geometry|ol.Extent} geometry Geometry. * @param {Array.<*>} objectStack Node stack. */ -ol.format.GML3.prototype.writeGeometryElement = - function(node, geometry, objectStack) { +ol.format.GML3.prototype.writeGeometryElement = function(node, geometry, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context), 'context should be an Object'); - var item = goog.object.clone(context); + var item = ol.object.assign({}, context); item.node = node; var value; - if (goog.isArray(geometry)) { + if (Array.isArray(geometry)) { if (context.dataProjection) { value = ol.proj.transformExtent( geometry, context.featureProjection, context.dataProjection); @@ -93980,7 +76522,7 @@ ol.format.GML3.prototype.writeGeometryElement = value = ol.format.Feature.transformWithOptions(geometry, true, context); } - ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */ + ol.xml.pushSerializeAndPop(/** @type {ol.XmlNodeStackItem} */ (item), ol.format.GML3.GEOMETRY_SERIALIZERS_, this.GEOMETRY_NODE_FACTORY_, [value], objectStack, undefined, this); @@ -93992,8 +76534,7 @@ ol.format.GML3.prototype.writeGeometryElement = * @param {ol.Feature} feature Feature. * @param {Array.<*>} objectStack Node stack. */ -ol.format.GML3.prototype.writeFeatureElement = - function(node, feature, objectStack) { +ol.format.GML3.prototype.writeFeatureElement = function(node, feature, objectStack) { var fid = feature.getId(); if (fid) { node.setAttribute('fid', fid); @@ -94026,9 +76567,9 @@ ol.format.GML3.prototype.writeFeatureElement = } } } - var item = goog.object.clone(context); + var item = ol.object.assign({}, context); item.node = node; - ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */ + ol.xml.pushSerializeAndPop(/** @type {ol.XmlNodeStackItem} */ (item), context.serializers, ol.xml.makeSimpleNodeFactory(undefined, featureNS), values, @@ -94042,8 +76583,7 @@ ol.format.GML3.prototype.writeFeatureElement = * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.GML3.prototype.writeFeatureMembers_ = - function(node, features, objectStack) { +ol.format.GML3.prototype.writeFeatureMembers_ = function(node, features, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context), 'context should be an Object'); var featureType = context['featureType']; @@ -94052,9 +76592,9 @@ ol.format.GML3.prototype.writeFeatureMembers_ = serializers[featureNS] = {}; serializers[featureNS][featureType] = ol.xml.makeChildAppender( this.writeFeatureElement, this); - var item = goog.object.clone(context); + var item = ol.object.assign({}, context); item.node = node; - ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */ + ol.xml.pushSerializeAndPop(/** @type {ol.XmlNodeStackItem} */ (item), serializers, ol.xml.makeSimpleNodeFactory(featureType, featureNS), features, @@ -94063,7 +76603,7 @@ ol.format.GML3.prototype.writeFeatureMembers_ = /** - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.GML3.SURFACEORPOLYGONMEMBER_SERIALIZERS_ = { @@ -94077,7 +76617,7 @@ ol.format.GML3.SURFACEORPOLYGONMEMBER_SERIALIZERS_ = { /** - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.GML3.POINTMEMBER_SERIALIZERS_ = { @@ -94089,7 +76629,7 @@ ol.format.GML3.POINTMEMBER_SERIALIZERS_ = { /** - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.GML3.LINESTRINGORCURVEMEMBER_SERIALIZERS_ = { @@ -94103,7 +76643,7 @@ ol.format.GML3.LINESTRINGORCURVEMEMBER_SERIALIZERS_ = { /** - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.GML3.RING_SERIALIZERS_ = { @@ -94115,7 +76655,7 @@ ol.format.GML3.RING_SERIALIZERS_ = { /** - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.GML3.GEOMETRY_SERIALIZERS_ = { @@ -94168,8 +76708,7 @@ ol.format.GML3.MULTIGEOMETRY_TO_MEMBER_NODENAME_ = { * @return {Node|undefined} Node. * @private */ -ol.format.GML3.prototype.MULTIGEOMETRY_MEMBER_NODE_FACTORY_ = - function(value, objectStack, opt_nodeName) { +ol.format.GML3.prototype.MULTIGEOMETRY_MEMBER_NODE_FACTORY_ = function(value, objectStack, opt_nodeName) { var parentNode = objectStack[objectStack.length - 1].node; goog.asserts.assert(ol.xml.isNode(parentNode), 'parentNode should be a node'); @@ -94186,8 +76725,7 @@ ol.format.GML3.prototype.MULTIGEOMETRY_MEMBER_NODE_FACTORY_ = * @return {Node|undefined} Node. * @private */ -ol.format.GML3.prototype.GEOMETRY_NODE_FACTORY_ = - function(value, objectStack, opt_nodeName) { +ol.format.GML3.prototype.GEOMETRY_NODE_FACTORY_ = function(value, objectStack, opt_nodeName) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context), 'context should be an Object'); var multiSurface = context['multiSurface']; @@ -94198,7 +76736,7 @@ ol.format.GML3.prototype.GEOMETRY_NODE_FACTORY_ = goog.asserts.assert(ol.xml.isNode(parentNode), 'parentNode should be a node'); var nodeName; - if (!goog.isArray(value)) { + if (!Array.isArray(value)) { goog.asserts.assertInstanceof(value, ol.geom.Geometry, 'value should be an ol.geom.Geometry'); nodeName = value.getType(); @@ -94234,7 +76772,7 @@ ol.format.GML3.prototype.writeGeometryNode = function(geometry, opt_options) { curve: this.curve_, surface: this.surface_, multiSurface: this.multiSurface_, multiCurve: this.multiCurve_}; if (opt_options) { - goog.object.extend(context, opt_options); + ol.object.assign(context, opt_options); } this.writeGeometryElement(geom, geometry, [context]); return geom; @@ -94277,14 +76815,13 @@ ol.format.GML3.prototype.writeFeaturesNode = function(features, opt_options) { featureType: this.featureType }; if (opt_options) { - goog.object.extend(context, opt_options); + ol.object.assign(context, opt_options); } this.writeFeatureMembers_(node, features, [context]); return node; }; - /** * @classdesc * Feature format for reading and writing data in the GML format @@ -94340,7 +76877,6 @@ goog.require('ol.proj'); goog.require('ol.xml'); - /** * @classdesc * Feature format for reading and writing data in the GPX format. @@ -94605,7 +77141,7 @@ ol.format.GPX.FEATURE_READER_ = { /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.GPX.GPX_PARSERS_ = ol.xml.makeStructureNS( @@ -94618,7 +77154,7 @@ ol.format.GPX.GPX_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.GPX.LINK_PARSERS_ = ol.xml.makeStructureNS( @@ -94632,7 +77168,7 @@ ol.format.GPX.LINK_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.GPX.RTE_PARSERS_ = ol.xml.makeStructureNS( @@ -94652,7 +77188,7 @@ ol.format.GPX.RTE_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.GPX.RTEPT_PARSERS_ = ol.xml.makeStructureNS( @@ -94664,7 +77200,7 @@ ol.format.GPX.RTEPT_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.GPX.TRK_PARSERS_ = ol.xml.makeStructureNS( @@ -94684,7 +77220,7 @@ ol.format.GPX.TRK_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.GPX.TRKSEG_PARSERS_ = ol.xml.makeStructureNS( @@ -94695,7 +77231,7 @@ ol.format.GPX.TRKSEG_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.GPX.TRKPT_PARSERS_ = ol.xml.makeStructureNS( @@ -94707,7 +77243,7 @@ ol.format.GPX.TRKPT_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.GPX.WPT_PARSERS_ = ol.xml.makeStructureNS( @@ -94738,7 +77274,7 @@ ol.format.GPX.WPT_PARSERS_ = ol.xml.makeStructureNS( /** - * @param {Array.<ol.Feature>} features + * @param {Array.<ol.Feature>} features List of features. * @private */ ol.format.GPX.prototype.handleReadExtensions_ = function(features) { @@ -94812,8 +77348,8 @@ ol.format.GPX.prototype.readFeaturesFromNode = function(node, opt_options) { return []; } if (node.localName == 'gpx') { - var features = ol.xml.pushParseAndPop( - /** @type {Array.<ol.Feature>} */ ([]), ol.format.GPX.GPX_PARSERS_, + /** @type {Array.<ol.Feature>} */ + var features = ol.xml.pushParseAndPop([], ol.format.GPX.GPX_PARSERS_, node, [this.getReadOptions(node, opt_options)]); if (features) { this.handleReadExtensions_(features); @@ -94852,7 +77388,7 @@ ol.format.GPX.writeLink_ = function(node, value, objectStack) { properties['linkText'], properties['linkType'] ]; - ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */ ({node: node}), + ol.xml.pushSerializeAndPop(/** @type {ol.XmlNodeStackItem} */ ({node: node}), ol.format.GPX.LINK_SERIALIZERS_, ol.xml.OBJECT_PROPERTY_NODE_FACTORY, link, objectStack, ol.format.GPX.LINK_SEQUENCE_); }; @@ -94876,12 +77412,12 @@ ol.format.GPX.writeWptType_ = function(node, coordinate, objectStack) { ol.xml.setAttributeNS(node, null, 'lat', coordinate[1]); ol.xml.setAttributeNS(node, null, 'lon', coordinate[0]); var geometryLayout = context['geometryLayout']; - /* jshint -W086 */ switch (geometryLayout) { case ol.geom.GeometryLayout.XYZM: if (coordinate[3] !== 0) { properties['time'] = coordinate[3]; } + // fall through case ol.geom.GeometryLayout.XYZ: if (coordinate[2] !== 0) { properties['ele'] = coordinate[2]; @@ -94891,11 +77427,13 @@ ol.format.GPX.writeWptType_ = function(node, coordinate, objectStack) { if (coordinate[2] !== 0) { properties['time'] = coordinate[2]; } + break; + default: + // pass } - /* jshint +W086 */ var orderedKeys = ol.format.GPX.WPT_TYPE_SEQUENCE_[namespaceURI]; var values = ol.xml.makeSequence(properties, orderedKeys); - ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */ + ol.xml.pushSerializeAndPop(/** @type {ol.XmlNodeStackItem} */ ({node: node, 'properties': properties}), ol.format.GPX.WPT_TYPE_SERIALIZERS_, ol.xml.OBJECT_PROPERTY_NODE_FACTORY, values, objectStack, orderedKeys); @@ -94924,7 +77462,7 @@ ol.format.GPX.writeRte_ = function(node, feature, objectStack) { var parentNode = objectStack[objectStack.length - 1].node; var orderedKeys = ol.format.GPX.RTE_SEQUENCE_[parentNode.namespaceURI]; var values = ol.xml.makeSequence(properties, orderedKeys); - ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */ (context), + ol.xml.pushSerializeAndPop(context, ol.format.GPX.RTE_SERIALIZERS_, ol.xml.OBJECT_PROPERTY_NODE_FACTORY, values, objectStack, orderedKeys); }; @@ -94939,6 +77477,7 @@ ol.format.GPX.writeRte_ = function(node, feature, objectStack) { ol.format.GPX.writeTrk_ = function(node, feature, objectStack) { var options = /** @type {olx.format.WriteOptions} */ (objectStack[0]); var properties = feature.getProperties(); + /** @type {ol.XmlNodeStackItem} */ var context = {node: node, 'properties': properties}; var geometry = feature.getGeometry(); if (geometry) { @@ -94951,7 +77490,7 @@ ol.format.GPX.writeTrk_ = function(node, feature, objectStack) { var parentNode = objectStack[objectStack.length - 1].node; var orderedKeys = ol.format.GPX.TRK_SEQUENCE_[parentNode.namespaceURI]; var values = ol.xml.makeSequence(properties, orderedKeys); - ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */ (context), + ol.xml.pushSerializeAndPop(context, ol.format.GPX.TRK_SERIALIZERS_, ol.xml.OBJECT_PROPERTY_NODE_FACTORY, values, objectStack, orderedKeys); }; @@ -94964,9 +77503,10 @@ ol.format.GPX.writeTrk_ = function(node, feature, objectStack) { * @private */ ol.format.GPX.writeTrkSeg_ = function(node, lineString, objectStack) { + /** @type {ol.XmlNodeStackItem} */ var context = {node: node, 'geometryLayout': lineString.getLayout(), 'properties': {}}; - ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */ (context), + ol.xml.pushSerializeAndPop(context, ol.format.GPX.TRKSEG_SERIALIZERS_, ol.format.GPX.TRKSEG_NODE_FACTORY_, lineString.getCoordinates(), objectStack); }; @@ -95004,7 +77544,7 @@ ol.format.GPX.LINK_SEQUENCE_ = ['text', 'type']; /** - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.GPX.LINK_SERIALIZERS_ = ol.xml.makeStructureNS( @@ -95027,7 +77567,7 @@ ol.format.GPX.RTE_SEQUENCE_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.GPX.RTE_SERIALIZERS_ = ol.xml.makeStructureNS( @@ -95058,7 +77598,7 @@ ol.format.GPX.TRK_SEQUENCE_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.GPX.TRK_SERIALIZERS_ = ol.xml.makeStructureNS( @@ -95086,7 +77626,7 @@ ol.format.GPX.TRKSEG_NODE_FACTORY_ = ol.xml.makeSimpleNodeFactory('trkpt'); /** * @const - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.GPX.TRKSEG_SERIALIZERS_ = ol.xml.makeStructureNS( @@ -95109,7 +77649,7 @@ ol.format.GPX.WPT_TYPE_SEQUENCE_ = ol.xml.makeStructureNS( /** - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.GPX.WPT_TYPE_SERIALIZERS_ = ol.xml.makeStructureNS( @@ -95177,7 +77717,7 @@ ol.format.GPX.GPX_NODE_FACTORY_ = function(value, objectStack, opt_nodeName) { /** * @const - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.GPX.GPX_SERIALIZERS_ = ol.xml.makeStructureNS( @@ -95190,6 +77730,8 @@ ol.format.GPX.GPX_SERIALIZERS_ = ol.xml.makeStructureNS( /** * Encode an array of features in the GPX format. + * LineString geometries are output as routes (`<rte>`), and MultiLineString + * as tracks (`<trk>`). * * @function * @param {Array.<ol.Feature>} features Features. @@ -95202,6 +77744,8 @@ ol.format.GPX.prototype.writeFeatures; /** * Encode an array of features in the GPX format as an XML node. + * LineString geometries are output as routes (`<rte>`), and MultiLineString + * as tracks (`<trk>`). * * @param {Array.<ol.Feature>} features Features. * @param {olx.format.WriteOptions=} opt_options Options. @@ -95213,167 +77757,12 @@ ol.format.GPX.prototype.writeFeaturesNode = function(features, opt_options) { //FIXME Serialize metadata var gpx = ol.xml.createElementNS('http://www.topografix.com/GPX/1/1', 'gpx'); - ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */ + ol.xml.pushSerializeAndPop(/** @type {ol.XmlNodeStackItem} */ ({node: gpx}), ol.format.GPX.GPX_SERIALIZERS_, ol.format.GPX.GPX_NODE_FACTORY_, features, [opt_options]); return gpx; }; -// Copyright 2013 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Utilities for string newlines. - * @author nnaze@google.com (Nathan Naze) - */ - - -/** - * Namespace for string utilities - */ -goog.provide('goog.string.newlines'); -goog.provide('goog.string.newlines.Line'); - -goog.require('goog.array'); - - -/** - * Splits a string into lines, properly handling universal newlines. - * @param {string} str String to split. - * @param {boolean=} opt_keepNewlines Whether to keep the newlines in the - * resulting strings. Defaults to false. - * @return {!Array<string>} String split into lines. - */ -goog.string.newlines.splitLines = function(str, opt_keepNewlines) { - var lines = goog.string.newlines.getLines(str); - return goog.array.map(lines, function(line) { - return opt_keepNewlines ? line.getFullLine() : line.getContent(); - }); -}; - - - -/** - * Line metadata class that records the start/end indicies of lines - * in a string. Can be used to implement common newline use cases such as - * splitLines() or determining line/column of an index in a string. - * Also implements methods to get line contents. - * - * Indexes are expressed as string indicies into string.substring(), inclusive - * at the start, exclusive at the end. - * - * Create an array of these with goog.string.newlines.getLines(). - * @param {string} string The original string. - * @param {number} startLineIndex The index of the start of the line. - * @param {number} endContentIndex The index of the end of the line, excluding - * newlines. - * @param {number} endLineIndex The index of the end of the line, index - * newlines. - * @constructor - * @struct - * @final - */ -goog.string.newlines.Line = function(string, startLineIndex, - endContentIndex, endLineIndex) { - /** - * The original string. - * @type {string} - */ - this.string = string; - - /** - * Index of the start of the line. - * @type {number} - */ - this.startLineIndex = startLineIndex; - - /** - * Index of the end of the line, excluding any newline characters. - * Index is the first character after the line, suitable for - * String.substring(). - * @type {number} - */ - this.endContentIndex = endContentIndex; - - /** - * Index of the end of the line, excluding any newline characters. - * Index is the first character after the line, suitable for - * String.substring(). - * @type {number} - */ - - this.endLineIndex = endLineIndex; -}; - - -/** - * @return {string} The content of the line, excluding any newline characters. - */ -goog.string.newlines.Line.prototype.getContent = function() { - return this.string.substring(this.startLineIndex, this.endContentIndex); -}; - - -/** - * @return {string} The full line, including any newline characters. - */ -goog.string.newlines.Line.prototype.getFullLine = function() { - return this.string.substring(this.startLineIndex, this.endLineIndex); -}; - - -/** - * @return {string} The newline characters, if any ('\n', \r', '\r\n', '', etc). - */ -goog.string.newlines.Line.prototype.getNewline = function() { - return this.string.substring(this.endContentIndex, this.endLineIndex); -}; - - -/** - * Splits a string into an array of line metadata. - * @param {string} str String to split. - * @return {!Array<!goog.string.newlines.Line>} Array of line metadata. - */ -goog.string.newlines.getLines = function(str) { - // We use the constructor because literals are evaluated only once in - // < ES 3.1. - // See http://www.mail-archive.com/es-discuss@mozilla.org/msg01796.html - var re = RegExp('\r\n|\r|\n', 'g'); - var sliceIndex = 0; - var result; - var lines = []; - - while (result = re.exec(str)) { - var line = new goog.string.newlines.Line( - str, sliceIndex, result.index, result.index + result[0].length); - lines.push(line); - - // remember where to start the slice from - sliceIndex = re.lastIndex; - } - - // If the string does not end with a newline, add the last line. - if (sliceIndex < str.length) { - var line = new goog.string.newlines.Line( - str, sliceIndex, str.length, str.length); - lines.push(line); - } - - return lines; -}; - goog.provide('ol.format.TextFeature'); goog.require('goog.asserts'); @@ -95381,7 +77770,6 @@ goog.require('ol.format.Feature'); goog.require('ol.format.FormatType'); - /** * @classdesc * Abstract base class; normally only used for creating subclasses and not @@ -95403,7 +77791,7 @@ goog.inherits(ol.format.TextFeature, ol.format.Feature); * @return {string} Text. */ ol.format.TextFeature.prototype.getText_ = function(source) { - if (goog.isString(source)) { + if (typeof source === 'string') { return source; } else { goog.asserts.fail(); @@ -95548,7 +77936,6 @@ goog.provide('ol.format.IGC'); goog.provide('ol.format.IGCZ'); goog.require('goog.asserts'); -goog.require('goog.string.newlines'); goog.require('ol.Feature'); goog.require('ol.format.Feature'); goog.require('ol.format.TextFeature'); @@ -95569,7 +77956,6 @@ ol.format.IGCZ = { }; - /** * @classdesc * Feature format for `*.igc` flight recording files. @@ -95635,6 +78021,16 @@ ol.format.IGC.HFDTE_RECORD_RE_ = /^HFDTE(\d{2})(\d{2})(\d{2})/; /** + * A regular expression matching the newline characters `\r\n`, `\r` and `\n`. + * + * @const + * @type {RegExp} + * @private + */ +ol.format.IGC.NEWLINE_RE_ = /\r\n|\r|\n/; + + +/** * @inheritDoc */ ol.format.IGC.prototype.getExtensions = function() { @@ -95659,7 +78055,7 @@ ol.format.IGC.prototype.readFeature; */ ol.format.IGC.prototype.readFeatureFromText = function(text, opt_options) { var altitudeMode = this.altitudeMode_; - var lines = goog.string.newlines.splitLines(text); + var lines = text.split(ol.format.IGC.NEWLINE_RE_); /** @type {Object.<string, string>} */ var properties = {}; var flatCoordinates = []; @@ -95710,7 +78106,6 @@ ol.format.IGC.prototype.readFeatureFromText = function(text, opt_options) { m = ol.format.IGC.H_RECORD_RE_.exec(line); if (m) { properties[m[1]] = m[2].trim(); - m = ol.format.IGC.HFDTE_RECORD_RE_.exec(line); } } } @@ -95780,6 +78175,3175 @@ ol.format.IGC.prototype.readProjection; // limitations under the License. /** + * @fileoverview Generics method for collection-like classes and objects. + * + * @author arv@google.com (Erik Arvidsson) + * + * This file contains functions to work with collections. It supports using + * Map, Set, Array and Object and other classes that implement collection-like + * methods. + */ + + +goog.provide('goog.structs'); + +goog.require('goog.array'); +goog.require('goog.object'); + + +// We treat an object as a dictionary if it has getKeys or it is an object that +// isn't arrayLike. + + +/** + * Returns the number of values in the collection-like object. + * @param {Object} col The collection-like object. + * @return {number} The number of values in the collection-like object. + */ +goog.structs.getCount = function(col) { + if (col.getCount && typeof col.getCount == 'function') { + return col.getCount(); + } + if (goog.isArrayLike(col) || goog.isString(col)) { + return col.length; + } + return goog.object.getCount(col); +}; + + +/** + * Returns the values of the collection-like object. + * @param {Object} col The collection-like object. + * @return {!Array<?>} The values in the collection-like object. + */ +goog.structs.getValues = function(col) { + if (col.getValues && typeof col.getValues == 'function') { + return col.getValues(); + } + if (goog.isString(col)) { + return col.split(''); + } + if (goog.isArrayLike(col)) { + var rv = []; + var l = col.length; + for (var i = 0; i < l; i++) { + rv.push(col[i]); + } + return rv; + } + return goog.object.getValues(col); +}; + + +/** + * Returns the keys of the collection. Some collections have no notion of + * keys/indexes and this function will return undefined in those cases. + * @param {Object} col The collection-like object. + * @return {!Array|undefined} The keys in the collection. + */ +goog.structs.getKeys = function(col) { + if (col.getKeys && typeof col.getKeys == 'function') { + return col.getKeys(); + } + // if we have getValues but no getKeys we know this is a key-less collection + if (col.getValues && typeof col.getValues == 'function') { + return undefined; + } + if (goog.isArrayLike(col) || goog.isString(col)) { + var rv = []; + var l = col.length; + for (var i = 0; i < l; i++) { + rv.push(i); + } + return rv; + } + + return goog.object.getKeys(col); +}; + + +/** + * Whether the collection contains the given value. This is O(n) and uses + * equals (==) to test the existence. + * @param {Object} col The collection-like object. + * @param {*} val The value to check for. + * @return {boolean} True if the map contains the value. + */ +goog.structs.contains = function(col, val) { + if (col.contains && typeof col.contains == 'function') { + return col.contains(val); + } + if (col.containsValue && typeof col.containsValue == 'function') { + return col.containsValue(val); + } + if (goog.isArrayLike(col) || goog.isString(col)) { + return goog.array.contains(/** @type {!Array<?>} */ (col), val); + } + return goog.object.containsValue(col, val); +}; + + +/** + * Whether the collection is empty. + * @param {Object} col The collection-like object. + * @return {boolean} True if empty. + */ +goog.structs.isEmpty = function(col) { + if (col.isEmpty && typeof col.isEmpty == 'function') { + return col.isEmpty(); + } + + // We do not use goog.string.isEmptyOrWhitespace because here we treat the + // string as + // collection and as such even whitespace matters + + if (goog.isArrayLike(col) || goog.isString(col)) { + return goog.array.isEmpty(/** @type {!Array<?>} */ (col)); + } + return goog.object.isEmpty(col); +}; + + +/** + * Removes all the elements from the collection. + * @param {Object} col The collection-like object. + */ +goog.structs.clear = function(col) { + // NOTE(arv): This should not contain strings because strings are immutable + if (col.clear && typeof col.clear == 'function') { + col.clear(); + } else if (goog.isArrayLike(col)) { + goog.array.clear(/** @type {IArrayLike<?>} */ (col)); + } else { + goog.object.clear(col); + } +}; + + +/** + * Calls a function for each value in a collection. The function takes + * three arguments; the value, the key and the collection. + * + * NOTE: This will be deprecated soon! Please use a more specific method if + * possible, e.g. goog.array.forEach, goog.object.forEach, etc. + * + * @param {S} col The collection-like object. + * @param {function(this:T,?,?,S):?} f The function to call for every value. + * This function takes + * 3 arguments (the value, the key or undefined if the collection has no + * notion of keys, and the collection) and the return value is irrelevant. + * @param {T=} opt_obj The object to be used as the value of 'this' + * within {@code f}. + * @template T,S + */ +goog.structs.forEach = function(col, f, opt_obj) { + if (col.forEach && typeof col.forEach == 'function') { + col.forEach(f, opt_obj); + } else if (goog.isArrayLike(col) || goog.isString(col)) { + goog.array.forEach(/** @type {!Array<?>} */ (col), f, opt_obj); + } else { + var keys = goog.structs.getKeys(col); + var values = goog.structs.getValues(col); + var l = values.length; + for (var i = 0; i < l; i++) { + f.call(/** @type {?} */ (opt_obj), values[i], keys && keys[i], col); + } + } +}; + + +/** + * Calls a function for every value in the collection. When a call returns true, + * adds the value to a new collection (Array is returned by default). + * + * @param {S} col The collection-like object. + * @param {function(this:T,?,?,S):boolean} f The function to call for every + * value. This function takes + * 3 arguments (the value, the key or undefined if the collection has no + * notion of keys, and the collection) and should return a Boolean. If the + * return value is true the value is added to the result collection. If it + * is false the value is not included. + * @param {T=} opt_obj The object to be used as the value of 'this' + * within {@code f}. + * @return {!Object|!Array<?>} A new collection where the passed values are + * present. If col is a key-less collection an array is returned. If col + * has keys and values a plain old JS object is returned. + * @template T,S + */ +goog.structs.filter = function(col, f, opt_obj) { + if (typeof col.filter == 'function') { + return col.filter(f, opt_obj); + } + if (goog.isArrayLike(col) || goog.isString(col)) { + return goog.array.filter(/** @type {!Array<?>} */ (col), f, opt_obj); + } + + var rv; + var keys = goog.structs.getKeys(col); + var values = goog.structs.getValues(col); + var l = values.length; + if (keys) { + rv = {}; + for (var i = 0; i < l; i++) { + if (f.call(/** @type {?} */ (opt_obj), values[i], keys[i], col)) { + rv[keys[i]] = values[i]; + } + } + } else { + // We should not use goog.array.filter here since we want to make sure that + // the index is undefined as well as make sure that col is passed to the + // function. + rv = []; + for (var i = 0; i < l; i++) { + if (f.call(opt_obj, values[i], undefined, col)) { + rv.push(values[i]); + } + } + } + return rv; +}; + + +/** + * Calls a function for every value in the collection and adds the result into a + * new collection (defaults to creating a new Array). + * + * @param {S} col The collection-like object. + * @param {function(this:T,?,?,S):V} f The function to call for every value. + * This function takes 3 arguments (the value, the key or undefined if the + * collection has no notion of keys, and the collection) and should return + * something. The result will be used as the value in the new collection. + * @param {T=} opt_obj The object to be used as the value of 'this' + * within {@code f}. + * @return {!Object<V>|!Array<V>} A new collection with the new values. If + * col is a key-less collection an array is returned. If col has keys and + * values a plain old JS object is returned. + * @template T,S,V + */ +goog.structs.map = function(col, f, opt_obj) { + if (typeof col.map == 'function') { + return col.map(f, opt_obj); + } + if (goog.isArrayLike(col) || goog.isString(col)) { + return goog.array.map(/** @type {!Array<?>} */ (col), f, opt_obj); + } + + var rv; + var keys = goog.structs.getKeys(col); + var values = goog.structs.getValues(col); + var l = values.length; + if (keys) { + rv = {}; + for (var i = 0; i < l; i++) { + rv[keys[i]] = f.call(/** @type {?} */ (opt_obj), values[i], keys[i], col); + } + } else { + // We should not use goog.array.map here since we want to make sure that + // the index is undefined as well as make sure that col is passed to the + // function. + rv = []; + for (var i = 0; i < l; i++) { + rv[i] = f.call(/** @type {?} */ (opt_obj), values[i], undefined, col); + } + } + return rv; +}; + + +/** + * Calls f for each value in a collection. If any call returns true this returns + * true (without checking the rest). If all returns false this returns false. + * + * @param {S} col The collection-like object. + * @param {function(this:T,?,?,S):boolean} f The function to call for every + * value. This function takes 3 arguments (the value, the key or undefined + * if the collection has no notion of keys, and the collection) and should + * return a boolean. + * @param {T=} opt_obj The object to be used as the value of 'this' + * within {@code f}. + * @return {boolean} True if any value passes the test. + * @template T,S + */ +goog.structs.some = function(col, f, opt_obj) { + if (typeof col.some == 'function') { + return col.some(f, opt_obj); + } + if (goog.isArrayLike(col) || goog.isString(col)) { + return goog.array.some(/** @type {!Array<?>} */ (col), f, opt_obj); + } + var keys = goog.structs.getKeys(col); + var values = goog.structs.getValues(col); + var l = values.length; + for (var i = 0; i < l; i++) { + if (f.call(/** @type {?} */ (opt_obj), values[i], keys && keys[i], col)) { + return true; + } + } + return false; +}; + + +/** + * Calls f for each value in a collection. If all calls return true this return + * true this returns true. If any returns false this returns false at this point + * and does not continue to check the remaining values. + * + * @param {S} col The collection-like object. + * @param {function(this:T,?,?,S):boolean} f The function to call for every + * value. This function takes 3 arguments (the value, the key or + * undefined if the collection has no notion of keys, and the collection) + * and should return a boolean. + * @param {T=} opt_obj The object to be used as the value of 'this' + * within {@code f}. + * @return {boolean} True if all key-value pairs pass the test. + * @template T,S + */ +goog.structs.every = function(col, f, opt_obj) { + if (typeof col.every == 'function') { + return col.every(f, opt_obj); + } + if (goog.isArrayLike(col) || goog.isString(col)) { + return goog.array.every(/** @type {!Array<?>} */ (col), f, opt_obj); + } + var keys = goog.structs.getKeys(col); + var values = goog.structs.getValues(col); + var l = values.length; + for (var i = 0; i < l; i++) { + if (!f.call(/** @type {?} */ (opt_obj), values[i], keys && keys[i], col)) { + return false; + } + } + return true; +}; + +// Copyright 2007 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Python style iteration utilities. + * @author arv@google.com (Erik Arvidsson) + */ + + +goog.provide('goog.iter'); +goog.provide('goog.iter.Iterable'); +goog.provide('goog.iter.Iterator'); +goog.provide('goog.iter.StopIteration'); + +goog.require('goog.array'); +goog.require('goog.asserts'); +goog.require('goog.functions'); +goog.require('goog.math'); + + +/** + * @typedef {goog.iter.Iterator|{length:number}|{__iterator__}} + */ +goog.iter.Iterable; + + +/** + * Singleton Error object that is used to terminate iterations. + * @const {!Error} + */ +goog.iter.StopIteration = ('StopIteration' in goog.global) ? + // For script engines that support legacy iterators. + goog.global['StopIteration'] : + {message: 'StopIteration', stack: ''}; + + + +/** + * Class/interface for iterators. An iterator needs to implement a {@code next} + * method and it needs to throw a {@code goog.iter.StopIteration} when the + * iteration passes beyond the end. Iterators have no {@code hasNext} method. + * It is recommended to always use the helper functions to iterate over the + * iterator or in case you are only targeting JavaScript 1.7 for in loops. + * @constructor + * @template VALUE + */ +goog.iter.Iterator = function() {}; + + +/** + * Returns the next value of the iteration. This will throw the object + * {@see goog.iter#StopIteration} when the iteration passes the end. + * @return {VALUE} Any object or value. + */ +goog.iter.Iterator.prototype.next = function() { + throw goog.iter.StopIteration; +}; + + +/** + * Returns the {@code Iterator} object itself. This is used to implement + * the iterator protocol in JavaScript 1.7 + * @param {boolean=} opt_keys Whether to return the keys or values. Default is + * to only return the values. This is being used by the for-in loop (true) + * and the for-each-in loop (false). Even though the param gives a hint + * about what the iterator will return there is no guarantee that it will + * return the keys when true is passed. + * @return {!goog.iter.Iterator<VALUE>} The object itself. + */ +goog.iter.Iterator.prototype.__iterator__ = function(opt_keys) { + return this; +}; + + +/** + * Returns an iterator that knows how to iterate over the values in the object. + * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable If the + * object is an iterator it will be returned as is. If the object has an + * {@code __iterator__} method that will be called to get the value + * iterator. If the object is an array-like object we create an iterator + * for that. + * @return {!goog.iter.Iterator<VALUE>} An iterator that knows how to iterate + * over the values in {@code iterable}. + * @template VALUE + */ +goog.iter.toIterator = function(iterable) { + if (iterable instanceof goog.iter.Iterator) { + return iterable; + } + if (typeof iterable.__iterator__ == 'function') { + return iterable.__iterator__(false); + } + if (goog.isArrayLike(iterable)) { + var i = 0; + var newIter = new goog.iter.Iterator; + newIter.next = function() { + while (true) { + if (i >= iterable.length) { + throw goog.iter.StopIteration; + } + // Don't include deleted elements. + if (!(i in iterable)) { + i++; + continue; + } + return iterable[i++]; + } + }; + return newIter; + } + + + // TODO(arv): Should we fall back on goog.structs.getValues()? + throw Error('Not implemented'); +}; + + +/** + * Calls a function for each element in the iterator with the element of the + * iterator passed as argument. + * + * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterator + * to iterate over. If the iterable is an object {@code toIterator} will be + * called on it. + * @param {function(this:THIS,VALUE,?,!goog.iter.Iterator<VALUE>)} f + * The function to call for every element. This function takes 3 arguments + * (the element, undefined, and the iterator) and the return value is + * irrelevant. The reason for passing undefined as the second argument is + * so that the same function can be used in {@see goog.array#forEach} as + * well as others. The third parameter is of type "number" for + * arraylike objects, undefined, otherwise. + * @param {THIS=} opt_obj The object to be used as the value of 'this' within + * {@code f}. + * @template THIS, VALUE + */ +goog.iter.forEach = function(iterable, f, opt_obj) { + if (goog.isArrayLike(iterable)) { + /** @preserveTry */ + try { + // NOTES: this passes the index number to the second parameter + // of the callback contrary to the documentation above. + goog.array.forEach( + /** @type {IArrayLike<?>} */ (iterable), f, opt_obj); + } catch (ex) { + if (ex !== goog.iter.StopIteration) { + throw ex; + } + } + } else { + iterable = goog.iter.toIterator(iterable); + /** @preserveTry */ + try { + while (true) { + f.call(opt_obj, iterable.next(), undefined, iterable); + } + } catch (ex) { + if (ex !== goog.iter.StopIteration) { + throw ex; + } + } + } +}; + + +/** + * Calls a function for every element in the iterator, and if the function + * returns true adds the element to a new iterator. + * + * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterator + * to iterate over. + * @param { + * function(this:THIS,VALUE,undefined,!goog.iter.Iterator<VALUE>):boolean} f + * The function to call for every element. This function takes 3 arguments + * (the element, undefined, and the iterator) and should return a boolean. + * If the return value is true the element will be included in the returned + * iterator. If it is false the element is not included. + * @param {THIS=} opt_obj The object to be used as the value of 'this' within + * {@code f}. + * @return {!goog.iter.Iterator<VALUE>} A new iterator in which only elements + * that passed the test are present. + * @template THIS, VALUE + */ +goog.iter.filter = function(iterable, f, opt_obj) { + var iterator = goog.iter.toIterator(iterable); + var newIter = new goog.iter.Iterator; + newIter.next = function() { + while (true) { + var val = iterator.next(); + if (f.call(opt_obj, val, undefined, iterator)) { + return val; + } + } + }; + return newIter; +}; + + +/** + * Calls a function for every element in the iterator, and if the function + * returns false adds the element to a new iterator. + * + * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterator + * to iterate over. + * @param { + * function(this:THIS,VALUE,undefined,!goog.iter.Iterator<VALUE>):boolean} f + * The function to call for every element. This function takes 3 arguments + * (the element, undefined, and the iterator) and should return a boolean. + * If the return value is false the element will be included in the returned + * iterator. If it is true the element is not included. + * @param {THIS=} opt_obj The object to be used as the value of 'this' within + * {@code f}. + * @return {!goog.iter.Iterator<VALUE>} A new iterator in which only elements + * that did not pass the test are present. + * @template THIS, VALUE + */ +goog.iter.filterFalse = function(iterable, f, opt_obj) { + return goog.iter.filter(iterable, goog.functions.not(f), opt_obj); +}; + + +/** + * Creates a new iterator that returns the values in a range. This function + * can take 1, 2 or 3 arguments: + * <pre> + * range(5) same as range(0, 5, 1) + * range(2, 5) same as range(2, 5, 1) + * </pre> + * + * @param {number} startOrStop The stop value if only one argument is provided. + * The start value if 2 or more arguments are provided. If only one + * argument is used the start value is 0. + * @param {number=} opt_stop The stop value. If left out then the first + * argument is used as the stop value. + * @param {number=} opt_step The number to increment with between each call to + * next. This can be negative. + * @return {!goog.iter.Iterator<number>} A new iterator that returns the values + * in the range. + */ +goog.iter.range = function(startOrStop, opt_stop, opt_step) { + var start = 0; + var stop = startOrStop; + var step = opt_step || 1; + if (arguments.length > 1) { + start = startOrStop; + stop = opt_stop; + } + if (step == 0) { + throw Error('Range step argument must not be zero'); + } + + var newIter = new goog.iter.Iterator; + newIter.next = function() { + if (step > 0 && start >= stop || step < 0 && start <= stop) { + throw goog.iter.StopIteration; + } + var rv = start; + start += step; + return rv; + }; + return newIter; +}; + + +/** + * Joins the values in a iterator with a delimiter. + * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterator + * to get the values from. + * @param {string} deliminator The text to put between the values. + * @return {string} The joined value string. + * @template VALUE + */ +goog.iter.join = function(iterable, deliminator) { + return goog.iter.toArray(iterable).join(deliminator); +}; + + +/** + * For every element in the iterator call a function and return a new iterator + * with that value. + * + * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The + * iterator to iterate over. + * @param { + * function(this:THIS,VALUE,undefined,!goog.iter.Iterator<VALUE>):RESULT} f + * The function to call for every element. This function takes 3 arguments + * (the element, undefined, and the iterator) and should return a new value. + * @param {THIS=} opt_obj The object to be used as the value of 'this' within + * {@code f}. + * @return {!goog.iter.Iterator<RESULT>} A new iterator that returns the + * results of applying the function to each element in the original + * iterator. + * @template THIS, VALUE, RESULT + */ +goog.iter.map = function(iterable, f, opt_obj) { + var iterator = goog.iter.toIterator(iterable); + var newIter = new goog.iter.Iterator; + newIter.next = function() { + var val = iterator.next(); + return f.call(opt_obj, val, undefined, iterator); + }; + return newIter; +}; + + +/** + * Passes every element of an iterator into a function and accumulates the + * result. + * + * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterator + * to iterate over. + * @param {function(this:THIS,VALUE,VALUE):VALUE} f The function to call for + * every element. This function takes 2 arguments (the function's previous + * result or the initial value, and the value of the current element). + * function(previousValue, currentElement) : newValue. + * @param {VALUE} val The initial value to pass into the function on the first + * call. + * @param {THIS=} opt_obj The object to be used as the value of 'this' within + * f. + * @return {VALUE} Result of evaluating f repeatedly across the values of + * the iterator. + * @template THIS, VALUE + */ +goog.iter.reduce = function(iterable, f, val, opt_obj) { + var rval = val; + goog.iter.forEach( + iterable, function(val) { rval = f.call(opt_obj, rval, val); }); + return rval; +}; + + +/** + * Goes through the values in the iterator. Calls f for each of these, and if + * any of them returns true, this returns true (without checking the rest). If + * all return false this will return false. + * + * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterator + * object. + * @param { + * function(this:THIS,VALUE,undefined,!goog.iter.Iterator<VALUE>):boolean} f + * The function to call for every value. This function takes 3 arguments + * (the value, undefined, and the iterator) and should return a boolean. + * @param {THIS=} opt_obj The object to be used as the value of 'this' within + * {@code f}. + * @return {boolean} true if any value passes the test. + * @template THIS, VALUE + */ +goog.iter.some = function(iterable, f, opt_obj) { + iterable = goog.iter.toIterator(iterable); + /** @preserveTry */ + try { + while (true) { + if (f.call(opt_obj, iterable.next(), undefined, iterable)) { + return true; + } + } + } catch (ex) { + if (ex !== goog.iter.StopIteration) { + throw ex; + } + } + return false; +}; + + +/** + * Goes through the values in the iterator. Calls f for each of these and if any + * of them returns false this returns false (without checking the rest). If all + * return true this will return true. + * + * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterator + * object. + * @param { + * function(this:THIS,VALUE,undefined,!goog.iter.Iterator<VALUE>):boolean} f + * The function to call for every value. This function takes 3 arguments + * (the value, undefined, and the iterator) and should return a boolean. + * @param {THIS=} opt_obj The object to be used as the value of 'this' within + * {@code f}. + * @return {boolean} true if every value passes the test. + * @template THIS, VALUE + */ +goog.iter.every = function(iterable, f, opt_obj) { + iterable = goog.iter.toIterator(iterable); + /** @preserveTry */ + try { + while (true) { + if (!f.call(opt_obj, iterable.next(), undefined, iterable)) { + return false; + } + } + } catch (ex) { + if (ex !== goog.iter.StopIteration) { + throw ex; + } + } + return true; +}; + + +/** + * Takes zero or more iterables and returns one iterator that will iterate over + * them in the order chained. + * @param {...!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} var_args Any + * number of iterable objects. + * @return {!goog.iter.Iterator<VALUE>} Returns a new iterator that will + * iterate over all the given iterables' contents. + * @template VALUE + */ +goog.iter.chain = function(var_args) { + return goog.iter.chainFromIterable(arguments); +}; + + +/** + * Takes a single iterable containing zero or more iterables and returns one + * iterator that will iterate over each one in the order given. + * @see https://goo.gl/5NRp5d + * @param {goog.iter.Iterable} iterable The iterable of iterables to chain. + * @return {!goog.iter.Iterator<VALUE>} Returns a new iterator that will + * iterate over all the contents of the iterables contained within + * {@code iterable}. + * @template VALUE + */ +goog.iter.chainFromIterable = function(iterable) { + var iterator = goog.iter.toIterator(iterable); + var iter = new goog.iter.Iterator(); + var current = null; + + iter.next = function() { + while (true) { + if (current == null) { + var it = iterator.next(); + current = goog.iter.toIterator(it); + } + try { + return current.next(); + } catch (ex) { + if (ex !== goog.iter.StopIteration) { + throw ex; + } + current = null; + } + } + }; + + return iter; +}; + + +/** + * Builds a new iterator that iterates over the original, but skips elements as + * long as a supplied function returns true. + * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterator + * object. + * @param { + * function(this:THIS,VALUE,undefined,!goog.iter.Iterator<VALUE>):boolean} f + * The function to call for every value. This function takes 3 arguments + * (the value, undefined, and the iterator) and should return a boolean. + * @param {THIS=} opt_obj The object to be used as the value of 'this' within + * {@code f}. + * @return {!goog.iter.Iterator<VALUE>} A new iterator that drops elements from + * the original iterator as long as {@code f} is true. + * @template THIS, VALUE + */ +goog.iter.dropWhile = function(iterable, f, opt_obj) { + var iterator = goog.iter.toIterator(iterable); + var newIter = new goog.iter.Iterator; + var dropping = true; + newIter.next = function() { + while (true) { + var val = iterator.next(); + if (dropping && f.call(opt_obj, val, undefined, iterator)) { + continue; + } else { + dropping = false; + } + return val; + } + }; + return newIter; +}; + + +/** + * Builds a new iterator that iterates over the original, but only as long as a + * supplied function returns true. + * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterator + * object. + * @param { + * function(this:THIS,VALUE,undefined,!goog.iter.Iterator<VALUE>):boolean} f + * The function to call for every value. This function takes 3 arguments + * (the value, undefined, and the iterator) and should return a boolean. + * @param {THIS=} opt_obj This is used as the 'this' object in f when called. + * @return {!goog.iter.Iterator<VALUE>} A new iterator that keeps elements in + * the original iterator as long as the function is true. + * @template THIS, VALUE + */ +goog.iter.takeWhile = function(iterable, f, opt_obj) { + var iterator = goog.iter.toIterator(iterable); + var iter = new goog.iter.Iterator(); + iter.next = function() { + var val = iterator.next(); + if (f.call(opt_obj, val, undefined, iterator)) { + return val; + } + throw goog.iter.StopIteration; + }; + return iter; +}; + + +/** + * Converts the iterator to an array + * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterator + * to convert to an array. + * @return {!Array<VALUE>} An array of the elements the iterator iterates over. + * @template VALUE + */ +goog.iter.toArray = function(iterable) { + // Fast path for array-like. + if (goog.isArrayLike(iterable)) { + return goog.array.toArray(/** @type {!IArrayLike<?>} */ (iterable)); + } + iterable = goog.iter.toIterator(iterable); + var array = []; + goog.iter.forEach(iterable, function(val) { array.push(val); }); + return array; +}; + + +/** + * Iterates over two iterables and returns true if they contain the same + * sequence of elements and have the same length. + * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable1 The first + * iterable object. + * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable2 The second + * iterable object. + * @param {function(VALUE,VALUE):boolean=} opt_equalsFn Optional comparison + * function. + * Should take two arguments to compare, and return true if the arguments + * are equal. Defaults to {@link goog.array.defaultCompareEquality} which + * compares the elements using the built-in '===' operator. + * @return {boolean} true if the iterables contain the same sequence of elements + * and have the same length. + * @template VALUE + */ +goog.iter.equals = function(iterable1, iterable2, opt_equalsFn) { + var fillValue = {}; + var pairs = goog.iter.zipLongest(fillValue, iterable1, iterable2); + var equalsFn = opt_equalsFn || goog.array.defaultCompareEquality; + return goog.iter.every( + pairs, function(pair) { return equalsFn(pair[0], pair[1]); }); +}; + + +/** + * Advances the iterator to the next position, returning the given default value + * instead of throwing an exception if the iterator has no more entries. + * @param {goog.iter.Iterator<VALUE>|goog.iter.Iterable} iterable The iterable + * object. + * @param {VALUE} defaultValue The value to return if the iterator is empty. + * @return {VALUE} The next item in the iteration, or defaultValue if the + * iterator was empty. + * @template VALUE + */ +goog.iter.nextOrValue = function(iterable, defaultValue) { + try { + return goog.iter.toIterator(iterable).next(); + } catch (e) { + if (e != goog.iter.StopIteration) { + throw e; + } + return defaultValue; + } +}; + + +/** + * Cartesian product of zero or more sets. Gives an iterator that gives every + * combination of one element chosen from each set. For example, + * ([1, 2], [3, 4]) gives ([1, 3], [1, 4], [2, 3], [2, 4]). + * @see http://docs.python.org/library/itertools.html#itertools.product + * @param {...!IArrayLike<VALUE>} var_args Zero or more sets, as + * arrays. + * @return {!goog.iter.Iterator<!Array<VALUE>>} An iterator that gives each + * n-tuple (as an array). + * @template VALUE + */ +goog.iter.product = function(var_args) { + var someArrayEmpty = + goog.array.some(arguments, function(arr) { return !arr.length; }); + + // An empty set in a cartesian product gives an empty set. + if (someArrayEmpty || !arguments.length) { + return new goog.iter.Iterator(); + } + + var iter = new goog.iter.Iterator(); + var arrays = arguments; + + // The first indices are [0, 0, ...] + var indicies = goog.array.repeat(0, arrays.length); + + iter.next = function() { + + if (indicies) { + var retVal = goog.array.map(indicies, function(valueIndex, arrayIndex) { + return arrays[arrayIndex][valueIndex]; + }); + + // Generate the next-largest indices for the next call. + // Increase the rightmost index. If it goes over, increase the next + // rightmost (like carry-over addition). + for (var i = indicies.length - 1; i >= 0; i--) { + // Assertion prevents compiler warning below. + goog.asserts.assert(indicies); + if (indicies[i] < arrays[i].length - 1) { + indicies[i]++; + break; + } + + // We're at the last indices (the last element of every array), so + // the iteration is over on the next call. + if (i == 0) { + indicies = null; + break; + } + // Reset the index in this column and loop back to increment the + // next one. + indicies[i] = 0; + } + return retVal; + } + + throw goog.iter.StopIteration; + }; + + return iter; +}; + + +/** + * Create an iterator to cycle over the iterable's elements indefinitely. + * For example, ([1, 2, 3]) would return : 1, 2, 3, 1, 2, 3, ... + * @see: http://docs.python.org/library/itertools.html#itertools.cycle. + * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The + * iterable object. + * @return {!goog.iter.Iterator<VALUE>} An iterator that iterates indefinitely + * over the values in {@code iterable}. + * @template VALUE + */ +goog.iter.cycle = function(iterable) { + var baseIterator = goog.iter.toIterator(iterable); + + // We maintain a cache to store the iterable elements as we iterate + // over them. The cache is used to return elements once we have + // iterated over the iterable once. + var cache = []; + var cacheIndex = 0; + + var iter = new goog.iter.Iterator(); + + // This flag is set after the iterable is iterated over once + var useCache = false; + + iter.next = function() { + var returnElement = null; + + // Pull elements off the original iterator if not using cache + if (!useCache) { + try { + // Return the element from the iterable + returnElement = baseIterator.next(); + cache.push(returnElement); + return returnElement; + } catch (e) { + // If an exception other than StopIteration is thrown + // or if there are no elements to iterate over (the iterable was empty) + // throw an exception + if (e != goog.iter.StopIteration || goog.array.isEmpty(cache)) { + throw e; + } + // set useCache to true after we know that a 'StopIteration' exception + // was thrown and the cache is not empty (to handle the 'empty iterable' + // use case) + useCache = true; + } + } + + returnElement = cache[cacheIndex]; + cacheIndex = (cacheIndex + 1) % cache.length; + + return returnElement; + }; + + return iter; +}; + + +/** + * Creates an iterator that counts indefinitely from a starting value. + * @see http://docs.python.org/2/library/itertools.html#itertools.count + * @param {number=} opt_start The starting value. Default is 0. + * @param {number=} opt_step The number to increment with between each call to + * next. Negative and floating point numbers are allowed. Default is 1. + * @return {!goog.iter.Iterator<number>} A new iterator that returns the values + * in the series. + */ +goog.iter.count = function(opt_start, opt_step) { + var counter = opt_start || 0; + var step = goog.isDef(opt_step) ? opt_step : 1; + var iter = new goog.iter.Iterator(); + + iter.next = function() { + var returnValue = counter; + counter += step; + return returnValue; + }; + + return iter; +}; + + +/** + * Creates an iterator that returns the same object or value repeatedly. + * @param {VALUE} value Any object or value to repeat. + * @return {!goog.iter.Iterator<VALUE>} A new iterator that returns the + * repeated value. + * @template VALUE + */ +goog.iter.repeat = function(value) { + var iter = new goog.iter.Iterator(); + + iter.next = goog.functions.constant(value); + + return iter; +}; + + +/** + * Creates an iterator that returns running totals from the numbers in + * {@code iterable}. For example, the array {@code [1, 2, 3, 4, 5]} yields + * {@code 1 -> 3 -> 6 -> 10 -> 15}. + * @see http://docs.python.org/3.2/library/itertools.html#itertools.accumulate + * @param {!goog.iter.Iterable<number>} iterable The iterable of numbers to + * accumulate. + * @return {!goog.iter.Iterator<number>} A new iterator that returns the + * numbers in the series. + */ +goog.iter.accumulate = function(iterable) { + var iterator = goog.iter.toIterator(iterable); + var total = 0; + var iter = new goog.iter.Iterator(); + + iter.next = function() { + total += iterator.next(); + return total; + }; + + return iter; +}; + + +/** + * Creates an iterator that returns arrays containing the ith elements from the + * provided iterables. The returned arrays will be the same size as the number + * of iterables given in {@code var_args}. Once the shortest iterable is + * exhausted, subsequent calls to {@code next()} will throw + * {@code goog.iter.StopIteration}. + * @see http://docs.python.org/2/library/itertools.html#itertools.izip + * @param {...!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} var_args Any + * number of iterable objects. + * @return {!goog.iter.Iterator<!Array<VALUE>>} A new iterator that returns + * arrays of elements from the provided iterables. + * @template VALUE + */ +goog.iter.zip = function(var_args) { + var args = arguments; + var iter = new goog.iter.Iterator(); + + if (args.length > 0) { + var iterators = goog.array.map(args, goog.iter.toIterator); + iter.next = function() { + var arr = goog.array.map(iterators, function(it) { return it.next(); }); + return arr; + }; + } + + return iter; +}; + + +/** + * Creates an iterator that returns arrays containing the ith elements from the + * provided iterables. The returned arrays will be the same size as the number + * of iterables given in {@code var_args}. Shorter iterables will be extended + * with {@code fillValue}. Once the longest iterable is exhausted, subsequent + * calls to {@code next()} will throw {@code goog.iter.StopIteration}. + * @see http://docs.python.org/2/library/itertools.html#itertools.izip_longest + * @param {VALUE} fillValue The object or value used to fill shorter iterables. + * @param {...!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} var_args Any + * number of iterable objects. + * @return {!goog.iter.Iterator<!Array<VALUE>>} A new iterator that returns + * arrays of elements from the provided iterables. + * @template VALUE + */ +goog.iter.zipLongest = function(fillValue, var_args) { + var args = goog.array.slice(arguments, 1); + var iter = new goog.iter.Iterator(); + + if (args.length > 0) { + var iterators = goog.array.map(args, goog.iter.toIterator); + + iter.next = function() { + var iteratorsHaveValues = false; // false when all iterators are empty. + var arr = goog.array.map(iterators, function(it) { + var returnValue; + try { + returnValue = it.next(); + // Iterator had a value, so we've not exhausted the iterators. + // Set flag accordingly. + iteratorsHaveValues = true; + } catch (ex) { + if (ex !== goog.iter.StopIteration) { + throw ex; + } + returnValue = fillValue; + } + return returnValue; + }); + + if (!iteratorsHaveValues) { + throw goog.iter.StopIteration; + } + return arr; + }; + } + + return iter; +}; + + +/** + * Creates an iterator that filters {@code iterable} based on a series of + * {@code selectors}. On each call to {@code next()}, one item is taken from + * both the {@code iterable} and {@code selectors} iterators. If the item from + * {@code selectors} evaluates to true, the item from {@code iterable} is given. + * Otherwise, it is skipped. Once either {@code iterable} or {@code selectors} + * is exhausted, subsequent calls to {@code next()} will throw + * {@code goog.iter.StopIteration}. + * @see http://docs.python.org/2/library/itertools.html#itertools.compress + * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The + * iterable to filter. + * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} selectors An + * iterable of items to be evaluated in a boolean context to determine if + * the corresponding element in {@code iterable} should be included in the + * result. + * @return {!goog.iter.Iterator<VALUE>} A new iterator that returns the + * filtered values. + * @template VALUE + */ +goog.iter.compress = function(iterable, selectors) { + var selectorIterator = goog.iter.toIterator(selectors); + + return goog.iter.filter( + iterable, function() { return !!selectorIterator.next(); }); +}; + + + +/** + * Implements the {@code goog.iter.groupBy} iterator. + * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The + * iterable to group. + * @param {function(VALUE): KEY=} opt_keyFunc Optional function for + * determining the key value for each group in the {@code iterable}. Default + * is the identity function. + * @constructor + * @extends {goog.iter.Iterator<!Array<?>>} + * @template KEY, VALUE + * @private + */ +goog.iter.GroupByIterator_ = function(iterable, opt_keyFunc) { + + /** + * The iterable to group, coerced to an iterator. + * @type {!goog.iter.Iterator} + */ + this.iterator = goog.iter.toIterator(iterable); + + /** + * A function for determining the key value for each element in the iterable. + * If no function is provided, the identity function is used and returns the + * element unchanged. + * @type {function(VALUE): KEY} + */ + this.keyFunc = opt_keyFunc || goog.functions.identity; + + /** + * The target key for determining the start of a group. + * @type {KEY} + */ + this.targetKey; + + /** + * The current key visited during iteration. + * @type {KEY} + */ + this.currentKey; + + /** + * The current value being added to the group. + * @type {VALUE} + */ + this.currentValue; +}; +goog.inherits(goog.iter.GroupByIterator_, goog.iter.Iterator); + + +/** @override */ +goog.iter.GroupByIterator_.prototype.next = function() { + while (this.currentKey == this.targetKey) { + this.currentValue = this.iterator.next(); // Exits on StopIteration + this.currentKey = this.keyFunc(this.currentValue); + } + this.targetKey = this.currentKey; + return [this.currentKey, this.groupItems_(this.targetKey)]; +}; + + +/** + * Performs the grouping of objects using the given key. + * @param {KEY} targetKey The target key object for the group. + * @return {!Array<VALUE>} An array of grouped objects. + * @private + */ +goog.iter.GroupByIterator_.prototype.groupItems_ = function(targetKey) { + var arr = []; + while (this.currentKey == targetKey) { + arr.push(this.currentValue); + try { + this.currentValue = this.iterator.next(); + } catch (ex) { + if (ex !== goog.iter.StopIteration) { + throw ex; + } + break; + } + this.currentKey = this.keyFunc(this.currentValue); + } + return arr; +}; + + +/** + * Creates an iterator that returns arrays containing elements from the + * {@code iterable} grouped by a key value. For iterables with repeated + * elements (i.e. sorted according to a particular key function), this function + * has a {@code uniq}-like effect. For example, grouping the array: + * {@code [A, B, B, C, C, A]} produces + * {@code [A, [A]], [B, [B, B]], [C, [C, C]], [A, [A]]}. + * @see http://docs.python.org/2/library/itertools.html#itertools.groupby + * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The + * iterable to group. + * @param {function(VALUE): KEY=} opt_keyFunc Optional function for + * determining the key value for each group in the {@code iterable}. Default + * is the identity function. + * @return {!goog.iter.Iterator<!Array<?>>} A new iterator that returns + * arrays of consecutive key and groups. + * @template KEY, VALUE + */ +goog.iter.groupBy = function(iterable, opt_keyFunc) { + return new goog.iter.GroupByIterator_(iterable, opt_keyFunc); +}; + + +/** + * Gives an iterator that gives the result of calling the given function + * <code>f</code> with the arguments taken from the next element from + * <code>iterable</code> (the elements are expected to also be iterables). + * + * Similar to {@see goog.iter#map} but allows the function to accept multiple + * arguments from the iterable. + * + * @param {!goog.iter.Iterable<!goog.iter.Iterable>} iterable The iterable of + * iterables to iterate over. + * @param {function(this:THIS,...*):RESULT} f The function to call for every + * element. This function takes N+2 arguments, where N represents the + * number of items from the next element of the iterable. The two + * additional arguments passed to the function are undefined and the + * iterator itself. The function should return a new value. + * @param {THIS=} opt_obj The object to be used as the value of 'this' within + * {@code f}. + * @return {!goog.iter.Iterator<RESULT>} A new iterator that returns the + * results of applying the function to each element in the original + * iterator. + * @template THIS, RESULT + */ +goog.iter.starMap = function(iterable, f, opt_obj) { + var iterator = goog.iter.toIterator(iterable); + var iter = new goog.iter.Iterator(); + + iter.next = function() { + var args = goog.iter.toArray(iterator.next()); + return f.apply(opt_obj, goog.array.concat(args, undefined, iterator)); + }; + + return iter; +}; + + +/** + * Returns an array of iterators each of which can iterate over the values in + * {@code iterable} without advancing the others. + * @see http://docs.python.org/2/library/itertools.html#itertools.tee + * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The + * iterable to tee. + * @param {number=} opt_num The number of iterators to create. Default is 2. + * @return {!Array<goog.iter.Iterator<VALUE>>} An array of iterators. + * @template VALUE + */ +goog.iter.tee = function(iterable, opt_num) { + var iterator = goog.iter.toIterator(iterable); + var num = goog.isNumber(opt_num) ? opt_num : 2; + var buffers = + goog.array.map(goog.array.range(num), function() { return []; }); + + var addNextIteratorValueToBuffers = function() { + var val = iterator.next(); + goog.array.forEach(buffers, function(buffer) { buffer.push(val); }); + }; + + var createIterator = function(buffer) { + // Each tee'd iterator has an associated buffer (initially empty). When a + // tee'd iterator's buffer is empty, it calls + // addNextIteratorValueToBuffers(), adding the next value to all tee'd + // iterators' buffers, and then returns that value. This allows each + // iterator to be advanced independently. + var iter = new goog.iter.Iterator(); + + iter.next = function() { + if (goog.array.isEmpty(buffer)) { + addNextIteratorValueToBuffers(); + } + goog.asserts.assert(!goog.array.isEmpty(buffer)); + return buffer.shift(); + }; + + return iter; + }; + + return goog.array.map(buffers, createIterator); +}; + + +/** + * Creates an iterator that returns arrays containing a count and an element + * obtained from the given {@code iterable}. + * @see http://docs.python.org/2/library/functions.html#enumerate + * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The + * iterable to enumerate. + * @param {number=} opt_start Optional starting value. Default is 0. + * @return {!goog.iter.Iterator<!Array<?>>} A new iterator containing + * count/item pairs. + * @template VALUE + */ +goog.iter.enumerate = function(iterable, opt_start) { + return goog.iter.zip(goog.iter.count(opt_start), iterable); +}; + + +/** + * Creates an iterator that returns the first {@code limitSize} elements from an + * iterable. If this number is greater than the number of elements in the + * iterable, all the elements are returned. + * @see http://goo.gl/V0sihp Inspired by the limit iterator in Guava. + * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The + * iterable to limit. + * @param {number} limitSize The maximum number of elements to return. + * @return {!goog.iter.Iterator<VALUE>} A new iterator containing + * {@code limitSize} elements. + * @template VALUE + */ +goog.iter.limit = function(iterable, limitSize) { + goog.asserts.assert(goog.math.isInt(limitSize) && limitSize >= 0); + + var iterator = goog.iter.toIterator(iterable); + + var iter = new goog.iter.Iterator(); + var remaining = limitSize; + + iter.next = function() { + if (remaining-- > 0) { + return iterator.next(); + } + throw goog.iter.StopIteration; + }; + + return iter; +}; + + +/** + * Creates an iterator that is advanced {@code count} steps ahead. Consumed + * values are silently discarded. If {@code count} is greater than the number + * of elements in {@code iterable}, an empty iterator is returned. Subsequent + * calls to {@code next()} will throw {@code goog.iter.StopIteration}. + * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The + * iterable to consume. + * @param {number} count The number of elements to consume from the iterator. + * @return {!goog.iter.Iterator<VALUE>} An iterator advanced zero or more steps + * ahead. + * @template VALUE + */ +goog.iter.consume = function(iterable, count) { + goog.asserts.assert(goog.math.isInt(count) && count >= 0); + + var iterator = goog.iter.toIterator(iterable); + + while (count-- > 0) { + goog.iter.nextOrValue(iterator, null); + } + + return iterator; +}; + + +/** + * Creates an iterator that returns a range of elements from an iterable. + * Similar to {@see goog.array#slice} but does not support negative indexes. + * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The + * iterable to slice. + * @param {number} start The index of the first element to return. + * @param {number=} opt_end The index after the last element to return. If + * defined, must be greater than or equal to {@code start}. + * @return {!goog.iter.Iterator<VALUE>} A new iterator containing a slice of + * the original. + * @template VALUE + */ +goog.iter.slice = function(iterable, start, opt_end) { + goog.asserts.assert(goog.math.isInt(start) && start >= 0); + + var iterator = goog.iter.consume(iterable, start); + + if (goog.isNumber(opt_end)) { + goog.asserts.assert(goog.math.isInt(opt_end) && opt_end >= start); + iterator = goog.iter.limit(iterator, opt_end - start /* limitSize */); + } + + return iterator; +}; + + +/** + * Checks an array for duplicate elements. + * @param {?IArrayLike<VALUE>} arr The array to check for + * duplicates. + * @return {boolean} True, if the array contains duplicates, false otherwise. + * @private + * @template VALUE + */ +// TODO(user): Consider moving this into goog.array as a public function. +goog.iter.hasDuplicates_ = function(arr) { + var deduped = []; + goog.array.removeDuplicates(arr, deduped); + return arr.length != deduped.length; +}; + + +/** + * Creates an iterator that returns permutations of elements in + * {@code iterable}. + * + * Permutations are obtained by taking the Cartesian product of + * {@code opt_length} iterables and filtering out those with repeated + * elements. For example, the permutations of {@code [1,2,3]} are + * {@code [[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]]}. + * @see http://docs.python.org/2/library/itertools.html#itertools.permutations + * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The + * iterable from which to generate permutations. + * @param {number=} opt_length Length of each permutation. If omitted, defaults + * to the length of {@code iterable}. + * @return {!goog.iter.Iterator<!Array<VALUE>>} A new iterator containing the + * permutations of {@code iterable}. + * @template VALUE + */ +goog.iter.permutations = function(iterable, opt_length) { + var elements = goog.iter.toArray(iterable); + var length = goog.isNumber(opt_length) ? opt_length : elements.length; + + var sets = goog.array.repeat(elements, length); + var product = goog.iter.product.apply(undefined, sets); + + return goog.iter.filter( + product, function(arr) { return !goog.iter.hasDuplicates_(arr); }); +}; + + +/** + * Creates an iterator that returns combinations of elements from + * {@code iterable}. + * + * Combinations are obtained by taking the {@see goog.iter#permutations} of + * {@code iterable} and filtering those whose elements appear in the order they + * are encountered in {@code iterable}. For example, the 3-length combinations + * of {@code [0,1,2,3]} are {@code [[0,1,2], [0,1,3], [0,2,3], [1,2,3]]}. + * @see http://docs.python.org/2/library/itertools.html#itertools.combinations + * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The + * iterable from which to generate combinations. + * @param {number} length The length of each combination. + * @return {!goog.iter.Iterator<!Array<VALUE>>} A new iterator containing + * combinations from the {@code iterable}. + * @template VALUE + */ +goog.iter.combinations = function(iterable, length) { + var elements = goog.iter.toArray(iterable); + var indexes = goog.iter.range(elements.length); + var indexIterator = goog.iter.permutations(indexes, length); + // sortedIndexIterator will now give arrays of with the given length that + // indicate what indexes into "elements" should be returned on each iteration. + var sortedIndexIterator = goog.iter.filter( + indexIterator, function(arr) { return goog.array.isSorted(arr); }); + + var iter = new goog.iter.Iterator(); + + function getIndexFromElements(index) { return elements[index]; } + + iter.next = function() { + return goog.array.map(sortedIndexIterator.next(), getIndexFromElements); + }; + + return iter; +}; + + +/** + * Creates an iterator that returns combinations of elements from + * {@code iterable}, with repeated elements possible. + * + * Combinations are obtained by taking the Cartesian product of {@code length} + * iterables and filtering those whose elements appear in the order they are + * encountered in {@code iterable}. For example, the 2-length combinations of + * {@code [1,2,3]} are {@code [[1,1], [1,2], [1,3], [2,2], [2,3], [3,3]]}. + * @see https://goo.gl/C0yXe4 + * @see https://goo.gl/djOCsk + * @param {!goog.iter.Iterator<VALUE>|!goog.iter.Iterable} iterable The + * iterable to combine. + * @param {number} length The length of each combination. + * @return {!goog.iter.Iterator<!Array<VALUE>>} A new iterator containing + * combinations from the {@code iterable}. + * @template VALUE + */ +goog.iter.combinationsWithReplacement = function(iterable, length) { + var elements = goog.iter.toArray(iterable); + var indexes = goog.array.range(elements.length); + var sets = goog.array.repeat(indexes, length); + var indexIterator = goog.iter.product.apply(undefined, sets); + // sortedIndexIterator will now give arrays of with the given length that + // indicate what indexes into "elements" should be returned on each iteration. + var sortedIndexIterator = goog.iter.filter( + indexIterator, function(arr) { return goog.array.isSorted(arr); }); + + var iter = new goog.iter.Iterator(); + + function getIndexFromElements(index) { return elements[index]; } + + iter.next = function() { + return goog.array.map( + /** @type {!Array<number>} */ + (sortedIndexIterator.next()), getIndexFromElements); + }; + + return iter; +}; + +// Copyright 2006 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Datastructure: Hash Map. + * + * @author arv@google.com (Erik Arvidsson) + * + * This file contains an implementation of a Map structure. It implements a lot + * of the methods used in goog.structs so those functions work on hashes. This + * is best suited for complex key types. For simple keys such as numbers and + * strings consider using the lighter-weight utilities in goog.object. + */ + + +goog.provide('goog.structs.Map'); + +goog.require('goog.iter.Iterator'); +goog.require('goog.iter.StopIteration'); +goog.require('goog.object'); + + + +/** + * Class for Hash Map datastructure. + * @param {*=} opt_map Map or Object to initialize the map with. + * @param {...*} var_args If 2 or more arguments are present then they + * will be used as key-value pairs. + * @constructor + * @template K, V + */ +goog.structs.Map = function(opt_map, var_args) { + + /** + * Underlying JS object used to implement the map. + * @private {!Object} + */ + this.map_ = {}; + + /** + * An array of keys. This is necessary for two reasons: + * 1. Iterating the keys using for (var key in this.map_) allocates an + * object for every key in IE which is really bad for IE6 GC perf. + * 2. Without a side data structure, we would need to escape all the keys + * as that would be the only way we could tell during iteration if the + * key was an internal key or a property of the object. + * + * This array can contain deleted keys so it's necessary to check the map + * as well to see if the key is still in the map (this doesn't require a + * memory allocation in IE). + * @private {!Array<string>} + */ + this.keys_ = []; + + /** + * The number of key value pairs in the map. + * @private {number} + */ + this.count_ = 0; + + /** + * Version used to detect changes while iterating. + * @private {number} + */ + this.version_ = 0; + + var argLength = arguments.length; + + if (argLength > 1) { + if (argLength % 2) { + throw Error('Uneven number of arguments'); + } + for (var i = 0; i < argLength; i += 2) { + this.set(arguments[i], arguments[i + 1]); + } + } else if (opt_map) { + this.addAll(/** @type {Object} */ (opt_map)); + } +}; + + +/** + * @return {number} The number of key-value pairs in the map. + */ +goog.structs.Map.prototype.getCount = function() { + return this.count_; +}; + + +/** + * Returns the values of the map. + * @return {!Array<V>} The values in the map. + */ +goog.structs.Map.prototype.getValues = function() { + this.cleanupKeysArray_(); + + var rv = []; + for (var i = 0; i < this.keys_.length; i++) { + var key = this.keys_[i]; + rv.push(this.map_[key]); + } + return rv; +}; + + +/** + * Returns the keys of the map. + * @return {!Array<string>} Array of string values. + */ +goog.structs.Map.prototype.getKeys = function() { + this.cleanupKeysArray_(); + return /** @type {!Array<string>} */ (this.keys_.concat()); +}; + + +/** + * Whether the map contains the given key. + * @param {*} key The key to check for. + * @return {boolean} Whether the map contains the key. + */ +goog.structs.Map.prototype.containsKey = function(key) { + return goog.structs.Map.hasKey_(this.map_, key); +}; + + +/** + * Whether the map contains the given value. This is O(n). + * @param {V} val The value to check for. + * @return {boolean} Whether the map contains the value. + */ +goog.structs.Map.prototype.containsValue = function(val) { + for (var i = 0; i < this.keys_.length; i++) { + var key = this.keys_[i]; + if (goog.structs.Map.hasKey_(this.map_, key) && this.map_[key] == val) { + return true; + } + } + return false; +}; + + +/** + * Whether this map is equal to the argument map. + * @param {goog.structs.Map} otherMap The map against which to test equality. + * @param {function(V, V): boolean=} opt_equalityFn Optional equality function + * to test equality of values. If not specified, this will test whether + * the values contained in each map are identical objects. + * @return {boolean} Whether the maps are equal. + */ +goog.structs.Map.prototype.equals = function(otherMap, opt_equalityFn) { + if (this === otherMap) { + return true; + } + + if (this.count_ != otherMap.getCount()) { + return false; + } + + var equalityFn = opt_equalityFn || goog.structs.Map.defaultEquals; + + this.cleanupKeysArray_(); + for (var key, i = 0; key = this.keys_[i]; i++) { + if (!equalityFn(this.get(key), otherMap.get(key))) { + return false; + } + } + + return true; +}; + + +/** + * Default equality test for values. + * @param {*} a The first value. + * @param {*} b The second value. + * @return {boolean} Whether a and b reference the same object. + */ +goog.structs.Map.defaultEquals = function(a, b) { + return a === b; +}; + + +/** + * @return {boolean} Whether the map is empty. + */ +goog.structs.Map.prototype.isEmpty = function() { + return this.count_ == 0; +}; + + +/** + * Removes all key-value pairs from the map. + */ +goog.structs.Map.prototype.clear = function() { + this.map_ = {}; + this.keys_.length = 0; + this.count_ = 0; + this.version_ = 0; +}; + + +/** + * Removes a key-value pair based on the key. This is O(logN) amortized due to + * updating the keys array whenever the count becomes half the size of the keys + * in the keys array. + * @param {*} key The key to remove. + * @return {boolean} Whether object was removed. + */ +goog.structs.Map.prototype.remove = function(key) { + if (goog.structs.Map.hasKey_(this.map_, key)) { + delete this.map_[key]; + this.count_--; + this.version_++; + + // clean up the keys array if the threshhold is hit + if (this.keys_.length > 2 * this.count_) { + this.cleanupKeysArray_(); + } + + return true; + } + return false; +}; + + +/** + * Cleans up the temp keys array by removing entries that are no longer in the + * map. + * @private + */ +goog.structs.Map.prototype.cleanupKeysArray_ = function() { + if (this.count_ != this.keys_.length) { + // First remove keys that are no longer in the map. + var srcIndex = 0; + var destIndex = 0; + while (srcIndex < this.keys_.length) { + var key = this.keys_[srcIndex]; + if (goog.structs.Map.hasKey_(this.map_, key)) { + this.keys_[destIndex++] = key; + } + srcIndex++; + } + this.keys_.length = destIndex; + } + + if (this.count_ != this.keys_.length) { + // If the count still isn't correct, that means we have duplicates. This can + // happen when the same key is added and removed multiple times. Now we have + // to allocate one extra Object to remove the duplicates. This could have + // been done in the first pass, but in the common case, we can avoid + // allocating an extra object by only doing this when necessary. + var seen = {}; + var srcIndex = 0; + var destIndex = 0; + while (srcIndex < this.keys_.length) { + var key = this.keys_[srcIndex]; + if (!(goog.structs.Map.hasKey_(seen, key))) { + this.keys_[destIndex++] = key; + seen[key] = 1; + } + srcIndex++; + } + this.keys_.length = destIndex; + } +}; + + +/** + * Returns the value for the given key. If the key is not found and the default + * value is not given this will return {@code undefined}. + * @param {*} key The key to get the value for. + * @param {DEFAULT=} opt_val The value to return if no item is found for the + * given key, defaults to undefined. + * @return {V|DEFAULT} The value for the given key. + * @template DEFAULT + */ +goog.structs.Map.prototype.get = function(key, opt_val) { + if (goog.structs.Map.hasKey_(this.map_, key)) { + return this.map_[key]; + } + return opt_val; +}; + + +/** + * Adds a key-value pair to the map. + * @param {*} key The key. + * @param {V} value The value to add. + * @return {*} Some subclasses return a value. + */ +goog.structs.Map.prototype.set = function(key, value) { + if (!(goog.structs.Map.hasKey_(this.map_, key))) { + this.count_++; + // TODO(johnlenz): This class lies, it claims to return an array of string + // keys, but instead returns the original object used. + this.keys_.push(/** @type {?} */ (key)); + // Only change the version if we add a new key. + this.version_++; + } + this.map_[key] = value; +}; + + +/** + * Adds multiple key-value pairs from another goog.structs.Map or Object. + * @param {Object} map Object containing the data to add. + */ +goog.structs.Map.prototype.addAll = function(map) { + var keys, values; + if (map instanceof goog.structs.Map) { + keys = map.getKeys(); + values = map.getValues(); + } else { + keys = goog.object.getKeys(map); + values = goog.object.getValues(map); + } + // we could use goog.array.forEach here but I don't want to introduce that + // dependency just for this. + for (var i = 0; i < keys.length; i++) { + this.set(keys[i], values[i]); + } +}; + + +/** + * Calls the given function on each entry in the map. + * @param {function(this:T, V, K, goog.structs.Map<K,V>)} f + * @param {T=} opt_obj The value of "this" inside f. + * @template T + */ +goog.structs.Map.prototype.forEach = function(f, opt_obj) { + var keys = this.getKeys(); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = this.get(key); + f.call(opt_obj, value, key, this); + } +}; + + +/** + * Clones a map and returns a new map. + * @return {!goog.structs.Map} A new map with the same key-value pairs. + */ +goog.structs.Map.prototype.clone = function() { + return new goog.structs.Map(this); +}; + + +/** + * Returns a new map in which all the keys and values are interchanged + * (keys become values and values become keys). If multiple keys map to the + * same value, the chosen transposed value is implementation-dependent. + * + * It acts very similarly to {goog.object.transpose(Object)}. + * + * @return {!goog.structs.Map} The transposed map. + */ +goog.structs.Map.prototype.transpose = function() { + var transposed = new goog.structs.Map(); + for (var i = 0; i < this.keys_.length; i++) { + var key = this.keys_[i]; + var value = this.map_[key]; + transposed.set(value, key); + } + + return transposed; +}; + + +/** + * @return {!Object} Object representation of the map. + */ +goog.structs.Map.prototype.toObject = function() { + this.cleanupKeysArray_(); + var obj = {}; + for (var i = 0; i < this.keys_.length; i++) { + var key = this.keys_[i]; + obj[key] = this.map_[key]; + } + return obj; +}; + + +/** + * Returns an iterator that iterates over the keys in the map. Removal of keys + * while iterating might have undesired side effects. + * @return {!goog.iter.Iterator} An iterator over the keys in the map. + */ +goog.structs.Map.prototype.getKeyIterator = function() { + return this.__iterator__(true); +}; + + +/** + * Returns an iterator that iterates over the values in the map. Removal of + * keys while iterating might have undesired side effects. + * @return {!goog.iter.Iterator} An iterator over the values in the map. + */ +goog.structs.Map.prototype.getValueIterator = function() { + return this.__iterator__(false); +}; + + +/** + * Returns an iterator that iterates over the values or the keys in the map. + * This throws an exception if the map was mutated since the iterator was + * created. + * @param {boolean=} opt_keys True to iterate over the keys. False to iterate + * over the values. The default value is false. + * @return {!goog.iter.Iterator} An iterator over the values or keys in the map. + */ +goog.structs.Map.prototype.__iterator__ = function(opt_keys) { + // Clean up keys to minimize the risk of iterating over dead keys. + this.cleanupKeysArray_(); + + var i = 0; + var version = this.version_; + var selfObj = this; + + var newIter = new goog.iter.Iterator; + newIter.next = function() { + if (version != selfObj.version_) { + throw Error('The map has changed since the iterator was created'); + } + if (i >= selfObj.keys_.length) { + throw goog.iter.StopIteration; + } + var key = selfObj.keys_[i++]; + return opt_keys ? key : selfObj.map_[key]; + }; + return newIter; +}; + + +/** + * Safe way to test for hasOwnProperty. It even allows testing for + * 'hasOwnProperty'. + * @param {Object} obj The object to test for presence of the given key. + * @param {*} key The key to check for. + * @return {boolean} Whether the object has the key. + * @private + */ +goog.structs.Map.hasKey_ = function(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); +}; + +// Copyright 2008 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Simple utilities for dealing with URI strings. + * + * This is intended to be a lightweight alternative to constructing goog.Uri + * objects. Whereas goog.Uri adds several kilobytes to the binary regardless + * of how much of its functionality you use, this is designed to be a set of + * mostly-independent utilities so that the compiler includes only what is + * necessary for the task. Estimated savings of porting is 5k pre-gzip and + * 1.5k post-gzip. To ensure the savings remain, future developers should + * avoid adding new functionality to existing functions, but instead create + * new ones and factor out shared code. + * + * Many of these utilities have limited functionality, tailored to common + * cases. The query parameter utilities assume that the parameter keys are + * already encoded, since most keys are compile-time alphanumeric strings. The + * query parameter mutation utilities also do not tolerate fragment identifiers. + * + * By design, these functions can be slower than goog.Uri equivalents. + * Repeated calls to some of functions may be quadratic in behavior for IE, + * although the effect is somewhat limited given the 2kb limit. + * + * One advantage of the limited functionality here is that this approach is + * less sensitive to differences in URI encodings than goog.Uri, since these + * functions operate on strings directly, rather than decoding them and + * then re-encoding. + * + * Uses features of RFC 3986 for parsing/formatting URIs: + * http://www.ietf.org/rfc/rfc3986.txt + * + * @author gboyer@google.com (Garrett Boyer) - The "lightened" design. + */ + +goog.provide('goog.uri.utils'); +goog.provide('goog.uri.utils.ComponentIndex'); +goog.provide('goog.uri.utils.QueryArray'); +goog.provide('goog.uri.utils.QueryValue'); +goog.provide('goog.uri.utils.StandardQueryParam'); + +goog.require('goog.asserts'); +goog.require('goog.string'); + + +/** + * Character codes inlined to avoid object allocations due to charCode. + * @enum {number} + * @private + */ +goog.uri.utils.CharCode_ = { + AMPERSAND: 38, + EQUAL: 61, + HASH: 35, + QUESTION: 63 +}; + + +/** + * Builds a URI string from already-encoded parts. + * + * No encoding is performed. Any component may be omitted as either null or + * undefined. + * + * @param {?string=} opt_scheme The scheme such as 'http'. + * @param {?string=} opt_userInfo The user name before the '@'. + * @param {?string=} opt_domain The domain such as 'www.google.com', already + * URI-encoded. + * @param {(string|number|null)=} opt_port The port number. + * @param {?string=} opt_path The path, already URI-encoded. If it is not + * empty, it must begin with a slash. + * @param {?string=} opt_queryData The URI-encoded query data. + * @param {?string=} opt_fragment The URI-encoded fragment identifier. + * @return {string} The fully combined URI. + */ +goog.uri.utils.buildFromEncodedParts = function( + opt_scheme, opt_userInfo, opt_domain, opt_port, opt_path, opt_queryData, + opt_fragment) { + var out = ''; + + if (opt_scheme) { + out += opt_scheme + ':'; + } + + if (opt_domain) { + out += '//'; + + if (opt_userInfo) { + out += opt_userInfo + '@'; + } + + out += opt_domain; + + if (opt_port) { + out += ':' + opt_port; + } + } + + if (opt_path) { + out += opt_path; + } + + if (opt_queryData) { + out += '?' + opt_queryData; + } + + if (opt_fragment) { + out += '#' + opt_fragment; + } + + return out; +}; + + +/** + * A regular expression for breaking a URI into its component parts. + * + * {@link http://www.ietf.org/rfc/rfc3986.txt} says in Appendix B + * As the "first-match-wins" algorithm is identical to the "greedy" + * disambiguation method used by POSIX regular expressions, it is natural and + * commonplace to use a regular expression for parsing the potential five + * components of a URI reference. + * + * The following line is the regular expression for breaking-down a + * well-formed URI reference into its components. + * + * <pre> + * ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? + * 12 3 4 5 6 7 8 9 + * </pre> + * + * The numbers in the second line above are only to assist readability; they + * indicate the reference points for each subexpression (i.e., each paired + * parenthesis). We refer to the value matched for subexpression <n> as $<n>. + * For example, matching the above expression to + * <pre> + * http://www.ics.uci.edu/pub/ietf/uri/#Related + * </pre> + * results in the following subexpression matches: + * <pre> + * $1 = http: + * $2 = http + * $3 = //www.ics.uci.edu + * $4 = www.ics.uci.edu + * $5 = /pub/ietf/uri/ + * $6 = <undefined> + * $7 = <undefined> + * $8 = #Related + * $9 = Related + * </pre> + * where <undefined> indicates that the component is not present, as is the + * case for the query component in the above example. Therefore, we can + * determine the value of the five components as + * <pre> + * scheme = $2 + * authority = $4 + * path = $5 + * query = $7 + * fragment = $9 + * </pre> + * + * The regular expression has been modified slightly to expose the + * userInfo, domain, and port separately from the authority. + * The modified version yields + * <pre> + * $1 = http scheme + * $2 = <undefined> userInfo -\ + * $3 = www.ics.uci.edu domain | authority + * $4 = <undefined> port -/ + * $5 = /pub/ietf/uri/ path + * $6 = <undefined> query without ? + * $7 = Related fragment without # + * </pre> + * @type {!RegExp} + * @private + */ +goog.uri.utils.splitRe_ = new RegExp( + '^' + + '(?:' + + '([^:/?#.]+)' + // scheme - ignore special characters + // used by other URL parts such as :, + // ?, /, #, and . + ':)?' + + '(?://' + + '(?:([^/?#]*)@)?' + // userInfo + '([^/#?]*?)' + // domain + '(?::([0-9]+))?' + // port + '(?=[/#?]|$)' + // authority-terminating character + ')?' + + '([^?#]+)?' + // path + '(?:\\?([^#]*))?' + // query + '(?:#(.*))?' + // fragment + '$'); + + +/** + * The index of each URI component in the return value of goog.uri.utils.split. + * @enum {number} + */ +goog.uri.utils.ComponentIndex = { + SCHEME: 1, + USER_INFO: 2, + DOMAIN: 3, + PORT: 4, + PATH: 5, + QUERY_DATA: 6, + FRAGMENT: 7 +}; + + +/** + * Splits a URI into its component parts. + * + * Each component can be accessed via the component indices; for example: + * <pre> + * goog.uri.utils.split(someStr)[goog.uri.utils.CompontentIndex.QUERY_DATA]; + * </pre> + * + * @param {string} uri The URI string to examine. + * @return {!Array<string|undefined>} Each component still URI-encoded. + * Each component that is present will contain the encoded value, whereas + * components that are not present will be undefined or empty, depending + * on the browser's regular expression implementation. Never null, since + * arbitrary strings may still look like path names. + */ +goog.uri.utils.split = function(uri) { + // See @return comment -- never null. + return /** @type {!Array<string|undefined>} */ ( + uri.match(goog.uri.utils.splitRe_)); +}; + + +/** + * @param {?string} uri A possibly null string. + * @param {boolean=} opt_preserveReserved If true, percent-encoding of RFC-3986 + * reserved characters will not be removed. + * @return {?string} The string URI-decoded, or null if uri is null. + * @private + */ +goog.uri.utils.decodeIfPossible_ = function(uri, opt_preserveReserved) { + if (!uri) { + return uri; + } + + return opt_preserveReserved ? decodeURI(uri) : decodeURIComponent(uri); +}; + + +/** + * Gets a URI component by index. + * + * It is preferred to use the getPathEncoded() variety of functions ahead, + * since they are more readable. + * + * @param {goog.uri.utils.ComponentIndex} componentIndex The component index. + * @param {string} uri The URI to examine. + * @return {?string} The still-encoded component, or null if the component + * is not present. + * @private + */ +goog.uri.utils.getComponentByIndex_ = function(componentIndex, uri) { + // Convert undefined, null, and empty string into null. + return goog.uri.utils.split(uri)[componentIndex] || null; +}; + + +/** + * @param {string} uri The URI to examine. + * @return {?string} The protocol or scheme, or null if none. Does not + * include trailing colons or slashes. + */ +goog.uri.utils.getScheme = function(uri) { + return goog.uri.utils.getComponentByIndex_( + goog.uri.utils.ComponentIndex.SCHEME, uri); +}; + + +/** + * Gets the effective scheme for the URL. If the URL is relative then the + * scheme is derived from the page's location. + * @param {string} uri The URI to examine. + * @return {string} The protocol or scheme, always lower case. + */ +goog.uri.utils.getEffectiveScheme = function(uri) { + var scheme = goog.uri.utils.getScheme(uri); + if (!scheme && goog.global.self && goog.global.self.location) { + var protocol = goog.global.self.location.protocol; + scheme = protocol.substr(0, protocol.length - 1); + } + // NOTE: When called from a web worker in Firefox 3.5, location maybe null. + // All other browsers with web workers support self.location from the worker. + return scheme ? scheme.toLowerCase() : ''; +}; + + +/** + * @param {string} uri The URI to examine. + * @return {?string} The user name still encoded, or null if none. + */ +goog.uri.utils.getUserInfoEncoded = function(uri) { + return goog.uri.utils.getComponentByIndex_( + goog.uri.utils.ComponentIndex.USER_INFO, uri); +}; + + +/** + * @param {string} uri The URI to examine. + * @return {?string} The decoded user info, or null if none. + */ +goog.uri.utils.getUserInfo = function(uri) { + return goog.uri.utils.decodeIfPossible_( + goog.uri.utils.getUserInfoEncoded(uri)); +}; + + +/** + * @param {string} uri The URI to examine. + * @return {?string} The domain name still encoded, or null if none. + */ +goog.uri.utils.getDomainEncoded = function(uri) { + return goog.uri.utils.getComponentByIndex_( + goog.uri.utils.ComponentIndex.DOMAIN, uri); +}; + + +/** + * @param {string} uri The URI to examine. + * @return {?string} The decoded domain, or null if none. + */ +goog.uri.utils.getDomain = function(uri) { + return goog.uri.utils.decodeIfPossible_( + goog.uri.utils.getDomainEncoded(uri), true /* opt_preserveReserved */); +}; + + +/** + * @param {string} uri The URI to examine. + * @return {?number} The port number, or null if none. + */ +goog.uri.utils.getPort = function(uri) { + // Coerce to a number. If the result of getComponentByIndex_ is null or + // non-numeric, the number coersion yields NaN. This will then return + // null for all non-numeric cases (though also zero, which isn't a relevant + // port number). + return Number( + goog.uri.utils.getComponentByIndex_( + goog.uri.utils.ComponentIndex.PORT, uri)) || + null; +}; + + +/** + * @param {string} uri The URI to examine. + * @return {?string} The path still encoded, or null if none. Includes the + * leading slash, if any. + */ +goog.uri.utils.getPathEncoded = function(uri) { + return goog.uri.utils.getComponentByIndex_( + goog.uri.utils.ComponentIndex.PATH, uri); +}; + + +/** + * @param {string} uri The URI to examine. + * @return {?string} The decoded path, or null if none. Includes the leading + * slash, if any. + */ +goog.uri.utils.getPath = function(uri) { + return goog.uri.utils.decodeIfPossible_( + goog.uri.utils.getPathEncoded(uri), true /* opt_preserveReserved */); +}; + + +/** + * @param {string} uri The URI to examine. + * @return {?string} The query data still encoded, or null if none. Does not + * include the question mark itself. + */ +goog.uri.utils.getQueryData = function(uri) { + return goog.uri.utils.getComponentByIndex_( + goog.uri.utils.ComponentIndex.QUERY_DATA, uri); +}; + + +/** + * @param {string} uri The URI to examine. + * @return {?string} The fragment identifier, or null if none. Does not + * include the hash mark itself. + */ +goog.uri.utils.getFragmentEncoded = function(uri) { + // The hash mark may not appear in any other part of the URL. + var hashIndex = uri.indexOf('#'); + return hashIndex < 0 ? null : uri.substr(hashIndex + 1); +}; + + +/** + * @param {string} uri The URI to examine. + * @param {?string} fragment The encoded fragment identifier, or null if none. + * Does not include the hash mark itself. + * @return {string} The URI with the fragment set. + */ +goog.uri.utils.setFragmentEncoded = function(uri, fragment) { + return goog.uri.utils.removeFragment(uri) + (fragment ? '#' + fragment : ''); +}; + + +/** + * @param {string} uri The URI to examine. + * @return {?string} The decoded fragment identifier, or null if none. Does + * not include the hash mark. + */ +goog.uri.utils.getFragment = function(uri) { + return goog.uri.utils.decodeIfPossible_( + goog.uri.utils.getFragmentEncoded(uri)); +}; + + +/** + * Extracts everything up to the port of the URI. + * @param {string} uri The URI string. + * @return {string} Everything up to and including the port. + */ +goog.uri.utils.getHost = function(uri) { + var pieces = goog.uri.utils.split(uri); + return goog.uri.utils.buildFromEncodedParts( + pieces[goog.uri.utils.ComponentIndex.SCHEME], + pieces[goog.uri.utils.ComponentIndex.USER_INFO], + pieces[goog.uri.utils.ComponentIndex.DOMAIN], + pieces[goog.uri.utils.ComponentIndex.PORT]); +}; + + +/** + * Extracts the path of the URL and everything after. + * @param {string} uri The URI string. + * @return {string} The URI, starting at the path and including the query + * parameters and fragment identifier. + */ +goog.uri.utils.getPathAndAfter = function(uri) { + var pieces = goog.uri.utils.split(uri); + return goog.uri.utils.buildFromEncodedParts( + null, null, null, null, pieces[goog.uri.utils.ComponentIndex.PATH], + pieces[goog.uri.utils.ComponentIndex.QUERY_DATA], + pieces[goog.uri.utils.ComponentIndex.FRAGMENT]); +}; + + +/** + * Gets the URI with the fragment identifier removed. + * @param {string} uri The URI to examine. + * @return {string} Everything preceding the hash mark. + */ +goog.uri.utils.removeFragment = function(uri) { + // The hash mark may not appear in any other part of the URL. + var hashIndex = uri.indexOf('#'); + return hashIndex < 0 ? uri : uri.substr(0, hashIndex); +}; + + +/** + * Ensures that two URI's have the exact same domain, scheme, and port. + * + * Unlike the version in goog.Uri, this checks protocol, and therefore is + * suitable for checking against the browser's same-origin policy. + * + * @param {string} uri1 The first URI. + * @param {string} uri2 The second URI. + * @return {boolean} Whether they have the same scheme, domain and port. + */ +goog.uri.utils.haveSameDomain = function(uri1, uri2) { + var pieces1 = goog.uri.utils.split(uri1); + var pieces2 = goog.uri.utils.split(uri2); + return pieces1[goog.uri.utils.ComponentIndex.DOMAIN] == + pieces2[goog.uri.utils.ComponentIndex.DOMAIN] && + pieces1[goog.uri.utils.ComponentIndex.SCHEME] == + pieces2[goog.uri.utils.ComponentIndex.SCHEME] && + pieces1[goog.uri.utils.ComponentIndex.PORT] == + pieces2[goog.uri.utils.ComponentIndex.PORT]; +}; + + +/** + * Asserts that there are no fragment or query identifiers, only in uncompiled + * mode. + * @param {string} uri The URI to examine. + * @private + */ +goog.uri.utils.assertNoFragmentsOrQueries_ = function(uri) { + // NOTE: would use goog.asserts here, but jscompiler doesn't know that + // indexOf has no side effects. + if (goog.DEBUG && (uri.indexOf('#') >= 0 || uri.indexOf('?') >= 0)) { + throw Error( + 'goog.uri.utils: Fragment or query identifiers are not ' + + 'supported: [' + uri + ']'); + } +}; + + +/** + * Supported query parameter values by the parameter serializing utilities. + * + * If a value is null or undefined, the key-value pair is skipped, as an easy + * way to omit parameters conditionally. Non-array parameters are converted + * to a string and URI encoded. Array values are expanded into multiple + * &key=value pairs, with each element stringized and URI-encoded. + * + * @typedef {*} + */ +goog.uri.utils.QueryValue; + + +/** + * An array representing a set of query parameters with alternating keys + * and values. + * + * Keys are assumed to be URI encoded already and live at even indices. See + * goog.uri.utils.QueryValue for details on how parameter values are encoded. + * + * Example: + * <pre> + * var data = [ + * // Simple param: ?name=BobBarker + * 'name', 'BobBarker', + * // Conditional param -- may be omitted entirely. + * 'specialDietaryNeeds', hasDietaryNeeds() ? getDietaryNeeds() : null, + * // Multi-valued param: &house=LosAngeles&house=NewYork&house=null + * 'house', ['LosAngeles', 'NewYork', null] + * ]; + * </pre> + * + * @typedef {!Array<string|goog.uri.utils.QueryValue>} + */ +goog.uri.utils.QueryArray; + + +/** + * Parses encoded query parameters and calls callback function for every + * parameter found in the string. + * + * Missing value of parameter (e.g. “…&key&…”) is treated as if the value was an + * empty string. Keys may be empty strings (e.g. “…&=value&…”) which also means + * that “…&=&…” and “…&&…” will result in an empty key and value. + * + * @param {string} encodedQuery Encoded query string excluding question mark at + * the beginning. + * @param {function(string, string)} callback Function called for every + * parameter found in query string. The first argument (name) will not be + * urldecoded (so the function is consistent with buildQueryData), but the + * second will. If the parameter has no value (i.e. “=” was not present) + * the second argument (value) will be an empty string. + */ +goog.uri.utils.parseQueryData = function(encodedQuery, callback) { + if (!encodedQuery) { + return; + } + var pairs = encodedQuery.split('&'); + for (var i = 0; i < pairs.length; i++) { + var indexOfEquals = pairs[i].indexOf('='); + var name = null; + var value = null; + if (indexOfEquals >= 0) { + name = pairs[i].substring(0, indexOfEquals); + value = pairs[i].substring(indexOfEquals + 1); + } else { + name = pairs[i]; + } + callback(name, value ? goog.string.urlDecode(value) : ''); + } +}; + + +/** + * Appends a URI and query data in a string buffer with special preconditions. + * + * Internal implementation utility, performing very few object allocations. + * + * @param {!Array<string|undefined>} buffer A string buffer. The first element + * must be the base URI, and may have a fragment identifier. If the array + * contains more than one element, the second element must be an ampersand, + * and may be overwritten, depending on the base URI. Undefined elements + * are treated as empty-string. + * @return {string} The concatenated URI and query data. + * @private + */ +goog.uri.utils.appendQueryData_ = function(buffer) { + if (buffer[1]) { + // At least one query parameter was added. We need to check the + // punctuation mark, which is currently an ampersand, and also make sure + // there aren't any interfering fragment identifiers. + var baseUri = /** @type {string} */ (buffer[0]); + var hashIndex = baseUri.indexOf('#'); + if (hashIndex >= 0) { + // Move the fragment off the base part of the URI into the end. + buffer.push(baseUri.substr(hashIndex)); + buffer[0] = baseUri = baseUri.substr(0, hashIndex); + } + var questionIndex = baseUri.indexOf('?'); + if (questionIndex < 0) { + // No question mark, so we need a question mark instead of an ampersand. + buffer[1] = '?'; + } else if (questionIndex == baseUri.length - 1) { + // Question mark is the very last character of the existing URI, so don't + // append an additional delimiter. + buffer[1] = undefined; + } + } + + return buffer.join(''); +}; + + +/** + * Appends key=value pairs to an array, supporting multi-valued objects. + * @param {string} key The key prefix. + * @param {goog.uri.utils.QueryValue} value The value to serialize. + * @param {!Array<string>} pairs The array to which the 'key=value' strings + * should be appended. + * @private + */ +goog.uri.utils.appendKeyValuePairs_ = function(key, value, pairs) { + if (goog.isArray(value)) { + // Convince the compiler it's an array. + goog.asserts.assertArray(value); + for (var j = 0; j < value.length; j++) { + // Convert to string explicitly, to short circuit the null and array + // logic in this function -- this ensures that null and undefined get + // written as literal 'null' and 'undefined', and arrays don't get + // expanded out but instead encoded in the default way. + goog.uri.utils.appendKeyValuePairs_(key, String(value[j]), pairs); + } + } else if (value != null) { + // Skip a top-level null or undefined entirely. + pairs.push( + '&', key, + // Check for empty string. Zero gets encoded into the url as literal + // strings. For empty string, skip the equal sign, to be consistent + // with UriBuilder.java. + value === '' ? '' : '=', goog.string.urlEncode(value)); + } +}; + + +/** + * Builds a buffer of query data from a sequence of alternating keys and values. + * + * @param {!Array<string|undefined>} buffer A string buffer to append to. The + * first element appended will be an '&', and may be replaced by the caller. + * @param {!goog.uri.utils.QueryArray|!Arguments} keysAndValues An array with + * alternating keys and values -- see the typedef. + * @param {number=} opt_startIndex A start offset into the arary, defaults to 0. + * @return {!Array<string|undefined>} The buffer argument. + * @private + */ +goog.uri.utils.buildQueryDataBuffer_ = function( + buffer, keysAndValues, opt_startIndex) { + goog.asserts.assert( + Math.max(keysAndValues.length - (opt_startIndex || 0), 0) % 2 == 0, + 'goog.uri.utils: Key/value lists must be even in length.'); + + for (var i = opt_startIndex || 0; i < keysAndValues.length; i += 2) { + goog.uri.utils.appendKeyValuePairs_( + keysAndValues[i], keysAndValues[i + 1], buffer); + } + + return buffer; +}; + + +/** + * Builds a query data string from a sequence of alternating keys and values. + * Currently generates "&key&" for empty args. + * + * @param {goog.uri.utils.QueryArray} keysAndValues Alternating keys and + * values. See the typedef. + * @param {number=} opt_startIndex A start offset into the arary, defaults to 0. + * @return {string} The encoded query string, in the form 'a=1&b=2'. + */ +goog.uri.utils.buildQueryData = function(keysAndValues, opt_startIndex) { + var buffer = + goog.uri.utils.buildQueryDataBuffer_([], keysAndValues, opt_startIndex); + buffer[0] = ''; // Remove the leading ampersand. + return buffer.join(''); +}; + + +/** + * Builds a buffer of query data from a map. + * + * @param {!Array<string|undefined>} buffer A string buffer to append to. The + * first element appended will be an '&', and may be replaced by the caller. + * @param {!Object<string, goog.uri.utils.QueryValue>} map An object where keys + * are URI-encoded parameter keys, and the values conform to the contract + * specified in the goog.uri.utils.QueryValue typedef. + * @return {!Array<string|undefined>} The buffer argument. + * @private + */ +goog.uri.utils.buildQueryDataBufferFromMap_ = function(buffer, map) { + for (var key in map) { + goog.uri.utils.appendKeyValuePairs_(key, map[key], buffer); + } + + return buffer; +}; + + +/** + * Builds a query data string from a map. + * Currently generates "&key&" for empty args. + * + * @param {!Object<string, goog.uri.utils.QueryValue>} map An object where keys + * are URI-encoded parameter keys, and the values are arbitrary types + * or arrays. Keys with a null value are dropped. + * @return {string} The encoded query string, in the form 'a=1&b=2'. + */ +goog.uri.utils.buildQueryDataFromMap = function(map) { + var buffer = goog.uri.utils.buildQueryDataBufferFromMap_([], map); + buffer[0] = ''; + return buffer.join(''); +}; + + +/** + * Appends URI parameters to an existing URI. + * + * The variable arguments may contain alternating keys and values. Keys are + * assumed to be already URI encoded. The values should not be URI-encoded, + * and will instead be encoded by this function. + * <pre> + * appendParams('http://www.foo.com?existing=true', + * 'key1', 'value1', + * 'key2', 'value?willBeEncoded', + * 'key3', ['valueA', 'valueB', 'valueC'], + * 'key4', null); + * result: 'http://www.foo.com?existing=true&' + + * 'key1=value1&' + + * 'key2=value%3FwillBeEncoded&' + + * 'key3=valueA&key3=valueB&key3=valueC' + * </pre> + * + * A single call to this function will not exhibit quadratic behavior in IE, + * whereas multiple repeated calls may, although the effect is limited by + * fact that URL's generally can't exceed 2kb. + * + * @param {string} uri The original URI, which may already have query data. + * @param {...(goog.uri.utils.QueryArray|string|goog.uri.utils.QueryValue)} + * var_args + * An array or argument list conforming to goog.uri.utils.QueryArray. + * @return {string} The URI with all query parameters added. + */ +goog.uri.utils.appendParams = function(uri, var_args) { + return goog.uri.utils.appendQueryData_( + arguments.length == 2 ? + goog.uri.utils.buildQueryDataBuffer_([uri], arguments[1], 0) : + goog.uri.utils.buildQueryDataBuffer_([uri], arguments, 1)); +}; + + +/** + * Appends query parameters from a map. + * + * @param {string} uri The original URI, which may already have query data. + * @param {!Object<goog.uri.utils.QueryValue>} map An object where keys are + * URI-encoded parameter keys, and the values are arbitrary types or arrays. + * Keys with a null value are dropped. + * @return {string} The new parameters. + */ +goog.uri.utils.appendParamsFromMap = function(uri, map) { + return goog.uri.utils.appendQueryData_( + goog.uri.utils.buildQueryDataBufferFromMap_([uri], map)); +}; + + +/** + * Appends a single URI parameter. + * + * Repeated calls to this can exhibit quadratic behavior in IE6 due to the + * way string append works, though it should be limited given the 2kb limit. + * + * @param {string} uri The original URI, which may already have query data. + * @param {string} key The key, which must already be URI encoded. + * @param {*=} opt_value The value, which will be stringized and encoded + * (assumed not already to be encoded). If omitted, undefined, or null, the + * key will be added as a valueless parameter. + * @return {string} The URI with the query parameter added. + */ +goog.uri.utils.appendParam = function(uri, key, opt_value) { + var paramArr = [uri, '&', key]; + if (goog.isDefAndNotNull(opt_value)) { + paramArr.push('=', goog.string.urlEncode(opt_value)); + } + return goog.uri.utils.appendQueryData_(paramArr); +}; + + +/** + * Finds the next instance of a query parameter with the specified name. + * + * Does not instantiate any objects. + * + * @param {string} uri The URI to search. May contain a fragment identifier + * if opt_hashIndex is specified. + * @param {number} startIndex The index to begin searching for the key at. A + * match may be found even if this is one character after the ampersand. + * @param {string} keyEncoded The URI-encoded key. + * @param {number} hashOrEndIndex Index to stop looking at. If a hash + * mark is present, it should be its index, otherwise it should be the + * length of the string. + * @return {number} The position of the first character in the key's name, + * immediately after either a question mark or a dot. + * @private + */ +goog.uri.utils.findParam_ = function( + uri, startIndex, keyEncoded, hashOrEndIndex) { + var index = startIndex; + var keyLength = keyEncoded.length; + + // Search for the key itself and post-filter for surronuding punctuation, + // rather than expensively building a regexp. + while ((index = uri.indexOf(keyEncoded, index)) >= 0 && + index < hashOrEndIndex) { + var precedingChar = uri.charCodeAt(index - 1); + // Ensure that the preceding character is '&' or '?'. + if (precedingChar == goog.uri.utils.CharCode_.AMPERSAND || + precedingChar == goog.uri.utils.CharCode_.QUESTION) { + // Ensure the following character is '&', '=', '#', or NaN + // (end of string). + var followingChar = uri.charCodeAt(index + keyLength); + if (!followingChar || followingChar == goog.uri.utils.CharCode_.EQUAL || + followingChar == goog.uri.utils.CharCode_.AMPERSAND || + followingChar == goog.uri.utils.CharCode_.HASH) { + return index; + } + } + index += keyLength + 1; + } + + return -1; +}; + + +/** + * Regular expression for finding a hash mark or end of string. + * @type {RegExp} + * @private + */ +goog.uri.utils.hashOrEndRe_ = /#|$/; + + +/** + * Determines if the URI contains a specific key. + * + * Performs no object instantiations. + * + * @param {string} uri The URI to process. May contain a fragment + * identifier. + * @param {string} keyEncoded The URI-encoded key. Case-sensitive. + * @return {boolean} Whether the key is present. + */ +goog.uri.utils.hasParam = function(uri, keyEncoded) { + return goog.uri.utils.findParam_( + uri, 0, keyEncoded, uri.search(goog.uri.utils.hashOrEndRe_)) >= 0; +}; + + +/** + * Gets the first value of a query parameter. + * @param {string} uri The URI to process. May contain a fragment. + * @param {string} keyEncoded The URI-encoded key. Case-sensitive. + * @return {?string} The first value of the parameter (URI-decoded), or null + * if the parameter is not found. + */ +goog.uri.utils.getParamValue = function(uri, keyEncoded) { + var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_); + var foundIndex = + goog.uri.utils.findParam_(uri, 0, keyEncoded, hashOrEndIndex); + + if (foundIndex < 0) { + return null; + } else { + var endPosition = uri.indexOf('&', foundIndex); + if (endPosition < 0 || endPosition > hashOrEndIndex) { + endPosition = hashOrEndIndex; + } + // Progress forth to the end of the "key=" or "key&" substring. + foundIndex += keyEncoded.length + 1; + // Use substr, because it (unlike substring) will return empty string + // if foundIndex > endPosition. + return goog.string.urlDecode( + uri.substr(foundIndex, endPosition - foundIndex)); + } +}; + + +/** + * Gets all values of a query parameter. + * @param {string} uri The URI to process. May contain a fragment. + * @param {string} keyEncoded The URI-encoded key. Case-sensitive. + * @return {!Array<string>} All URI-decoded values with the given key. + * If the key is not found, this will have length 0, but never be null. + */ +goog.uri.utils.getParamValues = function(uri, keyEncoded) { + var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_); + var position = 0; + var foundIndex; + var result = []; + + while ((foundIndex = goog.uri.utils.findParam_( + uri, position, keyEncoded, hashOrEndIndex)) >= 0) { + // Find where this parameter ends, either the '&' or the end of the + // query parameters. + position = uri.indexOf('&', foundIndex); + if (position < 0 || position > hashOrEndIndex) { + position = hashOrEndIndex; + } + + // Progress forth to the end of the "key=" or "key&" substring. + foundIndex += keyEncoded.length + 1; + // Use substr, because it (unlike substring) will return empty string + // if foundIndex > position. + result.push( + goog.string.urlDecode(uri.substr(foundIndex, position - foundIndex))); + } + + return result; +}; + + +/** + * Regexp to find trailing question marks and ampersands. + * @type {RegExp} + * @private + */ +goog.uri.utils.trailingQueryPunctuationRe_ = /[?&]($|#)/; + + +/** + * Removes all instances of a query parameter. + * @param {string} uri The URI to process. Must not contain a fragment. + * @param {string} keyEncoded The URI-encoded key. + * @return {string} The URI with all instances of the parameter removed. + */ +goog.uri.utils.removeParam = function(uri, keyEncoded) { + var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_); + var position = 0; + var foundIndex; + var buffer = []; + + // Look for a query parameter. + while ((foundIndex = goog.uri.utils.findParam_( + uri, position, keyEncoded, hashOrEndIndex)) >= 0) { + // Get the portion of the query string up to, but not including, the ? + // or & starting the parameter. + buffer.push(uri.substring(position, foundIndex)); + // Progress to immediately after the '&'. If not found, go to the end. + // Avoid including the hash mark. + position = Math.min( + (uri.indexOf('&', foundIndex) + 1) || hashOrEndIndex, hashOrEndIndex); + } + + // Append everything that is remaining. + buffer.push(uri.substr(position)); + + // Join the buffer, and remove trailing punctuation that remains. + return buffer.join('').replace( + goog.uri.utils.trailingQueryPunctuationRe_, '$1'); +}; + + +/** + * Replaces all existing definitions of a parameter with a single definition. + * + * Repeated calls to this can exhibit quadratic behavior due to the need to + * find existing instances and reconstruct the string, though it should be + * limited given the 2kb limit. Consider using appendParams to append multiple + * parameters in bulk. + * + * @param {string} uri The original URI, which may already have query data. + * @param {string} keyEncoded The key, which must already be URI encoded. + * @param {*} value The value, which will be stringized and encoded (assumed + * not already to be encoded). + * @return {string} The URI with the query parameter added. + */ +goog.uri.utils.setParam = function(uri, keyEncoded, value) { + return goog.uri.utils.appendParam( + goog.uri.utils.removeParam(uri, keyEncoded), keyEncoded, value); +}; + + +/** + * Generates a URI path using a given URI and a path with checks to + * prevent consecutive "//". The baseUri passed in must not contain + * query or fragment identifiers. The path to append may not contain query or + * fragment identifiers. + * + * @param {string} baseUri URI to use as the base. + * @param {string} path Path to append. + * @return {string} Updated URI. + */ +goog.uri.utils.appendPath = function(baseUri, path) { + goog.uri.utils.assertNoFragmentsOrQueries_(baseUri); + + // Remove any trailing '/' + if (goog.string.endsWith(baseUri, '/')) { + baseUri = baseUri.substr(0, baseUri.length - 1); + } + // Remove any leading '/' + if (goog.string.startsWith(path, '/')) { + path = path.substr(1); + } + return goog.string.buildString(baseUri, '/', path); +}; + + +/** + * Replaces the path. + * @param {string} uri URI to use as the base. + * @param {string} path New path. + * @return {string} Updated URI. + */ +goog.uri.utils.setPath = function(uri, path) { + // Add any missing '/'. + if (!goog.string.startsWith(path, '/')) { + path = '/' + path; + } + var parts = goog.uri.utils.split(uri); + return goog.uri.utils.buildFromEncodedParts( + parts[goog.uri.utils.ComponentIndex.SCHEME], + parts[goog.uri.utils.ComponentIndex.USER_INFO], + parts[goog.uri.utils.ComponentIndex.DOMAIN], + parts[goog.uri.utils.ComponentIndex.PORT], path, + parts[goog.uri.utils.ComponentIndex.QUERY_DATA], + parts[goog.uri.utils.ComponentIndex.FRAGMENT]); +}; + + +/** + * Standard supported query parameters. + * @enum {string} + */ +goog.uri.utils.StandardQueryParam = { + + /** Unused parameter for unique-ifying. */ + RANDOM: 'zx' +}; + + +/** + * Sets the zx parameter of a URI to a random value. + * @param {string} uri Any URI. + * @return {string} That URI with the "zx" parameter added or replaced to + * contain a random string. + */ +goog.uri.utils.makeUnique = function(uri) { + return goog.uri.utils.setParam( + uri, goog.uri.utils.StandardQueryParam.RANDOM, + goog.string.getRandomString()); +}; + +// Copyright 2006 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** * @fileoverview Class for parsing and formatting URIs. * * Use goog.Uri(string) to parse a URI string. Use goog.Uri.create(...) to @@ -95800,6 +81364,7 @@ goog.provide('goog.Uri'); goog.provide('goog.Uri.QueryData'); goog.require('goog.array'); +goog.require('goog.asserts'); goog.require('goog.string'); goog.require('goog.structs'); goog.require('goog.structs.Map'); @@ -95897,8 +81462,8 @@ goog.Uri = function(opt_uri, opt_ignoreCase) { // Parse in the uri string var m; if (opt_uri instanceof goog.Uri) { - this.ignoreCase_ = goog.isDef(opt_ignoreCase) ? - opt_ignoreCase : opt_uri.getIgnoreCase(); + this.ignoreCase_ = + goog.isDef(opt_ignoreCase) ? opt_ignoreCase : opt_uri.getIgnoreCase(); this.setScheme(opt_uri.getScheme()); this.setUserInfo(opt_uri.getUserInfo()); this.setDomain(opt_uri.getDomain()); @@ -95959,8 +81524,10 @@ goog.Uri.prototype.toString = function() { var scheme = this.getScheme(); if (scheme) { - out.push(goog.Uri.encodeSpecialChars_( - scheme, goog.Uri.reDisallowedInSchemeOrUserInfo_, true), ':'); + out.push( + goog.Uri.encodeSpecialChars_( + scheme, goog.Uri.reDisallowedInSchemeOrUserInfo_, true), + ':'); } var domain = this.getDomain(); @@ -95969,8 +81536,10 @@ goog.Uri.prototype.toString = function() { var userInfo = this.getUserInfo(); if (userInfo) { - out.push(goog.Uri.encodeSpecialChars_( - userInfo, goog.Uri.reDisallowedInSchemeOrUserInfo_, true), '@'); + out.push( + goog.Uri.encodeSpecialChars_( + userInfo, goog.Uri.reDisallowedInSchemeOrUserInfo_, true), + '@'); } out.push(goog.Uri.removeDoubleEncoding_(goog.string.urlEncode(domain))); @@ -95986,12 +81555,11 @@ goog.Uri.prototype.toString = function() { if (this.hasDomain() && path.charAt(0) != '/') { out.push('/'); } - out.push(goog.Uri.encodeSpecialChars_( - path, - path.charAt(0) == '/' ? - goog.Uri.reDisallowedInAbsolutePath_ : - goog.Uri.reDisallowedInRelativePath_, - true)); + out.push( + goog.Uri.encodeSpecialChars_( + path, path.charAt(0) == '/' ? goog.Uri.reDisallowedInAbsolutePath_ : + goog.Uri.reDisallowedInRelativePath_, + true)); } var query = this.getEncodedQuery(); @@ -96001,8 +81569,9 @@ goog.Uri.prototype.toString = function() { var fragment = this.getFragment(); if (fragment) { - out.push('#', goog.Uri.encodeSpecialChars_( - fragment, goog.Uri.reDisallowedInFragment_)); + out.push( + '#', goog.Uri.encodeSpecialChars_( + fragment, goog.Uri.reDisallowedInFragment_)); } return out.join(''); }; @@ -96123,8 +81692,8 @@ goog.Uri.prototype.getScheme = function() { */ goog.Uri.prototype.setScheme = function(newScheme, opt_decode) { this.enforceReadOnly(); - this.scheme_ = opt_decode ? goog.Uri.decodeOrEmpty_(newScheme, true) : - newScheme; + this.scheme_ = + opt_decode ? goog.Uri.decodeOrEmpty_(newScheme, true) : newScheme; // remove an : at the end of the scheme so somebody can pass in // window.location.protocol @@ -96161,8 +81730,8 @@ goog.Uri.prototype.getUserInfo = function() { */ goog.Uri.prototype.setUserInfo = function(newUserInfo, opt_decode) { this.enforceReadOnly(); - this.userInfo_ = opt_decode ? goog.Uri.decodeOrEmpty_(newUserInfo) : - newUserInfo; + this.userInfo_ = + opt_decode ? goog.Uri.decodeOrEmpty_(newUserInfo) : newUserInfo; return this; }; @@ -96193,8 +81762,8 @@ goog.Uri.prototype.getDomain = function() { */ goog.Uri.prototype.setDomain = function(newDomain, opt_decode) { this.enforceReadOnly(); - this.domain_ = opt_decode ? goog.Uri.decodeOrEmpty_(newDomain, true) : - newDomain; + this.domain_ = + opt_decode ? goog.Uri.decodeOrEmpty_(newDomain, true) : newDomain; return this; }; @@ -96301,8 +81870,8 @@ goog.Uri.prototype.setQueryData = function(queryData, opt_decode) { if (!opt_decode) { // QueryData accepts encoded query string, so encode it if // opt_decode flag is not true. - queryData = goog.Uri.encodeSpecialChars_(queryData, - goog.Uri.reDisallowedInQuery_); + queryData = goog.Uri.encodeSpecialChars_( + queryData, goog.Uri.reDisallowedInQuery_); } this.queryData_ = new goog.Uri.QueryData(queryData, null, this.ignoreCase_); } @@ -96445,8 +82014,8 @@ goog.Uri.prototype.getFragment = function() { */ goog.Uri.prototype.setFragment = function(newFragment, opt_decode) { this.enforceReadOnly(); - this.fragment_ = opt_decode ? goog.Uri.decodeOrEmpty_(newFragment) : - newFragment; + this.fragment_ = + opt_decode ? goog.Uri.decodeOrEmpty_(newFragment) : newFragment; return this; }; @@ -96468,7 +82037,7 @@ goog.Uri.prototype.hasSameDomainAs = function(uri2) { return ((!this.hasDomain() && !uri2.hasDomain()) || this.getDomain() == uri2.getDomain()) && ((!this.hasPort() && !uri2.hasPort()) || - this.getPort() == uri2.getPort()); + this.getPort() == uri2.getPort()); }; @@ -96571,8 +82140,8 @@ goog.Uri.prototype.getIgnoreCase = function() { * @return {!goog.Uri} The new URI object. */ goog.Uri.parse = function(uri, opt_ignoreCase) { - return uri instanceof goog.Uri ? - uri.clone() : new goog.Uri(uri, opt_ignoreCase); + return uri instanceof goog.Uri ? uri.clone() : + new goog.Uri(uri, opt_ignoreCase); }; @@ -96591,8 +82160,9 @@ goog.Uri.parse = function(uri, opt_ignoreCase) { * * @return {!goog.Uri} The new URI object. */ -goog.Uri.create = function(opt_scheme, opt_userInfo, opt_domain, opt_port, - opt_path, opt_query, opt_fragment, opt_ignoreCase) { +goog.Uri.create = function( + opt_scheme, opt_userInfo, opt_domain, opt_port, opt_path, opt_query, + opt_fragment, opt_ignoreCase) { var uri = new goog.Uri(null, opt_ignoreCase); @@ -96641,8 +82211,8 @@ goog.Uri.removeDotSegments = function(path) { if (path == '..' || path == '.') { return ''; - } else if (!goog.string.contains(path, './') && - !goog.string.contains(path, '/.')) { + } else if ( + !goog.string.contains(path, './') && !goog.string.contains(path, '/.')) { // This optimization detects uris which do not contain dot-segments, // and as a consequence do not require any processing. return path; @@ -96652,7 +82222,7 @@ goog.Uri.removeDotSegments = function(path) { var segments = path.split('/'); var out = []; - for (var pos = 0; pos < segments.length; ) { + for (var pos = 0; pos < segments.length;) { var segment = segments[pos++]; if (segment == '.') { @@ -96695,8 +82265,8 @@ goog.Uri.decodeOrEmpty_ = function(val, opt_preserveReserved) { // decodeURI has the same output for '%2f' and '%252f'. We double encode %25 // so that we can distinguish between the 2 inputs. This is later undone by // removeDoubleEncoding_. - return opt_preserveReserved ? - decodeURI(val.replace(/%25/g, '%2525')) : decodeURIComponent(val); + return opt_preserveReserved ? decodeURI(val.replace(/%25/g, '%2525')) : + decodeURIComponent(val); }; @@ -96712,11 +82282,10 @@ goog.Uri.decodeOrEmpty_ = function(val, opt_preserveReserved) { * @return {?string} null iff unescapedPart == null. * @private */ -goog.Uri.encodeSpecialChars_ = function(unescapedPart, extra, - opt_removeDoubleEncoding) { +goog.Uri.encodeSpecialChars_ = function( + unescapedPart, extra, opt_removeDoubleEncoding) { if (goog.isString(unescapedPart)) { - var encoded = encodeURI(unescapedPart). - replace(extra, goog.Uri.encodeChar_); + var encoded = encodeURI(unescapedPart).replace(extra, goog.Uri.encodeChar_); if (opt_removeDoubleEncoding) { // encodeURI double-escapes %XX sequences used to represent restricted // characters in some URI components, remove the double escaping here. @@ -96805,9 +82374,9 @@ goog.Uri.haveSameDomain = function(uri1String, uri2String) { var pieces1 = goog.uri.utils.split(uri1String); var pieces2 = goog.uri.utils.split(uri2String); return pieces1[goog.uri.utils.ComponentIndex.DOMAIN] == - pieces2[goog.uri.utils.ComponentIndex.DOMAIN] && - pieces1[goog.uri.utils.ComponentIndex.PORT] == - pieces2[goog.uri.utils.ComponentIndex.PORT]; + pieces2[goog.uri.utils.ComponentIndex.DOMAIN] && + pieces1[goog.uri.utils.ComponentIndex.PORT] == + pieces2[goog.uri.utils.ComponentIndex.PORT]; }; @@ -96965,7 +82534,7 @@ goog.Uri.QueryData.prototype.add = function(key, value) { this.keyMap_.set(key, (values = [])); } values.push(value); - this.count_++; + this.count_ = goog.asserts.assertNumber(this.count_) + 1; return this; }; @@ -96983,7 +82552,8 @@ goog.Uri.QueryData.prototype.remove = function(key) { this.invalidateCache_(); // Decrement parameter count. - this.count_ -= this.keyMap_.get(key).length; + this.count_ = + goog.asserts.assertNumber(this.count_) - this.keyMap_.get(key).length; return this.keyMap_.remove(key); } return false; @@ -97043,7 +82613,7 @@ goog.Uri.QueryData.prototype.containsValue = function(value) { goog.Uri.QueryData.prototype.getKeys = function() { this.ensureKeyMapInitialized_(); // We need to get the values to know how many keys to add. - var vals = /** @type {!Array<*>} */ (this.keyMap_.getValues()); + var vals = this.keyMap_.getValues(); var keys = this.keyMap_.getKeys(); var rv = []; for (var i = 0; i < keys.length; i++) { @@ -97099,10 +82669,11 @@ goog.Uri.QueryData.prototype.set = function(key, value) { // ordering. key = this.getKeyName_(key); if (this.containsKey(key)) { - this.count_ -= this.keyMap_.get(key).length; + this.count_ = + goog.asserts.assertNumber(this.count_) - this.keyMap_.get(key).length; } this.keyMap_.set(key, [value]); - this.count_++; + this.count_ = goog.asserts.assertNumber(this.count_) + 1; return this; }; @@ -97138,7 +82709,7 @@ goog.Uri.QueryData.prototype.setValues = function(key, values) { if (values.length > 0) { this.invalidateCache_(); this.keyMap_.set(this.getKeyName_(key), goog.array.clone(values)); - this.count_ += values.length; + this.count_ = goog.asserts.assertNumber(this.count_) + values.length; } }; @@ -97207,12 +82778,11 @@ goog.Uri.QueryData.prototype.invalidateCache_ = function() { */ goog.Uri.QueryData.prototype.filterKeys = function(keys) { this.ensureKeyMapInitialized_(); - this.keyMap_.forEach( - function(value, key) { - if (!goog.array.contains(keys, key)) { - this.remove(key); - } - }, this); + this.keyMap_.forEach(function(value, key) { + if (!goog.array.contains(keys, key)) { + this.remove(key); + } + }, this); return this; }; @@ -97259,14 +82829,13 @@ goog.Uri.QueryData.prototype.setIgnoreCase = function(ignoreCase) { if (resetKeys) { this.ensureKeyMapInitialized_(); this.invalidateCache_(); - this.keyMap_.forEach( - function(value, key) { - var lowerCase = key.toLowerCase(); - if (key != lowerCase) { - this.remove(key); - this.setValues(lowerCase, value); - } - }, this); + this.keyMap_.forEach(function(value, key) { + var lowerCase = key.toLowerCase(); + if (key != lowerCase) { + this.remove(key); + this.setValues(lowerCase, value); + } + }, this); } this.ignoreCase_ = ignoreCase; }; @@ -97282,11 +82851,8 @@ goog.Uri.QueryData.prototype.setIgnoreCase = function(ignoreCase) { goog.Uri.QueryData.prototype.extend = function(var_args) { for (var i = 0; i < arguments.length; i++) { var data = arguments[i]; - goog.structs.forEach(data, - /** @this {goog.Uri.QueryData} */ - function(value, key) { - this.add(key, value); - }, this); + goog.structs.forEach( + data, function(value, key) { this.add(key, value); }, this); } }; @@ -97296,7 +82862,6 @@ goog.provide('ol.style.Text'); goog.require('ol.style.Fill'); - /** * @classdesc * Set text style for vector features. @@ -97593,20 +83158,17 @@ ol.style.Text.prototype.setTextBaseline = function(textBaseline) { // FIXME http://earth.google.com/kml/1.0 namespace? // FIXME why does node.getAttribute return an unknown type? -// FIXME text // FIXME serialize arbitrary feature properties // FIXME don't parse style if extractStyles is false goog.provide('ol.format.KML'); goog.require('goog.Uri'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom.NodeType'); goog.require('goog.object'); goog.require('ol'); goog.require('ol.Feature'); -goog.require('ol.FeatureStyleFunction'); goog.require('ol.array'); goog.require('ol.color'); goog.require('ol.format.Feature'); @@ -97624,6 +83186,7 @@ goog.require('ol.geom.MultiPolygon'); goog.require('ol.geom.Point'); goog.require('ol.geom.Polygon'); goog.require('ol.math'); +goog.require('ol.object'); goog.require('ol.proj'); goog.require('ol.style.Fill'); goog.require('ol.style.Icon'); @@ -97637,21 +83200,6 @@ goog.require('ol.xml'); /** - * @typedef {{x: number, xunits: (ol.style.IconAnchorUnits|undefined), - * y: number, yunits: (ol.style.IconAnchorUnits|undefined)}} - */ -ol.format.KMLVec2_; - - -/** - * @typedef {{flatCoordinates: Array.<number>, - * whens: Array.<number>}} - */ -ol.format.KMLGxTrackObject_; - - - -/** * @classdesc * Feature format for reading and writing data in the KML format. * @@ -97912,7 +83460,6 @@ ol.format.KML.ICON_ANCHOR_UNITS_MAP_ = { * @private */ ol.format.KML.createNameStyleFunction_ = function(foundStyle, name) { - /** @type {?ol.style.Text} */ var textStyle = null; var textOffset = [0, 0]; var textAlign = 'start'; @@ -97926,7 +83473,7 @@ ol.format.KML.createNameStyleFunction_ = function(foundStyle, name) { textAlign = 'left'; } } - if (!goog.object.isEmpty(foundStyle.getText())) { + if (!ol.object.isEmpty(foundStyle.getText())) { textStyle = /** @type {ol.style.Text} */ (goog.object.clone(foundStyle.getText())); textStyle.setText(name); @@ -97972,7 +83519,6 @@ ol.format.KML.createFeatureStyleFunction_ = function(style, styleUrl, var drawName = showPointNames; /** @type {ol.style.Style|undefined} */ var nameStyle; - /** @type {string} */ var name = ''; if (drawName) { if (this.getGeometry()) { @@ -97982,7 +83528,7 @@ ol.format.KML.createFeatureStyleFunction_ = function(style, styleUrl, } if (drawName) { - name = /** @type {string} */ (this.getProperties()['name']); + name = /** @type {string} */ (this.get('name')); drawName = drawName && name; } @@ -98023,9 +83569,9 @@ ol.format.KML.createFeatureStyleFunction_ = function(style, styleUrl, * @private */ ol.format.KML.findStyle_ = function(styleValue, defaultStyle, sharedStyles) { - if (goog.isArray(styleValue)) { + if (Array.isArray(styleValue)) { return styleValue; - } else if (goog.isString(styleValue)) { + } else if (typeof styleValue === 'string') { // KML files in the wild occasionally forget the leading `#` on styleUrls // defined in the same document. Add a leading `#` if it enables to find // a style. @@ -98126,7 +83672,7 @@ ol.format.KML.readURI_ = function(node) { /** * @param {Node} node Node. * @private - * @return {ol.format.KMLVec2_} Vec2. + * @return {ol.KMLVec2_} Vec2. */ ol.format.KML.readVec2_ = function(node) { var xunits = node.getAttribute('xunits'); @@ -98162,8 +83708,7 @@ ol.format.KML.readScale_ = function(node) { * @return {Array.<ol.style.Style>|string|undefined} StyleMap. */ ol.format.KML.readStyleMapValue_ = function(node, objectStack) { - return ol.xml.pushParseAndPop( - /** @type {Array.<ol.style.Style>|string|undefined} */ (undefined), + return ol.xml.pushParseAndPop(undefined, ol.format.KML.STYLE_MAP_PARSERS_, node, objectStack); }; @@ -98202,7 +83747,7 @@ ol.format.KML.IconStyleParser_ = function(node, objectStack) { src = ol.format.KML.DEFAULT_IMAGE_STYLE_SRC_; } var anchor, anchorXUnits, anchorYUnits; - var hotSpot = /** @type {ol.format.KMLVec2_|undefined} */ + var hotSpot = /** @type {ol.KMLVec2_|undefined} */ (object['hotSpot']); if (hotSpot) { anchor = [hotSpot.x, hotSpot.y]; @@ -98379,8 +83924,8 @@ ol.format.KML.readFlatLinearRing_ = function(node, objectStack) { 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'LinearRing', 'localName should be LinearRing'); - return /** @type {Array.<number>} */ (ol.xml.pushParseAndPop( - null, ol.format.KML.FLAT_LINEAR_RING_PARSERS_, node, objectStack)); + return ol.xml.pushParseAndPop(null, + ol.format.KML.FLAT_LINEAR_RING_PARSERS_, node, objectStack); }; @@ -98396,7 +83941,7 @@ ol.format.KML.gxCoordParser_ = function(node, objectStack) { ol.format.KML.GX_NAMESPACE_URIS_, node.namespaceURI), 'namespaceURI of the node should be known to the KML parser'); goog.asserts.assert(node.localName == 'coord', 'localName should be coord'); - var gxTrackObject = /** @type {ol.format.KMLGxTrackObject_} */ + var gxTrackObject = /** @type {ol.KMLGxTrackObject_} */ (objectStack[objectStack.length - 1]); goog.asserts.assert(goog.isObject(gxTrackObject), 'gxTrackObject should be an Object'); @@ -98430,8 +83975,7 @@ ol.format.KML.readGxMultiTrack_ = function(node, objectStack) { 'namespaceURI of the node should be known to the KML parser'); goog.asserts.assert(node.localName == 'MultiTrack', 'localName should be MultiTrack'); - var lineStrings = ol.xml.pushParseAndPop( - /** @type {Array.<ol.geom.LineString>} */ ([]), + var lineStrings = ol.xml.pushParseAndPop([], ol.format.KML.GX_MULTITRACK_GEOMETRY_PARSERS_, node, objectStack); if (!lineStrings) { return undefined; @@ -98456,7 +84000,7 @@ ol.format.KML.readGxTrack_ = function(node, objectStack) { 'namespaceURI of the node should be known to the KML parser'); goog.asserts.assert(node.localName == 'Track', 'localName should be Track'); var gxTrackObject = ol.xml.pushParseAndPop( - /** @type {ol.format.KMLGxTrackObject_} */ ({ + /** @type {ol.KMLGxTrackObject_} */ ({ flatCoordinates: [], whens: [] }), ol.format.KML.GX_TRACK_PARSERS_, node, objectStack); @@ -98508,8 +84052,8 @@ ol.format.KML.readIcon_ = function(node, objectStack) { ol.format.KML.readFlatCoordinatesFromNode_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); - return /** @type {Array.<number>} */ (ol.xml.pushParseAndPop(null, - ol.format.KML.GEOMETRY_FLAT_COORDINATES_PARSERS_, node, objectStack)); + return ol.xml.pushParseAndPop(null, + ol.format.KML.GEOMETRY_FLAT_COORDINATES_PARSERS_, node, objectStack); }; @@ -98524,7 +84068,7 @@ ol.format.KML.readLineString_ = function(node, objectStack) { 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'LineString', 'localName should be LineString'); - var properties = ol.xml.pushParseAndPop(/** @type {Object<string,*>} */ ({}), + var properties = ol.xml.pushParseAndPop({}, ol.format.KML.EXTRUDE_AND_ALTITUDE_MODE_PARSERS_, node, objectStack); var flatCoordinates = @@ -98551,7 +84095,7 @@ ol.format.KML.readLinearRing_ = function(node, objectStack) { 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'LinearRing', 'localName should be LinearRing'); - var properties = ol.xml.pushParseAndPop(/** @type {Object<string,*>} */ ({}), + var properties = ol.xml.pushParseAndPop({}, ol.format.KML.EXTRUDE_AND_ALTITUDE_MODE_PARSERS_, node, objectStack); var flatCoordinates = @@ -98579,8 +84123,7 @@ ol.format.KML.readMultiGeometry_ = function(node, objectStack) { 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'MultiGeometry', 'localName should be MultiGeometry'); - var geometries = ol.xml.pushParseAndPop( - /** @type {Array.<ol.geom.Geometry>} */ ([]), + var geometries = ol.xml.pushParseAndPop([], ol.format.KML.MULTI_GEOMETRY_PARSERS_, node, objectStack); if (!geometries) { return null; @@ -98599,9 +84142,7 @@ ol.format.KML.readMultiGeometry_ = function(node, objectStack) { } } if (homogeneous) { - /** @type {ol.geom.GeometryLayout} */ var layout; - /** @type {Array.<number>} */ var flatCoordinates; if (type == ol.geom.GeometryType.POINT) { var point = geometries[0]; @@ -98615,7 +84156,7 @@ ol.format.KML.readMultiGeometry_ = function(node, objectStack) { 'geometry should be an ol.geom.Point'); goog.asserts.assert(geometry.getLayout() == layout, 'geometry layout should be consistent'); - goog.array.extend(flatCoordinates, geometry.getFlatCoordinates()); + ol.array.extend(flatCoordinates, geometry.getFlatCoordinates()); } var multiPoint = new ol.geom.MultiPoint(null); multiPoint.setFlatCoordinates(layout, flatCoordinates); @@ -98653,7 +84194,7 @@ ol.format.KML.readPoint_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'Point', 'localName should be Point'); - var properties = ol.xml.pushParseAndPop(/** @type {Object<string,*>} */ ({}), + var properties = ol.xml.pushParseAndPop({}, ol.format.KML.EXTRUDE_AND_ALTITUDE_MODE_PARSERS_, node, objectStack); var flatCoordinates = @@ -98685,8 +84226,7 @@ ol.format.KML.readPolygon_ = function(node, objectStack) { var properties = ol.xml.pushParseAndPop(/** @type {Object<string,*>} */ ({}), ol.format.KML.EXTRUDE_AND_ALTITUDE_MODE_PARSERS_, node, objectStack); - var flatLinearRings = ol.xml.pushParseAndPop( - /** @type {Array.<Array.<number>>} */ ([null]), + var flatLinearRings = ol.xml.pushParseAndPop([null], ol.format.KML.FLAT_LINEAR_RINGS_PARSERS_, node, objectStack); if (flatLinearRings && flatLinearRings[0]) { var polygon = new ol.geom.Polygon(null); @@ -98694,7 +84234,7 @@ ol.format.KML.readPolygon_ = function(node, objectStack) { var ends = [flatCoordinates.length]; var i, ii; for (i = 1, ii = flatLinearRings.length; i < ii; ++i) { - goog.array.extend(flatCoordinates, flatLinearRings[i]); + ol.array.extend(flatCoordinates, flatLinearRings[i]); ends.push(flatCoordinates.length); } polygon.setFlatCoordinates( @@ -98757,8 +84297,8 @@ ol.format.KML.readStyle_ = function(node, objectStack) { * Reads an array of geometries and creates arrays for common geometry * properties. Then sets them to the multi geometry. * @param {ol.geom.MultiPoint|ol.geom.MultiLineString|ol.geom.MultiPolygon} - * multiGeometry - * @param {Array.<ol.geom.Geometry>} geometries + * multiGeometry A multi-geometry. + * @param {Array.<ol.geom.Geometry>} geometries List of geometries. * @private */ ol.format.KML.setCommonGeometryProperties_ = function(multiGeometry, @@ -98870,9 +84410,9 @@ ol.format.KML.PlacemarkStyleMapParser_ = function(node, objectStack) { var placemarkObject = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(placemarkObject), 'placemarkObject should be an Object'); - if (goog.isArray(styleMapValue)) { + if (Array.isArray(styleMapValue)) { placemarkObject['Style'] = styleMapValue; - } else if (goog.isString(styleMapValue)) { + } else if (typeof styleMapValue === 'string') { placemarkObject['styleUrl'] = styleMapValue; } else { goog.asserts.fail('styleMapValue has an unknown type'); @@ -98924,13 +84464,13 @@ ol.format.KML.innerBoundaryIsParser_ = function(node, objectStack) { 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'innerBoundaryIs', 'localName should be innerBoundaryIs'); - var flatLinearRing = ol.xml.pushParseAndPop( - /** @type {Array.<number>|undefined} */ (undefined), + /** @type {Array.<number>|undefined} */ + var flatLinearRing = ol.xml.pushParseAndPop(undefined, ol.format.KML.INNER_BOUNDARY_IS_PARSERS_, node, objectStack); if (flatLinearRing) { var flatLinearRings = /** @type {Array.<Array.<number>>} */ (objectStack[objectStack.length - 1]); - goog.asserts.assert(goog.isArray(flatLinearRings), + goog.asserts.assert(Array.isArray(flatLinearRings), 'flatLinearRings should be an array'); goog.asserts.assert(flatLinearRings.length > 0, 'flatLinearRings array should not be empty'); @@ -98949,13 +84489,13 @@ ol.format.KML.outerBoundaryIsParser_ = function(node, objectStack) { 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'outerBoundaryIs', 'localName should be outerBoundaryIs'); - var flatLinearRing = ol.xml.pushParseAndPop( - /** @type {Array.<number>|undefined} */ (undefined), + /** @type {Array.<number>|undefined} */ + var flatLinearRing = ol.xml.pushParseAndPop(undefined, ol.format.KML.OUTER_BOUNDARY_IS_PARSERS_, node, objectStack); if (flatLinearRing) { var flatLinearRings = /** @type {Array.<Array.<number>>} */ (objectStack[objectStack.length - 1]); - goog.asserts.assert(goog.isArray(flatLinearRings), + goog.asserts.assert(Array.isArray(flatLinearRings), 'flatLinearRings should be an array'); goog.asserts.assert(flatLinearRings.length > 0, 'flatLinearRings array should not be empty'); @@ -98986,7 +84526,7 @@ ol.format.KML.whenParser_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'when', 'localName should be when'); - var gxTrackObject = /** @type {ol.format.KMLGxTrackObject_} */ + var gxTrackObject = /** @type {ol.KMLGxTrackObject_} */ (objectStack[objectStack.length - 1]); goog.asserts.assert(goog.isObject(gxTrackObject), 'gxTrackObject should be an Object'); @@ -99019,7 +84559,7 @@ ol.format.KML.whenParser_ = function(node, objectStack) { /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.DATA_PARSERS_ = ol.xml.makeStructureNS( @@ -99030,7 +84570,7 @@ ol.format.KML.DATA_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.EXTENDED_DATA_PARSERS_ = ol.xml.makeStructureNS( @@ -99042,7 +84582,7 @@ ol.format.KML.EXTENDED_DATA_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.EXTRUDE_AND_ALTITUDE_MODE_PARSERS_ = ol.xml.makeStructureNS( @@ -99054,7 +84594,7 @@ ol.format.KML.EXTRUDE_AND_ALTITUDE_MODE_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.FLAT_LINEAR_RING_PARSERS_ = ol.xml.makeStructureNS( @@ -99065,7 +84605,7 @@ ol.format.KML.FLAT_LINEAR_RING_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.FLAT_LINEAR_RINGS_PARSERS_ = ol.xml.makeStructureNS( @@ -99077,7 +84617,7 @@ ol.format.KML.FLAT_LINEAR_RINGS_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.GX_TRACK_PARSERS_ = ol.xml.makeStructureNS( @@ -99091,7 +84631,7 @@ ol.format.KML.GX_TRACK_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.GEOMETRY_FLAT_COORDINATES_PARSERS_ = ol.xml.makeStructureNS( @@ -99102,7 +84642,7 @@ ol.format.KML.GEOMETRY_FLAT_COORDINATES_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.ICON_PARSERS_ = ol.xml.makeStructureNS( @@ -99119,7 +84659,7 @@ ol.format.KML.ICON_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.ICON_STYLE_PARSERS_ = ol.xml.makeStructureNS( @@ -99133,7 +84673,7 @@ ol.format.KML.ICON_STYLE_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.INNER_BOUNDARY_IS_PARSERS_ = ol.xml.makeStructureNS( @@ -99144,7 +84684,7 @@ ol.format.KML.INNER_BOUNDARY_IS_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.LABEL_STYLE_PARSERS_ = ol.xml.makeStructureNS( @@ -99156,7 +84696,7 @@ ol.format.KML.LABEL_STYLE_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.LINE_STYLE_PARSERS_ = ol.xml.makeStructureNS( @@ -99168,7 +84708,7 @@ ol.format.KML.LINE_STYLE_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.MULTI_GEOMETRY_PARSERS_ = ol.xml.makeStructureNS( @@ -99183,7 +84723,7 @@ ol.format.KML.MULTI_GEOMETRY_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.GX_MULTITRACK_GEOMETRY_PARSERS_ = ol.xml.makeStructureNS( @@ -99194,7 +84734,7 @@ ol.format.KML.GX_MULTITRACK_GEOMETRY_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.NETWORK_LINK_PARSERS_ = ol.xml.makeStructureNS( @@ -99212,7 +84752,7 @@ ol.format.KML.NETWORK_LINK_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.LINK_PARSERS_ = ol.xml.makeStructureNS( @@ -99223,7 +84763,7 @@ ol.format.KML.LINK_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.OUTER_BOUNDARY_IS_PARSERS_ = ol.xml.makeStructureNS( @@ -99234,7 +84774,7 @@ ol.format.KML.OUTER_BOUNDARY_IS_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.PAIR_PARSERS_ = ol.xml.makeStructureNS( @@ -99247,7 +84787,7 @@ ol.format.KML.PAIR_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.PLACEMARK_PARSERS_ = ol.xml.makeStructureNS( @@ -99284,7 +84824,7 @@ ol.format.KML.PLACEMARK_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.POLY_STYLE_PARSERS_ = ol.xml.makeStructureNS( @@ -99297,7 +84837,7 @@ ol.format.KML.POLY_STYLE_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.SCHEMA_DATA_PARSERS_ = ol.xml.makeStructureNS( @@ -99308,7 +84848,7 @@ ol.format.KML.SCHEMA_DATA_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.STYLE_PARSERS_ = ol.xml.makeStructureNS( @@ -99322,7 +84862,7 @@ ol.format.KML.STYLE_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.KML.STYLE_MAP_PARSERS_ = ol.xml.makeStructureNS( @@ -99348,7 +84888,7 @@ ol.format.KML.prototype.getExtensions = function() { ol.format.KML.prototype.readDocumentOrFolder_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); - var localName = ol.xml.getLocalName(node); + var localName = node.localName; goog.asserts.assert(localName == 'Document' || localName == 'Folder', 'localName should be Document or Folder'); // FIXME use scope somehow @@ -99357,11 +84897,11 @@ ol.format.KML.prototype.readDocumentOrFolder_ = function(node, objectStack) { 'Document': ol.xml.makeArrayExtender(this.readDocumentOrFolder_, this), 'Folder': ol.xml.makeArrayExtender(this.readDocumentOrFolder_, this), 'Placemark': ol.xml.makeArrayPusher(this.readPlacemark_, this), - 'Style': goog.bind(this.readSharedStyle_, this), - 'StyleMap': goog.bind(this.readSharedStyleMap_, this) + 'Style': this.readSharedStyle_.bind(this), + 'StyleMap': this.readSharedStyleMap_.bind(this) }); - var features = ol.xml.pushParseAndPop(/** @type {Array.<ol.Feature>} */ ([]), - parsersNS, node, objectStack, this); + /** @type {Array.<ol.Feature>} */ + var features = ol.xml.pushParseAndPop([], parsersNS, node, objectStack, this); if (features) { return features; } else { @@ -99472,7 +85012,9 @@ ol.format.KML.prototype.readSharedStyleMap_ = function(node, objectStack) { /** - * Read the first feature from a KML source. + * Read the first feature from a KML source. MultiGeometries are converted into + * GeometryCollections if they are a mix of geometry types, and into MultiPoint/ + * MultiLineString/MultiPolygon if they are all of the same type. * * @function * @param {Document|Node|Object|string} source Source. @@ -99505,7 +85047,9 @@ ol.format.KML.prototype.readFeatureFromNode = function(node, opt_options) { /** - * Read all features from a KML source. + * Read all features from a KML source. MultiGeometries are converted into + * GeometryCollections if they are a mix of geometry types, and into MultiPoint/ + * MultiLineString/MultiPolygon if they are all of the same type. * * @function * @param {Document|Node|Object|string} source Source. @@ -99526,7 +85070,7 @@ ol.format.KML.prototype.readFeaturesFromNode = function(node, opt_options) { return []; } var features; - var localName = ol.xml.getLocalName(node); + var localName = node.localName; if (localName == 'Document' || localName == 'Folder') { features = this.readDocumentOrFolder_( node, [this.getReadOptions(node, opt_options)]); @@ -99549,7 +85093,7 @@ ol.format.KML.prototype.readFeaturesFromNode = function(node, opt_options) { for (n = node.firstElementChild; n; n = n.nextElementSibling) { var fs = this.readFeaturesFromNode(n, opt_options); if (fs) { - goog.array.extend(features, fs); + ol.array.extend(features, fs); } } return features; @@ -99571,7 +85115,7 @@ ol.format.KML.prototype.readName = function(source) { return this.readNameFromDocument(/** @type {Document} */ (source)); } else if (ol.xml.isNode(source)) { return this.readNameFromNode(/** @type {Node} */ (source)); - } else if (goog.isString(source)) { + } else if (typeof source === 'string') { var doc = ol.xml.parse(source); return this.readNameFromDocument(doc); } else { @@ -99612,7 +85156,7 @@ ol.format.KML.prototype.readNameFromNode = function(node) { } } for (n = node.firstElementChild; n; n = n.nextElementSibling) { - var localName = ol.xml.getLocalName(n); + var localName = n.localName; if (ol.array.includes(ol.format.KML.NAMESPACE_URIS_, n.namespaceURI) && (localName == 'Document' || localName == 'Folder' || @@ -99638,14 +85182,14 @@ ol.format.KML.prototype.readNameFromNode = function(node) { ol.format.KML.prototype.readNetworkLinks = function(source) { var networkLinks = []; if (ol.xml.isDocument(source)) { - goog.array.extend(networkLinks, this.readNetworkLinksFromDocument( + ol.array.extend(networkLinks, this.readNetworkLinksFromDocument( /** @type {Document} */ (source))); } else if (ol.xml.isNode(source)) { - goog.array.extend(networkLinks, this.readNetworkLinksFromNode( + ol.array.extend(networkLinks, this.readNetworkLinksFromNode( /** @type {Node} */ (source))); - } else if (goog.isString(source)) { + } else if (typeof source === 'string') { var doc = ol.xml.parse(source); - goog.array.extend(networkLinks, this.readNetworkLinksFromDocument(doc)); + ol.array.extend(networkLinks, this.readNetworkLinksFromDocument(doc)); } else { goog.asserts.fail('unknown type for source'); } @@ -99661,7 +85205,7 @@ ol.format.KML.prototype.readNetworkLinksFromDocument = function(doc) { var n, networkLinks = []; for (n = doc.firstChild; n; n = n.nextSibling) { if (n.nodeType == goog.dom.NodeType.ELEMENT) { - goog.array.extend(networkLinks, this.readNetworkLinksFromNode(n)); + ol.array.extend(networkLinks, this.readNetworkLinksFromNode(n)); } } return networkLinks; @@ -99683,12 +85227,12 @@ ol.format.KML.prototype.readNetworkLinksFromNode = function(node) { } } for (n = node.firstElementChild; n; n = n.nextElementSibling) { - var localName = ol.xml.getLocalName(n); + var localName = n.localName; if (ol.array.includes(ol.format.KML.NAMESPACE_URIS_, n.namespaceURI) && (localName == 'Document' || localName == 'Folder' || localName == 'kml')) { - goog.array.extend(networkLinks, this.readNetworkLinksFromNode(n)); + ol.array.extend(networkLinks, this.readNetworkLinksFromNode(n)); } } return networkLinks; @@ -99730,8 +85274,7 @@ ol.format.KML.writeColorTextNode_ = function(node, color) { * @param {Array.<*>} objectStack Object stack. * @private */ -ol.format.KML.writeCoordinatesTextNode_ = - function(node, coordinates, objectStack) { +ol.format.KML.writeCoordinatesTextNode_ = function(node, coordinates, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context), 'context should be an Object'); @@ -99776,7 +85319,7 @@ ol.format.KML.writeCoordinatesTextNode_ = * @private */ ol.format.KML.writeDocument_ = function(node, features, objectStack) { - var /** @type {ol.xml.NodeStackItem} */ context = {node: node}; + var /** @type {ol.XmlNodeStackItem} */ context = {node: node}; ol.xml.pushSerializeAndPop(context, ol.format.KML.DOCUMENT_SERIALIZERS_, ol.format.KML.DOCUMENT_NODE_FACTORY_, features, objectStack, undefined, this); @@ -99790,7 +85333,7 @@ ol.format.KML.writeDocument_ = function(node, features, objectStack) { * @private */ ol.format.KML.writeIcon_ = function(node, icon, objectStack) { - var /** @type {ol.xml.NodeStackItem} */ context = {node: node}; + var /** @type {ol.XmlNodeStackItem} */ context = {node: node}; var parentNode = objectStack[objectStack.length - 1].node; var orderedKeys = ol.format.KML.ICON_SEQUENCE_[parentNode.namespaceURI]; var values = ol.xml.makeSequence(icon, orderedKeys); @@ -99812,7 +85355,7 @@ ol.format.KML.writeIcon_ = function(node, icon, objectStack) { * @private */ ol.format.KML.writeIconStyle_ = function(node, style, objectStack) { - var /** @type {ol.xml.NodeStackItem} */ context = {node: node}; + var /** @type {ol.XmlNodeStackItem} */ context = {node: node}; var properties = {}; var src = style.getSrc(); var size = style.getSize(); @@ -99833,7 +85376,7 @@ ol.format.KML.writeIconStyle_ = function(node, style, objectStack) { } if (anchor && anchor[0] !== 0 && anchor[1] !== size[1]) { - var /** @type {ol.format.KMLVec2_} */ hotSpot = { + var /** @type {ol.KMLVec2_} */ hotSpot = { x: anchor[0], xunits: ol.style.IconAnchorUnits.PIXELS, y: size[1] - anchor[1], @@ -99870,7 +85413,7 @@ ol.format.KML.writeIconStyle_ = function(node, style, objectStack) { * @private */ ol.format.KML.writeLabelStyle_ = function(node, style, objectStack) { - var /** @type {ol.xml.NodeStackItem} */ context = {node: node}; + var /** @type {ol.XmlNodeStackItem} */ context = {node: node}; var properties = {}; var fill = style.getFill(); if (fill) { @@ -99896,7 +85439,7 @@ ol.format.KML.writeLabelStyle_ = function(node, style, objectStack) { * @private */ ol.format.KML.writeLineStyle_ = function(node, style, objectStack) { - var /** @type {ol.xml.NodeStackItem} */ context = {node: node}; + var /** @type {ol.XmlNodeStackItem} */ context = {node: node}; var properties = { 'color': style.getColor(), 'width': style.getWidth() @@ -99915,22 +85458,25 @@ ol.format.KML.writeLineStyle_ = function(node, style, objectStack) { * @param {Array.<*>} objectStack Object stack. * @private */ -ol.format.KML.writeMultiGeometry_ = - function(node, geometry, objectStack) { +ol.format.KML.writeMultiGeometry_ = function(node, geometry, objectStack) { goog.asserts.assert( + (geometry instanceof ol.geom.GeometryCollection) || (geometry instanceof ol.geom.MultiPoint) || (geometry instanceof ol.geom.MultiLineString) || (geometry instanceof ol.geom.MultiPolygon), - 'geometry should be one of: ol.geom.MultiPoint, ' + - 'ol.geom.MultiLineString or ol.geom.MultiPolygon'); - /** @type {ol.xml.NodeStackItem} */ + 'geometry should be one of: ol.geom.GeometryCollection, ' + + 'ol.geom.MultiPoint, ol.geom.MultiLineString or ol.geom.MultiPolygon'); + /** @type {ol.XmlNodeStackItem} */ var context = {node: node}; var type = geometry.getType(); /** @type {Array.<ol.geom.Geometry>} */ var geometries; /** @type {function(*, Array.<*>, string=): (Node|undefined)} */ var factory; - if (type == ol.geom.GeometryType.MULTI_POINT) { + if (type == ol.geom.GeometryType.GEOMETRY_COLLECTION) { + geometries = geometry.getGeometries(); + factory = ol.format.KML.GEOMETRY_NODE_FACTORY_; + } else if (type == ol.geom.GeometryType.MULTI_POINT) { geometries = (/** @type {ol.geom.MultiPoint} */ (geometry)).getPoints(); factory = ol.format.KML.POINT_NODE_FACTORY_; @@ -99958,7 +85504,7 @@ ol.format.KML.writeMultiGeometry_ = * @private */ ol.format.KML.writeBoundaryIs_ = function(node, linearRing, objectStack) { - var /** @type {ol.xml.NodeStackItem} */ context = {node: node}; + var /** @type {ol.XmlNodeStackItem} */ context = {node: node}; ol.xml.pushSerializeAndPop(context, ol.format.KML.BOUNDARY_IS_SERIALIZERS_, ol.format.KML.LINEAR_RING_NODE_FACTORY_, [linearRing], objectStack); @@ -99975,7 +85521,7 @@ ol.format.KML.writeBoundaryIs_ = function(node, linearRing, objectStack) { * @private */ ol.format.KML.writePlacemark_ = function(node, feature, objectStack) { - var /** @type {ol.xml.NodeStackItem} */ context = {node: node}; + var /** @type {ol.XmlNodeStackItem} */ context = {node: node}; // set id if (feature.getId()) { @@ -99990,10 +85536,10 @@ ol.format.KML.writePlacemark_ = function(node, feature, objectStack) { // FIXME the styles returned by the style function are supposed to be // resolution-independent here var styles = styleFunction.call(feature, 0); - if (styles && styles.length > 0) { - var style = styles[0]; + if (styles) { + var style = Array.isArray(styles) ? styles[0] : styles; if (this.writeStyles_) { - properties['Style'] = styles[0]; + properties['Style'] = style; } var textStyle = style.getText(); if (textStyle) { @@ -100033,7 +85579,7 @@ ol.format.KML.writePrimitiveGeometry_ = function(node, geometry, objectStack) { 'geometry should be one of ol.geom.Point, ol.geom.LineString ' + 'or ol.geom.LinearRing'); var flatCoordinates = geometry.getFlatCoordinates(); - var /** @type {ol.xml.NodeStackItem} */ context = {node: node}; + var /** @type {ol.XmlNodeStackItem} */ context = {node: node}; context['layout'] = geometry.getLayout(); context['stride'] = geometry.getStride(); ol.xml.pushSerializeAndPop(context, @@ -100056,7 +85602,7 @@ ol.format.KML.writePolygon_ = function(node, polygon, objectStack) { goog.asserts.assert(linearRings.length > 0, 'linearRings should not be empty'); var outerRing = linearRings.shift(); - var /** @type {ol.xml.NodeStackItem} */ context = {node: node}; + var /** @type {ol.XmlNodeStackItem} */ context = {node: node}; // inner rings ol.xml.pushSerializeAndPop(context, ol.format.KML.POLYGON_SERIALIZERS_, @@ -100077,7 +85623,7 @@ ol.format.KML.writePolygon_ = function(node, polygon, objectStack) { * @private */ ol.format.KML.writePolyStyle_ = function(node, style, objectStack) { - var /** @type {ol.xml.NodeStackItem} */ context = {node: node}; + var /** @type {ol.XmlNodeStackItem} */ context = {node: node}; ol.xml.pushSerializeAndPop(context, ol.format.KML.POLY_STYLE_SERIALIZERS_, ol.format.KML.COLOR_NODE_FACTORY_, [style.getColor()], objectStack); }; @@ -100089,7 +85635,9 @@ ol.format.KML.writePolyStyle_ = function(node, style, objectStack) { * @private */ ol.format.KML.writeScaleTextNode_ = function(node, scale) { - ol.format.XSD.writeDecimalTextNode(node, scale * scale); + // the Math is to remove any excess decimals created by float arithmetic + ol.format.XSD.writeDecimalTextNode(node, + Math.round(scale * scale * 1e6) / 1e6); }; @@ -100100,7 +85648,7 @@ ol.format.KML.writeScaleTextNode_ = function(node, scale) { * @private */ ol.format.KML.writeStyle_ = function(node, style, objectStack) { - var /** @type {ol.xml.NodeStackItem} */ context = {node: node}; + var /** @type {ol.XmlNodeStackItem} */ context = {node: node}; var properties = {}; var fillStyle = style.getFill(); var strokeStyle = style.getStroke(); @@ -100128,7 +85676,7 @@ ol.format.KML.writeStyle_ = function(node, style, objectStack) { /** * @param {Node} node Node to append a TextNode with the Vec2 to. - * @param {ol.format.KMLVec2_} vec2 Vec2. + * @param {ol.KMLVec2_} vec2 Vec2. * @private */ ol.format.KML.writeVec2_ = function(node, vec2) { @@ -100152,7 +85700,7 @@ ol.format.KML.KML_SEQUENCE_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.KML.KML_SERIALIZERS_ = ol.xml.makeStructureNS( @@ -100164,7 +85712,7 @@ ol.format.KML.KML_SERIALIZERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.KML.DOCUMENT_SERIALIZERS_ = ol.xml.makeStructureNS( @@ -100185,7 +85733,8 @@ ol.format.KML.GEOMETRY_TYPE_TO_NODENAME_ = { 'Polygon': 'Polygon', 'MultiPoint': 'MultiGeometry', 'MultiLineString': 'MultiGeometry', - 'MultiPolygon': 'MultiGeometry' + 'MultiPolygon': 'MultiGeometry', + 'GeometryCollection': 'MultiGeometry' }; @@ -100198,15 +85747,14 @@ ol.format.KML.ICON_SEQUENCE_ = ol.xml.makeStructureNS( ol.format.KML.NAMESPACE_URIS_, [ 'href' ], - ol.xml.makeStructureNS( - ol.format.KML.GX_NAMESPACE_URIS_, [ - 'x', 'y', 'w', 'h' + ol.xml.makeStructureNS(ol.format.KML.GX_NAMESPACE_URIS_, [ + 'x', 'y', 'w', 'h' ])); /** * @const - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.KML.ICON_SERIALIZERS_ = ol.xml.makeStructureNS( @@ -100234,7 +85782,7 @@ ol.format.KML.ICON_STYLE_SEQUENCE_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.KML.ICON_STYLE_SERIALIZERS_ = ol.xml.makeStructureNS( @@ -100259,7 +85807,7 @@ ol.format.KML.LABEL_STYLE_SEQUENCE_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.KML.LABEL_STYLE_SERIALIZERS_ = ol.xml.makeStructureNS( @@ -100282,7 +85830,7 @@ ol.format.KML.LINE_STYLE_SEQUENCE_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.KML.LINE_STYLE_SERIALIZERS_ = ol.xml.makeStructureNS( @@ -100294,7 +85842,7 @@ ol.format.KML.LINE_STYLE_SERIALIZERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.KML.BOUNDARY_IS_SERIALIZERS_ = ol.xml.makeStructureNS( @@ -100306,7 +85854,7 @@ ol.format.KML.BOUNDARY_IS_SERIALIZERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.KML.MULTI_GEOMETRY_SERIALIZERS_ = ol.xml.makeStructureNS( @@ -100315,7 +85863,9 @@ ol.format.KML.MULTI_GEOMETRY_SERIALIZERS_ = ol.xml.makeStructureNS( ol.format.KML.writePrimitiveGeometry_), 'Point': ol.xml.makeChildAppender( ol.format.KML.writePrimitiveGeometry_), - 'Polygon': ol.xml.makeChildAppender(ol.format.KML.writePolygon_) + 'Polygon': ol.xml.makeChildAppender(ol.format.KML.writePolygon_), + 'GeometryCollection': ol.xml.makeChildAppender( + ol.format.KML.writeMultiGeometry_) }); @@ -100333,7 +85883,7 @@ ol.format.KML.PLACEMARK_SEQUENCE_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.KML.PLACEMARK_SERIALIZERS_ = ol.xml.makeStructureNS( @@ -100363,7 +85913,7 @@ ol.format.KML.PLACEMARK_SERIALIZERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.KML.PRIMITIVE_GEOMETRY_SERIALIZERS_ = ol.xml.makeStructureNS( @@ -100375,7 +85925,7 @@ ol.format.KML.PRIMITIVE_GEOMETRY_SERIALIZERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.KML.POLYGON_SERIALIZERS_ = ol.xml.makeStructureNS( @@ -100389,7 +85939,7 @@ ol.format.KML.POLYGON_SERIALIZERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.KML.POLY_STYLE_SERIALIZERS_ = ol.xml.makeStructureNS( @@ -100411,7 +85961,7 @@ ol.format.KML.STYLE_SEQUENCE_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.KML.STYLE_SERIALIZERS_ = ol.xml.makeStructureNS( @@ -100558,7 +86108,8 @@ ol.format.KML.OUTER_BOUNDARY_NODE_FACTORY_ = /** - * Encode an array of features in the KML format. + * Encode an array of features in the KML format. GeometryCollections, MultiPoints, + * MultiLineStrings, and MultiPolygons are output as MultiGeometries. * * @function * @param {Array.<ol.Feature>} features Features. @@ -100570,7 +86121,8 @@ ol.format.KML.prototype.writeFeatures; /** - * Encode an array of features in the KML format as an XML node. + * Encode an array of features in the KML format as an XML node. GeometryCollections, + * MultiPoints, MultiLineStrings, and MultiPolygons are output as MultiGeometries. * * @param {Array.<ol.Feature>} features Features. * @param {olx.format.WriteOptions=} opt_options Options. @@ -100588,7 +86140,7 @@ ol.format.KML.prototype.writeFeaturesNode = function(features, opt_options) { ol.xml.setAttributeNS(kml, xmlSchemaInstanceUri, 'xsi:schemaLocation', ol.format.KML.SCHEMA_LOCATION_); - var /** @type {ol.xml.NodeStackItem} */ context = {node: kml}; + var /** @type {ol.XmlNodeStackItem} */ context = {node: kml}; var properties = {}; if (features.length > 1) { properties['Document'] = features; @@ -100615,6 +86167,92 @@ var define; * @suppress {accessControls, ambiguousFunctionDecl, checkDebuggerStatement, checkRegExp, checkTypes, checkVars, const, constantProperty, deprecated, duplicate, es5Strict, fileoverviewTags, missingProperties, nonStandardJsDocs, strictModuleDepCheck, suspiciousCode, undefinedNames, undefinedVars, unknownDefines, uselessCode, visibility} */ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.pbf = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ +exports.read = function (buffer, offset, isLE, mLen, nBytes) { + var e, m + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var nBits = -7 + var i = isLE ? (nBytes - 1) : 0 + var d = isLE ? -1 : 1 + var s = buffer[offset + i] + + i += d + + e = s & ((1 << (-nBits)) - 1) + s >>= (-nBits) + nBits += eLen + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1) + e >>= (-nBits) + nBits += mLen + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity) + } else { + m = m + Math.pow(2, mLen) + e = e - eBias + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen) +} + +exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) + var i = isLE ? 0 : (nBytes - 1) + var d = isLE ? 1 : -1 + var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 + + value = Math.abs(value) + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0 + e = eMax + } else { + e = Math.floor(Math.log(value) / Math.LN2) + if (value * (c = Math.pow(2, -e)) < 1) { + e-- + c *= 2 + } + if (e + eBias >= 1) { + value += rt / c + } else { + value += rt * Math.pow(2, 1 - eBias) + } + if (value * c >= 2) { + e++ + c /= 2 + } + + if (e + eBias >= eMax) { + m = 0 + e = eMax + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen) + e = e + eBias + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) + e = 0 + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + + e = (e << mLen) | m + eLen += mLen + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + + buffer[offset + i - d] |= s * 128 +} + +},{}],2:[function(_dereq_,module,exports){ 'use strict'; // lightweight Buffer shim for pbf browser build @@ -100775,7 +86413,7 @@ function encodeString(str) { return bytes; } -},{"ieee754":3}],2:[function(_dereq_,module,exports){ +},{"ieee754":1}],3:[function(_dereq_,module,exports){ (function (global){ 'use strict'; @@ -101205,93 +86843,7 @@ function writePackedFixed64(arr, pbf) { for (var i = 0; i < arr.length; i++) pb function writePackedSFixed64(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeSFixed64(arr[i]); } }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./buffer":1}],3:[function(_dereq_,module,exports){ -exports.read = function (buffer, offset, isLE, mLen, nBytes) { - var e, m - var eLen = nBytes * 8 - mLen - 1 - var eMax = (1 << eLen) - 1 - var eBias = eMax >> 1 - var nBits = -7 - var i = isLE ? (nBytes - 1) : 0 - var d = isLE ? -1 : 1 - var s = buffer[offset + i] - - i += d - - e = s & ((1 << (-nBits)) - 1) - s >>= (-nBits) - nBits += eLen - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} - - m = e & ((1 << (-nBits)) - 1) - e >>= (-nBits) - nBits += mLen - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} - - if (e === 0) { - e = 1 - eBias - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity) - } else { - m = m + Math.pow(2, mLen) - e = e - eBias - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen) -} - -exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { - var e, m, c - var eLen = nBytes * 8 - mLen - 1 - var eMax = (1 << eLen) - 1 - var eBias = eMax >> 1 - var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) - var i = isLE ? 0 : (nBytes - 1) - var d = isLE ? 1 : -1 - var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 - - value = Math.abs(value) - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0 - e = eMax - } else { - e = Math.floor(Math.log(value) / Math.LN2) - if (value * (c = Math.pow(2, -e)) < 1) { - e-- - c *= 2 - } - if (e + eBias >= 1) { - value += rt / c - } else { - value += rt * Math.pow(2, 1 - eBias) - } - if (value * c >= 2) { - e++ - c /= 2 - } - - if (e + eBias >= eMax) { - m = 0 - e = eMax - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen) - e = e + eBias - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) - e = 0 - } - } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} - - e = (e << mLen) | m - eLen += mLen - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} - - buffer[offset + i - d] |= s * 128 -} - -},{}]},{},[2])(2) +},{"./buffer":2}]},{},[3])(3) }); ol.ext.pbf = module.exports; })(); @@ -101308,11 +86860,144 @@ var define; * @suppress {accessControls, ambiguousFunctionDecl, checkDebuggerStatement, checkRegExp, checkTypes, checkVars, const, constantProperty, deprecated, duplicate, es5Strict, fileoverviewTags, missingProperties, nonStandardJsDocs, strictModuleDepCheck, suspiciousCode, undefinedNames, undefinedVars, unknownDefines, uselessCode, visibility} */ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.vectortile = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ +'use strict'; + +module.exports = Point; + +function Point(x, y) { + this.x = x; + this.y = y; +} + +Point.prototype = { + clone: function() { return new Point(this.x, this.y); }, + + add: function(p) { return this.clone()._add(p); }, + sub: function(p) { return this.clone()._sub(p); }, + mult: function(k) { return this.clone()._mult(k); }, + div: function(k) { return this.clone()._div(k); }, + rotate: function(a) { return this.clone()._rotate(a); }, + matMult: function(m) { return this.clone()._matMult(m); }, + unit: function() { return this.clone()._unit(); }, + perp: function() { return this.clone()._perp(); }, + round: function() { return this.clone()._round(); }, + + mag: function() { + return Math.sqrt(this.x * this.x + this.y * this.y); + }, + + equals: function(p) { + return this.x === p.x && + this.y === p.y; + }, + + dist: function(p) { + return Math.sqrt(this.distSqr(p)); + }, + + distSqr: function(p) { + var dx = p.x - this.x, + dy = p.y - this.y; + return dx * dx + dy * dy; + }, + + angle: function() { + return Math.atan2(this.y, this.x); + }, + + angleTo: function(b) { + return Math.atan2(this.y - b.y, this.x - b.x); + }, + + angleWith: function(b) { + return this.angleWithSep(b.x, b.y); + }, + + // Find the angle of the two vectors, solving the formula for the cross product a x b = |a||b|sin(θ) for θ. + angleWithSep: function(x, y) { + return Math.atan2( + this.x * y - this.y * x, + this.x * x + this.y * y); + }, + + _matMult: function(m) { + var x = m[0] * this.x + m[1] * this.y, + y = m[2] * this.x + m[3] * this.y; + this.x = x; + this.y = y; + return this; + }, + + _add: function(p) { + this.x += p.x; + this.y += p.y; + return this; + }, + + _sub: function(p) { + this.x -= p.x; + this.y -= p.y; + return this; + }, + + _mult: function(k) { + this.x *= k; + this.y *= k; + return this; + }, + + _div: function(k) { + this.x /= k; + this.y /= k; + return this; + }, + + _unit: function() { + this._div(this.mag()); + return this; + }, + + _perp: function() { + var y = this.y; + this.y = this.x; + this.x = -y; + return this; + }, + + _rotate: function(angle) { + var cos = Math.cos(angle), + sin = Math.sin(angle), + x = cos * this.x - sin * this.y, + y = sin * this.x + cos * this.y; + this.x = x; + this.y = y; + return this; + }, + + _round: function() { + this.x = Math.round(this.x); + this.y = Math.round(this.y); + return this; + } +}; + +// constructs Point from an array if necessary +Point.convert = function (a) { + if (a instanceof Point) { + return a; + } + if (Array.isArray(a)) { + return new Point(a[0], a[1]); + } + return a; +}; + +},{}],2:[function(_dereq_,module,exports){ module.exports.VectorTile = _dereq_('./lib/vectortile.js'); module.exports.VectorTileFeature = _dereq_('./lib/vectortilefeature.js'); module.exports.VectorTileLayer = _dereq_('./lib/vectortilelayer.js'); -},{"./lib/vectortile.js":2,"./lib/vectortilefeature.js":3,"./lib/vectortilelayer.js":4}],2:[function(_dereq_,module,exports){ +},{"./lib/vectortile.js":3,"./lib/vectortilefeature.js":4,"./lib/vectortilelayer.js":5}],3:[function(_dereq_,module,exports){ 'use strict'; var VectorTileLayer = _dereq_('./vectortilelayer'); @@ -101331,7 +87016,7 @@ function readTile(tag, layers, pbf) { } -},{"./vectortilelayer":4}],3:[function(_dereq_,module,exports){ +},{"./vectortilelayer":5}],4:[function(_dereq_,module,exports){ 'use strict'; var Point = _dereq_('point-geometry'); @@ -101465,10 +87150,10 @@ VectorTileFeature.prototype.toGeoJSON = function(x, y, z) { x0 = this.extent * x, y0 = this.extent * y, coords = this.loadGeometry(), - type = VectorTileFeature.types[this.type]; + type = VectorTileFeature.types[this.type], + i, j; - for (var i = 0; i < coords.length; i++) { - var line = coords[i]; + function project(line) { for (var j = 0; j < line.length; j++) { var p = line[j], y2 = 180 - (p.y + y0) * 360 / size; line[j] = [ @@ -101478,15 +87163,36 @@ VectorTileFeature.prototype.toGeoJSON = function(x, y, z) { } } - if (type === 'Point' && coords.length === 1) { - coords = coords[0][0]; - } else if (type === 'Point') { - coords = coords[0]; - type = 'MultiPoint'; - } else if (type === 'LineString' && coords.length === 1) { + switch (this.type) { + case 1: + var points = []; + for (i = 0; i < coords.length; i++) { + points[i] = coords[i][0]; + } + coords = points; + project(coords); + break; + + case 2: + for (i = 0; i < coords.length; i++) { + project(coords[i]); + } + break; + + case 3: + coords = classifyRings(coords); + for (i = 0; i < coords.length; i++) { + for (j = 0; j < coords[i].length; j++) { + project(coords[i][j]); + } + } + break; + } + + if (coords.length === 1) { coords = coords[0]; - } else if (type === 'LineString') { - type = 'MultiLineString'; + } else { + type = 'Multi' + type; } var result = { @@ -101505,7 +87211,47 @@ VectorTileFeature.prototype.toGeoJSON = function(x, y, z) { return result; }; -},{"point-geometry":5}],4:[function(_dereq_,module,exports){ +// classifies an array of rings into polygons with outer rings and holes + +function classifyRings(rings) { + var len = rings.length; + + if (len <= 1) return [rings]; + + var polygons = [], + polygon, + ccw; + + for (var i = 0; i < len; i++) { + var area = signedArea(rings[i]); + if (area === 0) continue; + + if (ccw === undefined) ccw = area < 0; + + if (ccw === area < 0) { + if (polygon) polygons.push(polygon); + polygon = [rings[i]]; + + } else { + polygon.push(rings[i]); + } + } + if (polygon) polygons.push(polygon); + + return polygons; +} + +function signedArea(ring) { + var sum = 0; + for (var i = 0, len = ring.length, j = len - 1, p1, p2; i < len; j = i++) { + p1 = ring[i]; + p2 = ring[j]; + sum += (p2.x - p1.x) * (p1.y + p2.y); + } + return sum; +} + +},{"point-geometry":1}],5:[function(_dereq_,module,exports){ 'use strict'; var VectorTileFeature = _dereq_('./vectortilefeature.js'); @@ -101568,140 +87314,7 @@ VectorTileLayer.prototype.feature = function(i) { return new VectorTileFeature(this._pbf, end, this.extent, this._keys, this._values); }; -},{"./vectortilefeature.js":3}],5:[function(_dereq_,module,exports){ -'use strict'; - -module.exports = Point; - -function Point(x, y) { - this.x = x; - this.y = y; -} - -Point.prototype = { - clone: function() { return new Point(this.x, this.y); }, - - add: function(p) { return this.clone()._add(p); }, - sub: function(p) { return this.clone()._sub(p); }, - mult: function(k) { return this.clone()._mult(k); }, - div: function(k) { return this.clone()._div(k); }, - rotate: function(a) { return this.clone()._rotate(a); }, - matMult: function(m) { return this.clone()._matMult(m); }, - unit: function() { return this.clone()._unit(); }, - perp: function() { return this.clone()._perp(); }, - round: function() { return this.clone()._round(); }, - - mag: function() { - return Math.sqrt(this.x * this.x + this.y * this.y); - }, - - equals: function(p) { - return this.x === p.x && - this.y === p.y; - }, - - dist: function(p) { - return Math.sqrt(this.distSqr(p)); - }, - - distSqr: function(p) { - var dx = p.x - this.x, - dy = p.y - this.y; - return dx * dx + dy * dy; - }, - - angle: function() { - return Math.atan2(this.y, this.x); - }, - - angleTo: function(b) { - return Math.atan2(this.y - b.y, this.x - b.x); - }, - - angleWith: function(b) { - return this.angleWithSep(b.x, b.y); - }, - - // Find the angle of the two vectors, solving the formula for the cross product a x b = |a||b|sin(θ) for θ. - angleWithSep: function(x, y) { - return Math.atan2( - this.x * y - this.y * x, - this.x * x + this.y * y); - }, - - _matMult: function(m) { - var x = m[0] * this.x + m[1] * this.y, - y = m[2] * this.x + m[3] * this.y; - this.x = x; - this.y = y; - return this; - }, - - _add: function(p) { - this.x += p.x; - this.y += p.y; - return this; - }, - - _sub: function(p) { - this.x -= p.x; - this.y -= p.y; - return this; - }, - - _mult: function(k) { - this.x *= k; - this.y *= k; - return this; - }, - - _div: function(k) { - this.x /= k; - this.y /= k; - return this; - }, - - _unit: function() { - this._div(this.mag()); - return this; - }, - - _perp: function() { - var y = this.y; - this.y = this.x; - this.x = -y; - return this; - }, - - _rotate: function(angle) { - var cos = Math.cos(angle), - sin = Math.sin(angle), - x = cos * this.x - sin * this.y, - y = sin * this.x + cos * this.y; - this.x = x; - this.y = y; - return this; - }, - - _round: function() { - this.x = Math.round(this.x); - this.y = Math.round(this.y); - return this; - } -}; - -// constructs Point from an array if necessary -Point.convert = function (a) { - if (a instanceof Point) { - return a; - } - if (Array.isArray(a)) { - return new Point(a[0], a[1]); - } - return a; -}; - -},{}]},{},[1])(1) +},{"./vectortilefeature.js":4}]},{},[2])(2) }); ol.ext.vectortile = module.exports; })(); @@ -101730,7 +87343,6 @@ goog.require('ol.proj.Units'); goog.require('ol.render.Feature'); - /** * @classdesc * Feature format for reading data in the Mapbox MVT format. @@ -101750,7 +87362,7 @@ ol.format.MVT = function(opt_options) { * @type {ol.proj.Projection} */ this.defaultDataProjection = new ol.proj.Projection({ - code: 'EPSG:3857', + code: '', units: ol.proj.Units.TILE_PIXELS }); @@ -101856,6 +87468,7 @@ ol.format.MVT.prototype.readRenderFeature_ = function(rawFeature, layer) { /** * @inheritDoc + * @api */ ol.format.MVT.prototype.readFeatures = function(source, opt_options) { goog.asserts.assertInstanceof(source, ArrayBuffer); @@ -101889,6 +87502,7 @@ ol.format.MVT.prototype.readFeatures = function(source, opt_options) { /** * @inheritDoc + * @api */ ol.format.MVT.prototype.readProjection = function(source) { return this.defaultDataProjection; @@ -101915,11 +87529,11 @@ ol.format.MVT.prototype.setLayers = function(layers) { ol.format.MVT.calculateFlatCoordinates_ = function( coords, flatCoordinates, ends) { var end = 0; - var line, coord; for (var i = 0, ii = coords.length; i < ii; ++i) { - line = coords[i]; - for (var j = 0, jj = line.length; j < jj; ++j) { - coord = line[j]; + var line = coords[i]; + var j, jj; + for (j = 0, jj = line.length; j < jj; ++j) { + var coord = line[j]; // Non-tilespace coords can be calculated here when a TileGrid and // TileCoord are known. flatCoordinates.push(coord.x, coord.y); @@ -101966,13 +87580,651 @@ ol.format.MVT.readGeometry_ = function(rawFeature) { return geom; }; +goog.provide('ol.format.ogc.filter'); +goog.provide('ol.format.ogc.filter.Filter'); +goog.provide('ol.format.ogc.filter.Logical'); +goog.provide('ol.format.ogc.filter.LogicalBinary'); +goog.provide('ol.format.ogc.filter.And'); +goog.provide('ol.format.ogc.filter.Or'); +goog.provide('ol.format.ogc.filter.Not'); +goog.provide('ol.format.ogc.filter.Bbox'); +goog.provide('ol.format.ogc.filter.Comparison'); +goog.provide('ol.format.ogc.filter.ComparisonBinary'); +goog.provide('ol.format.ogc.filter.EqualTo'); +goog.provide('ol.format.ogc.filter.NotEqualTo'); +goog.provide('ol.format.ogc.filter.LessThan'); +goog.provide('ol.format.ogc.filter.LessThanOrEqualTo'); +goog.provide('ol.format.ogc.filter.GreaterThan'); +goog.provide('ol.format.ogc.filter.GreaterThanOrEqualTo'); +goog.provide('ol.format.ogc.filter.IsNull'); +goog.provide('ol.format.ogc.filter.IsBetween'); +goog.provide('ol.format.ogc.filter.IsLike'); + +goog.require('ol.Extent'); +goog.require('ol.Object'); + + +/** + * Create a logical `<And>` operator between two filter conditions. + * + * @param {!ol.format.ogc.filter.Filter} conditionA First filter condition. + * @param {!ol.format.ogc.filter.Filter} conditionB Second filter condition. + * @returns {!ol.format.ogc.filter.And} `<And>` operator. + * @api + */ +ol.format.ogc.filter.and = function(conditionA, conditionB) { + return new ol.format.ogc.filter.And(conditionA, conditionB); +}; + + +/** + * Create a logical `<Or>` operator between two filter conditions. + * + * @param {!ol.format.ogc.filter.Filter} conditionA First filter condition. + * @param {!ol.format.ogc.filter.Filter} conditionB Second filter condition. + * @returns {!ol.format.ogc.filter.Or} `<Or>` operator. + * @api + */ +ol.format.ogc.filter.or = function(conditionA, conditionB) { + return new ol.format.ogc.filter.Or(conditionA, conditionB); +}; + + +/** + * Represents a logical `<Not>` operator for a filter condition. + * + * @param {!ol.format.ogc.filter.Filter} condition Filter condition. + * @returns {!ol.format.ogc.filter.Not} `<Not>` operator. + * @api + */ +ol.format.ogc.filter.not = function(condition) { + return new ol.format.ogc.filter.Not(condition); +}; + + +/** + * Create a `<BBOX>` operator to test whether a geometry-valued property + * intersects a fixed bounding box + * + * @param {!string} geometryName Geometry name to use. + * @param {!ol.Extent} extent Extent. + * @param {string=} opt_srsName SRS name. No srsName attribute will be + * set on geometries when this is not provided. + * @returns {!ol.format.ogc.filter.Bbox} `<BBOX>` operator. + * @api + */ +ol.format.ogc.filter.bbox = function(geometryName, extent, opt_srsName) { + return new ol.format.ogc.filter.Bbox(geometryName, extent, opt_srsName); +}; + + +/** + * Creates a `<PropertyIsEqualTo>` comparison operator. + * + * @param {!string} propertyName Name of the context property to compare. + * @param {!(string|number)} expression The value to compare. + * @param {boolean=} opt_matchCase Case-sensitive? + * @returns {!ol.format.ogc.filter.EqualTo} `<PropertyIsEqualTo>` operator. + * @api + */ +ol.format.ogc.filter.equalTo = function(propertyName, expression, opt_matchCase) { + return new ol.format.ogc.filter.EqualTo(propertyName, expression, opt_matchCase); +}; + + +/** + * Creates a `<PropertyIsNotEqualTo>` comparison operator. + * + * @param {!string} propertyName Name of the context property to compare. + * @param {!(string|number)} expression The value to compare. + * @param {boolean=} opt_matchCase Case-sensitive? + * @returns {!ol.format.ogc.filter.NotEqualTo} `<PropertyIsNotEqualTo>` operator. + * @api + */ +ol.format.ogc.filter.notEqualTo = function(propertyName, expression, opt_matchCase) { + return new ol.format.ogc.filter.NotEqualTo(propertyName, expression, opt_matchCase); +}; + + +/** + * Creates a `<PropertyIsLessThan>` comparison operator. + * + * @param {!string} propertyName Name of the context property to compare. + * @param {!number} expression The value to compare. + * @returns {!ol.format.ogc.filter.LessThan} `<PropertyIsLessThan>` operator. + * @api + */ +ol.format.ogc.filter.lessThan = function(propertyName, expression) { + return new ol.format.ogc.filter.LessThan(propertyName, expression); +}; + + +/** + * Creates a `<PropertyIsLessThanOrEqualTo>` comparison operator. + * + * @param {!string} propertyName Name of the context property to compare. + * @param {!number} expression The value to compare. + * @returns {!ol.format.ogc.filter.LessThanOrEqualTo} `<PropertyIsLessThanOrEqualTo>` operator. + * @api + */ +ol.format.ogc.filter.lessThanOrEqualTo = function(propertyName, expression) { + return new ol.format.ogc.filter.LessThanOrEqualTo(propertyName, expression); +}; + + +/** + * Creates a `<PropertyIsGreaterThan>` comparison operator. + * + * @param {!string} propertyName Name of the context property to compare. + * @param {!number} expression The value to compare. + * @returns {!ol.format.ogc.filter.GreaterThan} `<PropertyIsGreaterThan>` operator. + * @api + */ +ol.format.ogc.filter.greaterThan = function(propertyName, expression) { + return new ol.format.ogc.filter.GreaterThan(propertyName, expression); +}; + + +/** + * Creates a `<PropertyIsGreaterThanOrEqualTo>` comparison operator. + * + * @param {!string} propertyName Name of the context property to compare. + * @param {!number} expression The value to compare. + * @returns {!ol.format.ogc.filter.GreaterThanOrEqualTo} `<PropertyIsGreaterThanOrEqualTo>` operator. + * @api + */ +ol.format.ogc.filter.greaterThanOrEqualTo = function(propertyName, expression) { + return new ol.format.ogc.filter.GreaterThanOrEqualTo(propertyName, expression); +}; + + +/** + * Creates a `<PropertyIsNull>` comparison operator to test whether a property value + * is null. + * + * @param {!string} propertyName Name of the context property to compare. + * @returns {!ol.format.ogc.filter.IsNull} `<PropertyIsNull>` operator. + * @api + */ +ol.format.ogc.filter.isNull = function(propertyName) { + return new ol.format.ogc.filter.IsNull(propertyName); +}; + + +/** + * Creates a `<PropertyIsBetween>` comparison operator to test whether an expression + * value lies within a range given by a lower and upper bound (inclusive). + * + * @param {!string} propertyName Name of the context property to compare. + * @param {!number} lowerBoundary The lower bound of the range. + * @param {!number} upperBoundary The upper bound of the range. + * @returns {!ol.format.ogc.filter.IsBetween} `<PropertyIsBetween>` operator. + * @api + */ +ol.format.ogc.filter.between = function(propertyName, lowerBoundary, upperBoundary) { + return new ol.format.ogc.filter.IsBetween(propertyName, lowerBoundary, upperBoundary); +}; + + +/** + * Represents a `<PropertyIsLike>` comparison operator that matches a string property + * value against a text pattern. + * + * @param {!string} propertyName Name of the context property to compare. + * @param {!string} pattern Text pattern. + * @param {string=} opt_wildCard Pattern character which matches any sequence of + * zero or more string characters. Default is '*'. + * @param {string=} opt_singleChar pattern character which matches any single + * string character. Default is '.'. + * @param {string=} opt_escapeChar Escape character which can be used to escape + * the pattern characters. Default is '!'. + * @param {boolean=} opt_matchCase Case-sensitive? + * @returns {!ol.format.ogc.filter.IsLike} `<PropertyIsLike>` operator. + * @api + */ +ol.format.ogc.filter.like = function(propertyName, pattern, + opt_wildCard, opt_singleChar, opt_escapeChar, opt_matchCase) { + return new ol.format.ogc.filter.IsLike(propertyName, pattern, + opt_wildCard, opt_singleChar, opt_escapeChar, opt_matchCase); +}; + + +/** + * @classdesc + * Abstract class; normally only used for creating subclasses and not instantiated in apps. + * Base class for WFS GetFeature filters. + * + * @constructor + * @param {!string} tagName The XML tag name for this filter. + * @extends {ol.Object} + * @api + */ +ol.format.ogc.filter.Filter = function(tagName) { + + goog.base(this); + + /** + * @private + * @type {!string} + */ + this.tagName_ = tagName; +}; +goog.inherits(ol.format.ogc.filter.Filter, ol.Object); + +/** + * The XML tag name for a filter. + * @returns {!string} Name. + */ +ol.format.ogc.filter.Filter.prototype.getTagName = function() { + return this.tagName_; +}; + + +// Logical filters + + +/** + * @classdesc + * Abstract class; normally only used for creating subclasses and not instantiated in apps. + * Base class for WFS GetFeature logical filters. + * + * @constructor + * @param {!string} tagName The XML tag name for this filter. + * @extends {ol.format.ogc.filter.Filter} + */ +ol.format.ogc.filter.Logical = function(tagName) { + goog.base(this, tagName); +}; +goog.inherits(ol.format.ogc.filter.Logical, ol.format.ogc.filter.Filter); + + +/** + * @classdesc + * Abstract class; normally only used for creating subclasses and not instantiated in apps. + * Base class for WFS GetFeature binary logical filters. + * + * @constructor + * @param {!string} tagName The XML tag name for this filter. + * @param {!ol.format.ogc.filter.Filter} conditionA First filter condition. + * @param {!ol.format.ogc.filter.Filter} conditionB Second filter condition. + * @extends {ol.format.ogc.filter.Logical} + */ +ol.format.ogc.filter.LogicalBinary = function(tagName, conditionA, conditionB) { + + goog.base(this, tagName); + + /** + * @public + * @type {!ol.format.ogc.filter.Filter} + */ + this.conditionA = conditionA; + + /** + * @public + * @type {!ol.format.ogc.filter.Filter} + */ + this.conditionB = conditionB; + +}; +goog.inherits(ol.format.ogc.filter.LogicalBinary, ol.format.ogc.filter.Logical); + + +/** + * @classdesc + * Represents a logical `<And>` operator between two filter conditions. + * + * @constructor + * @param {!ol.format.ogc.filter.Filter} conditionA First filter condition. + * @param {!ol.format.ogc.filter.Filter} conditionB Second filter condition. + * @extends {ol.format.ogc.filter.LogicalBinary} + * @api + */ +ol.format.ogc.filter.And = function(conditionA, conditionB) { + goog.base(this, 'And', conditionA, conditionB); +}; +goog.inherits(ol.format.ogc.filter.And, ol.format.ogc.filter.LogicalBinary); + + +/** + * @classdesc + * Represents a logical `<Or>` operator between two filter conditions. + * + * @constructor + * @param {!ol.format.ogc.filter.Filter} conditionA First filter condition. + * @param {!ol.format.ogc.filter.Filter} conditionB Second filter condition. + * @extends {ol.format.ogc.filter.LogicalBinary} + * @api + */ +ol.format.ogc.filter.Or = function(conditionA, conditionB) { + goog.base(this, 'Or', conditionA, conditionB); +}; +goog.inherits(ol.format.ogc.filter.Or, ol.format.ogc.filter.LogicalBinary); + + +/** + * @classdesc + * Represents a logical `<Not>` operator for a filter condition. + * + * @constructor + * @param {!ol.format.ogc.filter.Filter} condition Filter condition. + * @extends {ol.format.ogc.filter.Logical} + * @api + */ +ol.format.ogc.filter.Not = function(condition) { + + goog.base(this, 'Not'); + + /** + * @public + * @type {!ol.format.ogc.filter.Filter} + */ + this.condition = condition; +}; +goog.inherits(ol.format.ogc.filter.Not, ol.format.ogc.filter.Logical); + + +// Spatial filters + + +/** + * @classdesc + * Represents a `<BBOX>` operator to test whether a geometry-valued property + * intersects a fixed bounding box + * + * @constructor + * @param {!string} geometryName Geometry name to use. + * @param {!ol.Extent} extent Extent. + * @param {string=} opt_srsName SRS name. No srsName attribute will be + * set on geometries when this is not provided. + * @extends {ol.format.ogc.filter.Filter} + * @api + */ +ol.format.ogc.filter.Bbox = function(geometryName, extent, opt_srsName) { + + goog.base(this, 'BBOX'); + + /** + * @public + * @type {!string} + */ + this.geometryName = geometryName; + + /** + * @public + * @type {!ol.Extent} + */ + this.extent = extent; + + /** + * @public + * @type {string|undefined} + */ + this.srsName = opt_srsName; +}; +goog.inherits(ol.format.ogc.filter.Bbox, ol.format.ogc.filter.Filter); + + +// Property comparison filters + + +/** + * @classdesc + * Abstract class; normally only used for creating subclasses and not instantiated in apps. + * Base class for WFS GetFeature property comparison filters. + * + * @constructor + * @param {!string} tagName The XML tag name for this filter. + * @param {!string} propertyName Name of the context property to compare. + * @extends {ol.format.ogc.filter.Filter} + * @api + */ +ol.format.ogc.filter.Comparison = function(tagName, propertyName) { + + goog.base(this, tagName); + + /** + * @public + * @type {!string} + */ + this.propertyName = propertyName; +}; +goog.inherits(ol.format.ogc.filter.Comparison, ol.format.ogc.filter.Filter); + + +/** + * @classdesc + * Abstract class; normally only used for creating subclasses and not instantiated in apps. + * Base class for WFS GetFeature property binary comparison filters. + * + * @constructor + * @param {!string} tagName The XML tag name for this filter. + * @param {!string} propertyName Name of the context property to compare. + * @param {!(string|number)} expression The value to compare. + * @param {boolean=} opt_matchCase Case-sensitive? + * @extends {ol.format.ogc.filter.Comparison} + * @api + */ +ol.format.ogc.filter.ComparisonBinary = function( + tagName, propertyName, expression, opt_matchCase) { + + goog.base(this, tagName, propertyName); + + /** + * @public + * @type {!(string|number)} + */ + this.expression = expression; + + /** + * @public + * @type {boolean|undefined} + */ + this.matchCase = opt_matchCase; +}; +goog.inherits(ol.format.ogc.filter.ComparisonBinary, ol.format.ogc.filter.Comparison); + + +/** + * @classdesc + * Represents a `<PropertyIsEqualTo>` comparison operator. + * + * @constructor + * @param {!string} propertyName Name of the context property to compare. + * @param {!(string|number)} expression The value to compare. + * @param {boolean=} opt_matchCase Case-sensitive? + * @extends {ol.format.ogc.filter.ComparisonBinary} + * @api + */ +ol.format.ogc.filter.EqualTo = function(propertyName, expression, opt_matchCase) { + goog.base(this, 'PropertyIsEqualTo', propertyName, expression, opt_matchCase); +}; +goog.inherits(ol.format.ogc.filter.EqualTo, ol.format.ogc.filter.ComparisonBinary); + + +/** + * @classdesc + * Represents a `<PropertyIsNotEqualTo>` comparison operator. + * + * @constructor + * @param {!string} propertyName Name of the context property to compare. + * @param {!(string|number)} expression The value to compare. + * @param {boolean=} opt_matchCase Case-sensitive? + * @extends {ol.format.ogc.filter.ComparisonBinary} + * @api + */ +ol.format.ogc.filter.NotEqualTo = function(propertyName, expression, opt_matchCase) { + goog.base(this, 'PropertyIsNotEqualTo', propertyName, expression, opt_matchCase); +}; +goog.inherits(ol.format.ogc.filter.NotEqualTo, ol.format.ogc.filter.ComparisonBinary); + + +/** + * @classdesc + * Represents a `<PropertyIsLessThan>` comparison operator. + * + * @constructor + * @param {!string} propertyName Name of the context property to compare. + * @param {!number} expression The value to compare. + * @extends {ol.format.ogc.filter.ComparisonBinary} + * @api + */ +ol.format.ogc.filter.LessThan = function(propertyName, expression) { + goog.base(this, 'PropertyIsLessThan', propertyName, expression); +}; +goog.inherits(ol.format.ogc.filter.LessThan, ol.format.ogc.filter.ComparisonBinary); + + +/** + * @classdesc + * Represents a `<PropertyIsLessThanOrEqualTo>` comparison operator. + * + * @constructor + * @param {!string} propertyName Name of the context property to compare. + * @param {!number} expression The value to compare. + * @extends {ol.format.ogc.filter.ComparisonBinary} + * @api + */ +ol.format.ogc.filter.LessThanOrEqualTo = function(propertyName, expression) { + goog.base(this, 'PropertyIsLessThanOrEqualTo', propertyName, expression); +}; +goog.inherits(ol.format.ogc.filter.LessThanOrEqualTo, ol.format.ogc.filter.ComparisonBinary); + + +/** + * @classdesc + * Represents a `<PropertyIsGreaterThan>` comparison operator. + * + * @constructor + * @param {!string} propertyName Name of the context property to compare. + * @param {!number} expression The value to compare. + * @extends {ol.format.ogc.filter.ComparisonBinary} + * @api + */ +ol.format.ogc.filter.GreaterThan = function(propertyName, expression) { + goog.base(this, 'PropertyIsGreaterThan', propertyName, expression); +}; +goog.inherits(ol.format.ogc.filter.GreaterThan, ol.format.ogc.filter.ComparisonBinary); + + +/** + * @classdesc + * Represents a `<PropertyIsGreaterThanOrEqualTo>` comparison operator. + * + * @constructor + * @param {!string} propertyName Name of the context property to compare. + * @param {!number} expression The value to compare. + * @extends {ol.format.ogc.filter.ComparisonBinary} + * @api + */ +ol.format.ogc.filter.GreaterThanOrEqualTo = function(propertyName, expression) { + goog.base(this, 'PropertyIsGreaterThanOrEqualTo', propertyName, expression); +}; +goog.inherits(ol.format.ogc.filter.GreaterThanOrEqualTo, ol.format.ogc.filter.ComparisonBinary); + + +/** + * @classdesc + * Represents a `<PropertyIsNull>` comparison operator. + * + * @constructor + * @param {!string} propertyName Name of the context property to compare. + * @extends {ol.format.ogc.filter.Comparison} + * @api + */ +ol.format.ogc.filter.IsNull = function(propertyName) { + goog.base(this, 'PropertyIsNull', propertyName); +}; +goog.inherits(ol.format.ogc.filter.IsNull, ol.format.ogc.filter.Comparison); + + +/** + * @classdesc + * Represents a `<PropertyIsBetween>` comparison operator. + * + * @constructor + * @param {!string} propertyName Name of the context property to compare. + * @param {!number} lowerBoundary The lower bound of the range. + * @param {!number} upperBoundary The upper bound of the range. + * @extends {ol.format.ogc.filter.Comparison} + * @api + */ +ol.format.ogc.filter.IsBetween = function(propertyName, lowerBoundary, upperBoundary) { + goog.base(this, 'PropertyIsBetween', propertyName); + + /** + * @public + * @type {!number} + */ + this.lowerBoundary = lowerBoundary; + + /** + * @public + * @type {!number} + */ + this.upperBoundary = upperBoundary; +}; +goog.inherits(ol.format.ogc.filter.IsBetween, ol.format.ogc.filter.Comparison); + + +/** + * @classdesc + * Represents a `<PropertyIsLike>` comparison operator. + * + * @constructor + * @param {!string} propertyName Name of the context property to compare. + * @param {!string} pattern Text pattern. + * @param {string=} opt_wildCard Pattern character which matches any sequence of + * zero or more string characters. Default is '*'. + * @param {string=} opt_singleChar pattern character which matches any single + * string character. Default is '.'. + * @param {string=} opt_escapeChar Escape character which can be used to escape + * the pattern characters. Default is '!'. + * @param {boolean=} opt_matchCase Case-sensitive? + * @extends {ol.format.ogc.filter.Comparison} + * @api + */ +ol.format.ogc.filter.IsLike = function(propertyName, pattern, + opt_wildCard, opt_singleChar, opt_escapeChar, opt_matchCase) { + goog.base(this, 'PropertyIsLike', propertyName); + + /** + * @public + * @type {!string} + */ + this.pattern = pattern; + + /** + * @public + * @type {!string} + */ + this.wildCard = (opt_wildCard !== undefined) ? opt_wildCard : '*'; + + /** + * @public + * @type {!string} + */ + this.singleChar = (opt_singleChar !== undefined) ? opt_singleChar : '.'; + + /** + * @public + * @type {!string} + */ + this.escapeChar = (opt_escapeChar !== undefined) ? opt_escapeChar : '!'; + + /** + * @public + * @type {boolean|undefined} + */ + this.matchCase = opt_matchCase; +}; +goog.inherits(ol.format.ogc.filter.IsLike, ol.format.ogc.filter.Comparison); + // FIXME add typedef for stack state objects goog.provide('ol.format.OSMXML'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom.NodeType'); -goog.require('goog.object'); +goog.require('ol.array'); goog.require('ol.Feature'); goog.require('ol.format.Feature'); goog.require('ol.format.XMLFeature'); @@ -101980,11 +88232,11 @@ goog.require('ol.geom.GeometryLayout'); goog.require('ol.geom.LineString'); goog.require('ol.geom.Point'); goog.require('ol.geom.Polygon'); +goog.require('ol.object'); goog.require('ol.proj'); goog.require('ol.xml'); - /** * @classdesc * Feature format for reading data in the @@ -102033,16 +88285,17 @@ ol.format.OSMXML.readNode_ = function(node, objectStack) { var options = /** @type {olx.format.ReadOptions} */ (objectStack[0]); var state = /** @type {Object} */ (objectStack[objectStack.length - 1]); var id = node.getAttribute('id'); - var coordinates = /** @type {Array.<number>} */ ([ + /** @type {ol.Coordinate} */ + var coordinates = [ parseFloat(node.getAttribute('lon')), parseFloat(node.getAttribute('lat')) - ]); + ]; state.nodes[id] = coordinates; var values = ol.xml.pushParseAndPop({ tags: {} }, ol.format.OSMXML.NODE_PARSERS_, node, objectStack); - if (!goog.object.isEmpty(values.tags)) { + if (!ol.object.isEmpty(values.tags)) { var geometry = new ol.geom.Point(coordinates); ol.format.Feature.transformWithOptions(geometry, false, options); var feature = new ol.Feature(geometry); @@ -102069,10 +88322,11 @@ ol.format.OSMXML.readWay_ = function(node, objectStack) { tags: {} }, ol.format.OSMXML.WAY_PARSERS_, node, objectStack); var state = /** @type {Object} */ (objectStack[objectStack.length - 1]); - var flatCoordinates = /** @type {Array.<number>} */ ([]); + /** @type {Array.<number>} */ + var flatCoordinates = []; for (var i = 0, ii = values.ndrefs.length; i < ii; i++) { var point = state.nodes[values.ndrefs[i]]; - goog.array.extend(flatCoordinates, point); + ol.array.extend(flatCoordinates, point); } var geometry; if (values.ndrefs[0] == values.ndrefs[values.ndrefs.length - 1]) { @@ -102096,7 +88350,6 @@ ol.format.OSMXML.readWay_ = function(node, objectStack) { * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. * @private - * @return {ol.Feature|undefined} Track. */ ol.format.OSMXML.readNd_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, @@ -102111,7 +88364,6 @@ ol.format.OSMXML.readNd_ = function(node, objectStack) { * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. * @private - * @return {ol.Feature|undefined} Track. */ ol.format.OSMXML.readTag_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, @@ -102134,7 +88386,7 @@ ol.format.OSMXML.NAMESPACE_URIS_ = [ /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.OSMXML.WAY_PARSERS_ = ol.xml.makeStructureNS( @@ -102146,7 +88398,7 @@ ol.format.OSMXML.WAY_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.OSMXML.PARSERS_ = ol.xml.makeStructureNS( @@ -102158,7 +88410,7 @@ ol.format.OSMXML.PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.OSMXML.NODE_PARSERS_ = ol.xml.makeStructureNS( @@ -102233,12 +88485,12 @@ goog.require('goog.asserts'); goog.require('ol.xml'); - /** * @classdesc * Generic format for reading non-feature XML data * * @constructor + * @struct */ ol.format.XML = function() { }; @@ -102246,14 +88498,14 @@ ol.format.XML = function() { /** * @param {Document|Node|string} source Source. - * @return {Object} + * @return {Object} The parsed result. */ ol.format.XML.prototype.read = function(source) { if (ol.xml.isDocument(source)) { return this.readFromDocument(/** @type {Document} */ (source)); } else if (ol.xml.isNode(source)) { return this.readFromNode(/** @type {Node} */ (source)); - } else if (goog.isString(source)) { + } else if (typeof source === 'string') { var doc = ol.xml.parse(source); return this.readFromDocument(doc); } else { @@ -102286,7 +88538,6 @@ goog.require('ol.format.XSD'); goog.require('ol.xml'); - /** * @constructor * @extends {ol.format.XML} @@ -102330,7 +88581,7 @@ ol.format.OWS.prototype.readFromNode = function(node) { * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. * @private - * @return {Object|undefined} + * @return {Object|undefined} The address. */ ol.format.OWS.readAddress_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, @@ -102346,7 +88597,7 @@ ol.format.OWS.readAddress_ = function(node, objectStack) { * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. * @private - * @return {Object|undefined} + * @return {Object|undefined} The values. */ ol.format.OWS.readAllowedValues_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, @@ -102362,7 +88613,7 @@ ol.format.OWS.readAllowedValues_ = function(node, objectStack) { * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. * @private - * @return {Object|undefined} + * @return {Object|undefined} The constraint. */ ol.format.OWS.readConstraint_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, @@ -102383,7 +88634,7 @@ ol.format.OWS.readConstraint_ = function(node, objectStack) { * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. * @private - * @return {Object|undefined} + * @return {Object|undefined} The contact info. */ ol.format.OWS.readContactInfo_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, @@ -102399,7 +88650,7 @@ ol.format.OWS.readContactInfo_ = function(node, objectStack) { * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. * @private - * @return {Object|undefined} + * @return {Object|undefined} The DCP. */ ol.format.OWS.readDcp_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, @@ -102414,7 +88665,7 @@ ol.format.OWS.readDcp_ = function(node, objectStack) { * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. * @private - * @return {Object|undefined} + * @return {Object|undefined} The GET object. */ ol.format.OWS.readGet_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, @@ -102433,7 +88684,7 @@ ol.format.OWS.readGet_ = function(node, objectStack) { * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. * @private - * @return {Object|undefined} + * @return {Object|undefined} The HTTP object. */ ol.format.OWS.readHttp_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, @@ -102448,7 +88699,7 @@ ol.format.OWS.readHttp_ = function(node, objectStack) { * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. * @private - * @return {Object|undefined} + * @return {Object|undefined} The operation. */ ol.format.OWS.readOperation_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, @@ -102473,7 +88724,7 @@ ol.format.OWS.readOperation_ = function(node, objectStack) { * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. * @private - * @return {Object|undefined} + * @return {Object|undefined} The operations metadata. */ ol.format.OWS.readOperationsMetadata_ = function(node, objectStack) { @@ -102491,7 +88742,7 @@ ol.format.OWS.readOperationsMetadata_ = function(node, * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. * @private - * @return {Object|undefined} + * @return {Object|undefined} The phone. */ ol.format.OWS.readPhone_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, @@ -102506,7 +88757,7 @@ ol.format.OWS.readPhone_ = function(node, objectStack) { * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. * @private - * @return {Object|undefined} + * @return {Object|undefined} The service identification. */ ol.format.OWS.readServiceIdentification_ = function(node, objectStack) { @@ -102524,7 +88775,7 @@ ol.format.OWS.readServiceIdentification_ = function(node, * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. * @private - * @return {Object|undefined} + * @return {Object|undefined} The service contact. */ ol.format.OWS.readServiceContact_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, @@ -102541,7 +88792,7 @@ ol.format.OWS.readServiceContact_ = function(node, objectStack) { * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. * @private - * @return {Object|undefined} + * @return {Object|undefined} The service provider. */ ol.format.OWS.readServiceProvider_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, @@ -102558,7 +88809,7 @@ ol.format.OWS.readServiceProvider_ = function(node, objectStack) { * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. * @private - * @return {string|undefined} + * @return {string|undefined} The value. */ ol.format.OWS.readValue_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, @@ -102581,7 +88832,7 @@ ol.format.OWS.NAMESPACE_URIS_ = [ /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.OWS.PARSERS_ = ol.xml.makeStructureNS( @@ -102597,7 +88848,7 @@ ol.format.OWS.PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.OWS.ADDRESS_PARSERS_ = ol.xml.makeStructureNS( @@ -102616,7 +88867,7 @@ ol.format.OWS.ADDRESS_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.OWS.ALLOWED_VALUES_PARSERS_ = ol.xml.makeStructureNS( @@ -102627,7 +88878,7 @@ ol.format.OWS.ALLOWED_VALUES_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.OWS.CONSTRAINT_PARSERS_ = ol.xml.makeStructureNS( @@ -102639,7 +88890,7 @@ ol.format.OWS.CONSTRAINT_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.OWS.CONTACT_INFO_PARSERS_ = ol.xml.makeStructureNS( @@ -102651,7 +88902,7 @@ ol.format.OWS.CONTACT_INFO_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.OWS.DCP_PARSERS_ = ol.xml.makeStructureNS( @@ -102662,7 +88913,7 @@ ol.format.OWS.DCP_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.OWS.HTTP_PARSERS_ = ol.xml.makeStructureNS( @@ -102674,7 +88925,7 @@ ol.format.OWS.HTTP_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.OWS.OPERATION_PARSERS_ = ol.xml.makeStructureNS( @@ -102685,7 +88936,7 @@ ol.format.OWS.OPERATION_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.OWS.OPERATIONS_METADATA_PARSERS_ = ol.xml.makeStructureNS( @@ -102696,7 +88947,7 @@ ol.format.OWS.OPERATIONS_METADATA_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.OWS.PHONE_PARSERS_ = ol.xml.makeStructureNS( @@ -102708,7 +88959,7 @@ ol.format.OWS.PHONE_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.OWS.REQUEST_METHOD_PARSERS_ = ol.xml.makeStructureNS( @@ -102720,7 +88971,7 @@ ol.format.OWS.REQUEST_METHOD_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.OWS.SERVICE_CONTACT_PARSERS_ = @@ -102736,7 +88987,7 @@ ol.format.OWS.SERVICE_CONTACT_PARSERS_ = /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.OWS.SERVICE_IDENTIFICATION_PARSERS_ = @@ -102751,7 +89002,7 @@ ol.format.OWS.SERVICE_IDENTIFICATION_PARSERS_ = /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.OWS.SERVICE_PROVIDER_PARSERS_ = @@ -102777,8 +89028,7 @@ goog.require('goog.asserts'); * @param {number=} opt_destOffset Destination offset. * @return {Array.<number>} Flat coordinates. */ -ol.geom.flat.flip.flipXY = - function(flatCoordinates, offset, end, stride, opt_dest, opt_destOffset) { +ol.geom.flat.flip.flipXY = function(flatCoordinates, offset, end, stride, opt_dest, opt_destOffset) { var dest, destOffset; if (opt_dest !== undefined) { dest = opt_dest; @@ -102789,12 +89039,12 @@ ol.geom.flat.flip.flipXY = dest = []; destOffset = 0; } - var j, k; - for (j = offset; j < end; ) { + var j = offset; + while (j < end) { var x = flatCoordinates[j++]; dest[destOffset++] = flatCoordinates[j++]; dest[destOffset++] = x; - for (k = 2; k < stride; ++k) { + for (var k = 2; k < stride; ++k) { dest[destOffset++] = flatCoordinates[j++]; } } @@ -102816,7 +89066,6 @@ goog.require('ol.geom.flat.inflate'); goog.require('ol.proj'); - /** * @classdesc * Feature format for reading and writing data in the Encoded @@ -103105,8 +89354,7 @@ ol.format.Polyline.prototype.readFeatures; /** * @inheritDoc */ -ol.format.Polyline.prototype.readFeaturesFromText = - function(text, opt_options) { +ol.format.Polyline.prototype.readFeaturesFromText = function(text, opt_options) { var feature = this.readFeatureFromText(text, opt_options); return [feature]; }; @@ -103127,8 +89375,7 @@ ol.format.Polyline.prototype.readGeometry; /** * @inheritDoc */ -ol.format.Polyline.prototype.readGeometryFromText = - function(text, opt_options) { +ol.format.Polyline.prototype.readGeometryFromText = function(text, opt_options) { var stride = ol.geom.SimpleGeometry.getStrideForLayout(this.geometryLayout_); var flatCoordinates = ol.format.Polyline.decodeDeltas( text, stride, this.factor_); @@ -103172,8 +89419,7 @@ ol.format.Polyline.prototype.writeFeatureText = function(feature, opt_options) { /** * @inheritDoc */ -ol.format.Polyline.prototype.writeFeaturesText = - function(features, opt_options) { +ol.format.Polyline.prototype.writeFeaturesText = function(features, opt_options) { goog.asserts.assert(features.length == 1, 'features array should have 1 item'); return this.writeFeatureText(features[0], opt_options); @@ -103195,8 +89441,7 @@ ol.format.Polyline.prototype.writeGeometry; /** * @inheritDoc */ -ol.format.Polyline.prototype.writeGeometryText = - function(geometry, opt_options) { +ol.format.Polyline.prototype.writeGeometryText = function(geometry, opt_options) { goog.asserts.assertInstanceof(geometry, ol.geom.LineString, 'geometry should be an ol.geom.LineString'); geometry = /** @type {ol.geom.LineString} */ @@ -103212,7 +89457,6 @@ ol.format.Polyline.prototype.writeGeometryText = goog.provide('ol.format.TopoJSON'); goog.require('goog.asserts'); -goog.require('goog.object'); goog.require('ol.Feature'); goog.require('ol.format.Feature'); goog.require('ol.format.JSONFeature'); @@ -103222,10 +89466,10 @@ goog.require('ol.geom.MultiPoint'); goog.require('ol.geom.MultiPolygon'); goog.require('ol.geom.Point'); goog.require('ol.geom.Polygon'); +goog.require('ol.object'); goog.require('ol.proj'); - /** * @classdesc * Feature format for reading data in the TopoJSON format. @@ -103511,7 +89755,7 @@ ol.format.TopoJSON.prototype.readFeaturesFromObject = function( } /** @type {Array.<ol.Feature>} */ var features = []; - var topoJSONFeatures = goog.object.getValues(topoJSONTopology.objects); + var topoJSONFeatures = ol.object.getValues(topoJSONTopology.objects); var i, ii; var feature; for (i = 0, ii = topoJSONFeatures.length; i < ii; ++i) { @@ -103622,18 +89866,25 @@ goog.provide('ol.format.WFS'); goog.require('goog.asserts'); goog.require('goog.dom.NodeType'); -goog.require('goog.object'); goog.require('ol'); goog.require('ol.format.GML3'); goog.require('ol.format.GMLBase'); +goog.require('ol.format.ogc.filter'); +goog.require('ol.format.ogc.filter.Bbox'); +goog.require('ol.format.ogc.filter.ComparisonBinary'); +goog.require('ol.format.ogc.filter.LogicalBinary'); +goog.require('ol.format.ogc.filter.Not'); +goog.require('ol.format.ogc.filter.IsBetween'); +goog.require('ol.format.ogc.filter.IsNull'); +goog.require('ol.format.ogc.filter.IsLike'); goog.require('ol.format.XMLFeature'); goog.require('ol.format.XSD'); goog.require('ol.geom.Geometry'); +goog.require('ol.object'); goog.require('ol.proj'); goog.require('ol.xml'); - /** * @classdesc * Feature format for reading and writing data in the WFS format. @@ -103696,26 +89947,6 @@ ol.format.WFS.XMLNS = 'http://www.w3.org/2000/xmlns/'; /** - * Number of features; bounds/extent. - * @typedef {{numberOfFeatures: number, - * bounds: ol.Extent}} - * @api stable - */ -ol.format.WFS.FeatureCollectionMetadata; - - -/** - * Total deleted; total inserted; total updated; array of insert ids. - * @typedef {{totalDeleted: number, - * totalInserted: number, - * totalUpdated: number, - * insertIds: Array.<string>}} - * @api stable - */ -ol.format.WFS.TransactionResponse; - - -/** * @const * @type {string} */ @@ -103743,7 +89974,7 @@ ol.format.WFS.prototype.readFeaturesFromNode = function(node, opt_options) { 'featureType': this.featureType_, 'featureNS': this.featureNS_ }; - goog.object.extend(context, this.getReadOptions(node, + ol.object.assign(context, this.getReadOptions(node, opt_options ? opt_options : {})); var objectStack = [context]; this.gmlFormat_.FEATURE_COLLECTION_PARSERS[ol.format.GMLBase.GMLNS][ @@ -103763,7 +89994,7 @@ ol.format.WFS.prototype.readFeaturesFromNode = function(node, opt_options) { * Read transaction response of the source. * * @param {Document|Node|Object|string} source Source. - * @return {ol.format.WFS.TransactionResponse|undefined} Transaction response. + * @return {ol.WFSTransactionResponse|undefined} Transaction response. * @api stable */ ol.format.WFS.prototype.readTransactionResponse = function(source) { @@ -103772,7 +90003,7 @@ ol.format.WFS.prototype.readTransactionResponse = function(source) { /** @type {Document} */ (source)); } else if (ol.xml.isNode(source)) { return this.readTransactionResponseFromNode(/** @type {Node} */ (source)); - } else if (goog.isString(source)) { + } else if (typeof source === 'string') { var doc = ol.xml.parse(source); return this.readTransactionResponseFromDocument(doc); } else { @@ -103786,7 +90017,7 @@ ol.format.WFS.prototype.readTransactionResponse = function(source) { * Read feature collection metadata of the source. * * @param {Document|Node|Object|string} source Source. - * @return {ol.format.WFS.FeatureCollectionMetadata|undefined} + * @return {ol.WFSFeatureCollectionMetadata|undefined} * FeatureCollection metadata. * @api stable */ @@ -103797,7 +90028,7 @@ ol.format.WFS.prototype.readFeatureCollectionMetadata = function(source) { } else if (ol.xml.isNode(source)) { return this.readFeatureCollectionMetadataFromNode( /** @type {Node} */ (source)); - } else if (goog.isString(source)) { + } else if (typeof source === 'string') { var doc = ol.xml.parse(source); return this.readFeatureCollectionMetadataFromDocument(doc); } else { @@ -103809,11 +90040,10 @@ ol.format.WFS.prototype.readFeatureCollectionMetadata = function(source) { /** * @param {Document} doc Document. - * @return {ol.format.WFS.FeatureCollectionMetadata|undefined} + * @return {ol.WFSFeatureCollectionMetadata|undefined} * FeatureCollection metadata. */ -ol.format.WFS.prototype.readFeatureCollectionMetadataFromDocument = - function(doc) { +ol.format.WFS.prototype.readFeatureCollectionMetadataFromDocument = function(doc) { goog.asserts.assert(doc.nodeType == goog.dom.NodeType.DOCUMENT, 'doc.nodeType should be DOCUMENT'); for (var n = doc.firstChild; n; n = n.nextSibling) { @@ -103827,7 +90057,7 @@ ol.format.WFS.prototype.readFeatureCollectionMetadataFromDocument = /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WFS.FEATURE_COLLECTION_PARSERS_ = { @@ -103840,7 +90070,7 @@ ol.format.WFS.FEATURE_COLLECTION_PARSERS_ = { /** * @param {Node} node Node. - * @return {ol.format.WFS.FeatureCollectionMetadata|undefined} + * @return {ol.WFSFeatureCollectionMetadata|undefined} * FeatureCollection metadata. */ ol.format.WFS.prototype.readFeatureCollectionMetadataFromNode = function(node) { @@ -103853,14 +90083,14 @@ ol.format.WFS.prototype.readFeatureCollectionMetadataFromNode = function(node) { node.getAttribute('numberOfFeatures')); result['numberOfFeatures'] = value; return ol.xml.pushParseAndPop( - /** @type {ol.format.WFS.FeatureCollectionMetadata} */ (result), + /** @type {ol.WFSFeatureCollectionMetadata} */ (result), ol.format.WFS.FEATURE_COLLECTION_PARSERS_, node, [], this.gmlFormat_); }; /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WFS.TRANSACTION_SUMMARY_PARSERS_ = { @@ -103889,7 +90119,7 @@ ol.format.WFS.readTransactionSummary_ = function(node, objectStack) { /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WFS.OGC_FID_PARSERS_ = { @@ -103913,7 +90143,7 @@ ol.format.WFS.fidParser_ = function(node, objectStack) { /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WFS.INSERT_RESULTS_PARSERS_ = { @@ -103937,7 +90167,7 @@ ol.format.WFS.readInsertResults_ = function(node, objectStack) { /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WFS.TRANSACTION_RESPONSE_PARSERS_ = { @@ -103952,7 +90182,7 @@ ol.format.WFS.TRANSACTION_RESPONSE_PARSERS_ = { /** * @param {Document} doc Document. - * @return {ol.format.WFS.TransactionResponse|undefined} Transaction response. + * @return {ol.WFSTransactionResponse|undefined} Transaction response. */ ol.format.WFS.prototype.readTransactionResponseFromDocument = function(doc) { goog.asserts.assert(doc.nodeType == goog.dom.NodeType.DOCUMENT, @@ -103968,7 +90198,7 @@ ol.format.WFS.prototype.readTransactionResponseFromDocument = function(doc) { /** * @param {Node} node Node. - * @return {ol.format.WFS.TransactionResponse|undefined} Transaction response. + * @return {ol.WFSTransactionResponse|undefined} Transaction response. */ ol.format.WFS.prototype.readTransactionResponseFromNode = function(node) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, @@ -103976,13 +90206,13 @@ ol.format.WFS.prototype.readTransactionResponseFromNode = function(node) { goog.asserts.assert(node.localName == 'TransactionResponse', 'localName should be TransactionResponse'); return ol.xml.pushParseAndPop( - /** @type {ol.format.WFS.TransactionResponse} */({}), + /** @type {ol.WFSTransactionResponse} */({}), ol.format.WFS.TRANSACTION_RESPONSE_PARSERS_, node, []); }; /** - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.WFS.QUERY_SERIALIZERS_ = { @@ -104033,6 +90263,7 @@ ol.format.WFS.writeOgcFidFilter_ = function(node, fid, objectStack) { ol.format.WFS.writeDelete_ = function(node, feature, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context), 'context should be an Object'); + goog.asserts.assert(feature.getId() !== undefined, 'feature should have an id'); var featureType = context['featureType']; var featurePrefix = context['featurePrefix']; featurePrefix = featurePrefix ? featurePrefix : @@ -104042,7 +90273,7 @@ ol.format.WFS.writeDelete_ = function(node, feature, objectStack) { ol.xml.setAttributeNS(node, ol.format.WFS.XMLNS, 'xmlns:' + featurePrefix, featureNS); var fid = feature.getId(); - if (fid) { + if (fid !== undefined) { ol.format.WFS.writeOgcFidFilter_(node, fid, objectStack); } }; @@ -104057,6 +90288,7 @@ ol.format.WFS.writeDelete_ = function(node, feature, objectStack) { ol.format.WFS.writeUpdate_ = function(node, feature, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context), 'context should be an Object'); + goog.asserts.assert(feature.getId() !== undefined, 'feature should have an id'); var featureType = context['featureType']; var featurePrefix = context['featurePrefix']; featurePrefix = featurePrefix ? featurePrefix : @@ -104066,7 +90298,7 @@ ol.format.WFS.writeUpdate_ = function(node, feature, objectStack) { ol.xml.setAttributeNS(node, ol.format.WFS.XMLNS, 'xmlns:' + featurePrefix, featureNS); var fid = feature.getId(); - if (fid) { + if (fid !== undefined) { var keys = feature.getKeys(); var values = []; for (var i = 0, ii = keys.length; i < ii; i++) { @@ -104129,7 +90361,7 @@ ol.format.WFS.writeNative_ = function(node, nativeElement, objectStack) { /** - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.WFS.TRANSACTION_SERIALIZERS_ = { @@ -104165,60 +90397,216 @@ ol.format.WFS.writeQuery_ = function(node, featureType, objectStack) { ol.xml.setAttributeNS(node, ol.format.WFS.XMLNS, 'xmlns:' + featurePrefix, featureNS); } - var item = goog.object.clone(context); + var item = ol.object.assign({}, context); item.node = node; ol.xml.pushSerializeAndPop(item, ol.format.WFS.QUERY_SERIALIZERS_, ol.xml.makeSimpleNodeFactory('PropertyName'), propertyNames, objectStack); - var bbox = context['bbox']; - if (bbox) { + var filter = context['filter']; + if (filter) { var child = ol.xml.createElementNS('http://www.opengis.net/ogc', 'Filter'); - ol.format.WFS.writeOgcBBOX_(child, bbox, objectStack); node.appendChild(child); + ol.format.WFS.writeFilterCondition_(child, filter, objectStack); } }; /** * @param {Node} node Node. - * @param {string} value PropertyName value. + * @param {ol.format.ogc.filter.Filter} filter Filter. * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.WFS.writeOgcPropertyName_ = function(node, value, objectStack) { - var property = ol.xml.createElementNS('http://www.opengis.net/ogc', - 'PropertyName'); - ol.format.XSD.writeStringTextNode(property, value); - node.appendChild(property); +ol.format.WFS.writeFilterCondition_ = function(node, filter, objectStack) { + var item = {node: node}; + ol.xml.pushSerializeAndPop(item, + ol.format.WFS.GETFEATURE_SERIALIZERS_, + ol.xml.makeSimpleNodeFactory(filter.getTagName()), + [filter], objectStack); }; /** * @param {Node} node Node. - * @param {ol.Extent} bbox Bounding box. + * @param {ol.format.ogc.filter.Filter} filter Filter. * @param {Array.<*>} objectStack Node stack. * @private */ -ol.format.WFS.writeOgcBBOX_ = function(node, bbox, objectStack) { +ol.format.WFS.writeBboxFilter_ = function(node, filter, objectStack) { + goog.asserts.assertInstanceof(filter, ol.format.ogc.filter.Bbox, + 'must be bbox filter'); + var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context), 'context should be an Object'); - var geometryName = context['geometryName']; - var bboxNode = ol.xml.createElementNS('http://www.opengis.net/ogc', 'BBOX'); - node.appendChild(bboxNode); - ol.format.WFS.writeOgcPropertyName_(bboxNode, geometryName, objectStack); - ol.format.GML3.prototype.writeGeometryElement(bboxNode, bbox, objectStack); + context.srsName = filter.srsName; + + ol.format.WFS.writeOgcPropertyName_(node, filter.geometryName); + ol.format.GML3.prototype.writeGeometryElement(node, filter.extent, objectStack); +}; + + +/** + * @param {Node} node Node. + * @param {ol.format.ogc.filter.Filter} filter Filter. + * @param {Array.<*>} objectStack Node stack. + * @private + */ +ol.format.WFS.writeLogicalFilter_ = function(node, filter, objectStack) { + goog.asserts.assertInstanceof(filter, ol.format.ogc.filter.LogicalBinary, + 'must be logical filter'); + var item = {node: node}; + var conditionA = filter.conditionA; + ol.xml.pushSerializeAndPop(item, + ol.format.WFS.GETFEATURE_SERIALIZERS_, + ol.xml.makeSimpleNodeFactory(conditionA.getTagName()), + [conditionA], objectStack); + var conditionB = filter.conditionB; + ol.xml.pushSerializeAndPop(item, + ol.format.WFS.GETFEATURE_SERIALIZERS_, + ol.xml.makeSimpleNodeFactory(conditionB.getTagName()), + [conditionB], objectStack); }; /** - * @type {Object.<string, Object.<string, ol.xml.Serializer>>} + * @param {Node} node Node. + * @param {ol.format.ogc.filter.Filter} filter Filter. + * @param {Array.<*>} objectStack Node stack. + * @private + */ +ol.format.WFS.writeNotFilter_ = function(node, filter, objectStack) { + goog.asserts.assertInstanceof(filter, ol.format.ogc.filter.Not, + 'must be Not filter'); + var item = {node: node}; + var condition = filter.condition; + ol.xml.pushSerializeAndPop(item, + ol.format.WFS.GETFEATURE_SERIALIZERS_, + ol.xml.makeSimpleNodeFactory(condition.getTagName()), + [condition], objectStack); +}; + + +/** + * @param {Node} node Node. + * @param {ol.format.ogc.filter.Filter} filter Filter. + * @param {Array.<*>} objectStack Node stack. + * @private + */ +ol.format.WFS.writeComparisonFilter_ = function(node, filter, objectStack) { + goog.asserts.assertInstanceof(filter, ol.format.ogc.filter.ComparisonBinary, + 'must be binary comparison filter'); + if (filter.matchCase !== undefined) { + node.setAttribute('matchCase', filter.matchCase.toString()); + } + ol.format.WFS.writeOgcPropertyName_(node, filter.propertyName); + ol.format.WFS.writeOgcLiteral_(node, '' + filter.expression); +}; + + +/** + * @param {Node} node Node. + * @param {ol.format.ogc.filter.Filter} filter Filter. + * @param {Array.<*>} objectStack Node stack. + * @private + */ +ol.format.WFS.writeIsNullFilter_ = function(node, filter, objectStack) { + goog.asserts.assertInstanceof(filter, ol.format.ogc.filter.IsNull, + 'must be IsNull comparison filter'); + ol.format.WFS.writeOgcPropertyName_(node, filter.propertyName); +}; + + +/** + * @param {Node} node Node. + * @param {ol.format.ogc.filter.Filter} filter Filter. + * @param {Array.<*>} objectStack Node stack. + * @private + */ +ol.format.WFS.writeIsBetweenFilter_ = function(node, filter, objectStack) { + goog.asserts.assertInstanceof(filter, ol.format.ogc.filter.IsBetween, + 'must be IsBetween comparison filter'); + ol.format.WFS.writeOgcPropertyName_(node, filter.propertyName); + ol.format.WFS.writeOgcExpression_('LowerBoundary', node, '' + filter.lowerBoundary); + ol.format.WFS.writeOgcExpression_('UpperBoundary', node, '' + filter.upperBoundary); +}; + + +/** + * @param {Node} node Node. + * @param {ol.format.ogc.filter.Filter} filter Filter. + * @param {Array.<*>} objectStack Node stack. + * @private + */ +ol.format.WFS.writeIsLikeFilter_ = function(node, filter, objectStack) { + goog.asserts.assertInstanceof(filter, ol.format.ogc.filter.IsLike, + 'must be IsLike comparison filter'); + node.setAttribute('wildCard', filter.wildCard); + node.setAttribute('singleChar', filter.singleChar); + node.setAttribute('escapeChar', filter.escapeChar); + if (filter.matchCase !== undefined) { + node.setAttribute('matchCase', filter.matchCase.toString()); + } + ol.format.WFS.writeOgcPropertyName_(node, filter.propertyName); + ol.format.WFS.writeOgcLiteral_(node, '' + filter.pattern); +}; + + +/** + * @param {string} tagName Tag name. + * @param {Node} node Node. + * @param {string} value Value. + * @private + */ +ol.format.WFS.writeOgcExpression_ = function(tagName, node, value) { + var property = ol.xml.createElementNS('http://www.opengis.net/ogc', tagName); + ol.format.XSD.writeStringTextNode(property, value); + node.appendChild(property); +}; + + +/** + * @param {Node} node Node. + * @param {string} value PropertyName value. + * @private + */ +ol.format.WFS.writeOgcPropertyName_ = function(node, value) { + ol.format.WFS.writeOgcExpression_('PropertyName', node, value); +}; + + +/** + * @param {Node} node Node. + * @param {string} value PropertyName value. + * @private + */ +ol.format.WFS.writeOgcLiteral_ = function(node, value) { + ol.format.WFS.writeOgcExpression_('Literal', node, value); +}; + + +/** + * @type {Object.<string, Object.<string, ol.XmlSerializer>>} * @private */ ol.format.WFS.GETFEATURE_SERIALIZERS_ = { 'http://www.opengis.net/wfs': { - 'Query': ol.xml.makeChildAppender( - ol.format.WFS.writeQuery_) + 'Query': ol.xml.makeChildAppender(ol.format.WFS.writeQuery_) + }, + 'http://www.opengis.net/ogc': { + 'And': ol.xml.makeChildAppender(ol.format.WFS.writeLogicalFilter_), + 'Or': ol.xml.makeChildAppender(ol.format.WFS.writeLogicalFilter_), + 'Not': ol.xml.makeChildAppender(ol.format.WFS.writeNotFilter_), + 'BBOX': ol.xml.makeChildAppender(ol.format.WFS.writeBboxFilter_), + 'PropertyIsEqualTo': ol.xml.makeChildAppender(ol.format.WFS.writeComparisonFilter_), + 'PropertyIsNotEqualTo': ol.xml.makeChildAppender(ol.format.WFS.writeComparisonFilter_), + 'PropertyIsLessThan': ol.xml.makeChildAppender(ol.format.WFS.writeComparisonFilter_), + 'PropertyIsLessThanOrEqualTo': ol.xml.makeChildAppender(ol.format.WFS.writeComparisonFilter_), + 'PropertyIsGreaterThan': ol.xml.makeChildAppender(ol.format.WFS.writeComparisonFilter_), + 'PropertyIsGreaterThanOrEqualTo': ol.xml.makeChildAppender(ol.format.WFS.writeComparisonFilter_), + 'PropertyIsNull': ol.xml.makeChildAppender(ol.format.WFS.writeIsNullFilter_), + 'PropertyIsBetween': ol.xml.makeChildAppender(ol.format.WFS.writeIsBetweenFilter_), + 'PropertyIsLike': ol.xml.makeChildAppender(ol.format.WFS.writeIsLikeFilter_) } }; @@ -104232,7 +90620,7 @@ ol.format.WFS.GETFEATURE_SERIALIZERS_ = { ol.format.WFS.writeGetFeature_ = function(node, featureTypes, objectStack) { var context = objectStack[objectStack.length - 1]; goog.asserts.assert(goog.isObject(context), 'context should be an Object'); - var item = goog.object.clone(context); + var item = ol.object.assign({}, context); item.node = node; ol.xml.pushSerializeAndPop(item, ol.format.WFS.GETFEATURE_SERIALIZERS_, @@ -104253,6 +90641,7 @@ ol.format.WFS.prototype.writeGetFeature = function(options) { 'GetFeature'); node.setAttribute('service', 'WFS'); node.setAttribute('version', '1.1.0'); + var filter; if (options) { if (options.handle) { node.setAttribute('handle', options.handle); @@ -104272,6 +90661,19 @@ ol.format.WFS.prototype.writeGetFeature = function(options) { if (options.count !== undefined) { node.setAttribute('count', options.count); } + filter = options.filter; + if (options.bbox) { + goog.asserts.assert(options.geometryName, + 'geometryName must be set when using bbox filter'); + var bbox = ol.format.ogc.filter.bbox( + options.geometryName, options.bbox, options.srsName); + if (filter) { + // if bbox and filter are both set, combine the two into a single filter + filter = ol.format.ogc.filter.and(filter, bbox); + } else { + filter = bbox; + } + } } ol.xml.setAttributeNS(node, 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:schemaLocation', this.schemaLocation_); @@ -104281,10 +90683,10 @@ ol.format.WFS.prototype.writeGetFeature = function(options) { featureNS: options.featureNS ? options.featureNS : this.featureNS_, featurePrefix: options.featurePrefix, geometryName: options.geometryName, - bbox: options.bbox, + filter: filter, propertyNames: options.propertyNames ? options.propertyNames : [] }; - goog.asserts.assert(goog.isArray(options.featureTypes), + goog.asserts.assert(Array.isArray(options.featureTypes), 'options.featureTypes should be an array'); ol.format.WFS.writeGetFeature_(node, options.featureTypes, [context]); return node; @@ -104320,7 +90722,7 @@ ol.format.WFS.prototype.writeTransaction = function(inserts, updates, deletes, if (inserts) { obj = {node: node, featureNS: options.featureNS, featureType: options.featureType, featurePrefix: options.featurePrefix}; - goog.object.extend(obj, baseObj); + ol.object.assign(obj, baseObj); ol.xml.pushSerializeAndPop(obj, ol.format.WFS.TRANSACTION_SERIALIZERS_, ol.xml.makeSimpleNodeFactory('Insert'), inserts, @@ -104329,7 +90731,7 @@ ol.format.WFS.prototype.writeTransaction = function(inserts, updates, deletes, if (updates) { obj = {node: node, featureNS: options.featureNS, featureType: options.featureType, featurePrefix: options.featurePrefix}; - goog.object.extend(obj, baseObj); + ol.object.assign(obj, baseObj); ol.xml.pushSerializeAndPop(obj, ol.format.WFS.TRANSACTION_SERIALIZERS_, ol.xml.makeSimpleNodeFactory('Update'), updates, @@ -104423,7 +90825,6 @@ goog.require('ol.geom.Point'); goog.require('ol.geom.Polygon'); - /** * @classdesc * Geometry format for reading and writing data in the `WellKnownText` (WKT) @@ -104775,12 +91176,6 @@ ol.format.WKT.prototype.writeGeometryText = function(geometry, opt_options) { /** - * @typedef {{type: number, value: (number|string|undefined), position: number}} - */ -ol.format.WKT.Token; - - -/** * @const * @enum {number} */ @@ -104794,7 +91189,6 @@ ol.format.WKT.TokenType = { }; - /** * Class to tokenize a WKT string. * @param {string} wkt WKT string. @@ -104860,7 +91254,7 @@ ol.format.WKT.Lexer.prototype.nextChar_ = function() { /** * Fetch and return the next token. - * @return {!ol.format.WKT.Token} Next string token. + * @return {!ol.WKTToken} Next string token. */ ol.format.WKT.Lexer.prototype.nextToken = function() { var c = this.nextChar_(); @@ -104931,10 +91325,9 @@ ol.format.WKT.Lexer.prototype.readText_ = function() { }; - /** * Class to parse the tokens from the WKT string. - * @param {ol.format.WKT.Lexer} lexer + * @param {ol.format.WKT.Lexer} lexer The lexer. * @constructor * @protected */ @@ -104947,7 +91340,7 @@ ol.format.WKT.Parser = function(lexer) { this.lexer_ = lexer; /** - * @type {ol.format.WKT.Token} + * @type {ol.WKTToken} * @private */ this.token_; @@ -104971,7 +91364,7 @@ ol.format.WKT.Parser.prototype.consume_ = function() { /** * If the given type matches the current token, consume it. - * @param {ol.format.WKT.TokenType.<number>} type Token type. + * @param {ol.format.WKT.TokenType} type Token type. * @return {boolean} Whether the token matches the given type. */ ol.format.WKT.Parser.prototype.match = function(type) { @@ -105248,7 +91641,7 @@ ol.format.WKT.Parser.prototype.formatErrorMessage_ = function() { /** - * @enum {function (new:ol.geom.Geometry, Array, ol.geom.GeometryLayout.<string>=)} + * @enum {function (new:ol.geom.Geometry, Array, ol.geom.GeometryLayout)} * @private */ ol.format.WKT.Parser.GeometryConstructor_ = { @@ -105278,7 +91671,6 @@ goog.provide('ol.format.WMSCapabilities'); goog.require('goog.asserts'); goog.require('goog.dom.NodeType'); -goog.require('goog.object'); goog.require('ol'); goog.require('ol.format.XLink'); goog.require('ol.format.XML'); @@ -105286,7 +91678,6 @@ goog.require('ol.format.XSD'); goog.require('ol.xml'); - /** * @classdesc * Format for reading WMS capabilities data @@ -105407,8 +91798,7 @@ ol.format.WMSCapabilities.readBoundingBox_ = function(node, objectStack) { * @param {Array.<*>} objectStack Object stack. * @return {ol.Extent|undefined} Bounding box object. */ -ol.format.WMSCapabilities.readEXGeographicBoundingBox_ = - function(node, objectStack) { +ol.format.WMSCapabilities.readEXGeographicBoundingBox_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'EX_GeographicBoundingBox', @@ -105432,10 +91822,10 @@ ol.format.WMSCapabilities.readEXGeographicBoundingBox_ = eastBoundLongitude === undefined || northBoundLatitude === undefined) { return undefined; } - return /** @type {ol.Extent} */ ([ + return [ westBoundLongitude, southBoundLatitude, eastBoundLongitude, northBoundLatitude - ]); + ]; }; @@ -105477,8 +91867,7 @@ ol.format.WMSCapabilities.readService_ = function(node, objectStack) { * @private * @return {Object|undefined} Contact information object. */ -ol.format.WMSCapabilities.readContactInformation_ = - function(node, objectStack) { +ol.format.WMSCapabilities.readContactInformation_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType shpuld be ELEMENT'); goog.asserts.assert(node.localName == 'ContactInformation', @@ -105495,8 +91884,7 @@ ol.format.WMSCapabilities.readContactInformation_ = * @private * @return {Object|undefined} Contact person object. */ -ol.format.WMSCapabilities.readContactPersonPrimary_ = - function(node, objectStack) { +ol.format.WMSCapabilities.readContactPersonPrimary_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'ContactPersonPrimary', @@ -105513,8 +91901,7 @@ ol.format.WMSCapabilities.readContactPersonPrimary_ = * @private * @return {Object|undefined} Contact address object. */ -ol.format.WMSCapabilities.readContactAddress_ = - function(node, objectStack) { +ol.format.WMSCapabilities.readContactAddress_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'ContactAddress', @@ -105569,8 +91956,8 @@ ol.format.WMSCapabilities.readLayer_ = function(node, objectStack) { var parentLayerObject = /** @type {Object.<string,*>} */ (objectStack[objectStack.length - 1]); - var layerObject = /** @type {Object.<string,*>} */ (ol.xml.pushParseAndPop( - {}, ol.format.WMSCapabilities.LAYER_PARSERS_, node, objectStack)); + var layerObject = ol.xml.pushParseAndPop( + {}, ol.format.WMSCapabilities.LAYER_PARSERS_, node, objectStack); if (!layerObject) { return undefined; @@ -105620,9 +92007,8 @@ ol.format.WMSCapabilities.readLayer_ = function(node, objectStack) { var addKeys = ['Style', 'CRS', 'AuthorityURL']; addKeys.forEach(function(key) { if (key in parentLayerObject) { - var childValue = goog.object.setIfUndefined(layerObject, key, []); - childValue = childValue.concat(parentLayerObject[key]); - layerObject[key] = childValue; + var childValue = layerObject[key] || []; + layerObject[key] = childValue.concat(parentLayerObject[key]); } }); @@ -105672,8 +92058,7 @@ ol.format.WMSCapabilities.readDimension_ = function(node, objectStack) { * @param {Array.<*>} objectStack Object stack. * @return {Object|undefined} Online resource object. */ -ol.format.WMSCapabilities.readFormatOnlineresource_ = - function(node, objectStack) { +ol.format.WMSCapabilities.readFormatOnlineresource_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); return ol.xml.pushParseAndPop( @@ -105749,8 +92134,7 @@ ol.format.WMSCapabilities.readOperationType_ = function(node, objectStack) { * @param {Array.<*>} objectStack Object stack. * @return {Object|undefined} Online resource object. */ -ol.format.WMSCapabilities.readSizedFormatOnlineresource_ = - function(node, objectStack) { +ol.format.WMSCapabilities.readSizedFormatOnlineresource_ = function(node, objectStack) { goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); var formatOnlineresource = @@ -105853,7 +92237,7 @@ ol.format.WMSCapabilities.NAMESPACE_URIS_ = [ /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMSCapabilities.PARSERS_ = ol.xml.makeStructureNS( @@ -105867,7 +92251,7 @@ ol.format.WMSCapabilities.PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMSCapabilities.CAPABILITY_PARSERS_ = ol.xml.makeStructureNS( @@ -105883,7 +92267,7 @@ ol.format.WMSCapabilities.CAPABILITY_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMSCapabilities.SERVICE_PARSERS_ = ol.xml.makeStructureNS( @@ -105911,7 +92295,7 @@ ol.format.WMSCapabilities.SERVICE_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMSCapabilities.CONTACT_INFORMATION_PARSERS_ = ol.xml.makeStructureNS( @@ -105933,7 +92317,7 @@ ol.format.WMSCapabilities.CONTACT_INFORMATION_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMSCapabilities.CONTACT_PERSON_PARSERS_ = ol.xml.makeStructureNS( @@ -105947,7 +92331,7 @@ ol.format.WMSCapabilities.CONTACT_PERSON_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMSCapabilities.CONTACT_ADDRESS_PARSERS_ = ol.xml.makeStructureNS( @@ -105964,7 +92348,7 @@ ol.format.WMSCapabilities.CONTACT_ADDRESS_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMSCapabilities.EXCEPTION_PARSERS_ = ol.xml.makeStructureNS( @@ -105975,7 +92359,7 @@ ol.format.WMSCapabilities.EXCEPTION_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMSCapabilities.LAYER_PARSERS_ = ol.xml.makeStructureNS( @@ -106016,7 +92400,7 @@ ol.format.WMSCapabilities.LAYER_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMSCapabilities.ATTRIBUTION_PARSERS_ = ol.xml.makeStructureNS( @@ -106031,7 +92415,7 @@ ol.format.WMSCapabilities.ATTRIBUTION_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMSCapabilities.EX_GEOGRAPHIC_BOUNDING_BOX_PARSERS_ = @@ -106049,7 +92433,7 @@ ol.format.WMSCapabilities.EX_GEOGRAPHIC_BOUNDING_BOX_PARSERS_ = /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMSCapabilities.REQUEST_PARSERS_ = ol.xml.makeStructureNS( @@ -106065,7 +92449,7 @@ ol.format.WMSCapabilities.REQUEST_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMSCapabilities.OPERATIONTYPE_PARSERS_ = ol.xml.makeStructureNS( @@ -106078,7 +92462,7 @@ ol.format.WMSCapabilities.OPERATIONTYPE_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMSCapabilities.DCPTYPE_PARSERS_ = ol.xml.makeStructureNS( @@ -106090,7 +92474,7 @@ ol.format.WMSCapabilities.DCPTYPE_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMSCapabilities.HTTP_PARSERS_ = ol.xml.makeStructureNS( @@ -106104,7 +92488,7 @@ ol.format.WMSCapabilities.HTTP_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMSCapabilities.STYLE_PARSERS_ = ol.xml.makeStructureNS( @@ -106123,7 +92507,7 @@ ol.format.WMSCapabilities.STYLE_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMSCapabilities.FORMAT_ONLINERESOURCE_PARSERS_ = @@ -106136,7 +92520,7 @@ ol.format.WMSCapabilities.FORMAT_ONLINERESOURCE_PARSERS_ = /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMSCapabilities.KEYWORDLIST_PARSERS_ = ol.xml.makeStructureNS( @@ -106146,16 +92530,15 @@ ol.format.WMSCapabilities.KEYWORDLIST_PARSERS_ = ol.xml.makeStructureNS( goog.provide('ol.format.WMSGetFeatureInfo'); -goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom.NodeType'); -goog.require('goog.object'); +goog.require('ol.array'); goog.require('ol.format.GML2'); goog.require('ol.format.XMLFeature'); +goog.require('ol.object'); goog.require('ol.xml'); - /** * @classdesc * Format for reading WMSGetFeatureInfo format. It uses @@ -106163,9 +92546,12 @@ goog.require('ol.xml'); * * @constructor * @extends {ol.format.XMLFeature} + * @param {olx.format.WMSGetFeatureInfoOptions=} opt_options Options. * @api */ -ol.format.WMSGetFeatureInfo = function() { +ol.format.WMSGetFeatureInfo = function(opt_options) { + + var options = opt_options ? opt_options : {}; /** * @private @@ -106180,6 +92566,13 @@ ol.format.WMSGetFeatureInfo = function() { */ this.gmlFormat_ = new ol.format.GML2(); + + /** + * @private + * @type {Array.<string>} + */ + this.layers_ = options.layers ? options.layers : null; + goog.base(this); }; goog.inherits(ol.format.WMSGetFeatureInfo, ol.format.XMLFeature); @@ -106207,13 +92600,12 @@ ol.format.WMSGetFeatureInfo.layerIdentifier_ = '_layer'; * @return {Array.<ol.Feature>} Features. * @private */ -ol.format.WMSGetFeatureInfo.prototype.readFeatures_ = - function(node, objectStack) { +ol.format.WMSGetFeatureInfo.prototype.readFeatures_ = function(node, objectStack) { - node.namespaceURI = this.featureNS_; + node.setAttribute('namespaceURI', this.featureNS_); goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT, 'node.nodeType should be ELEMENT'); - var localName = ol.xml.getLocalName(node); + var localName = node.localName; /** @type {Array.<ol.Feature>} */ var features = []; if (node.childNodes.length === 0) { @@ -106234,7 +92626,13 @@ ol.format.WMSGetFeatureInfo.prototype.readFeatures_ = 'localName of layer node should match layerIdentifier'); var toRemove = ol.format.WMSGetFeatureInfo.layerIdentifier_; - var featureType = layer.localName.replace(toRemove, '') + + var layerName = layer.localName.replace(toRemove, ''); + + if (this.layers_ && !ol.array.includes(this.layers_, layerName)) { + continue; + } + + var featureType = layerName + ol.format.WMSGetFeatureInfo.featureIdentifier_; context['featureType'] = featureType; @@ -106245,11 +92643,11 @@ ol.format.WMSGetFeatureInfo.prototype.readFeatures_ = this.gmlFormat_.readFeatureElement, this.gmlFormat_); var parsersNS = ol.xml.makeStructureNS( [context['featureNS'], null], parsers); - layer.namespaceURI = this.featureNS_; + layer.setAttribute('namespaceURI', this.featureNS_); var layerFeatures = ol.xml.pushParseAndPop( [], parsersNS, layer, objectStack, this.gmlFormat_); if (layerFeatures) { - goog.array.extend(features, layerFeatures); + ol.array.extend(features, layerFeatures); } } } @@ -106280,14 +92678,10 @@ ol.format.WMSGetFeatureInfo.prototype.readFeatures; /** * @inheritDoc */ -ol.format.WMSGetFeatureInfo.prototype.readFeaturesFromNode = - function(node, opt_options) { - var options = { - 'featureType': this.featureType, - 'featureNS': this.featureNS - }; +ol.format.WMSGetFeatureInfo.prototype.readFeaturesFromNode = function(node, opt_options) { + var options = {}; if (opt_options) { - goog.object.extend(options, this.getReadOptions(node, opt_options)); + ol.object.assign(options, this.getReadOptions(node, opt_options)); } return this.readFeatures_(node, [options]); }; @@ -106304,7 +92698,6 @@ goog.require('ol.format.XSD'); goog.require('ol.xml'); - /** * @classdesc * Format for reading WMTS capabilities data. @@ -106361,13 +92754,13 @@ ol.format.WMTSCapabilities.prototype.readFromNode = function(node) { 'node.nodeType should be ELEMENT'); goog.asserts.assert(node.localName == 'Capabilities', 'localName should be Capabilities'); - this.version = node.getAttribute('version').trim(); - goog.asserts.assertString(this.version, 'this.version should be a string'); + var version = node.getAttribute('version').trim(); + goog.asserts.assertString(version, 'version should be a string'); var WMTSCapabilityObject = this.owsParser_.readFromNode(node); if (!WMTSCapabilityObject) { return null; } - WMTSCapabilityObject['version'] = this.version; + WMTSCapabilityObject['version'] = version; WMTSCapabilityObject = ol.xml.pushParseAndPop(WMTSCapabilityObject, ol.format.WMTSCapabilities.PARSERS_, node, []); return WMTSCapabilityObject ? WMTSCapabilityObject : null; @@ -106572,7 +92965,7 @@ ol.format.WMTSCapabilities.OWS_NAMESPACE_URIS_ = [ /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMTSCapabilities.PARSERS_ = ol.xml.makeStructureNS( @@ -106584,7 +92977,7 @@ ol.format.WMTSCapabilities.PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMTSCapabilities.CONTENTS_PARSERS_ = ol.xml.makeStructureNS( @@ -106598,7 +92991,7 @@ ol.format.WMTSCapabilities.CONTENTS_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMTSCapabilities.LAYER_PARSERS_ = ol.xml.makeStructureNS( @@ -106627,7 +93020,7 @@ ol.format.WMTSCapabilities.LAYER_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMTSCapabilities.STYLE_PARSERS_ = ol.xml.makeStructureNS( @@ -106644,7 +93037,7 @@ ol.format.WMTSCapabilities.STYLE_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMTSCapabilities.TMS_LINKS_PARSERS_ = ol.xml.makeStructureNS( @@ -106656,7 +93049,7 @@ ol.format.WMTSCapabilities.TMS_LINKS_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMTSCapabilities.DIMENSION_PARSERS_ = ol.xml.makeStructureNS( @@ -106673,7 +93066,7 @@ ol.format.WMTSCapabilities.DIMENSION_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMTSCapabilities.WGS84_BBOX_READERS_ = ol.xml.makeStructureNS( @@ -106687,7 +93080,7 @@ ol.format.WMTSCapabilities.WGS84_BBOX_READERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMTSCapabilities.TMS_PARSERS_ = ol.xml.makeStructureNS( @@ -106706,7 +93099,7 @@ ol.format.WMTSCapabilities.TMS_PARSERS_ = ol.xml.makeStructureNS( /** * @const - * @type {Object.<string, Object.<string, ol.xml.Parser>>} + * @type {Object.<string, Object.<string, ol.XmlParser>>} * @private */ ol.format.WMTSCapabilities.TM_PARSERS_ = ol.xml.makeStructureNS( @@ -106728,26 +93121,13 @@ ol.format.WMTSCapabilities.TM_PARSERS_ = ol.xml.makeStructureNS( ol.format.XSD.readString) })); -goog.provide('ol.sphere.WGS84'); - -goog.require('ol.Sphere'); - - -/** - * A sphere with radius equal to the semi-major axis of the WGS84 ellipsoid. - * @const - * @type {ol.Sphere} - */ -ol.sphere.WGS84 = new ol.Sphere(6378137); - // FIXME handle geolocation not supported goog.provide('ol.Geolocation'); goog.provide('ol.GeolocationProperty'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('ol.Coordinate'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol.Object'); goog.require('ol.geom.Geometry'); goog.require('ol.geom.Polygon'); @@ -106774,7 +93154,6 @@ ol.GeolocationProperty = { }; - /** * @classdesc * Helper class for providing HTML5 Geolocation capabilities. @@ -106795,6 +93174,7 @@ ol.GeolocationProperty = { * window.console.log(geolocation.getPosition()); * }); * + * @fires error * @constructor * @extends {ol.Object} * @param {olx.GeolocationOptions=} opt_options Options. @@ -106825,12 +93205,12 @@ ol.Geolocation = function(opt_options) { */ this.watchId_ = undefined; - goog.events.listen( + ol.events.listen( this, ol.Object.getChangeEventType(ol.GeolocationProperty.PROJECTION), - this.handleProjectionChanged_, false, this); - goog.events.listen( + this.handleProjectionChanged_, this); + ol.events.listen( this, ol.Object.getChangeEventType(ol.GeolocationProperty.TRACKING), - this.handleTrackingChanged_, false, this); + this.handleTrackingChanged_, this); if (options.projection !== undefined) { this.setProjection(ol.proj.get(options.projection)); @@ -106877,12 +93257,12 @@ ol.Geolocation.prototype.handleTrackingChanged_ = function() { if (ol.has.GEOLOCATION) { var tracking = this.getTracking(); if (tracking && this.watchId_ === undefined) { - this.watchId_ = goog.global.navigator.geolocation.watchPosition( - goog.bind(this.positionChange_, this), - goog.bind(this.positionError_, this), + this.watchId_ = ol.global.navigator.geolocation.watchPosition( + this.positionChange_.bind(this), + this.positionError_.bind(this), this.getTrackingOptions()); } else if (!tracking && this.watchId_ !== undefined) { - goog.global.navigator.geolocation.clearWatch(this.watchId_); + ol.global.navigator.geolocation.clearWatch(this.watchId_); this.watchId_ = undefined; } } @@ -106920,15 +93300,20 @@ ol.Geolocation.prototype.positionChange_ = function(position) { this.changed(); }; +/** + * Triggered when the Geolocation returns an error. + * @event error + * @api + */ /** * @private * @param {GeolocationPositionError} error error object. */ ol.Geolocation.prototype.positionError_ = function(error) { - error.type = goog.events.EventType.ERROR; + error.type = ol.events.EventType.ERROR; this.setTracking(false); - this.dispatchEvent(error); + this.dispatchEvent(/** @type {{type: string, target: undefined}} */ (error)); }; @@ -107108,7 +93493,6 @@ goog.require('ol.geom.flat.deflate'); goog.require('ol.proj'); - /** * @classdesc * Circle geometry. @@ -107143,8 +93527,7 @@ ol.geom.Circle.prototype.clone = function() { /** * @inheritDoc */ -ol.geom.Circle.prototype.closestPointXY = - function(x, y, closestPoint, minSquaredDistance) { +ol.geom.Circle.prototype.closestPointXY = function(x, y, closestPoint, minSquaredDistance) { var flatCoordinates = this.flatCoordinates; var dx = x - flatCoordinates[0]; var dy = y - flatCoordinates[1]; @@ -107286,8 +93669,7 @@ ol.geom.Circle.prototype.setCenter = function(center) { * @param {ol.geom.GeometryLayout=} opt_layout Layout. * @api */ -ol.geom.Circle.prototype.setCenterAndRadius = - function(center, radius, opt_layout) { +ol.geom.Circle.prototype.setCenterAndRadius = function(center, radius, opt_layout) { if (!center) { this.setFlatCoordinates(ol.geom.GeometryLayout.XY, null); } else { @@ -107314,8 +93696,7 @@ ol.geom.Circle.prototype.setCenterAndRadius = * @param {ol.geom.GeometryLayout} layout Layout. * @param {Array.<number>} flatCoordinates Flat coordinates. */ -ol.geom.Circle.prototype.setFlatCoordinates = - function(layout, flatCoordinates) { +ol.geom.Circle.prototype.setFlatCoordinates = function(layout, flatCoordinates) { this.setFlatCoordinatesInternal(layout, flatCoordinates); this.changed(); }; @@ -107361,7 +93742,6 @@ ol.geom.Circle.prototype.transform; goog.provide('ol.geom.flat.geodesic'); goog.require('goog.asserts'); -goog.require('ol.TransformFunction'); goog.require('ol.math'); goog.require('ol.proj'); @@ -107374,8 +93754,7 @@ goog.require('ol.proj'); * @param {number} squaredTolerance Squared tolerance. * @return {Array.<number>} Flat coordinates. */ -ol.geom.flat.geodesic.line_ = - function(interpolate, transform, squaredTolerance) { +ol.geom.flat.geodesic.line_ = function(interpolate, transform, squaredTolerance) { // FIXME reduce garbage generation // FIXME optimize stack operations @@ -107501,8 +93880,7 @@ ol.geom.flat.geodesic.greatCircleArc = function( * @param {number} squaredTolerance Squared tolerance. * @return {Array.<number>} Flat coordinates. */ -ol.geom.flat.geodesic.meridian = - function(lon, lat1, lat2, projection, squaredTolerance) { +ol.geom.flat.geodesic.meridian = function(lon, lat1, lat2, projection, squaredTolerance) { var epsg4326Projection = ol.proj.get('EPSG:4326'); return ol.geom.flat.geodesic.line_( /** @@ -107525,8 +93903,7 @@ ol.geom.flat.geodesic.meridian = * @param {number} squaredTolerance Squared tolerance. * @return {Array.<number>} Flat coordinates. */ -ol.geom.flat.geodesic.parallel = - function(lat, lon1, lon2, projection, squaredTolerance) { +ol.geom.flat.geodesic.parallel = function(lat, lon1, lon2, projection, squaredTolerance) { var epsg4326Projection = ol.proj.get('EPSG:4326'); return ol.geom.flat.geodesic.line_( /** @@ -107552,7 +93929,6 @@ goog.require('ol.render.EventType'); goog.require('ol.style.Stroke'); - /** * Render a grid for a coordinate system on a map. * @constructor @@ -107708,8 +94084,7 @@ ol.Graticule.intervals_ = [90, 45, 30, 20, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05, * @return {number} Index. * @private */ -ol.Graticule.prototype.addMeridian_ = - function(lon, minLat, maxLat, squaredTolerance, extent, index) { +ol.Graticule.prototype.addMeridian_ = function(lon, minLat, maxLat, squaredTolerance, extent, index) { var lineString = this.getMeridian_(lon, minLat, maxLat, squaredTolerance, index); if (ol.extent.intersects(lineString.getExtent(), extent)) { @@ -107729,8 +94104,7 @@ ol.Graticule.prototype.addMeridian_ = * @return {number} Index. * @private */ -ol.Graticule.prototype.addParallel_ = - function(lat, minLon, maxLon, squaredTolerance, extent, index) { +ol.Graticule.prototype.addParallel_ = function(lat, minLon, maxLon, squaredTolerance, extent, index) { var lineString = this.getParallel_(lat, minLon, maxLon, squaredTolerance, index); if (ol.extent.intersects(lineString.getExtent(), extent)) { @@ -107747,8 +94121,7 @@ ol.Graticule.prototype.addParallel_ = * @param {number} squaredTolerance Squared tolerance. * @private */ -ol.Graticule.prototype.createGraticule_ = - function(extent, center, resolution, squaredTolerance) { +ol.Graticule.prototype.createGraticule_ = function(extent, center, resolution, squaredTolerance) { var interval = this.getInterval_(resolution); if (interval == -1) { @@ -107987,11 +94360,11 @@ ol.Graticule.prototype.handlePostCompose_ = function(e) { var i, l, line; for (i = 0, l = this.meridians_.length; i < l; ++i) { line = this.meridians_[i]; - vectorContext.drawLineStringGeometry(line, null); + vectorContext.drawLineString(line, null); } for (i = 0, l = this.parallels_.length; i < l; ++i) { line = this.parallels_[i]; - vectorContext.drawLineStringGeometry(line, null); + vectorContext.drawLineString(line, null); } }; @@ -108082,13 +94455,12 @@ ol.Graticule.prototype.setMap = function(map) { goog.provide('ol.Image'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.object'); goog.require('ol.ImageBase'); goog.require('ol.ImageState'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol.extent'); - +goog.require('ol.object'); /** @@ -108131,7 +94503,7 @@ ol.Image = function(extent, resolution, pixelRatio, attributions, src, /** * @private - * @type {Array.<goog.events.Key>} + * @type {Array.<ol.events.Key>} */ this.imageListenerKeys_ = null; @@ -108163,7 +94535,7 @@ ol.Image.prototype.getImage = function(opt_context) { var key = goog.getUid(opt_context); if (key in this.imageByContext_) { return this.imageByContext_[key]; - } else if (goog.object.isEmpty(this.imageByContext_)) { + } else if (ol.object.isEmpty(this.imageByContext_)) { image = this.image_; } else { image = /** @type {Image} */ (this.image_.cloneNode(false)); @@ -108213,10 +94585,10 @@ ol.Image.prototype.load = function() { goog.asserts.assert(!this.imageListenerKeys_, 'this.imageListenerKeys_ should be null'); this.imageListenerKeys_ = [ - goog.events.listenOnce(this.image_, goog.events.EventType.ERROR, - this.handleImageError_, false, this), - goog.events.listenOnce(this.image_, goog.events.EventType.LOAD, - this.handleImageLoad_, false, this) + ol.events.listenOnce(this.image_, ol.events.EventType.ERROR, + this.handleImageError_, this), + ol.events.listenOnce(this.image_, ol.events.EventType.LOAD, + this.handleImageLoad_, this) ]; this.imageLoadFunction_(this, this.src_); } @@ -108239,43 +94611,18 @@ ol.Image.prototype.setImage = function(image) { ol.Image.prototype.unlistenImage_ = function() { goog.asserts.assert(this.imageListenerKeys_, 'this.imageListenerKeys_ should not be null'); - this.imageListenerKeys_.forEach(goog.events.unlistenByKey); + this.imageListenerKeys_.forEach(ol.events.unlistenByKey); this.imageListenerKeys_ = null; }; -goog.provide('ol.ImageLoadFunctionType'); - - -/** - * A function that takes an {@link ol.Image} for the image and a `{string}` for - * the src as arguments. It is supposed to make it so the underlying image - * {@link ol.Image#getImage} is assigned the content specified by the src. If - * not specified, the default is - * - * function(image, src) { - * image.getImage().src = src; - * } - * - * Providing a custom `imageLoadFunction` can be useful to load images with - * post requests or - in general - through XHR requests, where the src of the - * image element would be set to a data URI when the content is loaded. - * - * @typedef {function(ol.Image, string)} - * @api - */ -ol.ImageLoadFunctionType; - goog.provide('ol.ImageTile'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.object'); goog.require('ol.Tile'); -goog.require('ol.TileCoord'); -goog.require('ol.TileLoadFunctionType'); goog.require('ol.TileState'); - +goog.require('ol.events'); +goog.require('ol.events.EventType'); +goog.require('ol.object'); /** @@ -108316,7 +94663,7 @@ ol.ImageTile = function(tileCoord, state, src, crossOrigin, tileLoadFunction) { /** * @private - * @type {Array.<goog.events.Key>} + * @type {Array.<ol.events.Key>} */ this.imageListenerKeys_ = null; @@ -108338,8 +94685,10 @@ ol.ImageTile.prototype.disposeInternal = function() { this.unlistenImage_(); } if (this.interimTile) { - goog.dispose(this.interimTile); + this.interimTile.dispose(); } + this.state = ol.TileState.ABORT; + this.changed(); goog.base(this, 'disposeInternal'); }; @@ -108355,7 +94704,7 @@ ol.ImageTile.prototype.getImage = function(opt_context) { var key = goog.getUid(opt_context); if (key in this.imageByContext_) { return this.imageByContext_[key]; - } else if (goog.object.isEmpty(this.imageByContext_)) { + } else if (ol.object.isEmpty(this.imageByContext_)) { image = this.image_; } else { image = /** @type {Image} */ (this.image_.cloneNode(false)); @@ -108414,10 +94763,10 @@ ol.ImageTile.prototype.load = function() { goog.asserts.assert(!this.imageListenerKeys_, 'this.imageListenerKeys_ should be null'); this.imageListenerKeys_ = [ - goog.events.listenOnce(this.image_, goog.events.EventType.ERROR, - this.handleImageError_, false, this), - goog.events.listenOnce(this.image_, goog.events.EventType.LOAD, - this.handleImageLoad_, false, this) + ol.events.listenOnce(this.image_, ol.events.EventType.ERROR, + this.handleImageError_, this), + ol.events.listenOnce(this.image_, ol.events.EventType.LOAD, + this.handleImageLoad_, this) ]; this.tileLoadFunction_(this, this.src_); } @@ -108432,1745 +94781,24 @@ ol.ImageTile.prototype.load = function() { ol.ImageTile.prototype.unlistenImage_ = function() { goog.asserts.assert(this.imageListenerKeys_, 'this.imageListenerKeys_ should not be null'); - this.imageListenerKeys_.forEach(goog.events.unlistenByKey); + this.imageListenerKeys_.forEach(ol.events.unlistenByKey); this.imageListenerKeys_ = null; }; -// Copyright 2010 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Provides a files drag and drop event detector. It works on - * HTML5 browsers. - * - * @see ../demos/filedrophandler.html - */ - -goog.provide('goog.events.FileDropHandler'); -goog.provide('goog.events.FileDropHandler.EventType'); - -goog.require('goog.array'); -goog.require('goog.dom'); -goog.require('goog.events.BrowserEvent'); -goog.require('goog.events.EventHandler'); -goog.require('goog.events.EventTarget'); -goog.require('goog.events.EventType'); -goog.require('goog.log'); -goog.require('goog.log.Level'); - - - -/** - * A files drag and drop event detector. Gets an {@code element} as parameter - * and fires {@code goog.events.FileDropHandler.EventType.DROP} event when files - * are dropped in the {@code element}. - * - * @param {Element|Document} element The element or document to listen on. - * @param {boolean=} opt_preventDropOutside Whether to prevent a drop on the - * area outside the {@code element}. Default false. - * @constructor - * @extends {goog.events.EventTarget} - * @final - */ -goog.events.FileDropHandler = function(element, opt_preventDropOutside) { - goog.events.EventTarget.call(this); - - /** - * Handler for drag/drop events. - * @type {!goog.events.EventHandler<!goog.events.FileDropHandler>} - * @private - */ - this.eventHandler_ = new goog.events.EventHandler(this); - - var doc = element; - if (opt_preventDropOutside) { - doc = goog.dom.getOwnerDocument(element); - } - - // Add dragenter listener to the owner document of the element. - this.eventHandler_.listen(doc, - goog.events.EventType.DRAGENTER, - this.onDocDragEnter_); - - // Add dragover listener to the owner document of the element only if the - // document is not the element itself. - if (doc != element) { - this.eventHandler_.listen(doc, - goog.events.EventType.DRAGOVER, - this.onDocDragOver_); - } - - // Add dragover and drop listeners to the element. - this.eventHandler_.listen(element, - goog.events.EventType.DRAGOVER, - this.onElemDragOver_); - this.eventHandler_.listen(element, - goog.events.EventType.DROP, - this.onElemDrop_); -}; -goog.inherits(goog.events.FileDropHandler, goog.events.EventTarget); - - -/** - * Whether the drag event contains files. It is initialized only in the - * dragenter event. It is used in all the drag events to prevent default actions - * only if the drag contains files. Preventing default actions is necessary to - * go from dragenter to dragover and from dragover to drop. However we do not - * always want to prevent default actions, e.g. when the user drags text or - * links on a text area we should not prevent the browser default action that - * inserts the text in the text area. It is also necessary to stop propagation - * when handling drag events on the element to prevent them from propagating - * to the document. - * @private - * @type {boolean} - */ -goog.events.FileDropHandler.prototype.dndContainsFiles_ = false; - - -/** - * A logger, used to help us debug the algorithm. - * @type {goog.log.Logger} - * @private - */ -goog.events.FileDropHandler.prototype.logger_ = - goog.log.getLogger('goog.events.FileDropHandler'); - - -/** - * The types of events fired by this class. - * @enum {string} - */ -goog.events.FileDropHandler.EventType = { - DROP: goog.events.EventType.DROP -}; - - -/** @override */ -goog.events.FileDropHandler.prototype.disposeInternal = function() { - goog.events.FileDropHandler.superClass_.disposeInternal.call(this); - this.eventHandler_.dispose(); -}; - - -/** - * Dispatches the DROP event. - * @param {goog.events.BrowserEvent} e The underlying browser event. - * @private - */ -goog.events.FileDropHandler.prototype.dispatch_ = function(e) { - goog.log.fine(this.logger_, 'Firing DROP event...'); - var event = new goog.events.BrowserEvent(e.getBrowserEvent()); - event.type = goog.events.FileDropHandler.EventType.DROP; - this.dispatchEvent(event); -}; - - -/** - * Handles dragenter on the document. - * @param {goog.events.BrowserEvent} e The dragenter event. - * @private - */ -goog.events.FileDropHandler.prototype.onDocDragEnter_ = function(e) { - goog.log.log(this.logger_, goog.log.Level.FINER, - '"' + e.target.id + '" (' + e.target + ') dispatched: ' + e.type); - var dt = e.getBrowserEvent().dataTransfer; - // Check whether the drag event contains files. - this.dndContainsFiles_ = !!(dt && - ((dt.types && - (goog.array.contains(dt.types, 'Files') || - goog.array.contains(dt.types, 'public.file-url'))) || - (dt.files && dt.files.length > 0))); - // If it does - if (this.dndContainsFiles_) { - // Prevent default actions. - e.preventDefault(); - } - goog.log.log(this.logger_, goog.log.Level.FINER, - 'dndContainsFiles_: ' + this.dndContainsFiles_); -}; - - -/** - * Handles dragging something over the document. - * @param {goog.events.BrowserEvent} e The dragover event. - * @private - */ -goog.events.FileDropHandler.prototype.onDocDragOver_ = function(e) { - goog.log.log(this.logger_, goog.log.Level.FINEST, - '"' + e.target.id + '" (' + e.target + ') dispatched: ' + e.type); - if (this.dndContainsFiles_) { - // Prevent default actions. - e.preventDefault(); - // Disable the drop on the document outside the drop zone. - var dt = e.getBrowserEvent().dataTransfer; - dt.dropEffect = 'none'; - } -}; - - -/** - * Handles dragging something over the element (drop zone). - * @param {goog.events.BrowserEvent} e The dragover event. - * @private - */ -goog.events.FileDropHandler.prototype.onElemDragOver_ = function(e) { - goog.log.log(this.logger_, goog.log.Level.FINEST, - '"' + e.target.id + '" (' + e.target + ') dispatched: ' + e.type); - if (this.dndContainsFiles_) { - // Prevent default actions and stop the event from propagating further to - // the document. Both lines are needed! (See comment above). - e.preventDefault(); - e.stopPropagation(); - // Allow the drop on the drop zone. - var dt = e.getBrowserEvent().dataTransfer; - - // IE bug #811625 (https://goo.gl/UWuxX0) will throw error SCRIPT65535 - // when attempting to set property effectAllowed on IE10+. - // See more: https://github.com/google/closure-library/issues/485. - try { - dt.effectAllowed = 'all'; - } catch (err) { - } - dt.dropEffect = 'copy'; - } -}; - - -/** - * Handles dropping something onto the element (drop zone). - * @param {goog.events.BrowserEvent} e The drop event. - * @private - */ -goog.events.FileDropHandler.prototype.onElemDrop_ = function(e) { - goog.log.log(this.logger_, goog.log.Level.FINER, - '"' + e.target.id + '" (' + e.target + ') dispatched: ' + e.type); - // If the drag and drop event contains files. - if (this.dndContainsFiles_) { - // Prevent default actions and stop the event from propagating further to - // the document. Both lines are needed! (See comment above). - e.preventDefault(); - e.stopPropagation(); - // Dispatch DROP event. - this.dispatch_(e); - } -}; - -// Copyright 2007 Bob Ippolito. All Rights Reserved. -// Modifications Copyright 2009 The Closure Library Authors. All Rights -// Reserved. - -/** - * @license Portions of this code are from MochiKit, received by - * The Closure Authors under the MIT license. All other code is Copyright - * 2005-2009 The Closure Authors. All Rights Reserved. - */ - -/** - * @fileoverview Classes for tracking asynchronous operations and handling the - * results. The Deferred object here is patterned after the Deferred object in - * the Twisted python networking framework. - * - * See: http://twistedmatrix.com/projects/core/documentation/howto/defer.html - * - * Based on the Dojo code which in turn is based on the MochiKit code. - * - * @author arv@google.com (Erik Arvidsson) - * @author brenneman@google.com (Shawn Brenneman) - */ - -goog.provide('goog.async.Deferred'); -goog.provide('goog.async.Deferred.AlreadyCalledError'); -goog.provide('goog.async.Deferred.CanceledError'); - -goog.require('goog.Promise'); -goog.require('goog.Thenable'); -goog.require('goog.array'); -goog.require('goog.asserts'); -goog.require('goog.debug.Error'); - - - -/** - * A Deferred represents the result of an asynchronous operation. A Deferred - * instance has no result when it is created, and is "fired" (given an initial - * result) by calling {@code callback} or {@code errback}. - * - * Once fired, the result is passed through a sequence of callback functions - * registered with {@code addCallback} or {@code addErrback}. The functions may - * mutate the result before it is passed to the next function in the sequence. - * - * Callbacks and errbacks may be added at any time, including after the Deferred - * has been "fired". If there are no pending actions in the execution sequence - * of a fired Deferred, any new callback functions will be called with the last - * computed result. Adding a callback function is the only way to access the - * result of the Deferred. - * - * If a Deferred operation is canceled, an optional user-provided cancellation - * function is invoked which may perform any special cleanup, followed by firing - * the Deferred's errback sequence with a {@code CanceledError}. If the - * Deferred has already fired, cancellation is ignored. - * - * Deferreds may be templated to a specific type they produce using generics - * with syntax such as: - * <code> - * /** @type {goog.async.Deferred<string>} */ - * var d = new goog.async.Deferred(); - * // Compiler can infer that foo is a string. - * d.addCallback(function(foo) {...}); - * d.callback('string'); // Checked to be passed a string - * </code> - * Since deferreds are often used to produce different values across a chain, - * the type information is not propagated across chains, but rather only - * associated with specifically cast objects. - * - * @param {Function=} opt_onCancelFunction A function that will be called if the - * Deferred is canceled. If provided, this function runs before the - * Deferred is fired with a {@code CanceledError}. - * @param {Object=} opt_defaultScope The default object context to call - * callbacks and errbacks in. - * @constructor - * @implements {goog.Thenable<VALUE>} - * @template VALUE - */ -goog.async.Deferred = function(opt_onCancelFunction, opt_defaultScope) { - /** - * Entries in the sequence are arrays containing a callback, an errback, and - * an optional scope. The callback or errback in an entry may be null. - * @type {!Array<!Array>} - * @private - */ - this.sequence_ = []; - - /** - * Optional function that will be called if the Deferred is canceled. - * @type {Function|undefined} - * @private - */ - this.onCancelFunction_ = opt_onCancelFunction; - - /** - * The default scope to execute callbacks and errbacks in. - * @type {Object} - * @private - */ - this.defaultScope_ = opt_defaultScope || null; - - /** - * Whether the Deferred has been fired. - * @type {boolean} - * @private - */ - this.fired_ = false; - - /** - * Whether the last result in the execution sequence was an error. - * @type {boolean} - * @private - */ - this.hadError_ = false; - - /** - * The current Deferred result, updated as callbacks and errbacks are - * executed. - * @type {*} - * @private - */ - this.result_ = undefined; - - /** - * Whether the Deferred is blocked waiting on another Deferred to fire. If a - * callback or errback returns a Deferred as a result, the execution sequence - * is blocked until that Deferred result becomes available. - * @type {boolean} - * @private - */ - this.blocked_ = false; - - /** - * Whether this Deferred is blocking execution of another Deferred. If this - * instance was returned as a result in another Deferred's execution - * sequence,that other Deferred becomes blocked until this instance's - * execution sequence completes. No additional callbacks may be added to a - * Deferred once it is blocking another instance. - * @type {boolean} - * @private - */ - this.blocking_ = false; - - /** - * Whether the Deferred has been canceled without having a custom cancel - * function. - * @type {boolean} - * @private - */ - this.silentlyCanceled_ = false; - - /** - * If an error is thrown during Deferred execution with no errback to catch - * it, the error is rethrown after a timeout. Reporting the error after a - * timeout allows execution to continue in the calling context (empty when - * no error is scheduled). - * @type {number} - * @private - */ - this.unhandledErrorId_ = 0; - - /** - * If this Deferred was created by branch(), this will be the "parent" - * Deferred. - * @type {goog.async.Deferred} - * @private - */ - this.parent_ = null; - - /** - * The number of Deferred objects that have been branched off this one. This - * will be decremented whenever a branch is fired or canceled. - * @type {number} - * @private - */ - this.branches_ = 0; - - if (goog.async.Deferred.LONG_STACK_TRACES) { - /** - * Holds the stack trace at time of deferred creation if the JS engine - * provides the Error.captureStackTrace API. - * @private {?string} - */ - this.constructorStack_ = null; - if (Error.captureStackTrace) { - var target = { stack: '' }; - Error.captureStackTrace(target, goog.async.Deferred); - // Check if Error.captureStackTrace worked. It fails in gjstest. - if (typeof target.stack == 'string') { - // Remove first line and force stringify to prevent memory leak due to - // holding on to actual stack frames. - this.constructorStack_ = target.stack.replace(/^[^\n]*\n/, ''); - } - } - } -}; - - -/** - * @define {boolean} Whether unhandled errors should always get rethrown to the - * global scope. Defaults to the value of goog.DEBUG. - */ -goog.define('goog.async.Deferred.STRICT_ERRORS', false); - - -/** - * @define {boolean} Whether to attempt to make stack traces long. Defaults to - * the value of goog.DEBUG. - */ -goog.define('goog.async.Deferred.LONG_STACK_TRACES', false); - - -/** - * Cancels a Deferred that has not yet been fired, or is blocked on another - * deferred operation. If this Deferred is waiting for a blocking Deferred to - * fire, the blocking Deferred will also be canceled. - * - * If this Deferred was created by calling branch() on a parent Deferred with - * opt_propagateCancel set to true, the parent may also be canceled. If - * opt_deepCancel is set, cancel() will be called on the parent (as well as any - * other ancestors if the parent is also a branch). If one or more branches were - * created with opt_propagateCancel set to true, the parent will be canceled if - * cancel() is called on all of those branches. - * - * @param {boolean=} opt_deepCancel If true, cancels this Deferred's parent even - * if cancel() hasn't been called on some of the parent's branches. Has no - * effect on a branch without opt_propagateCancel set to true. - */ -goog.async.Deferred.prototype.cancel = function(opt_deepCancel) { - if (!this.hasFired()) { - if (this.parent_) { - // Get rid of the parent reference before potentially running the parent's - // canceler function to ensure that this cancellation isn't - // double-counted. - var parent = this.parent_; - delete this.parent_; - if (opt_deepCancel) { - parent.cancel(opt_deepCancel); - } else { - parent.branchCancel_(); - } - } - - if (this.onCancelFunction_) { - // Call in user-specified scope. - this.onCancelFunction_.call(this.defaultScope_, this); - } else { - this.silentlyCanceled_ = true; - } - if (!this.hasFired()) { - this.errback(new goog.async.Deferred.CanceledError(this)); - } - } else if (this.result_ instanceof goog.async.Deferred) { - this.result_.cancel(); - } -}; - - -/** - * Handle a single branch being canceled. Once all branches are canceled, this - * Deferred will be canceled as well. - * - * @private - */ -goog.async.Deferred.prototype.branchCancel_ = function() { - this.branches_--; - if (this.branches_ <= 0) { - this.cancel(); - } -}; - - -/** - * Called after a blocking Deferred fires. Unblocks this Deferred and resumes - * its execution sequence. - * - * @param {boolean} isSuccess Whether the result is a success or an error. - * @param {*} res The result of the blocking Deferred. - * @private - */ -goog.async.Deferred.prototype.continue_ = function(isSuccess, res) { - this.blocked_ = false; - this.updateResult_(isSuccess, res); -}; - - -/** - * Updates the current result based on the success or failure of the last action - * in the execution sequence. - * - * @param {boolean} isSuccess Whether the new result is a success or an error. - * @param {*} res The result. - * @private - */ -goog.async.Deferred.prototype.updateResult_ = function(isSuccess, res) { - this.fired_ = true; - this.result_ = res; - this.hadError_ = !isSuccess; - this.fire_(); -}; - - -/** - * Verifies that the Deferred has not yet been fired. - * - * @private - * @throws {Error} If this has already been fired. - */ -goog.async.Deferred.prototype.check_ = function() { - if (this.hasFired()) { - if (!this.silentlyCanceled_) { - throw new goog.async.Deferred.AlreadyCalledError(this); - } - this.silentlyCanceled_ = false; - } -}; - - -/** - * Fire the execution sequence for this Deferred by passing the starting result - * to the first registered callback. - * @param {VALUE=} opt_result The starting result. - */ -goog.async.Deferred.prototype.callback = function(opt_result) { - this.check_(); - this.assertNotDeferred_(opt_result); - this.updateResult_(true /* isSuccess */, opt_result); -}; - - -/** - * Fire the execution sequence for this Deferred by passing the starting error - * result to the first registered errback. - * @param {*=} opt_result The starting error. - */ -goog.async.Deferred.prototype.errback = function(opt_result) { - this.check_(); - this.assertNotDeferred_(opt_result); - this.makeStackTraceLong_(opt_result); - this.updateResult_(false /* isSuccess */, opt_result); -}; - - -/** - * Attempt to make the error's stack trace be long in that it contains the - * stack trace from the point where the deferred was created on top of the - * current stack trace to give additional context. - * @param {*} error - * @private - */ -goog.async.Deferred.prototype.makeStackTraceLong_ = function(error) { - if (!goog.async.Deferred.LONG_STACK_TRACES) { - return; - } - if (this.constructorStack_ && goog.isObject(error) && error.stack && - // Stack looks like it was system generated. See - // https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi - (/^[^\n]+(\n [^\n]+)+/).test(error.stack)) { - error.stack = error.stack + '\nDEFERRED OPERATION:\n' + - this.constructorStack_; - } -}; - - -/** - * Asserts that an object is not a Deferred. - * @param {*} obj The object to test. - * @throws {Error} Throws an exception if the object is a Deferred. - * @private - */ -goog.async.Deferred.prototype.assertNotDeferred_ = function(obj) { - goog.asserts.assert( - !(obj instanceof goog.async.Deferred), - 'An execution sequence may not be initiated with a blocking Deferred.'); -}; - - -/** - * Register a callback function to be called with a successful result. If no - * value is returned by the callback function, the result value is unchanged. If - * a new value is returned, it becomes the Deferred result and will be passed to - * the next callback in the execution sequence. - * - * If the function throws an error, the error becomes the new result and will be - * passed to the next errback in the execution chain. - * - * If the function returns a Deferred, the execution sequence will be blocked - * until that Deferred fires. Its result will be passed to the next callback (or - * errback if it is an error result) in this Deferred's execution sequence. - * - * @param {!function(this:T,VALUE):?} cb The function to be called with a - * successful result. - * @param {T=} opt_scope An optional scope to call the callback in. - * @return {!goog.async.Deferred} This Deferred. - * @template T - */ -goog.async.Deferred.prototype.addCallback = function(cb, opt_scope) { - return this.addCallbacks(cb, null, opt_scope); -}; - - -/** - * Register a callback function to be called with an error result. If no value - * is returned by the function, the error result is unchanged. If a new error - * value is returned or thrown, that error becomes the Deferred result and will - * be passed to the next errback in the execution sequence. - * - * If the errback function handles the error by returning a non-error value, - * that result will be passed to the next normal callback in the sequence. - * - * If the function returns a Deferred, the execution sequence will be blocked - * until that Deferred fires. Its result will be passed to the next callback (or - * errback if it is an error result) in this Deferred's execution sequence. - * - * @param {!function(this:T,?):?} eb The function to be called on an - * unsuccessful result. - * @param {T=} opt_scope An optional scope to call the errback in. - * @return {!goog.async.Deferred<VALUE>} This Deferred. - * @template T - */ -goog.async.Deferred.prototype.addErrback = function(eb, opt_scope) { - return this.addCallbacks(null, eb, opt_scope); -}; - - -/** - * Registers one function as both a callback and errback. - * - * @param {!function(this:T,?):?} f The function to be called on any result. - * @param {T=} opt_scope An optional scope to call the function in. - * @return {!goog.async.Deferred} This Deferred. - * @template T - */ -goog.async.Deferred.prototype.addBoth = function(f, opt_scope) { - return this.addCallbacks(f, f, opt_scope); -}; - - -/** - * Like addBoth, but propagates uncaught exceptions in the errback. - * - * @param {function(this:T,?):?} f The function to be called on any result. - * @param {T=} opt_scope An optional scope to call the function in. - * @return {!goog.async.Deferred<VALUE>} This Deferred. - * @template T - */ -goog.async.Deferred.prototype.addFinally = function(f, opt_scope) { - var self = this; - return this.addCallbacks(f, function(err) { - var result = f.call(self, err); - if (!goog.isDef(result)) { - throw err; - } - return result; - }, opt_scope); -}; - - -/** - * Registers a callback function and an errback function at the same position - * in the execution sequence. Only one of these functions will execute, - * depending on the error state during the execution sequence. - * - * NOTE: This is not equivalent to {@code def.addCallback().addErrback()}! If - * the callback is invoked, the errback will be skipped, and vice versa. - * - * @param {?(function(this:T,VALUE):?)} cb The function to be called on a - * successful result. - * @param {?(function(this:T,?):?)} eb The function to be called on an - * unsuccessful result. - * @param {T=} opt_scope An optional scope to call the functions in. - * @return {!goog.async.Deferred} This Deferred. - * @template T - */ -goog.async.Deferred.prototype.addCallbacks = function(cb, eb, opt_scope) { - goog.asserts.assert(!this.blocking_, 'Blocking Deferreds can not be re-used'); - this.sequence_.push([cb, eb, opt_scope]); - if (this.hasFired()) { - this.fire_(); - } - return this; -}; - - -/** - * Implements {@see goog.Thenable} for seamless integration with - * {@see goog.Promise}. - * Deferred results are mutable and may represent multiple values over - * their lifetime. Calling {@code then} on a Deferred returns a Promise - * with the result of the Deferred at that point in its callback chain. - * Note that if the Deferred result is never mutated, and only - * {@code then} calls are made, the Deferred will behave like a Promise. - * - * @override - */ -goog.async.Deferred.prototype.then = function(opt_onFulfilled, opt_onRejected, - opt_context) { - var resolve, reject; - var promise = new goog.Promise(function(res, rej) { - // Copying resolvers to outer scope, so that they are available when the - // deferred callback fires (which may be synchronous). - resolve = res; - reject = rej; - }); - this.addCallbacks(resolve, function(reason) { - if (reason instanceof goog.async.Deferred.CanceledError) { - promise.cancel(); - } else { - reject(reason); - } - }); - return promise.then(opt_onFulfilled, opt_onRejected, opt_context); -}; -goog.Thenable.addImplementation(goog.async.Deferred); - - -/** - * Links another Deferred to the end of this Deferred's execution sequence. The - * result of this execution sequence will be passed as the starting result for - * the chained Deferred, invoking either its first callback or errback. - * - * @param {!goog.async.Deferred} otherDeferred The Deferred to chain. - * @return {!goog.async.Deferred} This Deferred. - */ -goog.async.Deferred.prototype.chainDeferred = function(otherDeferred) { - this.addCallbacks( - otherDeferred.callback, otherDeferred.errback, otherDeferred); - return this; -}; - - -/** - * Makes this Deferred wait for another Deferred's execution sequence to - * complete before continuing. - * - * This is equivalent to adding a callback that returns {@code otherDeferred}, - * but doesn't prevent additional callbacks from being added to - * {@code otherDeferred}. - * - * @param {!goog.async.Deferred|!goog.Thenable} otherDeferred The Deferred - * to wait for. - * @return {!goog.async.Deferred} This Deferred. - */ -goog.async.Deferred.prototype.awaitDeferred = function(otherDeferred) { - if (!(otherDeferred instanceof goog.async.Deferred)) { - // The Thenable case. - return this.addCallback(function() { - return otherDeferred; - }); - } - return this.addCallback(goog.bind(otherDeferred.branch, otherDeferred)); -}; - - -/** - * Creates a branch off this Deferred's execution sequence, and returns it as a - * new Deferred. The branched Deferred's starting result will be shared with the - * parent at the point of the branch, even if further callbacks are added to the - * parent. - * - * All branches at the same stage in the execution sequence will receive the - * same starting value. - * - * @param {boolean=} opt_propagateCancel If cancel() is called on every child - * branch created with opt_propagateCancel, the parent will be canceled as - * well. - * @return {!goog.async.Deferred<VALUE>} A Deferred that will be started with - * the computed result from this stage in the execution sequence. - */ -goog.async.Deferred.prototype.branch = function(opt_propagateCancel) { - var d = new goog.async.Deferred(); - this.chainDeferred(d); - if (opt_propagateCancel) { - d.parent_ = this; - this.branches_++; - } - return d; -}; - - -/** - * @return {boolean} Whether the execution sequence has been started on this - * Deferred by invoking {@code callback} or {@code errback}. - */ -goog.async.Deferred.prototype.hasFired = function() { - return this.fired_; -}; - - -/** - * @param {*} res The latest result in the execution sequence. - * @return {boolean} Whether the current result is an error that should cause - * the next errback to fire. May be overridden by subclasses to handle - * special error types. - * @protected - */ -goog.async.Deferred.prototype.isError = function(res) { - return res instanceof Error; -}; - - -/** - * @return {boolean} Whether an errback exists in the remaining sequence. - * @private - */ -goog.async.Deferred.prototype.hasErrback_ = function() { - return goog.array.some(this.sequence_, function(sequenceRow) { - // The errback is the second element in the array. - return goog.isFunction(sequenceRow[1]); - }); -}; - - -/** - * Exhausts the execution sequence while a result is available. The result may - * be modified by callbacks or errbacks, and execution will block if the - * returned result is an incomplete Deferred. - * - * @private - */ -goog.async.Deferred.prototype.fire_ = function() { - if (this.unhandledErrorId_ && this.hasFired() && this.hasErrback_()) { - // It is possible to add errbacks after the Deferred has fired. If a new - // errback is added immediately after the Deferred encountered an unhandled - // error, but before that error is rethrown, the error is unscheduled. - goog.async.Deferred.unscheduleError_(this.unhandledErrorId_); - this.unhandledErrorId_ = 0; - } - - if (this.parent_) { - this.parent_.branches_--; - delete this.parent_; - } - - var res = this.result_; - var unhandledException = false; - var isNewlyBlocked = false; - - while (this.sequence_.length && !this.blocked_) { - var sequenceEntry = this.sequence_.shift(); - - var callback = sequenceEntry[0]; - var errback = sequenceEntry[1]; - var scope = sequenceEntry[2]; - - var f = this.hadError_ ? errback : callback; - if (f) { - /** @preserveTry */ - try { - var ret = f.call(scope || this.defaultScope_, res); - - // If no result, then use previous result. - if (goog.isDef(ret)) { - // Bubble up the error as long as the return value hasn't changed. - this.hadError_ = this.hadError_ && (ret == res || this.isError(ret)); - this.result_ = res = ret; - } - - if (goog.Thenable.isImplementedBy(res) || - (typeof goog.global['Promise'] === 'function' && - res instanceof goog.global['Promise'])) { - isNewlyBlocked = true; - this.blocked_ = true; - } - - } catch (ex) { - res = ex; - this.hadError_ = true; - this.makeStackTraceLong_(res); - - if (!this.hasErrback_()) { - // If an error is thrown with no additional errbacks in the queue, - // prepare to rethrow the error. - unhandledException = true; - } - } - } - } - - this.result_ = res; - - if (isNewlyBlocked) { - var onCallback = goog.bind(this.continue_, this, true /* isSuccess */); - var onErrback = goog.bind(this.continue_, this, false /* isSuccess */); - - if (res instanceof goog.async.Deferred) { - res.addCallbacks(onCallback, onErrback); - res.blocking_ = true; - } else { - res.then(onCallback, onErrback); - } - } else if (goog.async.Deferred.STRICT_ERRORS && this.isError(res) && - !(res instanceof goog.async.Deferred.CanceledError)) { - this.hadError_ = true; - unhandledException = true; - } - - if (unhandledException) { - // Rethrow the unhandled error after a timeout. Execution will continue, but - // the error will be seen by global handlers and the user. The throw will - // be canceled if another errback is appended before the timeout executes. - // The error's original stack trace is preserved where available. - this.unhandledErrorId_ = goog.async.Deferred.scheduleError_(res); - } -}; - - -/** - * Creates a Deferred that has an initial result. - * - * @param {*=} opt_result The result. - * @return {!goog.async.Deferred} The new Deferred. - */ -goog.async.Deferred.succeed = function(opt_result) { - var d = new goog.async.Deferred(); - d.callback(opt_result); - return d; -}; - - -/** - * Creates a Deferred that fires when the given promise resolves. - * Use only during migration to Promises. - * - * @param {!goog.Promise<T>} promise - * @return {!goog.async.Deferred<T>} The new Deferred. - * @template T - */ -goog.async.Deferred.fromPromise = function(promise) { - var d = new goog.async.Deferred(); - d.callback(); - d.addCallback(function() { - return promise; - }); - return d; -}; - - -/** - * Creates a Deferred that has an initial error result. - * - * @param {*} res The error result. - * @return {!goog.async.Deferred} The new Deferred. - */ -goog.async.Deferred.fail = function(res) { - var d = new goog.async.Deferred(); - d.errback(res); - return d; -}; - - -/** - * Creates a Deferred that has already been canceled. - * - * @return {!goog.async.Deferred} The new Deferred. - */ -goog.async.Deferred.canceled = function() { - var d = new goog.async.Deferred(); - d.cancel(); - return d; -}; - - -/** - * Normalizes values that may or may not be Deferreds. - * - * If the input value is a Deferred, the Deferred is branched (so the original - * execution sequence is not modified) and the input callback added to the new - * branch. The branch is returned to the caller. - * - * If the input value is not a Deferred, the callback will be executed - * immediately and an already firing Deferred will be returned to the caller. - * - * In the following (contrived) example, if <code>isImmediate</code> is true - * then 3 is alerted immediately, otherwise 6 is alerted after a 2-second delay. - * - * <pre> - * var value; - * if (isImmediate) { - * value = 3; - * } else { - * value = new goog.async.Deferred(); - * setTimeout(function() { value.callback(6); }, 2000); - * } - * - * var d = goog.async.Deferred.when(value, alert); - * </pre> - * - * @param {*} value Deferred or normal value to pass to the callback. - * @param {!function(this:T, ?):?} callback The callback to execute. - * @param {T=} opt_scope An optional scope to call the callback in. - * @return {!goog.async.Deferred} A new Deferred that will call the input - * callback with the input value. - * @template T - */ -goog.async.Deferred.when = function(value, callback, opt_scope) { - if (value instanceof goog.async.Deferred) { - return value.branch(true).addCallback(callback, opt_scope); - } else { - return goog.async.Deferred.succeed(value).addCallback(callback, opt_scope); - } -}; - - - -/** - * An error sub class that is used when a Deferred has already been called. - * @param {!goog.async.Deferred} deferred The Deferred. - * - * @constructor - * @extends {goog.debug.Error} - */ -goog.async.Deferred.AlreadyCalledError = function(deferred) { - goog.debug.Error.call(this); - - /** - * The Deferred that raised this error. - * @type {goog.async.Deferred} - */ - this.deferred = deferred; -}; -goog.inherits(goog.async.Deferred.AlreadyCalledError, goog.debug.Error); - - -/** @override */ -goog.async.Deferred.AlreadyCalledError.prototype.message = - 'Deferred has already fired'; - - -/** @override */ -goog.async.Deferred.AlreadyCalledError.prototype.name = 'AlreadyCalledError'; - - - -/** - * An error sub class that is used when a Deferred is canceled. - * - * @param {!goog.async.Deferred} deferred The Deferred object. - * @constructor - * @extends {goog.debug.Error} - */ -goog.async.Deferred.CanceledError = function(deferred) { - goog.debug.Error.call(this); - - /** - * The Deferred that raised this error. - * @type {goog.async.Deferred} - */ - this.deferred = deferred; -}; -goog.inherits(goog.async.Deferred.CanceledError, goog.debug.Error); - - -/** @override */ -goog.async.Deferred.CanceledError.prototype.message = 'Deferred was canceled'; - - -/** @override */ -goog.async.Deferred.CanceledError.prototype.name = 'CanceledError'; - - - -/** - * Wrapper around errors that are scheduled to be thrown by failing deferreds - * after a timeout. - * - * @param {*} error Error from a failing deferred. - * @constructor - * @final - * @private - * @struct - */ -goog.async.Deferred.Error_ = function(error) { - /** @const @private {number} */ - this.id_ = goog.global.setTimeout(goog.bind(this.throwError, this), 0); - - /** @const @private {*} */ - this.error_ = error; -}; - - -/** - * Actually throws the error and removes it from the list of pending - * deferred errors. - */ -goog.async.Deferred.Error_.prototype.throwError = function() { - goog.asserts.assert(goog.async.Deferred.errorMap_[this.id_], - 'Cannot throw an error that is not scheduled.'); - delete goog.async.Deferred.errorMap_[this.id_]; - throw this.error_; -}; - - -/** - * Resets the error throw timer. - */ -goog.async.Deferred.Error_.prototype.resetTimer = function() { - goog.global.clearTimeout(this.id_); -}; - - -/** - * Map of unhandled errors scheduled to be rethrown in a future timestep. - * @private {!Object<number|string, goog.async.Deferred.Error_>} - */ -goog.async.Deferred.errorMap_ = {}; - - -/** - * Schedules an error to be thrown after a delay. - * @param {*} error Error from a failing deferred. - * @return {number} Id of the error. - * @private - */ -goog.async.Deferred.scheduleError_ = function(error) { - var deferredError = new goog.async.Deferred.Error_(error); - goog.async.Deferred.errorMap_[deferredError.id_] = deferredError; - return deferredError.id_; -}; - - -/** - * Unschedules an error from being thrown. - * @param {number} id Id of the deferred error to unschedule. - * @private - */ -goog.async.Deferred.unscheduleError_ = function(id) { - var error = goog.async.Deferred.errorMap_[id]; - if (error) { - error.resetTimer(); - delete goog.async.Deferred.errorMap_[id]; - } -}; - - -/** - * Asserts that there are no pending deferred errors. If there are any - * scheduled errors, one will be thrown immediately to make this function fail. - */ -goog.async.Deferred.assertNoErrors = function() { - var map = goog.async.Deferred.errorMap_; - for (var key in map) { - var error = map[key]; - error.resetTimer(); - error.throwError(); - } -}; - -// Copyright 2011 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview A wrapper for the HTML5 FileError object. - * - */ - -goog.provide('goog.fs.Error'); -goog.provide('goog.fs.Error.ErrorCode'); - -goog.require('goog.debug.Error'); -goog.require('goog.object'); -goog.require('goog.string'); - - - -/** - * A filesystem error. Since the filesystem API is asynchronous, stack traces - * are less useful for identifying where errors come from, so this includes a - * large amount of metadata in the message. - * - * @param {!DOMError} error - * @param {string} action The action being undertaken when the error was raised. - * @constructor - * @extends {goog.debug.Error} - * @final - */ -goog.fs.Error = function(error, action) { - /** @type {string} */ - this.name; - - /** - * @type {goog.fs.Error.ErrorCode} - * @deprecated Use the 'name' or 'message' field instead. - */ - this.code; - - if (goog.isDef(error.name)) { - this.name = error.name; - // TODO(user): Remove warning suppression after JSCompiler stops - // firing a spurious warning here. - /** @suppress {deprecated} */ - this.code = goog.fs.Error.getCodeFromName_(error.name); - } else { - this.code = error.code; - this.name = goog.fs.Error.getNameFromCode_(error.code); - } - goog.fs.Error.base(this, 'constructor', - goog.string.subs('%s %s', this.name, action)); -}; -goog.inherits(goog.fs.Error, goog.debug.Error); - - -/** - * Names of errors that may be thrown by the File API, the File System API, or - * the File Writer API. - * - * @see http://dev.w3.org/2006/webapi/FileAPI/#ErrorAndException - * @see http://www.w3.org/TR/file-system-api/#definitions - * @see http://dev.w3.org/2009/dap/file-system/file-writer.html#definitions - * @enum {string} - */ -goog.fs.Error.ErrorName = { - ABORT: 'AbortError', - ENCODING: 'EncodingError', - INVALID_MODIFICATION: 'InvalidModificationError', - INVALID_STATE: 'InvalidStateError', - NOT_FOUND: 'NotFoundError', - NOT_READABLE: 'NotReadableError', - NO_MODIFICATION_ALLOWED: 'NoModificationAllowedError', - PATH_EXISTS: 'PathExistsError', - QUOTA_EXCEEDED: 'QuotaExceededError', - SECURITY: 'SecurityError', - SYNTAX: 'SyntaxError', - TYPE_MISMATCH: 'TypeMismatchError' -}; - - -/** - * Error codes for file errors. - * @see http://www.w3.org/TR/file-system-api/#idl-def-FileException - * - * @enum {number} - * @deprecated Use the 'name' or 'message' attribute instead. - */ -goog.fs.Error.ErrorCode = { - NOT_FOUND: 1, - SECURITY: 2, - ABORT: 3, - NOT_READABLE: 4, - ENCODING: 5, - NO_MODIFICATION_ALLOWED: 6, - INVALID_STATE: 7, - SYNTAX: 8, - INVALID_MODIFICATION: 9, - QUOTA_EXCEEDED: 10, - TYPE_MISMATCH: 11, - PATH_EXISTS: 12 -}; - - -/** - * @param {goog.fs.Error.ErrorCode} code - * @return {string} name - * @private - */ -goog.fs.Error.getNameFromCode_ = function(code) { - var name = goog.object.findKey(goog.fs.Error.NameToCodeMap_, function(c) { - return code == c; - }); - if (!goog.isDef(name)) { - throw new Error('Invalid code: ' + code); - } - return name; -}; - - -/** - * Returns the code that corresponds to the given name. - * @param {string} name - * @return {goog.fs.Error.ErrorCode} code - * @private - */ -goog.fs.Error.getCodeFromName_ = function(name) { - return goog.fs.Error.NameToCodeMap_[name]; -}; - - -/** - * Mapping from error names to values from the ErrorCode enum. - * @see http://www.w3.org/TR/file-system-api/#definitions. - * @private {!Object<string, goog.fs.Error.ErrorCode>} - */ -goog.fs.Error.NameToCodeMap_ = goog.object.create( - goog.fs.Error.ErrorName.ABORT, - goog.fs.Error.ErrorCode.ABORT, - - goog.fs.Error.ErrorName.ENCODING, - goog.fs.Error.ErrorCode.ENCODING, - - goog.fs.Error.ErrorName.INVALID_MODIFICATION, - goog.fs.Error.ErrorCode.INVALID_MODIFICATION, - - goog.fs.Error.ErrorName.INVALID_STATE, - goog.fs.Error.ErrorCode.INVALID_STATE, - - goog.fs.Error.ErrorName.NOT_FOUND, - goog.fs.Error.ErrorCode.NOT_FOUND, - - goog.fs.Error.ErrorName.NOT_READABLE, - goog.fs.Error.ErrorCode.NOT_READABLE, - - goog.fs.Error.ErrorName.NO_MODIFICATION_ALLOWED, - goog.fs.Error.ErrorCode.NO_MODIFICATION_ALLOWED, - - goog.fs.Error.ErrorName.PATH_EXISTS, - goog.fs.Error.ErrorCode.PATH_EXISTS, - - goog.fs.Error.ErrorName.QUOTA_EXCEEDED, - goog.fs.Error.ErrorCode.QUOTA_EXCEEDED, - - goog.fs.Error.ErrorName.SECURITY, - goog.fs.Error.ErrorCode.SECURITY, - - goog.fs.Error.ErrorName.SYNTAX, - goog.fs.Error.ErrorCode.SYNTAX, - - goog.fs.Error.ErrorName.TYPE_MISMATCH, - goog.fs.Error.ErrorCode.TYPE_MISMATCH); - -// Copyright 2011 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview A wrapper for the HTML5 File ProgressEvent objects. - * - */ -goog.provide('goog.fs.ProgressEvent'); - -goog.require('goog.events.Event'); - - - -/** - * A wrapper for the progress events emitted by the File APIs. - * - * @param {!ProgressEvent} event The underlying event object. - * @param {!Object} target The file access object emitting the event. - * @extends {goog.events.Event} - * @constructor - * @final - */ -goog.fs.ProgressEvent = function(event, target) { - goog.fs.ProgressEvent.base(this, 'constructor', event.type, target); - - /** - * The underlying event object. - * @type {!ProgressEvent} - * @private - */ - this.event_ = event; -}; -goog.inherits(goog.fs.ProgressEvent, goog.events.Event); - - -/** - * @return {boolean} Whether or not the total size of the of the file being - * saved is known. - */ -goog.fs.ProgressEvent.prototype.isLengthComputable = function() { - return this.event_.lengthComputable; -}; - - -/** - * @return {number} The number of bytes saved so far. - */ -goog.fs.ProgressEvent.prototype.getLoaded = function() { - return this.event_.loaded; -}; - - -/** - * @return {number} The total number of bytes in the file being saved. - */ -goog.fs.ProgressEvent.prototype.getTotal = function() { - return this.event_.total; -}; - -// Copyright 2011 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview A wrapper for the HTML5 FileReader object. - * - */ - -goog.provide('goog.fs.FileReader'); -goog.provide('goog.fs.FileReader.EventType'); -goog.provide('goog.fs.FileReader.ReadyState'); - -goog.require('goog.async.Deferred'); -goog.require('goog.events.EventTarget'); -goog.require('goog.fs.Error'); -goog.require('goog.fs.ProgressEvent'); - - - -/** - * An object for monitoring the reading of files. This emits ProgressEvents of - * the types listed in {@link goog.fs.FileReader.EventType}. - * - * @constructor - * @extends {goog.events.EventTarget} - * @final - */ -goog.fs.FileReader = function() { - goog.fs.FileReader.base(this, 'constructor'); - - /** - * The underlying FileReader object. - * - * @type {!FileReader} - * @private - */ - this.reader_ = new FileReader(); - - this.reader_.onloadstart = goog.bind(this.dispatchProgressEvent_, this); - this.reader_.onprogress = goog.bind(this.dispatchProgressEvent_, this); - this.reader_.onload = goog.bind(this.dispatchProgressEvent_, this); - this.reader_.onabort = goog.bind(this.dispatchProgressEvent_, this); - this.reader_.onerror = goog.bind(this.dispatchProgressEvent_, this); - this.reader_.onloadend = goog.bind(this.dispatchProgressEvent_, this); -}; -goog.inherits(goog.fs.FileReader, goog.events.EventTarget); - - -/** - * Possible states for a FileReader. - * - * @enum {number} - */ -goog.fs.FileReader.ReadyState = { - /** - * The object has been constructed, but there is no pending read. - */ - INIT: 0, - /** - * Data is being read. - */ - LOADING: 1, - /** - * The data has been read from the file, the read was aborted, or an error - * occurred. - */ - DONE: 2 -}; - - -/** - * Events emitted by a FileReader. - * - * @enum {string} - */ -goog.fs.FileReader.EventType = { - /** - * Emitted when the reading begins. readyState will be LOADING. - */ - LOAD_START: 'loadstart', - /** - * Emitted when progress has been made in reading the file. readyState will be - * LOADING. - */ - PROGRESS: 'progress', - /** - * Emitted when the data has been successfully read. readyState will be - * LOADING. - */ - LOAD: 'load', - /** - * Emitted when the reading has been aborted. readyState will be LOADING. - */ - ABORT: 'abort', - /** - * Emitted when an error is encountered or the reading has been aborted. - * readyState will be LOADING. - */ - ERROR: 'error', - /** - * Emitted when the reading is finished, whether successfully or not. - * readyState will be DONE. - */ - LOAD_END: 'loadend' -}; - - -/** - * Abort the reading of the file. - */ -goog.fs.FileReader.prototype.abort = function() { - try { - this.reader_.abort(); - } catch (e) { - throw new goog.fs.Error(e, 'aborting read'); - } -}; - - -/** - * @return {goog.fs.FileReader.ReadyState} The current state of the FileReader. - */ -goog.fs.FileReader.prototype.getReadyState = function() { - return /** @type {goog.fs.FileReader.ReadyState} */ (this.reader_.readyState); -}; - - -/** - * @return {*} The result of the file read. - */ -goog.fs.FileReader.prototype.getResult = function() { - return this.reader_.result; -}; - - -/** - * @return {goog.fs.Error} The error encountered while reading, if any. - */ -goog.fs.FileReader.prototype.getError = function() { - return this.reader_.error && - new goog.fs.Error(this.reader_.error, 'reading file'); -}; - - -/** - * Wrap a progress event emitted by the underlying file reader and re-emit it. - * - * @param {!ProgressEvent} event The underlying event. - * @private - */ -goog.fs.FileReader.prototype.dispatchProgressEvent_ = function(event) { - this.dispatchEvent(new goog.fs.ProgressEvent(event, this)); -}; - - -/** @override */ -goog.fs.FileReader.prototype.disposeInternal = function() { - goog.fs.FileReader.base(this, 'disposeInternal'); - delete this.reader_; -}; - - -/** - * Starts reading a blob as a binary string. - * @param {!Blob} blob The blob to read. - */ -goog.fs.FileReader.prototype.readAsBinaryString = function(blob) { - this.reader_.readAsBinaryString(blob); -}; - - -/** - * Reads a blob as a binary string. - * @param {!Blob} blob The blob to read. - * @return {!goog.async.Deferred} The deferred Blob contents as a binary string. - * If an error occurs, the errback is called with a {@link goog.fs.Error}. - */ -goog.fs.FileReader.readAsBinaryString = function(blob) { - var reader = new goog.fs.FileReader(); - var d = goog.fs.FileReader.createDeferred_(reader); - reader.readAsBinaryString(blob); - return d; -}; - - -/** - * Starts reading a blob as an array buffer. - * @param {!Blob} blob The blob to read. - */ -goog.fs.FileReader.prototype.readAsArrayBuffer = function(blob) { - this.reader_.readAsArrayBuffer(blob); -}; - - -/** - * Reads a blob as an array buffer. - * @param {!Blob} blob The blob to read. - * @return {!goog.async.Deferred} The deferred Blob contents as an array buffer. - * If an error occurs, the errback is called with a {@link goog.fs.Error}. - */ -goog.fs.FileReader.readAsArrayBuffer = function(blob) { - var reader = new goog.fs.FileReader(); - var d = goog.fs.FileReader.createDeferred_(reader); - reader.readAsArrayBuffer(blob); - return d; -}; - - -/** - * Starts reading a blob as text. - * @param {!Blob} blob The blob to read. - * @param {string=} opt_encoding The name of the encoding to use. - */ -goog.fs.FileReader.prototype.readAsText = function(blob, opt_encoding) { - this.reader_.readAsText(blob, opt_encoding); -}; - - -/** - * Reads a blob as text. - * @param {!Blob} blob The blob to read. - * @param {string=} opt_encoding The name of the encoding to use. - * @return {!goog.async.Deferred} The deferred Blob contents as text. - * If an error occurs, the errback is called with a {@link goog.fs.Error}. - */ -goog.fs.FileReader.readAsText = function(blob, opt_encoding) { - var reader = new goog.fs.FileReader(); - var d = goog.fs.FileReader.createDeferred_(reader); - reader.readAsText(blob, opt_encoding); - return d; -}; - - -/** - * Starts reading a blob as a data URL. - * @param {!Blob} blob The blob to read. - */ -goog.fs.FileReader.prototype.readAsDataUrl = function(blob) { - this.reader_.readAsDataURL(blob); -}; - - -/** - * Reads a blob as a data URL. - * @param {!Blob} blob The blob to read. - * @return {!goog.async.Deferred} The deferred Blob contents as a data URL. - * If an error occurs, the errback is called with a {@link goog.fs.Error}. - */ -goog.fs.FileReader.readAsDataUrl = function(blob) { - var reader = new goog.fs.FileReader(); - var d = goog.fs.FileReader.createDeferred_(reader); - reader.readAsDataUrl(blob); - return d; -}; - - -/** - * Creates a new deferred object for the results of a read method. - * @param {goog.fs.FileReader} reader The reader to create a deferred for. - * @return {!goog.async.Deferred} The deferred results. - * @private - */ -goog.fs.FileReader.createDeferred_ = function(reader) { - var deferred = new goog.async.Deferred(); - reader.listen(goog.fs.FileReader.EventType.LOAD_END, - goog.partial(function(d, r, e) { - var result = r.getResult(); - var error = r.getError(); - if (result != null && !error) { - d.callback(result); - } else { - d.errback(error); - } - r.dispose(); - }, deferred, reader)); - return deferred; -}; - // FIXME should handle all geo-referenced data, not just vector data goog.provide('ol.interaction.DragAndDrop'); goog.provide('ol.interaction.DragAndDropEvent'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.Event'); -goog.require('goog.events.FileDropHandler'); -goog.require('goog.events.FileDropHandler.EventType'); -goog.require('goog.fs.FileReader'); -goog.require('goog.functions'); +goog.require('ol.functions'); +goog.require('ol.events'); +goog.require('ol.events.Event'); +goog.require('ol.events.EventType'); goog.require('ol.interaction.Interaction'); goog.require('ol.proj'); - /** * @classdesc * Handles input of vector data by drag and drop. @@ -110205,54 +94833,56 @@ ol.interaction.DragAndDrop = function(opt_options) { /** * @private - * @type {goog.events.FileDropHandler} + * @type {Array.<ol.events.Key>} */ - this.fileDropHandler_ = null; + this.dropListenKeys_ = null; /** * @private - * @type {goog.events.Key|undefined} + * @type {Element} */ - this.dropListenKey_ = undefined; + this.target = options.target ? options.target : null; }; goog.inherits(ol.interaction.DragAndDrop, ol.interaction.Interaction); /** - * @inheritDoc + * @param {Event} event Event. + * @this {ol.interaction.DragAndDrop} + * @private */ -ol.interaction.DragAndDrop.prototype.disposeInternal = function() { - if (this.dropListenKey_) { - goog.events.unlistenByKey(this.dropListenKey_); +ol.interaction.DragAndDrop.handleDrop_ = function(event) { + var files = event.dataTransfer.files; + var i, ii, file; + for (i = 0, ii = files.length; i < ii; ++i) { + file = files.item(i); + var reader = new FileReader(); + reader.addEventListener(ol.events.EventType.LOAD, + this.handleResult_.bind(this, file)); + reader.readAsText(file); } - goog.base(this, 'disposeInternal'); }; /** - * @param {goog.events.BrowserEvent} event Event. + * @param {Event} event Event. * @private */ -ol.interaction.DragAndDrop.prototype.handleDrop_ = function(event) { - var files = event.getBrowserEvent().dataTransfer.files; - var i, ii, file; - for (i = 0, ii = files.length; i < ii; ++i) { - file = files[i]; - // The empty string param is a workaround for - // https://code.google.com/p/closure-library/issues/detail?id=524 - var reader = goog.fs.FileReader.readAsText(file, ''); - reader.addCallback(goog.partial(this.handleResult_, file), this); - } +ol.interaction.DragAndDrop.handleStop_ = function(event) { + event.stopPropagation(); + event.preventDefault(); + event.dataTransfer.dropEffect = 'copy'; }; /** * @param {File} file File. - * @param {string} result Result. + * @param {Event} event Load event. * @private */ -ol.interaction.DragAndDrop.prototype.handleResult_ = function(file, result) { +ol.interaction.DragAndDrop.prototype.handleResult_ = function(file, event) { + var result = event.target.result; var map = this.getMap(); goog.asserts.assert(map, 'map must be set'); var projection = this.projection_; @@ -110269,19 +94899,11 @@ ol.interaction.DragAndDrop.prototype.handleResult_ = function(file, result) { for (i = 0, ii = formatConstructors.length; i < ii; ++i) { var formatConstructor = formatConstructors[i]; var format = new formatConstructor(); - var readFeatures = this.tryReadFeatures_(format, result); - if (readFeatures) { - var featureProjection = format.readProjection(result); - var transform = ol.proj.getTransform(featureProjection, projection); - var j, jj; - for (j = 0, jj = readFeatures.length; j < jj; ++j) { - var feature = readFeatures[j]; - var geometry = feature.getGeometry(); - if (geometry) { - geometry.applyTransform(transform); - } - features.push(feature); - } + features = this.tryReadFeatures_(format, result, { + featureProjection: projection + }); + if (features && features.length > 0) { + break; } } this.dispatchEvent( @@ -110299,29 +94921,30 @@ ol.interaction.DragAndDrop.prototype.handleResult_ = function(file, result) { * @this {ol.interaction.DragAndDrop} * @api */ -ol.interaction.DragAndDrop.handleEvent = goog.functions.TRUE; +ol.interaction.DragAndDrop.handleEvent = ol.functions.TRUE; /** * @inheritDoc */ ol.interaction.DragAndDrop.prototype.setMap = function(map) { - if (this.dropListenKey_) { - goog.events.unlistenByKey(this.dropListenKey_); - this.dropListenKey_ = undefined; - } - if (this.fileDropHandler_) { - goog.dispose(this.fileDropHandler_); - this.fileDropHandler_ = null; + if (this.dropListenKeys_) { + this.dropListenKeys_.forEach(ol.events.unlistenByKey); + this.dropListenKeys_ = null; } - goog.asserts.assert(this.dropListenKey_ === undefined, - 'this.dropListenKey_ should be undefined'); goog.base(this, 'setMap', map); if (map) { - this.fileDropHandler_ = new goog.events.FileDropHandler(map.getViewport()); - this.dropListenKey_ = goog.events.listen( - this.fileDropHandler_, goog.events.FileDropHandler.EventType.DROP, - this.handleDrop_, false, this); + var dropArea = this.target ? this.target : map.getViewport(); + this.dropListenKeys_ = [ + ol.events.listen(dropArea, ol.events.EventType.DROP, + ol.interaction.DragAndDrop.handleDrop_, this), + ol.events.listen(dropArea, ol.events.EventType.DRAGENTER, + ol.interaction.DragAndDrop.handleStop_, this), + ol.events.listen(dropArea, ol.events.EventType.DRAGOVER, + ol.interaction.DragAndDrop.handleStop_, this), + ol.events.listen(dropArea, ol.events.EventType.DROP, + ol.interaction.DragAndDrop.handleStop_, this) + ] } }; @@ -110329,12 +94952,13 @@ ol.interaction.DragAndDrop.prototype.setMap = function(map) { /** * @param {ol.format.Feature} format Format. * @param {string} text Text. + * @param {olx.format.ReadOptions} options Read options. * @private * @return {Array.<ol.Feature>} Features. */ -ol.interaction.DragAndDrop.prototype.tryReadFeatures_ = function(format, text) { +ol.interaction.DragAndDrop.prototype.tryReadFeatures_ = function(format, text, options) { try { - return format.readFeatures(text); + return format.readFeatures(text, options); } catch (e) { return null; } @@ -110354,14 +94978,13 @@ ol.interaction.DragAndDropEventType = { }; - /** * @classdesc * Events emitted by {@link ol.interaction.DragAndDrop} instances are instances * of this type. * * @constructor - * @extends {goog.events.Event} + * @extends {ol.events.Event} * @implements {oli.interaction.DragAndDropEvent} * @param {ol.interaction.DragAndDropEventType} type Type. * @param {Object} target Target. @@ -110369,8 +94992,7 @@ ol.interaction.DragAndDropEventType = { * @param {Array.<ol.Feature>=} opt_features Features. * @param {ol.proj.Projection=} opt_projection Projection. */ -ol.interaction.DragAndDropEvent = - function(type, target, file, opt_features, opt_projection) { +ol.interaction.DragAndDropEvent = function(type, target, file, opt_features, opt_projection) { goog.base(this, type, target); @@ -110396,316 +95018,17 @@ ol.interaction.DragAndDropEvent = this.projection = opt_projection; }; -goog.inherits(ol.interaction.DragAndDropEvent, goog.events.Event); - -// Copyright 2007 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Defines a 2-element vector class that can be used for - * coordinate math, useful for animation systems and point manipulation. - * - * Vec2 objects inherit from goog.math.Coordinate and may be used wherever a - * Coordinate is required. Where appropriate, Vec2 functions accept both Vec2 - * and Coordinate objects as input. - * - * @author brenneman@google.com (Shawn Brenneman) - */ - -goog.provide('goog.math.Vec2'); - -goog.require('goog.math'); -goog.require('goog.math.Coordinate'); - - - -/** - * Class for a two-dimensional vector object and assorted functions useful for - * manipulating points. - * - * @param {number} x The x coordinate for the vector. - * @param {number} y The y coordinate for the vector. - * @struct - * @constructor - * @extends {goog.math.Coordinate} - */ -goog.math.Vec2 = function(x, y) { - /** - * X-value - * @type {number} - */ - this.x = x; - - /** - * Y-value - * @type {number} - */ - this.y = y; -}; -goog.inherits(goog.math.Vec2, goog.math.Coordinate); - - -/** - * @return {!goog.math.Vec2} A random unit-length vector. - */ -goog.math.Vec2.randomUnit = function() { - var angle = Math.random() * Math.PI * 2; - return new goog.math.Vec2(Math.cos(angle), Math.sin(angle)); -}; - - -/** - * @return {!goog.math.Vec2} A random vector inside the unit-disc. - */ -goog.math.Vec2.random = function() { - var mag = Math.sqrt(Math.random()); - var angle = Math.random() * Math.PI * 2; - - return new goog.math.Vec2(Math.cos(angle) * mag, Math.sin(angle) * mag); -}; - - -/** - * Returns a new Vec2 object from a given coordinate. - * @param {!goog.math.Coordinate} a The coordinate. - * @return {!goog.math.Vec2} A new vector object. - */ -goog.math.Vec2.fromCoordinate = function(a) { - return new goog.math.Vec2(a.x, a.y); -}; - - -/** - * @return {!goog.math.Vec2} A new vector with the same coordinates as this one. - * @override - */ -goog.math.Vec2.prototype.clone = function() { - return new goog.math.Vec2(this.x, this.y); -}; - - -/** - * Returns the magnitude of the vector measured from the origin. - * @return {number} The length of the vector. - */ -goog.math.Vec2.prototype.magnitude = function() { - return Math.sqrt(this.x * this.x + this.y * this.y); -}; - - -/** - * Returns the squared magnitude of the vector measured from the origin. - * NOTE(brenneman): Leaving out the square root is not a significant - * optimization in JavaScript. - * @return {number} The length of the vector, squared. - */ -goog.math.Vec2.prototype.squaredMagnitude = function() { - return this.x * this.x + this.y * this.y; -}; - - -/** - * @return {!goog.math.Vec2} This coordinate after scaling. - * @override - */ -goog.math.Vec2.prototype.scale = - /** @type {function(number, number=):!goog.math.Vec2} */ - (goog.math.Coordinate.prototype.scale); - - -/** - * Reverses the sign of the vector. Equivalent to scaling the vector by -1. - * @return {!goog.math.Vec2} The inverted vector. - */ -goog.math.Vec2.prototype.invert = function() { - this.x = -this.x; - this.y = -this.y; - return this; -}; - - -/** - * Normalizes the current vector to have a magnitude of 1. - * @return {!goog.math.Vec2} The normalized vector. - */ -goog.math.Vec2.prototype.normalize = function() { - return this.scale(1 / this.magnitude()); -}; - - -/** - * Adds another vector to this vector in-place. - * @param {!goog.math.Coordinate} b The vector to add. - * @return {!goog.math.Vec2} This vector with {@code b} added. - */ -goog.math.Vec2.prototype.add = function(b) { - this.x += b.x; - this.y += b.y; - return this; -}; - - -/** - * Subtracts another vector from this vector in-place. - * @param {!goog.math.Coordinate} b The vector to subtract. - * @return {!goog.math.Vec2} This vector with {@code b} subtracted. - */ -goog.math.Vec2.prototype.subtract = function(b) { - this.x -= b.x; - this.y -= b.y; - return this; -}; - - -/** - * Rotates this vector in-place by a given angle, specified in radians. - * @param {number} angle The angle, in radians. - * @return {!goog.math.Vec2} This vector rotated {@code angle} radians. - */ -goog.math.Vec2.prototype.rotate = function(angle) { - var cos = Math.cos(angle); - var sin = Math.sin(angle); - var newX = this.x * cos - this.y * sin; - var newY = this.y * cos + this.x * sin; - this.x = newX; - this.y = newY; - return this; -}; - - -/** - * Rotates a vector by a given angle, specified in radians, relative to a given - * axis rotation point. The returned vector is a newly created instance - no - * in-place changes are done. - * @param {!goog.math.Vec2} v A vector. - * @param {!goog.math.Vec2} axisPoint The rotation axis point. - * @param {number} angle The angle, in radians. - * @return {!goog.math.Vec2} The rotated vector in a newly created instance. - */ -goog.math.Vec2.rotateAroundPoint = function(v, axisPoint, angle) { - var res = v.clone(); - return res.subtract(axisPoint).rotate(angle).add(axisPoint); -}; - - -/** - * Compares this vector with another for equality. - * @param {!goog.math.Vec2} b The other vector. - * @return {boolean} Whether this vector has the same x and y as the given - * vector. - */ -goog.math.Vec2.prototype.equals = function(b) { - return this == b || !!b && this.x == b.x && this.y == b.y; -}; - - -/** - * Returns the distance between two vectors. - * @param {!goog.math.Coordinate} a The first vector. - * @param {!goog.math.Coordinate} b The second vector. - * @return {number} The distance. - */ -goog.math.Vec2.distance = goog.math.Coordinate.distance; - - -/** - * Returns the squared distance between two vectors. - * @param {!goog.math.Coordinate} a The first vector. - * @param {!goog.math.Coordinate} b The second vector. - * @return {number} The squared distance. - */ -goog.math.Vec2.squaredDistance = goog.math.Coordinate.squaredDistance; - - -/** - * Compares vectors for equality. - * @param {!goog.math.Coordinate} a The first vector. - * @param {!goog.math.Coordinate} b The second vector. - * @return {boolean} Whether the vectors have the same x and y coordinates. - */ -goog.math.Vec2.equals = goog.math.Coordinate.equals; - - -/** - * Returns the sum of two vectors as a new Vec2. - * @param {!goog.math.Coordinate} a The first vector. - * @param {!goog.math.Coordinate} b The second vector. - * @return {!goog.math.Vec2} The sum vector. - */ -goog.math.Vec2.sum = function(a, b) { - return new goog.math.Vec2(a.x + b.x, a.y + b.y); -}; - - -/** - * Returns the difference between two vectors as a new Vec2. - * @param {!goog.math.Coordinate} a The first vector. - * @param {!goog.math.Coordinate} b The second vector. - * @return {!goog.math.Vec2} The difference vector. - */ -goog.math.Vec2.difference = function(a, b) { - return new goog.math.Vec2(a.x - b.x, a.y - b.y); -}; - - -/** - * Returns the dot-product of two vectors. - * @param {!goog.math.Coordinate} a The first vector. - * @param {!goog.math.Coordinate} b The second vector. - * @return {number} The dot-product of the two vectors. - */ -goog.math.Vec2.dot = function(a, b) { - return a.x * b.x + a.y * b.y; -}; - - -/** - * Returns the determinant of two vectors. - * @param {!goog.math.Vec2} a The first vector. - * @param {!goog.math.Vec2} b The second vector. - * @return {number} The determinant of the two vectors. - */ -goog.math.Vec2.determinant = function(a, b) { - return a.x * b.y - a.y * b.x; -}; - - -/** - * Returns a new Vec2 that is the linear interpolant between vectors a and b at - * scale-value x. - * @param {!goog.math.Coordinate} a Vector a. - * @param {!goog.math.Coordinate} b Vector b. - * @param {number} x The proportion between a and b. - * @return {!goog.math.Vec2} The interpolated vector. - */ -goog.math.Vec2.lerp = function(a, b, x) { - return new goog.math.Vec2(goog.math.lerp(a.x, b.x, x), - goog.math.lerp(a.y, b.y, x)); -}; +goog.inherits(ol.interaction.DragAndDropEvent, ol.events.Event); goog.provide('ol.interaction.DragRotateAndZoom'); -goog.require('goog.math.Vec2'); goog.require('ol'); goog.require('ol.ViewHint'); -goog.require('ol.events.ConditionType'); goog.require('ol.events.condition'); goog.require('ol.interaction.Interaction'); goog.require('ol.interaction.Pointer'); - /** * @classdesc * Allows the user to zoom and rotate the map by clicking and dragging @@ -110779,11 +95102,10 @@ ol.interaction.DragRotateAndZoom.handleDragEvent_ = function(mapBrowserEvent) { var map = mapBrowserEvent.map; var size = map.getSize(); var offset = mapBrowserEvent.pixel; - var delta = new goog.math.Vec2( - offset[0] - size[0] / 2, - size[1] / 2 - offset[1]); - var theta = Math.atan2(delta.y, delta.x); - var magnitude = delta.magnitude(); + var deltaX = offset[0] - size[0] / 2; + var deltaY = size[1] / 2 - offset[1]; + var theta = Math.atan2(deltaY, deltaX); + var magnitude = Math.sqrt(deltaX * deltaX + deltaY * deltaY); var view = map.getView(); map.render(); if (this.lastAngle_ !== undefined) { @@ -110850,19 +95172,18 @@ ol.interaction.DragRotateAndZoom.handleDownEvent_ = function(mapBrowserEvent) { goog.provide('ol.interaction.Draw'); goog.provide('ol.interaction.DrawEvent'); goog.provide('ol.interaction.DrawEventType'); -goog.provide('ol.interaction.DrawGeometryFunctionType'); goog.provide('ol.interaction.DrawMode'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.Event'); +goog.require('ol.events'); +goog.require('ol.events.Event'); goog.require('ol.Collection'); -goog.require('ol.Coordinate'); goog.require('ol.Feature'); goog.require('ol.MapBrowserEvent'); goog.require('ol.MapBrowserEvent.EventType'); goog.require('ol.Object'); goog.require('ol.coordinate'); +goog.require('ol.functions'); goog.require('ol.events.condition'); goog.require('ol.geom.Circle'); goog.require('ol.geom.GeometryType'); @@ -110898,14 +95219,13 @@ ol.interaction.DrawEventType = { }; - /** * @classdesc * Events emitted by {@link ol.interaction.Draw} instances are instances of * this type. * * @constructor - * @extends {goog.events.Event} + * @extends {ol.events.Event} * @implements {oli.DrawEvent} * @param {ol.interaction.DrawEventType} type Type. * @param {ol.Feature} feature The feature drawn. @@ -110922,8 +95242,7 @@ ol.interaction.DrawEvent = function(type, feature) { this.feature = feature; }; -goog.inherits(ol.interaction.DrawEvent, goog.events.Event); - +goog.inherits(ol.interaction.DrawEvent, ol.events.Event); /** @@ -111010,13 +95329,21 @@ ol.interaction.Draw = function(options) { */ this.maxPoints_ = options.maxPoints ? options.maxPoints : Infinity; + /** + * A function to decide if a potential finish coordinate is permissable + * @private + * @type {ol.events.ConditionType} + */ + this.finishCondition_ = options.finishCondition ? options.finishCondition : ol.functions.TRUE; + var geometryFunction = options.geometryFunction; if (!geometryFunction) { if (this.type_ === ol.geom.GeometryType.CIRCLE) { /** * @param {ol.Coordinate|Array.<ol.Coordinate>|Array.<Array.<ol.Coordinate>>} coordinates - * @param {ol.geom.SimpleGeometry=} opt_geometry - * @return {ol.geom.SimpleGeometry} + * The coordinates. + * @param {ol.geom.SimpleGeometry=} opt_geometry Optional geometry. + * @return {ol.geom.SimpleGeometry} A geometry. */ geometryFunction = function(coordinates, opt_geometry) { var circle = opt_geometry ? opt_geometry : @@ -111040,8 +95367,9 @@ ol.interaction.Draw = function(options) { } /** * @param {ol.Coordinate|Array.<ol.Coordinate>|Array.<Array.<ol.Coordinate>>} coordinates - * @param {ol.geom.SimpleGeometry=} opt_geometry - * @return {ol.geom.SimpleGeometry} + * The coordinates. + * @param {ol.geom.SimpleGeometry=} opt_geometry Optional geometry. + * @return {ol.geom.SimpleGeometry} A geometry. */ geometryFunction = function(coordinates, opt_geometry) { var geometry = opt_geometry; @@ -111149,9 +95477,9 @@ ol.interaction.Draw = function(options) { this.freehandCondition_ = options.freehandCondition ? options.freehandCondition : ol.events.condition.shiftKeyOnly; - goog.events.listen(this, + ol.events.listen(this, ol.Object.getChangeEventType(ol.interaction.InteractionProperty.ACTIVE), - this.updateState_, false, this); + this.updateState_, this); }; goog.inherits(ol.interaction.Draw, ol.interaction.Pointer); @@ -111186,6 +95514,11 @@ ol.interaction.Draw.prototype.setMap = function(map) { * @api */ ol.interaction.Draw.handleEvent = function(mapBrowserEvent) { + if ((this.mode_ === ol.interaction.DrawMode.LINE_STRING || + this.mode_ === ol.interaction.DrawMode.POLYGON) && + this.freehandCondition_(mapBrowserEvent)) { + this.freehand_ = true; + } var pass = !this.freehand_; if (this.freehand_ && mapBrowserEvent.type === ol.MapBrowserEvent.EventType.POINTERDRAG) { @@ -111211,11 +95544,8 @@ ol.interaction.Draw.handleDownEvent_ = function(event) { if (this.condition_(event)) { this.downPx_ = event.pixel; return true; - } else if ((this.mode_ === ol.interaction.DrawMode.LINE_STRING || - this.mode_ === ol.interaction.DrawMode.POLYGON) && - this.freehandCondition_(event)) { + } else if (this.freehand_) { this.downPx_ = event.pixel; - this.freehand_ = true; if (!this.finishCoordinate_) { this.startDrawing_(event); } @@ -111250,7 +95580,9 @@ ol.interaction.Draw.handleUpEvent_ = function(event) { } else if (this.mode_ === ol.interaction.DrawMode.CIRCLE) { this.finishDrawing(); } else if (this.atFinish_(event)) { - this.finishDrawing(); + if (this.finishCondition_(event)) { + this.finishDrawing(); + } } else { this.addToDrawing_(event); } @@ -111588,7 +95920,7 @@ ol.interaction.Draw.prototype.extend = function(feature) { /** * @inheritDoc */ -ol.interaction.Draw.prototype.shouldStopEvent = goog.functions.FALSE; +ol.interaction.Draw.prototype.shouldStopEvent = ol.functions.FALSE; /** @@ -111690,19 +96022,6 @@ ol.interaction.Draw.getMode_ = function(type) { /** - * Function that takes coordinates and an optional existing geometry as - * arguments, and returns a geometry. The optional existing geometry is the - * geometry that is returned when the function is called without a second - * argument. - * @typedef {function(!(ol.Coordinate|Array.<ol.Coordinate>| - * Array.<Array.<ol.Coordinate>>), ol.geom.SimpleGeometry=): - * ol.geom.SimpleGeometry} - * @api - */ -ol.interaction.DrawGeometryFunctionType; - - -/** * Draw mode. This collapses multi-part geometry types with their single-part * cousins. * @enum {string} @@ -111717,12 +96036,10 @@ ol.interaction.DrawMode = { goog.provide('ol.interaction.Modify'); goog.provide('ol.interaction.ModifyEvent'); -goog.require('goog.array'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.Event'); -goog.require('goog.events.EventType'); -goog.require('goog.functions'); +goog.require('ol.events'); +goog.require('ol.events.Event'); +goog.require('ol.events.EventType'); goog.require('ol'); goog.require('ol.Collection'); goog.require('ol.CollectionEventType'); @@ -111730,6 +96047,7 @@ goog.require('ol.Feature'); goog.require('ol.MapBrowserEvent.EventType'); goog.require('ol.MapBrowserPointerEvent'); goog.require('ol.ViewHint'); +goog.require('ol.array'); goog.require('ol.coordinate'); goog.require('ol.events.condition'); goog.require('ol.extent'); @@ -111765,14 +96083,13 @@ ol.ModifyEventType = { }; - /** * @classdesc * Events emitted by {@link ol.interaction.Modify} instances are instances of * this type. * * @constructor - * @extends {goog.events.Event} + * @extends {ol.events.Event} * @implements {oli.ModifyEvent} * @param {ol.ModifyEventType} type Type. * @param {ol.Collection.<ol.Feature>} features The features modified. @@ -111797,18 +96114,7 @@ ol.interaction.ModifyEvent = function(type, features, mapBrowserPointerEvent) { */ this.mapBrowserPointerEvent = mapBrowserPointerEvent; }; -goog.inherits(ol.interaction.ModifyEvent, goog.events.Event); - - -/** - * @typedef {{depth: (Array.<number>|undefined), - * feature: ol.Feature, - * geometry: ol.geom.SimpleGeometry, - * index: (number|undefined), - * segment: Array.<ol.Extent>}} - */ -ol.interaction.SegmentDataType; - +goog.inherits(ol.interaction.ModifyEvent, ol.events.Event); /** @@ -111831,14 +96137,29 @@ ol.interaction.Modify = function(options) { }); /** + * @private + * @type {ol.events.ConditionType} + */ + this.condition_ = options.condition ? + options.condition : ol.events.condition.primaryAction; + + + /** + * @private + * @param {ol.MapBrowserEvent} mapBrowserEvent Browser event. + * @return {boolean} Combined condition result. + */ + this.defaultDeleteCondition_ = function(mapBrowserEvent) { + return ol.events.condition.noModifierKeys(mapBrowserEvent) && + ol.events.condition.singleClick(mapBrowserEvent); + } + + /** * @type {ol.events.ConditionType} * @private */ this.deleteCondition_ = options.deleteCondition ? - options.deleteCondition : - /** @type {ol.events.ConditionType} */ (goog.functions.and( - ol.events.condition.noModifierKeys, - ol.events.condition.singleClick)); + options.deleteCondition : this.defaultDeleteCondition_; /** * Editing vertex. @@ -111906,7 +96227,7 @@ ol.interaction.Modify = function(options) { * @type {Array} * @private */ - this.dragSegments_ = null; + this.dragSegments_ = []; /** * Draw overlay where sketch features are drawn. @@ -111947,10 +96268,16 @@ ol.interaction.Modify = function(options) { this.features_ = options.features; this.features_.forEach(this.addFeature_, this); - goog.events.listen(this.features_, ol.CollectionEventType.ADD, - this.handleFeatureAdd_, false, this); - goog.events.listen(this.features_, ol.CollectionEventType.REMOVE, - this.handleFeatureRemove_, false, this); + ol.events.listen(this.features_, ol.CollectionEventType.ADD, + this.handleFeatureAdd_, this); + ol.events.listen(this.features_, ol.CollectionEventType.REMOVE, + this.handleFeatureRemove_, this); + + /** + * @type {ol.MapBrowserPointerEvent} + * @private + */ + this.lastPointerEvent_ = null; }; goog.inherits(ol.interaction.Modify, ol.interaction.Pointer); @@ -111969,8 +96296,8 @@ ol.interaction.Modify.prototype.addFeature_ = function(feature) { if (map) { this.handlePointerAtPixel_(this.lastPixel_, map); } - goog.events.listen(feature, goog.events.EventType.CHANGE, - this.handleFeatureChange_, false, this); + ol.events.listen(feature, ol.events.EventType.CHANGE, + this.handleFeatureChange_, this); }; @@ -111999,8 +96326,8 @@ ol.interaction.Modify.prototype.removeFeature_ = function(feature) { this.overlay_.getSource().removeFeature(this.vertexFeature_); this.vertexFeature_ = null; } - goog.events.unlisten(feature, goog.events.EventType.CHANGE, - this.handleFeatureChange_, false, this); + ol.events.unlisten(feature, ol.events.EventType.CHANGE, + this.handleFeatureChange_, this); }; @@ -112048,7 +96375,7 @@ ol.interaction.Modify.prototype.handleFeatureAdd_ = function(evt) { /** - * @param {goog.events.Event} evt Event. + * @param {ol.events.Event} evt Event. * @private */ ol.interaction.Modify.prototype.handleFeatureChange_ = function(evt) { @@ -112075,8 +96402,7 @@ ol.interaction.Modify.prototype.handleFeatureRemove_ = function(evt) { * @param {ol.geom.Point} geometry Geometry. * @private */ -ol.interaction.Modify.prototype.writePointGeometry_ = - function(feature, geometry) { +ol.interaction.Modify.prototype.writePointGeometry_ = function(feature, geometry) { var coordinates = geometry.getCoordinates(); var segmentData = /** @type {ol.interaction.SegmentDataType} */ ({ feature: feature, @@ -112092,8 +96418,7 @@ ol.interaction.Modify.prototype.writePointGeometry_ = * @param {ol.geom.MultiPoint} geometry Geometry. * @private */ -ol.interaction.Modify.prototype.writeMultiPointGeometry_ = - function(feature, geometry) { +ol.interaction.Modify.prototype.writeMultiPointGeometry_ = function(feature, geometry) { var points = geometry.getCoordinates(); var coordinates, i, ii, segmentData; for (i = 0, ii = points.length; i < ii; ++i) { @@ -112115,8 +96440,7 @@ ol.interaction.Modify.prototype.writeMultiPointGeometry_ = * @param {ol.geom.LineString} geometry Geometry. * @private */ -ol.interaction.Modify.prototype.writeLineStringGeometry_ = - function(feature, geometry) { +ol.interaction.Modify.prototype.writeLineStringGeometry_ = function(feature, geometry) { var coordinates = geometry.getCoordinates(); var i, ii, segment, segmentData; for (i = 0, ii = coordinates.length - 1; i < ii; ++i) { @@ -112137,8 +96461,7 @@ ol.interaction.Modify.prototype.writeLineStringGeometry_ = * @param {ol.geom.MultiLineString} geometry Geometry. * @private */ -ol.interaction.Modify.prototype.writeMultiLineStringGeometry_ = - function(feature, geometry) { +ol.interaction.Modify.prototype.writeMultiLineStringGeometry_ = function(feature, geometry) { var lines = geometry.getCoordinates(); var coordinates, i, ii, j, jj, segment, segmentData; for (j = 0, jj = lines.length; j < jj; ++j) { @@ -112163,8 +96486,7 @@ ol.interaction.Modify.prototype.writeMultiLineStringGeometry_ = * @param {ol.geom.Polygon} geometry Geometry. * @private */ -ol.interaction.Modify.prototype.writePolygonGeometry_ = - function(feature, geometry) { +ol.interaction.Modify.prototype.writePolygonGeometry_ = function(feature, geometry) { var rings = geometry.getCoordinates(); var coordinates, i, ii, j, jj, segment, segmentData; for (j = 0, jj = rings.length; j < jj; ++j) { @@ -112189,8 +96511,7 @@ ol.interaction.Modify.prototype.writePolygonGeometry_ = * @param {ol.geom.MultiPolygon} geometry Geometry. * @private */ -ol.interaction.Modify.prototype.writeMultiPolygonGeometry_ = - function(feature, geometry) { +ol.interaction.Modify.prototype.writeMultiPolygonGeometry_ = function(feature, geometry) { var polygons = geometry.getCoordinates(); var coordinates, i, ii, j, jj, k, kk, rings, segment, segmentData; for (k = 0, kk = polygons.length; k < kk; ++k) { @@ -112218,8 +96539,7 @@ ol.interaction.Modify.prototype.writeMultiPolygonGeometry_ = * @param {ol.geom.GeometryCollection} geometry Geometry. * @private */ -ol.interaction.Modify.prototype.writeGeometryCollectionGeometry_ = - function(feature, geometry) { +ol.interaction.Modify.prototype.writeGeometryCollectionGeometry_ = function(feature, geometry) { var i, geometries = geometry.getGeometriesArray(); for (i = 0; i < geometries.length; ++i) { this.SEGMENT_WRITERS_[geometries[i].getType()].call( @@ -112233,8 +96553,7 @@ ol.interaction.Modify.prototype.writeGeometryCollectionGeometry_ = * @return {ol.Feature} Vertex feature. * @private */ -ol.interaction.Modify.prototype.createOrUpdateVertexFeature_ = - function(coordinates) { +ol.interaction.Modify.prototype.createOrUpdateVertexFeature_ = function(coordinates) { var vertexFeature = this.vertexFeature_; if (!vertexFeature) { vertexFeature = new ol.Feature(new ol.geom.Point(coordinates)); @@ -112249,9 +96568,9 @@ ol.interaction.Modify.prototype.createOrUpdateVertexFeature_ = /** - * @param {ol.interaction.SegmentDataType} a - * @param {ol.interaction.SegmentDataType} b - * @return {number} + * @param {ol.interaction.SegmentDataType} a The first segment data. + * @param {ol.interaction.SegmentDataType} b The second segment data. + * @return {number} The difference in indexes. * @private */ ol.interaction.Modify.compareIndexes_ = function(a, b) { @@ -112266,8 +96585,11 @@ ol.interaction.Modify.compareIndexes_ = function(a, b) { * @private */ ol.interaction.Modify.handleDownEvent_ = function(evt) { + if (!this.condition_(evt)) { + return false; + } this.handlePointerAtPixel_(evt.pixel, evt.map); - this.dragSegments_ = []; + this.dragSegments_.length = 0; this.modified_ = false; var vertexFeature = this.vertexFeature_; if (vertexFeature) { @@ -112316,8 +96638,8 @@ ol.interaction.Modify.handleDownEvent_ = function(evt) { if (insertVertices.length) { this.willModifyFeatures_(evt); } - for (i = insertVertices.length - 1; i >= 0; --i) { - this.insertVertex_.apply(this, insertVertices[i]); + for (var j = insertVertices.length - 1; j >= 0; --j) { + this.insertVertex_.apply(this, insertVertices[j]); } } return !!this.vertexFeature_; @@ -112372,6 +96694,8 @@ ol.interaction.Modify.handleDragEvent_ = function(evt) { coordinates[depth[1]][depth[0]][segmentData.index + index] = vertex; segment[index] = vertex; break; + default: + // pass } this.setGeometryCoordinates_(geometry, coordinates); @@ -112414,6 +96738,7 @@ ol.interaction.Modify.handleEvent = function(mapBrowserEvent) { if (!(mapBrowserEvent instanceof ol.MapBrowserPointerEvent)) { return true; } + this.lastPointerEvent_ = mapBrowserEvent; var handled; if (!mapBrowserEvent.map.getView().getHints()[ol.ViewHint.INTERACTING] && @@ -112427,11 +96752,7 @@ ol.interaction.Modify.handleEvent = function(mapBrowserEvent) { var geometry = this.vertexFeature_.getGeometry(); goog.asserts.assertInstanceof(geometry, ol.geom.Point, 'geometry should be an ol.geom.Point'); - this.willModifyFeatures_(mapBrowserEvent); - handled = this.removeVertex_(); - this.dispatchEvent(new ol.interaction.ModifyEvent( - ol.ModifyEventType.MODIFYEND, this.features_, mapBrowserEvent)); - this.modified_ = false; + handled = this.removePoint(); } else { handled = true; } @@ -112597,6 +96918,23 @@ ol.interaction.Modify.prototype.insertVertex_ = function(segmentData, vertex) { this.ignoreNextSingleClick_ = true; }; +/** + * Removes the vertex currently being pointed. + * @return {boolean} True when a vertex was removed. + * @api + */ +ol.interaction.Modify.prototype.removePoint = function() { + var handled = false; + if (this.lastPointerEvent_ && this.lastPointerEvent_.type != ol.MapBrowserEvent.EventType.POINTERDRAG) { + var evt = this.lastPointerEvent_; + this.willModifyFeatures_(evt); + handled = this.removeVertex_(); + this.dispatchEvent(new ol.interaction.ModifyEvent( + ol.ModifyEventType.MODIFYEND, this.features_, evt)); + this.modified_ = false; + } + return handled; +}; /** * Removes a vertex from all matching features. @@ -112607,91 +96945,111 @@ ol.interaction.Modify.prototype.removeVertex_ = function() { var dragSegments = this.dragSegments_; var segmentsByFeature = {}; var component, coordinates, dragSegment, geometry, i, index, left; - var newIndex, newSegment, right, segmentData, uid, deleted; + var newIndex, right, segmentData, uid, deleted; for (i = dragSegments.length - 1; i >= 0; --i) { dragSegment = dragSegments[i]; segmentData = dragSegment[0]; - geometry = segmentData.geometry; - coordinates = geometry.getCoordinates(); uid = goog.getUid(segmentData.feature); if (segmentData.depth) { // separate feature components uid += '-' + segmentData.depth.join('-'); } - left = right = index = undefined; + if (!(uid in segmentsByFeature)) { + segmentsByFeature[uid] = {}; + } if (dragSegment[1] === 0) { - right = segmentData; - index = segmentData.index; + segmentsByFeature[uid].right = segmentData; + segmentsByFeature[uid].index = segmentData.index; } else if (dragSegment[1] == 1) { - left = segmentData; - index = segmentData.index + 1; - } - if (!(uid in segmentsByFeature)) { - segmentsByFeature[uid] = [left, right, index]; + segmentsByFeature[uid].left = segmentData; + segmentsByFeature[uid].index = segmentData.index + 1; } - newSegment = segmentsByFeature[uid]; + + } + for (uid in segmentsByFeature) { + right = segmentsByFeature[uid].right; + left = segmentsByFeature[uid].left; + index = segmentsByFeature[uid].index; + newIndex = index - 1; if (left !== undefined) { - newSegment[0] = left; + segmentData = left; + } else { + segmentData = right; } - if (right !== undefined) { - newSegment[1] = right; + if (newIndex < 0) { + newIndex = 0; } - if (newSegment[0] !== undefined && newSegment[1] !== undefined) { - component = coordinates; - deleted = false; - newIndex = index - 1; - switch (geometry.getType()) { - case ol.geom.GeometryType.MULTI_LINE_STRING: + geometry = segmentData.geometry; + coordinates = geometry.getCoordinates(); + component = coordinates; + deleted = false; + switch (geometry.getType()) { + case ol.geom.GeometryType.MULTI_LINE_STRING: + if (coordinates[segmentData.depth[0]].length > 2) { coordinates[segmentData.depth[0]].splice(index, 1); deleted = true; - break; - case ol.geom.GeometryType.LINE_STRING: + } + break; + case ol.geom.GeometryType.LINE_STRING: + if (coordinates.length > 2) { coordinates.splice(index, 1); deleted = true; - break; - case ol.geom.GeometryType.MULTI_POLYGON: - component = component[segmentData.depth[1]]; - /* falls through */ - case ol.geom.GeometryType.POLYGON: - component = component[segmentData.depth[0]]; - if (component.length > 4) { - if (index == component.length - 1) { - index = 0; - } - component.splice(index, 1); - deleted = true; - if (index === 0) { - // close the ring again - component.pop(); - component.push(component[0]); - newIndex = component.length - 1; - } + } + break; + case ol.geom.GeometryType.MULTI_POLYGON: + component = component[segmentData.depth[1]]; + /* falls through */ + case ol.geom.GeometryType.POLYGON: + component = component[segmentData.depth[0]]; + if (component.length > 4) { + if (index == component.length - 1) { + index = 0; } - break; - } + component.splice(index, 1); + deleted = true; + if (index === 0) { + // close the ring again + component.pop(); + component.push(component[0]); + newIndex = component.length - 1; + } + } + break; + default: + // pass + } - if (deleted) { - this.rBush_.remove(newSegment[0]); - this.rBush_.remove(newSegment[1]); - this.setGeometryCoordinates_(geometry, coordinates); + if (deleted) { + this.setGeometryCoordinates_(geometry, coordinates); + var segments = []; + if (left !== undefined) { + this.rBush_.remove(left); + segments.push(left.segment[0]); + } + if (right !== undefined) { + this.rBush_.remove(right); + segments.push(right.segment[1]); + } + if (left !== undefined && right !== undefined) { goog.asserts.assert(newIndex >= 0, 'newIndex should be larger than 0'); + var newSegmentData = /** @type {ol.interaction.SegmentDataType} */ ({ depth: segmentData.depth, feature: segmentData.feature, geometry: segmentData.geometry, index: newIndex, - segment: [newSegment[0].segment[0], newSegment[1].segment[1]] + segment: segments }); this.rBush_.insert(ol.extent.boundingExtent(newSegmentData.segment), newSegmentData); - this.updateSegmentIndices_(geometry, index, segmentData.depth, -1); - - if (this.vertexFeature_) { - this.overlay_.getSource().removeFeature(this.vertexFeature_); - this.vertexFeature_ = null; - } + } + this.updateSegmentIndices_(geometry, index, segmentData.depth, -1); + if (this.vertexFeature_) { + this.overlay_.getSource().removeFeature(this.vertexFeature_); + this.vertexFeature_ = null; } } + } return true; }; @@ -112702,8 +97060,7 @@ ol.interaction.Modify.prototype.removeVertex_ = function() { * @param {Array} coordinates Coordinates. * @private */ -ol.interaction.Modify.prototype.setGeometryCoordinates_ = - function(geometry, coordinates) { +ol.interaction.Modify.prototype.setGeometryCoordinates_ = function(geometry, coordinates) { this.changingFeature_ = true; geometry.setCoordinates(coordinates); this.changingFeature_ = false; @@ -112722,9 +97079,7 @@ ol.interaction.Modify.prototype.updateSegmentIndices_ = function( this.rBush_.forEachInExtent(geometry.getExtent(), function(segmentDataMatch) { if (segmentDataMatch.geometry === geometry && (depth === undefined || segmentDataMatch.depth === undefined || - goog.array.equals( - /** @type {null|{length: number}} */ (segmentDataMatch.depth), - depth)) && + ol.array.equals(segmentDataMatch.depth, depth)) && segmentDataMatch.index > index) { segmentDataMatch.index += delta; } @@ -112745,21 +97100,19 @@ ol.interaction.Modify.getDefaultStyleFunction = function() { goog.provide('ol.interaction.Select'); goog.provide('ol.interaction.SelectEvent'); goog.provide('ol.interaction.SelectEventType'); -goog.provide('ol.interaction.SelectFilterFunction'); -goog.require('goog.array'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.Event'); -goog.require('goog.functions'); -goog.require('goog.object'); +goog.require('ol.functions'); goog.require('ol.CollectionEventType'); goog.require('ol.Feature'); goog.require('ol.array'); +goog.require('ol.events'); +goog.require('ol.events.Event'); goog.require('ol.events.condition'); goog.require('ol.geom.GeometryType'); goog.require('ol.interaction.Interaction'); goog.require('ol.layer.Vector'); +goog.require('ol.object'); goog.require('ol.source.Vector'); @@ -112777,18 +97130,6 @@ ol.interaction.SelectEventType = { /** - * A function that takes an {@link ol.Feature} or {@link ol.render.Feature} and - * an {@link ol.layer.Layer} and returns `true` if the feature may be selected - * or `false` otherwise. - * @typedef {function((ol.Feature|ol.render.Feature), ol.layer.Layer): - * boolean} - * @api - */ -ol.interaction.SelectFilterFunction; - - - -/** * @classdesc * Events emitted by {@link ol.interaction.Select} instances are instances of * this type. @@ -112799,11 +97140,10 @@ ol.interaction.SelectFilterFunction; * @param {ol.MapBrowserEvent} mapBrowserEvent Associated * {@link ol.MapBrowserEvent}. * @implements {oli.SelectEvent} - * @extends {goog.events.Event} + * @extends {ol.events.Event} * @constructor */ -ol.interaction.SelectEvent = - function(type, selected, deselected, mapBrowserEvent) { +ol.interaction.SelectEvent = function(type, selected, deselected, mapBrowserEvent) { goog.base(this, type); /** @@ -112827,8 +97167,7 @@ ol.interaction.SelectEvent = */ this.mapBrowserEvent = mapBrowserEvent; }; -goog.inherits(ol.interaction.SelectEvent, goog.events.Event); - +goog.inherits(ol.interaction.SelectEvent, ol.events.Event); /** @@ -112896,25 +97235,49 @@ ol.interaction.Select = function(opt_options) { * @type {ol.interaction.SelectFilterFunction} */ this.filter_ = options.filter ? options.filter : - goog.functions.TRUE; + ol.functions.TRUE; + + var featureOverlay = new ol.layer.Vector({ + source: new ol.source.Vector({ + useSpatialIndex: false, + features: options.features, + wrapX: options.wrapX + }), + style: options.style ? options.style : + ol.interaction.Select.getDefaultStyleFunction(), + updateWhileAnimating: true, + updateWhileInteracting: true + }); + + /** + * @private + * @type {ol.layer.Vector} + */ + this.featureOverlay_ = featureOverlay; var layerFilter; if (options.layers) { if (goog.isFunction(options.layers)) { - layerFilter = options.layers; + /** + * @param {ol.layer.Layer} layer Layer. + * @return {boolean} Include. + */ + layerFilter = function(layer) { + goog.asserts.assertFunction(options.layers); + return options.layers(layer); + }; } else { var layers = options.layers; - layerFilter = - /** - * @param {ol.layer.Layer} layer Layer. - * @return {boolean} Include. - */ - function(layer) { + /** + * @param {ol.layer.Layer} layer Layer. + * @return {boolean} Include. + */ + layerFilter = function(layer) { return ol.array.includes(layers, layer); }; } } else { - layerFilter = goog.functions.TRUE; + layerFilter = ol.functions.TRUE; } /** @@ -112931,27 +97294,11 @@ ol.interaction.Select = function(opt_options) { */ this.featureLayerAssociation_ = {}; - /** - * @private - * @type {ol.layer.Vector} - */ - this.featureOverlay_ = new ol.layer.Vector({ - source: new ol.source.Vector({ - useSpatialIndex: false, - features: options.features, - wrapX: options.wrapX - }), - style: options.style ? options.style : - ol.interaction.Select.getDefaultStyleFunction(), - updateWhileAnimating: true, - updateWhileInteracting: true - }); - var features = this.featureOverlay_.getSource().getFeaturesCollection(); - goog.events.listen(features, ol.CollectionEventType.ADD, - this.addFeature_, false, this); - goog.events.listen(features, ol.CollectionEventType.REMOVE, - this.removeFeature_, false, this); + ol.events.listen(features, ol.CollectionEventType.ADD, + this.addFeature_, this); + ol.events.listen(features, ol.CollectionEventType.REMOVE, + this.removeFeature_, this); }; goog.inherits(ol.interaction.Select, ol.interaction.Interaction); @@ -112962,8 +97309,7 @@ goog.inherits(ol.interaction.Select, ol.interaction.Interaction); * @param {ol.layer.Layer} layer Layer. * @private */ -ol.interaction.Select.prototype.addFeatureLayerAssociation_ = - function(feature, layer) { +ol.interaction.Select.prototype.addFeatureLayerAssociation_ = function(feature, layer) { var key = goog.getUid(feature); this.featureLayerAssociation_[key] = layer; }; @@ -113014,17 +97360,19 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) { var set = !add && !remove && !toggle; var map = mapBrowserEvent.map; var features = this.featureOverlay_.getSource().getFeaturesCollection(); - var /** @type {!Array.<ol.Feature>} */ deselected = []; - var /** @type {!Array.<ol.Feature>} */ selected = []; + var deselected = []; + var selected = []; var change = false; if (set) { // Replace the currently selected feature(s) with the feature(s) at the // pixel, or clear the selected feature(s) if there is no feature at // the pixel. + ol.object.clear(this.featureLayerAssociation_); map.forEachFeatureAtPixel(mapBrowserEvent.pixel, /** * @param {ol.Feature|ol.render.Feature} feature Feature. * @param {ol.layer.Layer} layer Layer. + * @return {boolean|undefined} Continue to iterate over the features. */ function(feature, layer) { if (this.filter_(feature, layer)) { @@ -113043,16 +97391,6 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) { features.clear(); } features.extend(selected); - // Modify object this.featureLayerAssociation_ - if (selected.length === 0) { - goog.object.clear(this.featureLayerAssociation_); - } else { - if (deselected.length > 0) { - deselected.forEach(function(feature) { - this.removeFeatureLayerAssociation_(feature); - }, this); - } - } } } else { // Modify the currently selected feature(s). @@ -113060,20 +97398,20 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) { /** * @param {ol.Feature|ol.render.Feature} feature Feature. * @param {ol.layer.Layer} layer Layer. + * @return {boolean|undefined} Continue to iterate over the features. */ function(feature, layer) { - if (!ol.array.includes(features.getArray(), feature)) { - if (add || toggle) { - if (this.filter_(feature, layer)) { - selected.push(feature); - this.addFeatureLayerAssociation_(feature, layer); - } - } - } else { - if (remove || toggle) { + if (this.filter_(feature, layer)) { + if ((add || toggle) && + !ol.array.includes(features.getArray(), feature)) { + selected.push(feature); + this.addFeatureLayerAssociation_(feature, layer); + } else if ((remove || toggle) && + ol.array.includes(features.getArray(), feature)) { deselected.push(feature); this.removeFeatureLayerAssociation_(feature); } + return !this.multi_; } }, this, this.layerFilter_); var i; @@ -113120,9 +97458,9 @@ ol.interaction.Select.prototype.setMap = function(map) { */ ol.interaction.Select.getDefaultStyleFunction = function() { var styles = ol.style.createDefaultEditingStyles(); - goog.array.extend(styles[ol.geom.GeometryType.POLYGON], + ol.array.extend(styles[ol.geom.GeometryType.POLYGON], styles[ol.geom.GeometryType.LINE_STRING]); - goog.array.extend(styles[ol.geom.GeometryType.GEOMETRY_COLLECTION], + ol.array.extend(styles[ol.geom.GeometryType.GEOMETRY_COLLECTION], styles[ol.geom.GeometryType.LINE_STRING]); return function(feature, resolution) { @@ -113165,8 +97503,7 @@ ol.interaction.Select.prototype.removeFeature_ = function(evt) { * @param {ol.Feature|ol.render.Feature} feature Feature. * @private */ -ol.interaction.Select.prototype.removeFeatureLayerAssociation_ = - function(feature) { +ol.interaction.Select.prototype.removeFeatureLayerAssociation_ = function(feature) { var key = goog.getUid(feature); delete this.featureLayerAssociation_[key]; }; @@ -113175,28 +97512,27 @@ goog.provide('ol.interaction.Snap'); goog.provide('ol.interaction.SnapProperty'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.object'); goog.require('ol'); goog.require('ol.Collection'); goog.require('ol.CollectionEvent'); goog.require('ol.CollectionEventType'); -goog.require('ol.Extent'); goog.require('ol.Feature'); goog.require('ol.Object'); goog.require('ol.Observable'); goog.require('ol.coordinate'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol.extent'); goog.require('ol.geom.Geometry'); goog.require('ol.interaction.Pointer'); +goog.require('ol.functions'); +goog.require('ol.object'); goog.require('ol.source.Vector'); goog.require('ol.source.VectorEvent'); goog.require('ol.source.VectorEventType'); goog.require('ol.structs.RBush'); - /** * @classdesc * Handles snapping of vector features while modifying or drawing them. The @@ -113223,7 +97559,7 @@ ol.interaction.Snap = function(opt_options) { goog.base(this, { handleEvent: ol.interaction.Snap.handleEvent_, - handleDownEvent: goog.functions.TRUE, + handleDownEvent: ol.functions.TRUE, handleUpEvent: ol.interaction.Snap.handleUpEvent_ }); @@ -113236,25 +97572,37 @@ ol.interaction.Snap = function(opt_options) { this.source_ = options.source ? options.source : null; /** + * @private + * @type {boolean} + */ + this.vertex_ = options.vertex !== undefined ? options.vertex : true; + + /** + * @private + * @type {boolean} + */ + this.edge_ = options.edge !== undefined ? options.edge : true; + + /** * @type {ol.Collection.<ol.Feature>} * @private */ this.features_ = options.features ? options.features : null; /** - * @type {Array.<goog.events.Key>} + * @type {Array.<ol.events.Key>} * @private */ this.featuresListenerKeys_ = []; /** - * @type {Object.<number, goog.events.Key>} + * @type {Object.<number, ol.events.Key>} * @private */ this.geometryChangeListenerKeys_ = {}; /** - * @type {Object.<number, goog.events.Key>} + * @type {Object.<number, ol.events.Key>} * @private */ this.geometryModifyListenerKeys_ = {}; @@ -113291,15 +97639,15 @@ ol.interaction.Snap = function(opt_options) { options.pixelTolerance : 10; /** - * @type {function(ol.interaction.Snap.SegmentDataType, ol.interaction.Snap.SegmentDataType): number} + * @type {function(ol.interaction.SnapSegmentDataType, ol.interaction.SnapSegmentDataType): number} * @private */ - this.sortByDistance_ = goog.bind(ol.interaction.Snap.sortByDistance, this); + this.sortByDistance_ = ol.interaction.Snap.sortByDistance.bind(this); /** * Segment RTree for each layer - * @type {ol.structs.RBush.<ol.interaction.Snap.SegmentDataType>} + * @type {ol.structs.RBush.<ol.interaction.SnapSegmentDataType>} * @private */ this.rBush_ = new ol.structs.RBush(); @@ -113333,24 +97681,31 @@ goog.inherits(ol.interaction.Snap, ol.interaction.Pointer); */ ol.interaction.Snap.prototype.addFeature = function(feature, opt_listen) { var listen = opt_listen !== undefined ? opt_listen : true; + var feature_uid = goog.getUid(feature); var geometry = feature.getGeometry(); - var segmentWriter = this.SEGMENT_WRITERS_[geometry.getType()]; - if (segmentWriter) { - var feature_uid = goog.getUid(feature); - this.indexedFeaturesExtents_[feature_uid] = geometry.getExtent( - ol.extent.createEmpty()); - segmentWriter.call(this, feature, geometry); - - if (listen) { - this.geometryModifyListenerKeys_[feature_uid] = geometry.on( - goog.events.EventType.CHANGE, - goog.bind(this.handleGeometryModify_, this, feature), - this); - this.geometryChangeListenerKeys_[feature_uid] = feature.on( - ol.Object.getChangeEventType(feature.getGeometryName()), - this.handleGeometryChange_, this); + if (geometry) { + var segmentWriter = this.SEGMENT_WRITERS_[geometry.getType()]; + if (segmentWriter) { + this.indexedFeaturesExtents_[feature_uid] = geometry.getExtent( + ol.extent.createEmpty()); + segmentWriter.call(this, feature, geometry); + + if (listen) { + this.geometryModifyListenerKeys_[feature_uid] = ol.events.listen( + geometry, + ol.events.EventType.CHANGE, + this.handleGeometryModify_.bind(this, feature), + this); + } } } + + if (listen) { + this.geometryChangeListenerKeys_[feature_uid] = ol.events.listen( + feature, + ol.Object.getChangeEventType(feature.getGeometryName()), + this.handleGeometryChange_, this); + } }; @@ -113373,7 +97728,7 @@ ol.interaction.Snap.prototype.forEachFeatureRemove_ = function(feature) { /** - * @return {ol.Collection.<ol.Feature>|Array.<ol.Feature>} + * @return {ol.Collection.<ol.Feature>|Array.<ol.Feature>} Features. * @private */ ol.interaction.Snap.prototype.getFeatures_ = function() { @@ -113423,11 +97778,11 @@ ol.interaction.Snap.prototype.handleFeatureRemove_ = function(evt) { /** - * @param {goog.events.Event} evt Event. + * @param {ol.events.Event} evt Event. * @private */ ol.interaction.Snap.prototype.handleGeometryChange_ = function(evt) { - var feature = evt.currentTarget; + var feature = evt.target; goog.asserts.assertInstanceof(feature, ol.Feature); this.removeFeature(feature, true); this.addFeature(feature, true); @@ -113436,7 +97791,7 @@ ol.interaction.Snap.prototype.handleGeometryChange_ = function(evt) { /** * @param {ol.Feature} feature Feature which geometry was modified. - * @param {goog.events.Event} evt Event. + * @param {ol.events.Event} evt Event. * @private */ ol.interaction.Snap.prototype.handleGeometryModify_ = function(feature, evt) { @@ -113476,11 +97831,13 @@ ol.interaction.Snap.prototype.removeFeature = function(feature, opt_unlisten) { if (unlisten) { ol.Observable.unByKey(this.geometryModifyListenerKeys_[feature_uid]); delete this.geometryModifyListenerKeys_[feature_uid]; - - ol.Observable.unByKey(this.geometryChangeListenerKeys_[feature_uid]); - delete this.geometryChangeListenerKeys_[feature_uid]; } } + + if (unlisten) { + ol.Observable.unByKey(this.geometryChangeListenerKeys_[feature_uid]); + delete this.geometryChangeListenerKeys_[feature_uid]; + } }; @@ -113502,15 +97859,19 @@ ol.interaction.Snap.prototype.setMap = function(map) { if (map) { if (this.features_) { - keys.push(this.features_.on(ol.CollectionEventType.ADD, - this.handleFeatureAdd_, this)); - keys.push(this.features_.on(ol.CollectionEventType.REMOVE, - this.handleFeatureRemove_, this)); + keys.push( + ol.events.listen(this.features_, ol.CollectionEventType.ADD, + this.handleFeatureAdd_, this), + ol.events.listen(this.features_, ol.CollectionEventType.REMOVE, + this.handleFeatureRemove_, this) + ); } else if (this.source_) { - keys.push(this.source_.on(ol.source.VectorEventType.ADDFEATURE, - this.handleFeatureAdd_, this)); - keys.push(this.source_.on(ol.source.VectorEventType.REMOVEFEATURE, - this.handleFeatureRemove_, this)); + keys.push( + ol.events.listen(this.source_, ol.source.VectorEventType.ADDFEATURE, + this.handleFeatureAdd_, this), + ol.events.listen(this.source_, ol.source.VectorEventType.REMOVEFEATURE, + this.handleFeatureRemove_, this) + ); } features.forEach(this.forEachFeatureAdd_, this); } @@ -113520,14 +97881,14 @@ ol.interaction.Snap.prototype.setMap = function(map) { /** * @inheritDoc */ -ol.interaction.Snap.prototype.shouldStopEvent = goog.functions.FALSE; +ol.interaction.Snap.prototype.shouldStopEvent = ol.functions.FALSE; /** * @param {ol.Pixel} pixel Pixel * @param {ol.Coordinate} pixelCoordinate Coordinate * @param {ol.Map} map Map. - * @return {ol.interaction.Snap.ResultType} Snap result + * @return {ol.interaction.SnapResultType} Snap result */ ol.interaction.Snap.prototype.snapTo = function(pixel, pixelCoordinate, map) { @@ -113542,31 +97903,51 @@ ol.interaction.Snap.prototype.snapTo = function(pixel, pixelCoordinate, map) { var snapped = false; var vertex = null; var vertexPixel = null; + var dist, pixel1, pixel2, squaredDist1, squaredDist2; if (segments.length > 0) { this.pixelCoordinate_ = pixelCoordinate; segments.sort(this.sortByDistance_); var closestSegment = segments[0].segment; - vertex = (ol.coordinate.closestOnSegment(pixelCoordinate, - closestSegment)); - vertexPixel = map.getPixelFromCoordinate(vertex); - if (Math.sqrt(ol.coordinate.squaredDistance(pixel, vertexPixel)) <= - this.pixelTolerance_) { - snapped = true; - var pixel1 = map.getPixelFromCoordinate(closestSegment[0]); - var pixel2 = map.getPixelFromCoordinate(closestSegment[1]); - var squaredDist1 = ol.coordinate.squaredDistance(vertexPixel, pixel1); - var squaredDist2 = ol.coordinate.squaredDistance(vertexPixel, pixel2); - var dist = Math.sqrt(Math.min(squaredDist1, squaredDist2)); + if (this.vertex_ && !this.edge_) { + pixel1 = map.getPixelFromCoordinate(closestSegment[0]); + pixel2 = map.getPixelFromCoordinate(closestSegment[1]); + squaredDist1 = ol.coordinate.squaredDistance(pixel, pixel1); + squaredDist2 = ol.coordinate.squaredDistance(pixel, pixel2); + dist = Math.sqrt(Math.min(squaredDist1, squaredDist2)); snappedToVertex = dist <= this.pixelTolerance_; if (snappedToVertex) { + snapped = true; vertex = squaredDist1 > squaredDist2 ? closestSegment[1] : closestSegment[0]; vertexPixel = map.getPixelFromCoordinate(vertex); - vertexPixel = [Math.round(vertexPixel[0]), Math.round(vertexPixel[1])]; } + } else if (this.edge_) { + vertex = (ol.coordinate.closestOnSegment(pixelCoordinate, + closestSegment)); + vertexPixel = map.getPixelFromCoordinate(vertex); + if (Math.sqrt(ol.coordinate.squaredDistance(pixel, vertexPixel)) <= + this.pixelTolerance_) { + snapped = true; + if (this.vertex_) { + pixel1 = map.getPixelFromCoordinate(closestSegment[0]); + pixel2 = map.getPixelFromCoordinate(closestSegment[1]); + squaredDist1 = ol.coordinate.squaredDistance(vertexPixel, pixel1); + squaredDist2 = ol.coordinate.squaredDistance(vertexPixel, pixel2); + dist = Math.sqrt(Math.min(squaredDist1, squaredDist2)); + snappedToVertex = dist <= this.pixelTolerance_; + if (snappedToVertex) { + vertex = squaredDist1 > squaredDist2 ? + closestSegment[1] : closestSegment[0]; + vertexPixel = map.getPixelFromCoordinate(vertex); + } + } + } + } + if (snapped) { + vertexPixel = [Math.round(vertexPixel[0]), Math.round(vertexPixel[1])]; } } - return /** @type {ol.interaction.Snap.ResultType} */ ({ + return /** @type {ol.interaction.SnapResultType} */ ({ snapped: snapped, vertex: vertex, vertexPixel: vertexPixel @@ -113589,8 +97970,7 @@ ol.interaction.Snap.prototype.updateFeature_ = function(feature) { * @param {ol.geom.GeometryCollection} geometry Geometry. * @private */ -ol.interaction.Snap.prototype.writeGeometryCollectionGeometry_ = - function(feature, geometry) { +ol.interaction.Snap.prototype.writeGeometryCollectionGeometry_ = function(feature, geometry) { var i, geometries = geometry.getGeometriesArray(); for (i = 0; i < geometries.length; ++i) { this.SEGMENT_WRITERS_[geometries[i].getType()].call( @@ -113604,13 +97984,12 @@ ol.interaction.Snap.prototype.writeGeometryCollectionGeometry_ = * @param {ol.geom.LineString} geometry Geometry. * @private */ -ol.interaction.Snap.prototype.writeLineStringGeometry_ = - function(feature, geometry) { +ol.interaction.Snap.prototype.writeLineStringGeometry_ = function(feature, geometry) { var coordinates = geometry.getCoordinates(); var i, ii, segment, segmentData; for (i = 0, ii = coordinates.length - 1; i < ii; ++i) { segment = coordinates.slice(i, i + 2); - segmentData = /** @type {ol.interaction.Snap.SegmentDataType} */ ({ + segmentData = /** @type {ol.interaction.SnapSegmentDataType} */ ({ feature: feature, segment: segment }); @@ -113624,15 +98003,14 @@ ol.interaction.Snap.prototype.writeLineStringGeometry_ = * @param {ol.geom.MultiLineString} geometry Geometry. * @private */ -ol.interaction.Snap.prototype.writeMultiLineStringGeometry_ = - function(feature, geometry) { +ol.interaction.Snap.prototype.writeMultiLineStringGeometry_ = function(feature, geometry) { var lines = geometry.getCoordinates(); var coordinates, i, ii, j, jj, segment, segmentData; for (j = 0, jj = lines.length; j < jj; ++j) { coordinates = lines[j]; for (i = 0, ii = coordinates.length - 1; i < ii; ++i) { segment = coordinates.slice(i, i + 2); - segmentData = /** @type {ol.interaction.Snap.SegmentDataType} */ ({ + segmentData = /** @type {ol.interaction.SnapSegmentDataType} */ ({ feature: feature, segment: segment }); @@ -113647,13 +98025,12 @@ ol.interaction.Snap.prototype.writeMultiLineStringGeometry_ = * @param {ol.geom.MultiPoint} geometry Geometry. * @private */ -ol.interaction.Snap.prototype.writeMultiPointGeometry_ = - function(feature, geometry) { +ol.interaction.Snap.prototype.writeMultiPointGeometry_ = function(feature, geometry) { var points = geometry.getCoordinates(); var coordinates, i, ii, segmentData; for (i = 0, ii = points.length; i < ii; ++i) { coordinates = points[i]; - segmentData = /** @type {ol.interaction.Snap.SegmentDataType} */ ({ + segmentData = /** @type {ol.interaction.SnapSegmentDataType} */ ({ feature: feature, segment: [coordinates, coordinates] }); @@ -113667,8 +98044,7 @@ ol.interaction.Snap.prototype.writeMultiPointGeometry_ = * @param {ol.geom.MultiPolygon} geometry Geometry. * @private */ -ol.interaction.Snap.prototype.writeMultiPolygonGeometry_ = - function(feature, geometry) { +ol.interaction.Snap.prototype.writeMultiPolygonGeometry_ = function(feature, geometry) { var polygons = geometry.getCoordinates(); var coordinates, i, ii, j, jj, k, kk, rings, segment, segmentData; for (k = 0, kk = polygons.length; k < kk; ++k) { @@ -113677,7 +98053,7 @@ ol.interaction.Snap.prototype.writeMultiPolygonGeometry_ = coordinates = rings[j]; for (i = 0, ii = coordinates.length - 1; i < ii; ++i) { segment = coordinates.slice(i, i + 2); - segmentData = /** @type {ol.interaction.Snap.SegmentDataType} */ ({ + segmentData = /** @type {ol.interaction.SnapSegmentDataType} */ ({ feature: feature, segment: segment }); @@ -113693,10 +98069,9 @@ ol.interaction.Snap.prototype.writeMultiPolygonGeometry_ = * @param {ol.geom.Point} geometry Geometry. * @private */ -ol.interaction.Snap.prototype.writePointGeometry_ = - function(feature, geometry) { +ol.interaction.Snap.prototype.writePointGeometry_ = function(feature, geometry) { var coordinates = geometry.getCoordinates(); - var segmentData = /** @type {ol.interaction.Snap.SegmentDataType} */ ({ + var segmentData = /** @type {ol.interaction.SnapSegmentDataType} */ ({ feature: feature, segment: [coordinates, coordinates] }); @@ -113709,15 +98084,14 @@ ol.interaction.Snap.prototype.writePointGeometry_ = * @param {ol.geom.Polygon} geometry Geometry. * @private */ -ol.interaction.Snap.prototype.writePolygonGeometry_ = - function(feature, geometry) { +ol.interaction.Snap.prototype.writePolygonGeometry_ = function(feature, geometry) { var rings = geometry.getCoordinates(); var coordinates, i, ii, j, jj, segment, segmentData; for (j = 0, jj = rings.length; j < jj; ++j) { coordinates = rings[j]; for (i = 0, ii = coordinates.length - 1; i < ii; ++i) { segment = coordinates.slice(i, i + 2); - segmentData = /** @type {ol.interaction.Snap.SegmentDataType} */ ({ + segmentData = /** @type {ol.interaction.SnapSegmentDataType} */ ({ feature: feature, segment: segment }); @@ -113728,25 +98102,6 @@ ol.interaction.Snap.prototype.writePolygonGeometry_ = /** - * @typedef {{ - * snapped: {boolean}, - * vertex: (ol.Coordinate|null), - * vertexPixel: (ol.Pixel|null) - * }} - */ -ol.interaction.Snap.ResultType; - - -/** - * @typedef {{ - * feature: ol.Feature, - * segment: Array.<ol.Coordinate> - * }} - */ -ol.interaction.Snap.SegmentDataType; - - -/** * Handle all pointer events events. * @param {ol.MapBrowserEvent} evt A move event. * @return {boolean} Pass the event to other interactions. @@ -113770,7 +98125,7 @@ ol.interaction.Snap.handleEvent_ = function(evt) { * @private */ ol.interaction.Snap.handleUpEvent_ = function(evt) { - var featuresToUpdate = goog.object.getValues(this.pendingFeatures_); + var featuresToUpdate = ol.object.getValues(this.pendingFeatures_); if (featuresToUpdate.length) { featuresToUpdate.forEach(this.updateFeature_, this); this.pendingFeatures_ = {}; @@ -113781,9 +98136,9 @@ ol.interaction.Snap.handleUpEvent_ = function(evt) { /** * Sort segments by distance, helper function - * @param {ol.interaction.Snap.SegmentDataType} a - * @param {ol.interaction.Snap.SegmentDataType} b - * @return {number} + * @param {ol.interaction.SnapSegmentDataType} a The first segment data. + * @param {ol.interaction.SnapSegmentDataType} b The second segment data. + * @return {number} The difference in distance. * @this {ol.interaction.Snap} */ ol.interaction.Snap.sortByDistance = function(a, b) { @@ -113796,8 +98151,9 @@ ol.interaction.Snap.sortByDistance = function(a, b) { goog.provide('ol.interaction.Translate'); goog.provide('ol.interaction.TranslateEvent'); -goog.require('goog.events'); -goog.require('goog.events.Event'); +goog.require('goog.asserts'); +goog.require('ol.events'); +goog.require('ol.events.Event'); goog.require('ol.array'); goog.require('ol.interaction.Pointer'); @@ -113827,14 +98183,13 @@ ol.interaction.TranslateEventType = { }; - /** * @classdesc * Events emitted by {@link ol.interaction.Translate} instances are instances of * this type. * * @constructor - * @extends {goog.events.Event} + * @extends {ol.events.Event} * @implements {oli.interaction.TranslateEvent} * @param {ol.interaction.TranslateEventType} type Type. * @param {ol.Collection.<ol.Feature>} features The features translated. @@ -113859,8 +98214,7 @@ ol.interaction.TranslateEvent = function(type, features, coordinate) { */ this.coordinate = coordinate; }; -goog.inherits(ol.interaction.TranslateEvent, goog.events.Event); - +goog.inherits(ol.interaction.TranslateEvent, ol.events.Event); /** @@ -113903,6 +98257,37 @@ ol.interaction.Translate = function(options) { */ this.features_ = options.features !== undefined ? options.features : null; + var layerFilter; + if (options.layers) { + if (goog.isFunction(options.layers)) { + /** + * @param {ol.layer.Layer} layer Layer. + * @return {boolean} Include. + */ + layerFilter = function(layer) { + goog.asserts.assertFunction(options.layers); + return options.layers(layer); + }; + } else { + var layers = options.layers; + /** + * @param {ol.layer.Layer} layer Layer. + * @return {boolean} Include. + */ + layerFilter = function(layer) { + return ol.array.includes(layers, layer); + }; + } + } else { + layerFilter = ol.functions.TRUE; + } + + /** + * @private + * @type {function(ol.layer.Layer): boolean} + */ + this.layerFilter_ = layerFilter; + /** * @type {ol.Feature} * @private @@ -113990,8 +98375,7 @@ ol.interaction.Translate.handleDragEvent_ = function(event) { * @this {ol.interaction.Translate} * @private */ -ol.interaction.Translate.handleMoveEvent_ = function(event) - { +ol.interaction.Translate.handleMoveEvent_ = function(event) { var elem = event.map.getTargetElement(); var intersectingFeature = event.map.forEachFeatureAtPixel(event.pixel, function(feature) { @@ -114040,7 +98424,7 @@ ol.interaction.Translate.prototype.featuresAtPixel_ = function(pixel, map) { var intersectingFeature = map.forEachFeatureAtPixel(pixel, function(feature) { return feature; - }); + }, this, this.layerFilter_); if (this.features_ && ol.array.includes(this.features_.getArray(), intersectingFeature)) { @@ -114053,13 +98437,13 @@ ol.interaction.Translate.prototype.featuresAtPixel_ = function(pixel, map) { goog.provide('ol.layer.Heatmap'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.object'); +goog.require('ol.events'); goog.require('ol'); goog.require('ol.Object'); goog.require('ol.dom'); goog.require('ol.layer.Vector'); goog.require('ol.math'); +goog.require('ol.object'); goog.require('ol.render.EventType'); goog.require('ol.style.Icon'); goog.require('ol.style.Style'); @@ -114075,7 +98459,6 @@ ol.layer.HeatmapLayerProperty = { }; - /** * @classdesc * Layer for rendering vector data as a heatmap. @@ -114092,7 +98475,7 @@ ol.layer.HeatmapLayerProperty = { ol.layer.Heatmap = function(opt_options) { var options = opt_options ? opt_options : {}; - var baseOptions = goog.object.clone(options); + var baseOptions = ol.object.assign({}, options); delete baseOptions.gradient; delete baseOptions.radius; @@ -114125,9 +98508,9 @@ ol.layer.Heatmap = function(opt_options) { */ this.styleCache_ = null; - goog.events.listen(this, + ol.events.listen(this, ol.Object.getChangeEventType(ol.layer.HeatmapLayerProperty.GRADIENT), - this.handleGradientChanged_, false, this); + this.handleGradientChanged_, this); this.setGradient(options.gradient ? options.gradient : ol.layer.Heatmap.DEFAULT_GRADIENT); @@ -114136,16 +98519,18 @@ ol.layer.Heatmap = function(opt_options) { this.setRadius(options.radius !== undefined ? options.radius : 8); - goog.events.listen(this, [ - ol.Object.getChangeEventType(ol.layer.HeatmapLayerProperty.BLUR), - ol.Object.getChangeEventType(ol.layer.HeatmapLayerProperty.RADIUS) - ], this.handleStyleChanged_, false, this); + ol.events.listen(this, + ol.Object.getChangeEventType(ol.layer.HeatmapLayerProperty.BLUR), + this.handleStyleChanged_, this); + ol.events.listen(this, + ol.Object.getChangeEventType(ol.layer.HeatmapLayerProperty.RADIUS), + this.handleStyleChanged_, this); this.handleStyleChanged_(); var weight = options.weight ? options.weight : 'weight'; var weightFunction; - if (goog.isString(weight)) { + if (typeof weight === 'string') { weightFunction = function(feature) { return feature.get(weight); }; @@ -114155,7 +98540,7 @@ ol.layer.Heatmap = function(opt_options) { goog.asserts.assert(goog.isFunction(weightFunction), 'weightFunction should be a function'); - this.setStyle(goog.bind(function(feature, resolution) { + this.setStyle(function(feature, resolution) { goog.asserts.assert(this.styleCache_, 'this.styleCache_ expected'); goog.asserts.assert(this.circleImage_ !== undefined, 'this.circleImage_ should be defined'); @@ -114176,14 +98561,13 @@ ol.layer.Heatmap = function(opt_options) { this.styleCache_[index] = style; } return style; - }, this)); + }.bind(this)); // For performance reasons, don't sort the features before rendering. // The render order is not relevant for a heatmap representation. this.setRenderOrder(null); - goog.events.listen(this, ol.render.EventType.RENDER, - this.handleRender_, false, this); + ol.events.listen(this, ol.render.EventType.RENDER, this.handleRender_, this); }; goog.inherits(ol.layer.Heatmap, ol.layer.Vector); @@ -114197,8 +98581,8 @@ ol.layer.Heatmap.DEFAULT_GRADIENT = ['#00f', '#0ff', '#0f0', '#ff0', '#f00']; /** - * @param {Array.<string>} colors - * @return {Uint8ClampedArray} + * @param {Array.<string>} colors A list of colored. + * @return {Uint8ClampedArray} An array. * @private */ ol.layer.Heatmap.createGradient_ = function(colors) { @@ -114220,7 +98604,7 @@ ol.layer.Heatmap.createGradient_ = function(colors) { /** - * @return {string} + * @return {string} Data URL for a circle. * @private */ ol.layer.Heatmap.prototype.createCircle_ = function() { @@ -114351,7 +98735,44 @@ ol.layer.Heatmap.prototype.setRadius = function(radius) { this.set(ol.layer.HeatmapLayerProperty.RADIUS, radius); }; -goog.provide('ol.raster.Operation'); +goog.provide('ol.net'); + + +/** + * Simple JSONP helper. Supports error callbacks and a custom callback param. + * The error callback will be called when no JSONP is executed after 10 seconds. + * + * @param {string} url Request url. A 'callback' query parameter will be + * appended. + * @param {Function} callback Callback on success. + * @param {function()=} opt_errback Callback on error. + * @param {string=} opt_callbackParam Custom query parameter for the JSONP + * callback. Default is 'callback'. + */ +ol.net.jsonp = function(url, callback, opt_errback, opt_callbackParam) { + var script = ol.global.document.createElement('script'); + var key = 'olc_' + goog.getUid(callback); + function cleanup() { + delete ol.global[key]; + script.parentNode.removeChild(script); + } + script.async = true; + script.src = url + (url.indexOf('?') == -1 ? '?' : '&') + + (opt_callbackParam || 'callback') + '=' + key; + var timer = ol.global.setTimeout(function() { + cleanup(); + if (opt_errback) { + opt_errback(); + } + }, 10000); + ol.global[key] = function(data) { + ol.global.clearTimeout(timer); + cleanup(); + callback(data); + }; + ol.global.document.getElementsByTagName('head')[0].appendChild(script); +}; + goog.provide('ol.raster.OperationType'); @@ -114365,35 +98786,6 @@ ol.raster.OperationType = { IMAGE: 'image' }; - -/** - * A function that takes an array of input data, performs some operation, and - * returns an array of ouput data. For `'pixel'` type operations, functions - * will be called with an array of {@link ol.raster.Pixel} data and should - * return an array of the same. For `'image'` type operations, functions will - * be called with an array of {@link ImageData - * https://developer.mozilla.org/en-US/docs/Web/API/ImageData} and should return - * an array of the same. The operations are called with a second "data" - * argument, which can be used for storage. The data object is accessible - * from raster events, where it can be initialized in "beforeoperations" and - * accessed again in "afteroperations". - * - * @typedef {function((Array.<ol.raster.Pixel>|Array.<ImageData>), Object): - * (Array.<ol.raster.Pixel>|Array.<ImageData>)} - * @api - */ -ol.raster.Operation; - -goog.provide('ol.raster.Pixel'); - - -/** - * An array of numbers representing pixel values. - * @typedef {Array.<number>} ol.raster.Pixel - * @api - */ -ol.raster.Pixel; - goog.provide('ol.render'); goog.require('goog.vec.Mat4'); @@ -114412,13 +98804,10 @@ goog.require('ol.vec.Mat4'); * var render = ol.render.toContext(canvas.getContext('2d'), * { size: [100, 100] }); * render.setFillStrokeStyle(new ol.style.Fill({ color: blue })); - * render.drawPolygonGeometry( + * render.drawPolygon( * new ol.geom.Polygon([[[0, 0], [100, 100], [100, 0], [0, 0]]])); * ``` * - * Note that {@link ol.render.canvas.Immediate#drawAsync} and - * {@link ol.render.canvas.Immediate#drawFeature} cannot be used. - * * @param {CanvasRenderingContext2D} context Canvas context. * @param {olx.render.ToContextOptions=} opt_options Options. * @return {ol.render.canvas.Immediate} Canvas Immediate. @@ -114443,30 +98832,21 @@ ol.render.toContext = function(context, opt_options) { }; goog.provide('ol.reproj.Tile'); -goog.provide('ol.reproj.TileFunctionType'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.math'); -goog.require('goog.object'); goog.require('ol.Tile'); goog.require('ol.TileState'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol.extent'); goog.require('ol.math'); +goog.require('ol.object'); goog.require('ol.proj'); goog.require('ol.reproj'); goog.require('ol.reproj.Triangulation'); /** - * @typedef {function(number, number, number, number) : ol.Tile} - */ -ol.reproj.TileFunctionType; - - - -/** * @classdesc * Class encapsulating single reprojected tile. * See {@link ol.source.TileImage}. @@ -114480,14 +98860,15 @@ ol.reproj.TileFunctionType; * @param {ol.TileCoord} tileCoord Coordinate of the tile. * @param {ol.TileCoord} wrappedTileCoord Coordinate of the tile wrapped in X. * @param {number} pixelRatio Pixel ratio. - * @param {ol.reproj.TileFunctionType} getTileFunction + * @param {number} gutter Gutter of the source tiles. + * @param {ol.ReprojTileFunctionType} getTileFunction * Function returning source tiles (z, x, y, pixelRatio). * @param {number=} opt_errorThreshold Acceptable reprojection error (in px). * @param {boolean=} opt_renderEdges Render reprojection edges. */ ol.reproj.Tile = function(sourceProj, sourceTileGrid, targetProj, targetTileGrid, tileCoord, wrappedTileCoord, - pixelRatio, getTileFunction, + pixelRatio, gutter, getTileFunction, opt_errorThreshold, opt_renderEdges) { goog.base(this, tileCoord, ol.TileState.IDLE); @@ -114506,6 +98887,12 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid, /** * @private + * @type {number} + */ + this.gutter_ = gutter; + + /** + * @private * @type {HTMLCanvasElement} */ this.canvas_ = null; @@ -114542,7 +98929,7 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid, /** * @private - * @type {Array.<goog.events.Key>} + * @type {Array.<ol.events.Key>} */ this.sourcesListenerKeys_ = null; @@ -114583,7 +98970,7 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid, var sourceResolution = ol.reproj.calculateSourceResolution( sourceProj, targetProj, targetCenter, targetResolution); - if (!goog.math.isFiniteNumber(sourceResolution) || sourceResolution <= 0) { + if (!isFinite(sourceResolution) || sourceResolution <= 0) { // invalid sourceResolution -> EMPTY // probably edges of the projections when no extent is defined this.state = ol.TileState.EMPTY; @@ -114671,7 +99058,7 @@ ol.reproj.Tile.prototype.getImage = function(opt_context) { var key = goog.getUid(opt_context); if (key in this.canvasByContext_) { return this.canvasByContext_[key]; - } else if (goog.object.isEmpty(this.canvasByContext_)) { + } else if (ol.object.isEmpty(this.canvasByContext_)) { image = this.canvas_; } else { image = /** @type {HTMLCanvasElement} */ (this.canvas_.cloneNode(false)); @@ -114699,21 +99086,25 @@ ol.reproj.Tile.prototype.reproject_ = function() { }, this); this.sourceTiles_.length = 0; - var z = this.wrappedTileCoord_[0]; - var size = this.targetTileGrid_.getTileSize(z); - var width = goog.isNumber(size) ? size : size[0]; - var height = goog.isNumber(size) ? size : size[1]; - var targetResolution = this.targetTileGrid_.getResolution(z); - var sourceResolution = this.sourceTileGrid_.getResolution(this.sourceZ_); - - var targetExtent = this.targetTileGrid_.getTileCoordExtent( - this.wrappedTileCoord_); - this.canvas_ = ol.reproj.render(width, height, this.pixelRatio_, - sourceResolution, this.sourceTileGrid_.getExtent(), - targetResolution, targetExtent, this.triangulation_, sources, - this.renderEdges_); - - this.state = ol.TileState.LOADED; + if (sources.length === 0) { + this.state = ol.TileState.ERROR; + } else { + var z = this.wrappedTileCoord_[0]; + var size = this.targetTileGrid_.getTileSize(z); + var width = goog.isNumber(size) ? size : size[0]; + var height = goog.isNumber(size) ? size : size[1]; + var targetResolution = this.targetTileGrid_.getResolution(z); + var sourceResolution = this.sourceTileGrid_.getResolution(this.sourceZ_); + + var targetExtent = this.targetTileGrid_.getTileCoordExtent( + this.wrappedTileCoord_); + this.canvas_ = ol.reproj.render(width, height, this.pixelRatio_, + sourceResolution, this.sourceTileGrid_.getExtent(), + targetResolution, targetExtent, this.triangulation_, sources, + this.gutter_, this.renderEdges_); + + this.state = ol.TileState.LOADED; + } this.changed(); }; @@ -114738,13 +99129,13 @@ ol.reproj.Tile.prototype.load = function() { leftToLoad++; var sourceListenKey; - sourceListenKey = tile.listen(goog.events.EventType.CHANGE, + sourceListenKey = ol.events.listen(tile, ol.events.EventType.CHANGE, function(e) { var state = tile.getState(); if (state == ol.TileState.LOADED || state == ol.TileState.ERROR || state == ol.TileState.EMPTY) { - goog.events.unlistenByKey(sourceListenKey); + ol.events.unlistenByKey(sourceListenKey); leftToLoad--; goog.asserts.assert(leftToLoad >= 0, 'leftToLoad should not be negative'); @@ -114753,7 +99144,7 @@ ol.reproj.Tile.prototype.load = function() { this.reproject_(); } } - }, false, this); + }, this); this.sourcesListenerKeys_.push(sourceListenKey); } }, this); @@ -114766,7 +99157,7 @@ ol.reproj.Tile.prototype.load = function() { }); if (leftToLoad === 0) { - this.reproject_(); + ol.global.setTimeout(this.reproject_.bind(this), 0); } } }; @@ -114778,751 +99169,23 @@ ol.reproj.Tile.prototype.load = function() { ol.reproj.Tile.prototype.unlistenSources_ = function() { goog.asserts.assert(this.sourcesListenerKeys_, 'this.sourcesListenerKeys_ should not be null'); - this.sourcesListenerKeys_.forEach(goog.events.unlistenByKey); + this.sourcesListenerKeys_.forEach(ol.events.unlistenByKey); this.sourcesListenerKeys_ = null; }; -// Copyright 2011 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview A utility to load JavaScript files via DOM script tags. - * Refactored from goog.net.Jsonp. Works cross-domain. - * - */ - -goog.provide('goog.net.jsloader'); -goog.provide('goog.net.jsloader.Error'); -goog.provide('goog.net.jsloader.ErrorCode'); -goog.provide('goog.net.jsloader.Options'); - -goog.require('goog.array'); -goog.require('goog.async.Deferred'); -goog.require('goog.debug.Error'); -goog.require('goog.dom'); -goog.require('goog.dom.TagName'); -goog.require('goog.object'); - - -/** - * The name of the property of goog.global under which the JavaScript - * verification object is stored by the loaded script. - * @private {string} - */ -goog.net.jsloader.GLOBAL_VERIFY_OBJS_ = 'closure_verification'; - - -/** - * The default length of time, in milliseconds, we are prepared to wait for a - * load request to complete. - * @type {number} - */ -goog.net.jsloader.DEFAULT_TIMEOUT = 5000; - - -/** - * Optional parameters for goog.net.jsloader.send. - * timeout: The length of time, in milliseconds, we are prepared to wait - * for a load request to complete. Default it 5 seconds. - * document: The HTML document under which to load the JavaScript. Default is - * the current document. - * cleanupWhenDone: If true clean up the script tag after script completes to - * load. This is important if you just want to read data from the JavaScript - * and then throw it away. Default is false. - * attributes: Additional attributes to set on the script tag. - * - * @typedef {{ - * timeout: (number|undefined), - * document: (HTMLDocument|undefined), - * cleanupWhenDone: (boolean|undefined), - * attributes: (!Object<string, string>|undefined) - * }} - */ -goog.net.jsloader.Options; - - -/** - * Scripts (URIs) waiting to be loaded. - * @private {!Array<string>} - */ -goog.net.jsloader.scriptsToLoad_ = []; - - -/** - * The deferred result of loading the URIs in scriptsToLoad_. - * We need to return this to a caller that wants to load URIs while - * a deferred is already working on them. - * @private {!goog.async.Deferred<null>} - */ -goog.net.jsloader.scriptLoadingDeferred_; - - -/** - * Loads and evaluates the JavaScript files at the specified URIs, guaranteeing - * the order of script loads. - * - * Because we have to load the scripts in serial (load script 1, exec script 1, - * load script 2, exec script 2, and so on), this will be slower than doing - * the network fetches in parallel. - * - * If you need to load a large number of scripts but dependency order doesn't - * matter, you should just call goog.net.jsloader.load N times. - * - * If you need to load a large number of scripts on the same domain, - * you may want to use goog.module.ModuleLoader. - * - * @param {Array<string>} uris The URIs to load. - * @param {goog.net.jsloader.Options=} opt_options Optional parameters. See - * goog.net.jsloader.options documentation for details. - * @return {!goog.async.Deferred} The deferred result, that may be used to add - * callbacks - */ -goog.net.jsloader.loadMany = function(uris, opt_options) { - // Loading the scripts in serial introduces asynchronosity into the flow. - // Therefore, there are race conditions where client A can kick off the load - // sequence for client B, even though client A's scripts haven't all been - // loaded yet. - // - // To work around this issue, all module loads share a queue. - if (!uris.length) { - return goog.async.Deferred.succeed(null); - } - - var isAnotherModuleLoading = goog.net.jsloader.scriptsToLoad_.length; - goog.array.extend(goog.net.jsloader.scriptsToLoad_, uris); - if (isAnotherModuleLoading) { - // jsloader is still loading some other scripts. - // In order to prevent the race condition noted above, we just add - // these URIs to the end of the scripts' queue and return the deferred - // result of the ongoing script load, so the caller knows when they - // finish loading. - return goog.net.jsloader.scriptLoadingDeferred_; - } - - uris = goog.net.jsloader.scriptsToLoad_; - var popAndLoadNextScript = function() { - var uri = uris.shift(); - var deferred = goog.net.jsloader.load(uri, opt_options); - if (uris.length) { - deferred.addBoth(popAndLoadNextScript); - } - return deferred; - }; - goog.net.jsloader.scriptLoadingDeferred_ = popAndLoadNextScript(); - return goog.net.jsloader.scriptLoadingDeferred_; -}; - - -/** - * Loads and evaluates a JavaScript file. - * When the script loads, a user callback is called. - * It is the client's responsibility to verify that the script ran successfully. - * - * @param {string} uri The URI of the JavaScript. - * @param {goog.net.jsloader.Options=} opt_options Optional parameters. See - * goog.net.jsloader.Options documentation for details. - * @return {!goog.async.Deferred} The deferred result, that may be used to add - * callbacks and/or cancel the transmission. - * The error callback will be called with a single goog.net.jsloader.Error - * parameter. - */ -goog.net.jsloader.load = function(uri, opt_options) { - var options = opt_options || {}; - var doc = options.document || document; - - var script = goog.dom.createElement(goog.dom.TagName.SCRIPT); - var request = {script_: script, timeout_: undefined}; - var deferred = new goog.async.Deferred(goog.net.jsloader.cancel_, request); - - // Set a timeout. - var timeout = null; - var timeoutDuration = goog.isDefAndNotNull(options.timeout) ? - options.timeout : goog.net.jsloader.DEFAULT_TIMEOUT; - if (timeoutDuration > 0) { - timeout = window.setTimeout(function() { - goog.net.jsloader.cleanup_(script, true); - deferred.errback(new goog.net.jsloader.Error( - goog.net.jsloader.ErrorCode.TIMEOUT, - 'Timeout reached for loading script ' + uri)); - }, timeoutDuration); - request.timeout_ = timeout; - } - - // Hang the user callback to be called when the script completes to load. - // NOTE(user): This callback will be called in IE even upon error. In any - // case it is the client's responsibility to verify that the script ran - // successfully. - script.onload = script.onreadystatechange = function() { - if (!script.readyState || script.readyState == 'loaded' || - script.readyState == 'complete') { - var removeScriptNode = options.cleanupWhenDone || false; - goog.net.jsloader.cleanup_(script, removeScriptNode, timeout); - deferred.callback(null); - } - }; - - // Add an error callback. - // NOTE(user): Not supported in IE. - script.onerror = function() { - goog.net.jsloader.cleanup_(script, true, timeout); - deferred.errback(new goog.net.jsloader.Error( - goog.net.jsloader.ErrorCode.LOAD_ERROR, - 'Error while loading script ' + uri)); - }; - - var properties = options.attributes || {}; - goog.object.extend(properties, { - 'type': 'text/javascript', - 'charset': 'UTF-8', - // NOTE(user): Safari never loads the script if we don't set - // the src attribute before appending. - 'src': uri - }); - goog.dom.setProperties(script, properties); - var scriptParent = goog.net.jsloader.getScriptParentElement_(doc); - scriptParent.appendChild(script); - - return deferred; -}; - - -/** - * Loads a JavaScript file and verifies it was evaluated successfully, using a - * verification object. - * The verification object is set by the loaded JavaScript at the end of the - * script. - * We verify this object was set and return its value in the success callback. - * If the object is not defined we trigger an error callback. - * - * @param {string} uri The URI of the JavaScript. - * @param {string} verificationObjName The name of the verification object that - * the loaded script should set. - * @param {goog.net.jsloader.Options} options Optional parameters. See - * goog.net.jsloader.Options documentation for details. - * @return {!goog.async.Deferred} The deferred result, that may be used to add - * callbacks and/or cancel the transmission. - * The success callback will be called with a single parameter containing - * the value of the verification object. - * The error callback will be called with a single goog.net.jsloader.Error - * parameter. - */ -goog.net.jsloader.loadAndVerify = function(uri, verificationObjName, options) { - // Define the global objects variable. - if (!goog.global[goog.net.jsloader.GLOBAL_VERIFY_OBJS_]) { - goog.global[goog.net.jsloader.GLOBAL_VERIFY_OBJS_] = {}; - } - var verifyObjs = goog.global[goog.net.jsloader.GLOBAL_VERIFY_OBJS_]; - - // Verify that the expected object does not exist yet. - if (goog.isDef(verifyObjs[verificationObjName])) { - // TODO(user): Error or reset variable? - return goog.async.Deferred.fail(new goog.net.jsloader.Error( - goog.net.jsloader.ErrorCode.VERIFY_OBJECT_ALREADY_EXISTS, - 'Verification object ' + verificationObjName + ' already defined.')); - } - - // Send request to load the JavaScript. - var sendDeferred = goog.net.jsloader.load(uri, options); - - // Create a deferred object wrapping the send result. - var deferred = new goog.async.Deferred( - goog.bind(sendDeferred.cancel, sendDeferred)); - - // Call user back with object that was set by the script. - sendDeferred.addCallback(function() { - var result = verifyObjs[verificationObjName]; - if (goog.isDef(result)) { - deferred.callback(result); - delete verifyObjs[verificationObjName]; - } else { - // Error: script was not loaded properly. - deferred.errback(new goog.net.jsloader.Error( - goog.net.jsloader.ErrorCode.VERIFY_ERROR, - 'Script ' + uri + ' loaded, but verification object ' + - verificationObjName + ' was not defined.')); - } - }); - - // Pass error to new deferred object. - sendDeferred.addErrback(function(error) { - if (goog.isDef(verifyObjs[verificationObjName])) { - delete verifyObjs[verificationObjName]; - } - deferred.errback(error); - }); - - return deferred; -}; - - -/** - * Gets the DOM element under which we should add new script elements. - * How? Take the first head element, and if not found take doc.documentElement, - * which always exists. - * - * @param {!HTMLDocument} doc The relevant document. - * @return {!Element} The script parent element. - * @private - */ -goog.net.jsloader.getScriptParentElement_ = function(doc) { - var headElements = doc.getElementsByTagName(goog.dom.TagName.HEAD); - if (!headElements || goog.array.isEmpty(headElements)) { - return doc.documentElement; - } else { - return headElements[0]; - } -}; - - -/** - * Cancels a given request. - * @this {{script_: Element, timeout_: number}} The request context. - * @private - */ -goog.net.jsloader.cancel_ = function() { - var request = this; - if (request && request.script_) { - var scriptNode = request.script_; - if (scriptNode && scriptNode.tagName == goog.dom.TagName.SCRIPT) { - goog.net.jsloader.cleanup_(scriptNode, true, request.timeout_); - } - } -}; - - -/** - * Removes the script node and the timeout. - * - * @param {Node} scriptNode The node to be cleaned up. - * @param {boolean} removeScriptNode If true completely remove the script node. - * @param {?number=} opt_timeout The timeout handler to cleanup. - * @private - */ -goog.net.jsloader.cleanup_ = function(scriptNode, removeScriptNode, - opt_timeout) { - if (goog.isDefAndNotNull(opt_timeout)) { - goog.global.clearTimeout(opt_timeout); - } - - scriptNode.onload = goog.nullFunction; - scriptNode.onerror = goog.nullFunction; - scriptNode.onreadystatechange = goog.nullFunction; - - // Do this after a delay (removing the script node of a running script can - // confuse older IEs). - if (removeScriptNode) { - window.setTimeout(function() { - goog.dom.removeNode(scriptNode); - }, 0); - } -}; - - -/** - * Possible error codes for jsloader. - * @enum {number} - */ -goog.net.jsloader.ErrorCode = { - LOAD_ERROR: 0, - TIMEOUT: 1, - VERIFY_ERROR: 2, - VERIFY_OBJECT_ALREADY_EXISTS: 3 -}; - - - -/** - * A jsloader error. - * - * @param {goog.net.jsloader.ErrorCode} code The error code. - * @param {string=} opt_message Additional message. - * @constructor - * @extends {goog.debug.Error} - * @final - */ -goog.net.jsloader.Error = function(code, opt_message) { - var msg = 'Jsloader error (code #' + code + ')'; - if (opt_message) { - msg += ': ' + opt_message; - } - goog.net.jsloader.Error.base(this, 'constructor', msg); - - /** - * The code for this error. - * - * @type {goog.net.jsloader.ErrorCode} - */ - this.code = code; -}; -goog.inherits(goog.net.jsloader.Error, goog.debug.Error); - -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// The original file lives here: http://go/cross_domain_channel.js - -/** - * @fileoverview Implements a cross-domain communication channel. A - * typical web page is prevented by browser security from sending - * request, such as a XMLHttpRequest, to other servers than the ones - * from which it came. The Jsonp class provides a workaround by - * using dynamically generated script tags. Typical usage:. - * - * var jsonp = new goog.net.Jsonp(new goog.Uri('http://my.host.com/servlet')); - * var payload = { 'foo': 1, 'bar': true }; - * jsonp.send(payload, function(reply) { alert(reply) }); - * - * This script works in all browsers that are currently supported by - * the Google Maps API, which is IE 6.0+, Firefox 0.8+, Safari 1.2.4+, - * Netscape 7.1+, Mozilla 1.4+, Opera 8.02+. - * - */ - -goog.provide('goog.net.Jsonp'); - -goog.require('goog.Uri'); -goog.require('goog.net.jsloader'); - -// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING -// -// This class allows us (Google) to send data from non-Google and thus -// UNTRUSTED pages to our servers. Under NO CIRCUMSTANCES return -// anything sensitive, such as session or cookie specific data. Return -// only data that you want parties external to Google to have. Also -// NEVER use this method to send data from web pages to untrusted -// servers, or redirects to unknown servers (www.google.com/cache, -// /q=xx&btnl, /url, www.googlepages.com, etc.) -// -// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING - - - -/** - * Creates a new cross domain channel that sends data to the specified - * host URL. By default, if no reply arrives within 5s, the channel - * assumes the call failed to complete successfully. - * - * @param {goog.Uri|string} uri The Uri of the server side code that receives - * data posted through this channel (e.g., - * "http://maps.google.com/maps/geo"). - * - * @param {string=} opt_callbackParamName The parameter name that is used to - * specify the callback. Defaults to "callback". - * - * @constructor - * @final - */ -goog.net.Jsonp = function(uri, opt_callbackParamName) { - /** - * The uri_ object will be used to encode the payload that is sent to the - * server. - * @type {goog.Uri} - * @private - */ - this.uri_ = new goog.Uri(uri); - - /** - * This is the callback parameter name that is added to the uri. - * @type {string} - * @private - */ - this.callbackParamName_ = opt_callbackParamName ? - opt_callbackParamName : 'callback'; - - /** - * The length of time, in milliseconds, this channel is prepared - * to wait for for a request to complete. The default value is 5 seconds. - * @type {number} - * @private - */ - this.timeout_ = 5000; -}; - - -/** - * The name of the property of goog.global under which the callback is - * stored. - */ -goog.net.Jsonp.CALLBACKS = '_callbacks_'; - - -/** - * Used to generate unique callback IDs. The counter must be global because - * all channels share a common callback object. - * @private - */ -goog.net.Jsonp.scriptCounter_ = 0; - - -/** - * Sets the length of time, in milliseconds, this channel is prepared - * to wait for for a request to complete. If the call is not competed - * within the set time span, it is assumed to have failed. To wait - * indefinitely for a request to complete set the timout to a negative - * number. - * - * @param {number} timeout The length of time before calls are - * interrupted. - */ -goog.net.Jsonp.prototype.setRequestTimeout = function(timeout) { - this.timeout_ = timeout; -}; - - -/** - * Returns the current timeout value, in milliseconds. - * - * @return {number} The timeout value. - */ -goog.net.Jsonp.prototype.getRequestTimeout = function() { - return this.timeout_; -}; - - -/** - * Sends the given payload to the URL specified at the construction - * time. The reply is delivered to the given replyCallback. If the - * errorCallback is specified and the reply does not arrive within the - * timeout period set on this channel, the errorCallback is invoked - * with the original payload. - * - * If no reply callback is specified, then the response is expected to - * consist of calls to globally registered functions. No &callback= - * URL parameter will be sent in the request, and the script element - * will be cleaned up after the timeout. - * - * @param {Object=} opt_payload Name-value pairs. If given, these will be - * added as parameters to the supplied URI as GET parameters to the - * given server URI. - * - * @param {Function=} opt_replyCallback A function expecting one - * argument, called when the reply arrives, with the response data. - * - * @param {Function=} opt_errorCallback A function expecting one - * argument, called on timeout, with the payload (if given), otherwise - * null. - * - * @param {string=} opt_callbackParamValue Value to be used as the - * parameter value for the callback parameter (callbackParamName). - * To be used when the value needs to be fixed by the client for a - * particular request, to make use of the cached responses for the request. - * NOTE: If multiple requests are made with the same - * opt_callbackParamValue, only the last call will work whenever the - * response comes back. - * - * @return {!Object} A request descriptor that may be used to cancel this - * transmission, or null, if the message may not be cancelled. - */ -goog.net.Jsonp.prototype.send = function(opt_payload, - opt_replyCallback, - opt_errorCallback, - opt_callbackParamValue) { - - var payload = opt_payload || null; - - var id = opt_callbackParamValue || - '_' + (goog.net.Jsonp.scriptCounter_++).toString(36) + - goog.now().toString(36); - - if (!goog.global[goog.net.Jsonp.CALLBACKS]) { - goog.global[goog.net.Jsonp.CALLBACKS] = {}; - } - - // Create a new Uri object onto which this payload will be added - var uri = this.uri_.clone(); - if (payload) { - goog.net.Jsonp.addPayloadToUri_(payload, uri); - } - - if (opt_replyCallback) { - var reply = goog.net.Jsonp.newReplyHandler_(id, opt_replyCallback); - goog.global[goog.net.Jsonp.CALLBACKS][id] = reply; - - uri.setParameterValues(this.callbackParamName_, - goog.net.Jsonp.CALLBACKS + '.' + id); - } - - var deferred = goog.net.jsloader.load(uri.toString(), - {timeout: this.timeout_, cleanupWhenDone: true}); - var error = goog.net.Jsonp.newErrorHandler_(id, payload, opt_errorCallback); - deferred.addErrback(error); - - return {id_: id, deferred_: deferred}; -}; - - -/** - * Cancels a given request. The request must be exactly the object returned by - * the send method. - * - * @param {Object} request The request object returned by the send method. - */ -goog.net.Jsonp.prototype.cancel = function(request) { - if (request) { - if (request.deferred_) { - request.deferred_.cancel(); - } - if (request.id_) { - goog.net.Jsonp.cleanup_(request.id_, false); - } - } -}; - - -/** - * Creates a timeout callback that calls the given timeoutCallback with the - * original payload. - * - * @param {string} id The id of the script node. - * @param {Object} payload The payload that was sent to the server. - * @param {Function=} opt_errorCallback The function called on timeout. - * @return {!Function} A zero argument function that handles callback duties. - * @private - */ -goog.net.Jsonp.newErrorHandler_ = function(id, - payload, - opt_errorCallback) { - /** - * When we call across domains with a request, this function is the - * timeout handler. Once it's done executing the user-specified - * error-handler, it removes the script node and original function. - */ - return function() { - goog.net.Jsonp.cleanup_(id, false); - if (opt_errorCallback) { - opt_errorCallback(payload); - } - }; -}; - - -/** - * Creates a reply callback that calls the given replyCallback with data - * returned by the server. - * - * @param {string} id The id of the script node. - * @param {Function} replyCallback The function called on reply. - * @return {!Function} A reply callback function. - * @private - */ -goog.net.Jsonp.newReplyHandler_ = function(id, replyCallback) { - /** - * This function is the handler for the all-is-well response. It - * clears the error timeout handler, calls the user's handler, then - * removes the script node and itself. - * - * @param {...Object} var_args The response data sent from the server. - */ - var handler = function(var_args) { - goog.net.Jsonp.cleanup_(id, true); - replyCallback.apply(undefined, arguments); - }; - return handler; -}; - - -/** - * Removes the script node and reply handler with the given id. - * - * @param {string} id The id of the script node to be removed. - * @param {boolean} deleteReplyHandler If true, delete the reply handler - * instead of setting it to nullFunction (if we know the callback could - * never be called again). - * @private - */ -goog.net.Jsonp.cleanup_ = function(id, deleteReplyHandler) { - if (goog.global[goog.net.Jsonp.CALLBACKS][id]) { - if (deleteReplyHandler) { - delete goog.global[goog.net.Jsonp.CALLBACKS][id]; - } else { - // Removing the script tag doesn't necessarily prevent the script - // from firing, so we make the callback a noop. - goog.global[goog.net.Jsonp.CALLBACKS][id] = goog.nullFunction; - } - } -}; - - -/** - * Returns URL encoded payload. The payload should be a map of name-value - * pairs, in the form {"foo": 1, "bar": true, ...}. If the map is empty, - * the URI will be unchanged. - * - * <p>The method uses hasOwnProperty() to assure the properties are on the - * object, not on its prototype. - * - * @param {!Object} payload A map of value name pairs to be encoded. - * A value may be specified as an array, in which case a query parameter - * will be created for each value, e.g.: - * {"foo": [1,2]} will encode to "foo=1&foo=2". - * - * @param {!goog.Uri} uri A Uri object onto which the payload key value pairs - * will be encoded. - * - * @return {!goog.Uri} A reference to the Uri sent as a parameter. - * @private - */ -goog.net.Jsonp.addPayloadToUri_ = function(payload, uri) { - for (var name in payload) { - // NOTE(user): Safari/1.3 doesn't have hasOwnProperty(). In that - // case, we iterate over all properties as a very lame workaround. - if (!payload.hasOwnProperty || payload.hasOwnProperty(name)) { - uri.setParameterValues(name, payload[name]); - } - } - return uri; -}; - - -// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING -// -// This class allows us (Google) to send data from non-Google and thus -// UNTRUSTED pages to our servers. Under NO CIRCUMSTANCES return -// anything sensitive, such as session or cookie specific data. Return -// only data that you want parties external to Google to have. Also -// NEVER use this method to send data from web pages to untrusted -// servers, or redirects to unknown servers (www.google.com/cache, -// /q=xx&btnl, /url, www.googlepages.com, etc.) -// -// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING - goog.provide('ol.source.TileImage'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.object'); goog.require('ol.ImageTile'); goog.require('ol.TileCache'); goog.require('ol.TileState'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol.proj'); goog.require('ol.reproj.Tile'); goog.require('ol.source.UrlTile'); - /** * @classdesc * Base class for sources providing images divided into a tile grid. @@ -115537,12 +99200,12 @@ ol.source.TileImage = function(options) { goog.base(this, { attributions: options.attributions, + cacheSize: options.cacheSize, extent: options.extent, logo: options.logo, opaque: options.opaque, projection: options.projection, - state: options.state !== undefined ? - /** @type {ol.source.State} */ (options.state) : undefined, + state: options.state, tileGrid: options.tileGrid, tileLoadFunction: options.tileLoadFunction ? options.tileLoadFunction : ol.source.TileImage.defaultTileLoadFunction, @@ -115602,14 +99265,16 @@ ol.source.TileImage.prototype.canExpireCache = function() { if (!ol.ENABLE_RASTER_REPROJECTION) { return goog.base(this, 'canExpireCache'); } - var canExpire = this.tileCache.canExpireCache(); - if (canExpire) { + if (this.tileCache.canExpireCache()) { return true; } else { - return goog.object.some(this.tileCacheForProjection, function(tileCache) { - return tileCache.canExpireCache(); - }); + for (var key in this.tileCacheForProjection) { + if (this.tileCacheForProjection[key].canExpireCache()) { + return true; + } + } } + return false; }; @@ -115624,9 +99289,47 @@ ol.source.TileImage.prototype.expireCache = function(projection, usedTiles) { var usedTileCache = this.getTileCacheForProjection(projection); this.tileCache.expireCache(this.tileCache == usedTileCache ? usedTiles : {}); - goog.object.forEach(this.tileCacheForProjection, function(tileCache) { + for (var id in this.tileCacheForProjection) { + var tileCache = this.tileCacheForProjection[id]; tileCache.expireCache(tileCache == usedTileCache ? usedTiles : {}); - }); + } +}; + + +/** + * @inheritDoc + */ +ol.source.TileImage.prototype.getGutter = function(projection) { + if (ol.ENABLE_RASTER_REPROJECTION && + this.getProjection() && projection && + !ol.proj.equivalent(this.getProjection(), projection)) { + return 0; + } else { + return this.getGutterInternal(); + } +}; + + +/** + * @protected + * @return {number} Gutter. + */ +ol.source.TileImage.prototype.getGutterInternal = function() { + return 0; +}; + + +/** + * @inheritDoc + */ +ol.source.TileImage.prototype.getOpaque = function(projection) { + if (ol.ENABLE_RASTER_REPROJECTION && + this.getProjection() && projection && + !ol.proj.equivalent(this.getProjection(), projection)) { + return false; + } else { + return goog.base(this, 'getOpaque', projection); + } }; @@ -115682,8 +99385,7 @@ ol.source.TileImage.prototype.getTileCacheForProjection = function(projection) { * @return {ol.Tile} Tile. * @private */ -ol.source.TileImage.prototype.createTile_ = - function(z, x, y, pixelRatio, projection, key) { +ol.source.TileImage.prototype.createTile_ = function(z, x, y, pixelRatio, projection, key) { var tileCoord = [z, x, y]; var urlTileCoord = this.getTileCoordForTileUrlFunction( tileCoord, projection); @@ -115696,8 +99398,8 @@ ol.source.TileImage.prototype.createTile_ = this.crossOrigin, this.tileLoadFunction); tile.key = key; - goog.events.listen(tile, goog.events.EventType.CHANGE, - this.handleTileChange, false, this); + ol.events.listen(tile, ol.events.EventType.CHANGE, + this.handleTileChange, this); return tile; }; @@ -115705,8 +99407,7 @@ ol.source.TileImage.prototype.createTile_ = /** * @inheritDoc */ -ol.source.TileImage.prototype.getTile = - function(z, x, y, pixelRatio, projection) { +ol.source.TileImage.prototype.getTile = function(z, x, y, pixelRatio, projection) { if (!ol.ENABLE_RASTER_REPROJECTION || !this.getProjection() || !projection || @@ -115727,10 +99428,11 @@ ol.source.TileImage.prototype.getTile = var tile = new ol.reproj.Tile( sourceProjection, sourceTileGrid, projection, targetTileGrid, - tileCoord, wrappedTileCoord, this.getTilePixelRatio(), - goog.bind(function(z, x, y, pixelRatio) { + tileCoord, wrappedTileCoord, this.getTilePixelRatio(pixelRatio), + this.getGutterInternal(), + function(z, x, y, pixelRatio) { return this.getTileInternal(z, x, y, pixelRatio, sourceProjection); - }, this), this.reprojectionErrorThreshold_, + }.bind(this), this.reprojectionErrorThreshold_, this.renderReprojectionEdges_); cache.set(tileCoordKey, tile); @@ -115749,23 +99451,22 @@ ol.source.TileImage.prototype.getTile = * @return {!ol.Tile} Tile. * @protected */ -ol.source.TileImage.prototype.getTileInternal = - function(z, x, y, pixelRatio, projection) { +ol.source.TileImage.prototype.getTileInternal = function(z, x, y, pixelRatio, projection) { var /** @type {ol.Tile} */ tile = null; var tileCoordKey = this.getKeyZXY(z, x, y); - var paramsKey = this.getKeyParams(); + var key = this.getKey(); if (!this.tileCache.containsKey(tileCoordKey)) { goog.asserts.assert(projection, 'argument projection is truthy'); - tile = this.createTile_(z, x, y, pixelRatio, projection, paramsKey); + tile = this.createTile_(z, x, y, pixelRatio, projection, key); this.tileCache.set(tileCoordKey, tile); } else { tile = /** @type {!ol.Tile} */ (this.tileCache.get(tileCoordKey)); - if (tile.key != paramsKey) { + if (tile.key != key) { // The source's params changed. If the tile has an interim tile and if we // can use it then we use it. Otherwise we create a new tile. In both // cases we attempt to assign an interim tile to the new tile. var /** @type {ol.Tile} */ interimTile = tile; - if (tile.interimTile && tile.interimTile.key == paramsKey) { + if (tile.interimTile && tile.interimTile.key == key) { goog.asserts.assert(tile.interimTile.getState() == ol.TileState.LOADED); goog.asserts.assert(tile.interimTile.interimTile === null); tile = tile.interimTile; @@ -115773,7 +99474,7 @@ ol.source.TileImage.prototype.getTileInternal = tile.interimTile = interimTile; } } else { - tile = this.createTile_(z, x, y, pixelRatio, projection, paramsKey); + tile = this.createTile_(z, x, y, pixelRatio, projection, key); if (interimTile.getState() == ol.TileState.LOADED) { tile.interimTile = interimTile; } else if (interimTile.interimTile && @@ -115804,9 +99505,9 @@ ol.source.TileImage.prototype.setRenderReprojectionEdges = function(render) { return; } this.renderReprojectionEdges_ = render; - goog.object.forEach(this.tileCacheForProjection, function(tileCache) { - tileCache.clear(); - }); + for (var id in this.tileCacheForProjection) { + this.tileCacheForProjection[id].clear(); + } this.changed(); }; @@ -115823,8 +99524,7 @@ ol.source.TileImage.prototype.setRenderReprojectionEdges = function(render) { * @param {ol.tilegrid.TileGrid} tilegrid Tile grid to use for the projection. * @api */ -ol.source.TileImage.prototype.setTileGridForProjection = - function(projection, tilegrid) { +ol.source.TileImage.prototype.setTileGridForProjection = function(projection, tilegrid) { if (ol.ENABLE_RASTER_REPROJECTION) { var proj = ol.proj.get(projection); if (proj) { @@ -115847,20 +99547,18 @@ ol.source.TileImage.defaultTileLoadFunction = function(imageTile, src) { goog.provide('ol.source.BingMaps'); -goog.require('goog.Uri'); goog.require('goog.asserts'); -goog.require('goog.net.Jsonp'); goog.require('ol.Attribution'); goog.require('ol.TileRange'); goog.require('ol.TileUrlFunction'); goog.require('ol.extent'); +goog.require('ol.net'); goog.require('ol.proj'); goog.require('ol.source.State'); goog.require('ol.source.TileImage'); goog.require('ol.tilecoord'); - /** * @classdesc * Layer source for Bing Maps tile data. @@ -115873,6 +99571,7 @@ goog.require('ol.tilecoord'); ol.source.BingMaps = function(options) { goog.base(this, { + cacheSize: options.cacheSize, crossOrigin: 'anonymous', opaque: true, projection: ol.proj.get('EPSG:3857'), @@ -115894,16 +99593,12 @@ ol.source.BingMaps = function(options) { */ this.maxZoom_ = options.maxZoom !== undefined ? options.maxZoom : -1; - var uri = new goog.Uri( - 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/' + - options.imagerySet); + var url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/' + + options.imagerySet + + '?uriScheme=https&include=ImageryProviders&key=' + options.key; - var jsonp = new goog.net.Jsonp(uri, 'jsonp'); - jsonp.send({ - 'include': 'ImageryProviders', - 'uriScheme': 'https', - 'key': options.key - }, goog.bind(this.handleImageryMetadataResponse, this)); + ol.net.jsonp(url, this.handleImageryMetadataResponse.bind(this), undefined, + 'jsonp'); }; goog.inherits(ol.source.BingMaps, ol.source.TileImage); @@ -115926,8 +99621,7 @@ ol.source.BingMaps.TOS_ATTRIBUTION = new ol.Attribution({ /** * @param {BingMapsImageryMetadataResponse} response Response. */ -ol.source.BingMaps.prototype.handleImageryMetadataResponse = - function(response) { +ol.source.BingMaps.prototype.handleImageryMetadataResponse = function(response) { if (response.statusCode != 200 || response.statusDescription != 'OK' || @@ -116026,28 +99720,252 @@ ol.source.BingMaps.prototype.handleImageryMetadataResponse = }; +goog.provide('ol.source.XYZ'); + +goog.require('ol.source.TileImage'); + + +/** + * @classdesc + * Layer source for tile data with URLs in a set XYZ format that are + * defined in a URL template. By default, this follows the widely-used + * Google grid where `x` 0 and `y` 0 are in the top left. Grids like + * TMS where `x` 0 and `y` 0 are in the bottom left can be used by + * using the `{-y}` placeholder in the URL template, so long as the + * source does not have a custom tile grid. In this case, + * {@link ol.source.TileImage} can be used with a `tileUrlFunction` + * such as: + * + * tileUrlFunction: function(coordinate) { + * return 'http://mapserver.com/' + coordinate[0] + '/' + + * coordinate[1] + '/' + coordinate[2] + '.png'; + * } + * + * + * @constructor + * @extends {ol.source.TileImage} + * @param {olx.source.XYZOptions=} opt_options XYZ options. + * @api stable + */ +ol.source.XYZ = function(opt_options) { + var options = opt_options || {}; + var projection = options.projection !== undefined ? + options.projection : 'EPSG:3857'; + + var tileGrid = options.tileGrid !== undefined ? options.tileGrid : + ol.tilegrid.createXYZ({ + extent: ol.tilegrid.extentFromProjection(projection), + maxZoom: options.maxZoom, + minZoom: options.minZoom, + tileSize: options.tileSize + }); + + goog.base(this, { + attributions: options.attributions, + cacheSize: options.cacheSize, + crossOrigin: options.crossOrigin, + logo: options.logo, + opaque: options.opaque, + projection: projection, + reprojectionErrorThreshold: options.reprojectionErrorThreshold, + tileGrid: tileGrid, + tileLoadFunction: options.tileLoadFunction, + tilePixelRatio: options.tilePixelRatio, + tileUrlFunction: options.tileUrlFunction, + url: options.url, + urls: options.urls, + wrapX: options.wrapX !== undefined ? options.wrapX : true + }); + +}; +goog.inherits(ol.source.XYZ, ol.source.TileImage); + +goog.provide('ol.source.CartoDB'); + +goog.require('ol.object'); +goog.require('ol.source.State'); +goog.require('ol.source.XYZ'); + + +/** + * @classdesc + * Layer source for the CartoDB tiles. + * + * @constructor + * @extends {ol.source.XYZ} + * @param {olx.source.CartoDBOptions} options CartoDB options. + * @api + */ +ol.source.CartoDB = function(options) { + + /** + * @type {string} + * @private + */ + this.account_ = options.account; + + /** + * @type {string} + * @private + */ + this.mapId_ = options.map || ''; + + /** + * @type {!Object} + * @private + */ + this.config_ = options.config || {}; + + /** + * @type {!Object.<string, CartoDBLayerInfo>} + * @private + */ + this.templateCache_ = {}; + + goog.base(this, { + attributions: options.attributions, + cacheSize: options.cacheSize, + crossOrigin: options.crossOrigin, + logo: options.logo, + maxZoom: options.maxZoom !== undefined ? options.maxZoom : 18, + minZoom: options.minZoom, + projection: options.projection, + state: ol.source.State.LOADING, + wrapX: options.wrapX + }); + this.initializeMap_(); +}; +goog.inherits(ol.source.CartoDB, ol.source.XYZ); + + +/** + * Returns the current config. + * @return {!Object} The current configuration. + * @api + */ +ol.source.CartoDB.prototype.getConfig = function() { + return this.config_; +}; + + +/** + * Updates the carto db config. + * @param {Object} config a key-value lookup. Values will replace current values + * in the config. + * @api + */ +ol.source.CartoDB.prototype.updateConfig = function(config) { + ol.object.assign(this.config_, config); + this.initializeMap_(); +}; + + +/** + * Sets the CartoDB config + * @param {Object} config In the case of anonymous maps, a CartoDB configuration + * object. + * If using named maps, a key-value lookup with the template parameters. + * @api + */ +ol.source.CartoDB.prototype.setConfig = function(config) { + this.config_ = config || {}; + this.initializeMap_(); +}; + + +/** + * Issue a request to initialize the CartoDB map. + * @private + */ +ol.source.CartoDB.prototype.initializeMap_ = function() { + var paramHash = JSON.stringify(this.config_); + if (this.templateCache_[paramHash]) { + this.applyTemplate_(this.templateCache_[paramHash]); + return; + } + var mapUrl = 'https://' + this.account_ + '.cartodb.com/api/v1/map'; + + if (this.mapId_) { + mapUrl += '/named/' + this.mapId_; + } + + var client = new XMLHttpRequest(); + client.addEventListener('load', this.handleInitResponse_.bind(this, paramHash)); + client.addEventListener('error', this.handleInitError_.bind(this)); + client.open('POST', mapUrl); + client.setRequestHeader('Content-type', 'application/json'); + client.send(JSON.stringify(this.config_)); +}; + + +/** + * Handle map initialization response. + * @param {string} paramHash a hash representing the parameter set that was used + * for the request + * @param {Event} event Event. + * @private + */ +ol.source.CartoDB.prototype.handleInitResponse_ = function(paramHash, event) { + var client = /** @type {XMLHttpRequest} */ (event.target); + if (client.status >= 200 && client.status < 300) { + var response; + try { + response = /** @type {CartoDBLayerInfo} */(JSON.parse(client.responseText)); + } catch (err) { + this.setState(ol.source.State.ERROR); + return; + } + this.applyTemplate_(response); + this.templateCache_[paramHash] = response; + this.setState(ol.source.State.READY); + } else { + this.setState(ol.source.State.ERROR); + } +}; + + +/** + * @private + * @param {Event} event Event. + */ +ol.source.CartoDB.prototype.handleInitError_ = function(event) { + this.setState(ol.source.State.ERROR); +} + + +/** + * Apply the new tile urls returned by carto db + * @param {CartoDBLayerInfo} data Result of carto db call. + * @private + */ +ol.source.CartoDB.prototype.applyTemplate_ = function(data) { + var tilesUrl = 'https://' + data.cdn_url.https + '/' + this.account_ + + '/api/v1/map/' + data.layergroupid + '/{z}/{x}/{y}.png'; + this.setUrl(tilesUrl); +}; + // FIXME keep cluster cache by resolution ? // FIXME distance not respected because of the centroid goog.provide('ol.source.Cluster'); goog.require('goog.asserts'); -goog.require('goog.events.EventType'); -goog.require('goog.object'); goog.require('ol.Feature'); goog.require('ol.coordinate'); +goog.require('ol.events.EventType'); goog.require('ol.extent'); goog.require('ol.geom.Point'); goog.require('ol.source.Vector'); - /** * @classdesc - * Layer source to cluster vector data. + * Layer source to cluster vector data. Works out of the box with point + * geometries. For other geometry types, or if not all geometries should be + * considered for clustering, a custom `geometryFunction` can be defined. * * @constructor - * @param {olx.source.ClusterOptions} options + * @param {olx.source.ClusterOptions} options Constructor options. * @extends {ol.source.Vector} * @api */ @@ -116079,12 +99997,23 @@ ol.source.Cluster = function(options) { this.features_ = []; /** + * @param {ol.Feature} feature Feature. + * @return {ol.geom.Point} Cluster calculation point. + */ + this.geometryFunction_ = options.geometryFunction || function(feature) { + var geometry = feature.getGeometry(); + goog.asserts.assert(geometry instanceof ol.geom.Point, + 'feature geometry is a ol.geom.Point instance'); + return geometry; + }; + + /** * @type {ol.source.Vector} * @private */ this.source_ = options.source; - this.source_.on(goog.events.EventType.CHANGE, + this.source_.on(ol.events.EventType.CHANGE, ol.source.Cluster.prototype.onSourceChange_, this); }; goog.inherits(ol.source.Cluster, ol.source.Vector); @@ -116140,74 +100069,340 @@ ol.source.Cluster.prototype.cluster_ = function() { var features = this.source_.getFeatures(); /** - * @type {Object.<string, boolean>} + * @type {!Object.<string, boolean>} */ var clustered = {}; for (var i = 0, ii = features.length; i < ii; i++) { var feature = features[i]; if (!(goog.getUid(feature).toString() in clustered)) { - var geometry = feature.getGeometry(); - goog.asserts.assert(geometry instanceof ol.geom.Point, - 'feature geometry is a ol.geom.Point instance'); - var coordinates = geometry.getCoordinates(); - ol.extent.createOrUpdateFromCoordinate(coordinates, extent); - ol.extent.buffer(extent, mapDistance, extent); - - var neighbors = this.source_.getFeaturesInExtent(extent); - goog.asserts.assert(neighbors.length >= 1, 'at least one neighbor found'); - neighbors = neighbors.filter(function(neighbor) { - var uid = goog.getUid(neighbor).toString(); - if (!(uid in clustered)) { - clustered[uid] = true; - return true; - } else { - return false; - } - }); - this.features_.push(this.createCluster_(neighbors)); + var geometry = this.geometryFunction_(feature); + if (geometry) { + var coordinates = geometry.getCoordinates(); + ol.extent.createOrUpdateFromCoordinate(coordinates, extent); + ol.extent.buffer(extent, mapDistance, extent); + + var neighbors = this.source_.getFeaturesInExtent(extent); + goog.asserts.assert(neighbors.length >= 1, 'at least one neighbor found'); + neighbors = neighbors.filter(function(neighbor) { + var uid = goog.getUid(neighbor).toString(); + if (!(uid in clustered)) { + clustered[uid] = true; + return true; + } else { + return false; + } + }); + this.features_.push(this.createCluster_(neighbors)); + } } } goog.asserts.assert( - goog.object.getCount(clustered) == this.source_.getFeatures().length, + Object.keys(clustered).length == this.source_.getFeatures().length, 'number of clustered equals number of features in the source'); }; /** * @param {Array.<ol.Feature>} features Features - * @return {ol.Feature} + * @return {ol.Feature} The cluster feature. * @private */ ol.source.Cluster.prototype.createCluster_ = function(features) { - var length = features.length; var centroid = [0, 0]; - for (var i = 0; i < length; i++) { - var geometry = features[i].getGeometry(); - goog.asserts.assert(geometry instanceof ol.geom.Point, - 'feature geometry is a ol.geom.Point instance'); - var coordinates = geometry.getCoordinates(); - ol.coordinate.add(centroid, coordinates); + for (var i = features.length - 1; i >= 0; --i) { + var geometry = this.geometryFunction_(features[i]); + if (geometry) { + ol.coordinate.add(centroid, geometry.getCoordinates()); + } else { + features.splice(i, 1); + } } - ol.coordinate.scale(centroid, 1 / length); + ol.coordinate.scale(centroid, 1 / features.length); var cluster = new ol.Feature(new ol.geom.Point(centroid)); cluster.set('features', features); return cluster; }; -goog.provide('ol.source.ImageMapGuide'); +goog.provide('ol.source.ImageArcGISRest'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.object'); +goog.require('goog.asserts'); goog.require('goog.uri.utils'); +goog.require('ol'); goog.require('ol.Image'); -goog.require('ol.ImageLoadFunctionType'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol.extent'); +goog.require('ol.object'); +goog.require('ol.proj'); goog.require('ol.source.Image'); +/** + * @classdesc + * Source for data from ArcGIS Rest services providing single, untiled images. + * Useful when underlying map service has labels. + * + * If underlying map service is not using labels, + * take advantage of ol image caching and use + * {@link ol.source.TileArcGISRest} data source. + * + * @constructor + * @fires ol.source.ImageEvent + * @extends {ol.source.Image} + * @param {olx.source.ImageArcGISRestOptions=} opt_options Image ArcGIS Rest Options. + * @api + */ +ol.source.ImageArcGISRest = function(opt_options) { + + var options = opt_options || {}; + + goog.base(this, { + attributions: options.attributions, + logo: options.logo, + projection: options.projection, + resolutions: options.resolutions + }); + + /** + * @private + * @type {?string} + */ + this.crossOrigin_ = + options.crossOrigin !== undefined ? options.crossOrigin : null; + + /** + * @private + * @type {string|undefined} + */ + this.url_ = options.url; + + /** + * @private + * @type {ol.ImageLoadFunctionType} + */ + this.imageLoadFunction_ = options.imageLoadFunction !== undefined ? + options.imageLoadFunction : ol.source.Image.defaultImageLoadFunction; + + + /** + * @private + * @type {!Object} + */ + this.params_ = options.params || {}; + + /** + * @private + * @type {ol.Image} + */ + this.image_ = null; + + /** + * @private + * @type {ol.Size} + */ + this.imageSize_ = [0, 0]; + + + /** + * @private + * @type {number} + */ + this.renderedRevision_ = 0; + + /** + * @private + * @type {number} + */ + this.ratio_ = options.ratio !== undefined ? options.ratio : 1.5; + +}; +goog.inherits(ol.source.ImageArcGISRest, ol.source.Image); + + +/** + * Get the user-provided params, i.e. those passed to the constructor through + * the "params" option, and possibly updated using the updateParams method. + * @return {Object} Params. + * @api stable + */ +ol.source.ImageArcGISRest.prototype.getParams = function() { + return this.params_; +}; + + +/** + * @inheritDoc + */ +ol.source.ImageArcGISRest.prototype.getImageInternal = function(extent, resolution, pixelRatio, projection) { + + if (this.url_ === undefined) { + return null; + } + + resolution = this.findNearestResolution(resolution); + + var image = this.image_; + if (image && + this.renderedRevision_ == this.getRevision() && + image.getResolution() == resolution && + image.getPixelRatio() == pixelRatio && + ol.extent.containsExtent(image.getExtent(), extent)) { + return image; + } + + var params = { + 'F': 'image', + 'FORMAT': 'PNG32', + 'TRANSPARENT': true + }; + ol.object.assign(params, this.params_); + + extent = extent.slice(); + var centerX = (extent[0] + extent[2]) / 2; + var centerY = (extent[1] + extent[3]) / 2; + if (this.ratio_ != 1) { + var halfWidth = this.ratio_ * ol.extent.getWidth(extent) / 2; + var halfHeight = this.ratio_ * ol.extent.getHeight(extent) / 2; + extent[0] = centerX - halfWidth; + extent[1] = centerY - halfHeight; + extent[2] = centerX + halfWidth; + extent[3] = centerY + halfHeight; + } + + var imageResolution = resolution / pixelRatio; + + // Compute an integer width and height. + var width = Math.ceil(ol.extent.getWidth(extent) / imageResolution); + var height = Math.ceil(ol.extent.getHeight(extent) / imageResolution); + + // Modify the extent to match the integer width and height. + extent[0] = centerX - imageResolution * width / 2; + extent[2] = centerX + imageResolution * width / 2; + extent[1] = centerY - imageResolution * height / 2; + extent[3] = centerY + imageResolution * height / 2; + + this.imageSize_[0] = width; + this.imageSize_[1] = height; + + var url = this.getRequestUrl_(extent, this.imageSize_, pixelRatio, + projection, params); + + this.image_ = new ol.Image(extent, resolution, pixelRatio, + this.getAttributions(), url, this.crossOrigin_, this.imageLoadFunction_); + + this.renderedRevision_ = this.getRevision(); + + ol.events.listen(this.image_, ol.events.EventType.CHANGE, + this.handleImageChange, this); + + return this.image_; + +}; + + +/** + * Return the image load function of the source. + * @return {ol.ImageLoadFunctionType} The image load function. + * @api + */ +ol.source.ImageArcGISRest.prototype.getImageLoadFunction = function() { + return this.imageLoadFunction_; +}; + + +/** + * @param {ol.Extent} extent Extent. + * @param {ol.Size} size Size. + * @param {number} pixelRatio Pixel ratio. + * @param {ol.proj.Projection} projection Projection. + * @param {Object} params Params. + * @return {string} Request URL. + * @private + */ +ol.source.ImageArcGISRest.prototype.getRequestUrl_ = function(extent, size, pixelRatio, projection, params) { + + goog.asserts.assert(this.url_ !== undefined, 'url is defined'); + + // ArcGIS Server only wants the numeric portion of the projection ID. + var srid = projection.getCode().split(':').pop(); + + params['SIZE'] = size[0] + ',' + size[1]; + params['BBOX'] = extent.join(','); + params['BBOXSR'] = srid; + params['IMAGESR'] = srid; + params['DPI'] = 90 * pixelRatio; + + var url = this.url_; + + var modifiedUrl = url + .replace(/MapServer\/?$/, 'MapServer/export') + .replace(/ImageServer\/?$/, 'ImageServer/exportImage'); + if (modifiedUrl == url) { + goog.asserts.fail('Unknown Rest Service', url); + } + return goog.uri.utils.appendParamsFromMap(modifiedUrl, params); +}; + + +/** + * Return the URL used for this ArcGIS source. + * @return {string|undefined} URL. + * @api stable + */ +ol.source.ImageArcGISRest.prototype.getUrl = function() { + return this.url_; +}; + + +/** + * Set the image load function of the source. + * @param {ol.ImageLoadFunctionType} imageLoadFunction Image load function. + * @api + */ +ol.source.ImageArcGISRest.prototype.setImageLoadFunction = function(imageLoadFunction) { + this.image_ = null; + this.imageLoadFunction_ = imageLoadFunction; + this.changed(); +}; + + +/** + * Set the URL to use for requests. + * @param {string|undefined} url URL. + * @api stable + */ +ol.source.ImageArcGISRest.prototype.setUrl = function(url) { + if (url != this.url_) { + this.url_ = url; + this.image_ = null; + this.changed(); + } +}; + + +/** + * Update the user-provided params. + * @param {Object} params Params. + * @api stable + */ +ol.source.ImageArcGISRest.prototype.updateParams = function(params) { + ol.object.assign(this.params_, params); + this.image_ = null; + this.changed(); +}; + +goog.provide('ol.source.ImageMapGuide'); + +goog.require('ol.events'); +goog.require('ol.events.EventType'); +goog.require('goog.uri.utils'); +goog.require('ol.Image'); +goog.require('ol.extent'); +goog.require('ol.object'); +goog.require('ol.source.Image'); + /** * @classdesc @@ -116242,9 +100437,9 @@ ol.source.ImageMapGuide = function(options) { /** * @private - * @type {Object} + * @type {!Object} */ - this.params_ = options.params !== undefined ? options.params : {}; + this.params_ = options.params || {}; /** * @private @@ -116315,8 +100510,7 @@ ol.source.ImageMapGuide.prototype.getParams = function() { /** * @inheritDoc */ -ol.source.ImageMapGuide.prototype.getImageInternal = - function(extent, resolution, pixelRatio, projection) { +ol.source.ImageMapGuide.prototype.getImageInternal = function(extent, resolution, pixelRatio, projection) { resolution = this.findNearestResolution(resolution); pixelRatio = this.hidpi_ ? pixelRatio : 1; @@ -116343,8 +100537,8 @@ ol.source.ImageMapGuide.prototype.getImageInternal = image = new ol.Image(extent, resolution, pixelRatio, this.getAttributions(), imageUrl, this.crossOrigin_, this.imageLoadFunction_); - goog.events.listen(image, goog.events.EventType.CHANGE, - this.handleImageChange, false, this); + ol.events.listen(image, ol.events.EventType.CHANGE, + this.handleImageChange, this); } else { image = null; } @@ -116392,7 +100586,7 @@ ol.source.ImageMapGuide.getScale = function(extent, size, metersPerUnit, dpi) { * @api stable */ ol.source.ImageMapGuide.prototype.updateParams = function(params) { - goog.object.extend(this.params_, params); + ol.object.assign(this.params_, params); this.changed(); }; @@ -116405,8 +100599,7 @@ ol.source.ImageMapGuide.prototype.updateParams = function(params) { * @param {ol.proj.Projection} projection Projection. * @return {string} The mapagent map image request URL. */ -ol.source.ImageMapGuide.prototype.getUrl = - function(baseUrl, params, extent, size, projection) { +ol.source.ImageMapGuide.prototype.getUrl = function(baseUrl, params, extent, size, projection) { var scale = ol.source.ImageMapGuide.getScale(extent, size, this.metersPerUnit_, this.displayDpi_); var center = ol.extent.getCenter(extent); @@ -116423,7 +100616,7 @@ ol.source.ImageMapGuide.prototype.getUrl = 'SETVIEWCENTERX': center[0], 'SETVIEWCENTERY': center[1] }; - goog.object.extend(baseParams, params); + ol.object.assign(baseParams, params); return goog.uri.utils.appendParamsFromMap(baseUrl, baseParams); }; @@ -116442,17 +100635,16 @@ ol.source.ImageMapGuide.prototype.setImageLoadFunction = function( goog.provide('ol.source.ImageStatic'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol.Image'); -goog.require('ol.ImageLoadFunctionType'); goog.require('ol.ImageState'); +goog.require('ol.dom'); goog.require('ol.extent'); goog.require('ol.proj'); goog.require('ol.source.Image'); - /** * @classdesc * A layer source for displaying a single, static image. @@ -116463,10 +100655,6 @@ goog.require('ol.source.Image'); * @api stable */ ol.source.ImageStatic = function(options) { - - var attributions = options.attributions !== undefined ? - options.attributions : null; - var imageExtent = options.imageExtent; var crossOrigin = options.crossOrigin !== undefined ? @@ -116477,7 +100665,7 @@ ol.source.ImageStatic = function(options) { options.imageLoadFunction : ol.source.Image.defaultImageLoadFunction; goog.base(this, { - attributions: attributions, + attributions: options.attributions, logo: options.logo, projection: ol.proj.get(options.projection) }); @@ -116486,7 +100674,7 @@ ol.source.ImageStatic = function(options) { * @private * @type {ol.Image} */ - this.image_ = new ol.Image(imageExtent, undefined, 1, attributions, + this.image_ = new ol.Image(imageExtent, undefined, 1, this.getAttributions(), options.url, crossOrigin, imageLoadFunction); /** @@ -116495,8 +100683,8 @@ ol.source.ImageStatic = function(options) { */ this.imageSize_ = options.imageSize ? options.imageSize : null; - goog.events.listen(this.image_, goog.events.EventType.CHANGE, - this.handleImageChange, false, this); + ol.events.listen(this.image_, ol.events.EventType.CHANGE, + this.handleImageChange, this); }; goog.inherits(ol.source.ImageStatic, ol.source.Image); @@ -116505,8 +100693,7 @@ goog.inherits(ol.source.ImageStatic, ol.source.Image); /** * @inheritDoc */ -ol.source.ImageStatic.prototype.getImageInternal = - function(extent, resolution, pixelRatio, projection) { +ol.source.ImageStatic.prototype.getImageInternal = function(extent, resolution, pixelRatio, projection) { if (ol.extent.intersects(extent, this.image_.getExtent())) { return this.image_; } @@ -116526,17 +100713,16 @@ ol.source.ImageStatic.prototype.handleImageChange = function(evt) { imageWidth = this.imageSize_[0]; imageHeight = this.imageSize_[1]; } else { - imageWidth = image.width; - imageHeight = image.height; + // TODO: remove the type cast when a closure-compiler > 20160315 is used. + // see: https://github.com/google/closure-compiler/pull/1664 + imageWidth = /** @type {number} */ (image.width); + imageHeight = /** @type {number} */ (image.height); } var resolution = ol.extent.getHeight(imageExtent) / imageHeight; var targetWidth = Math.ceil(ol.extent.getWidth(imageExtent) / resolution); if (targetWidth != imageWidth) { - var canvas = /** @type {HTMLCanvasElement} */ - (document.createElement('canvas')); - canvas.width = targetWidth; - canvas.height = /** @type {number} */ (imageHeight); - var context = canvas.getContext('2d'); + var context = ol.dom.createCanvasContext2D(targetWidth, imageHeight); + var canvas = context.canvas; context.drawImage(image, 0, 0, imageWidth, imageHeight, 0, 0, canvas.width, canvas.height); this.image_.setImage(canvas); @@ -116568,20 +100754,18 @@ ol.source.wms.ServerType = { goog.provide('ol.source.ImageWMS'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.object'); -goog.require('goog.string'); goog.require('goog.uri.utils'); goog.require('ol'); goog.require('ol.Image'); -goog.require('ol.ImageLoadFunctionType'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol.extent'); +goog.require('ol.object'); goog.require('ol.proj'); goog.require('ol.source.Image'); goog.require('ol.source.wms'); goog.require('ol.source.wms.ServerType'); - +goog.require('ol.string'); /** @@ -116627,9 +100811,9 @@ ol.source.ImageWMS = function(opt_options) { /** * @private - * @type {Object} + * @type {!Object} */ - this.params_ = options.params; + this.params_ = options.params || {}; /** * @private @@ -116701,8 +100885,7 @@ ol.source.ImageWMS.GETFEATUREINFO_IMAGE_SIZE_ = [101, 101]; * @return {string|undefined} GetFeatureInfo URL. * @api stable */ -ol.source.ImageWMS.prototype.getGetFeatureInfoUrl = - function(coordinate, resolution, projection, params) { +ol.source.ImageWMS.prototype.getGetFeatureInfoUrl = function(coordinate, resolution, projection, params) { goog.asserts.assert(!('VERSION' in params), 'key VERSION is not allowed in params'); @@ -116723,7 +100906,7 @@ ol.source.ImageWMS.prototype.getGetFeatureInfoUrl = 'TRANSPARENT': true, 'QUERY_LAYERS': this.params_['LAYERS'] }; - goog.object.extend(baseParams, this.params_, params); + ol.object.assign(baseParams, this.params_, params); var x = Math.floor((coordinate[0] - extent[0]) / resolution); var y = Math.floor((extent[3] - coordinate[1]) / resolution); @@ -116750,8 +100933,7 @@ ol.source.ImageWMS.prototype.getParams = function() { /** * @inheritDoc */ -ol.source.ImageWMS.prototype.getImageInternal = - function(extent, resolution, pixelRatio, projection) { +ol.source.ImageWMS.prototype.getImageInternal = function(extent, resolution, pixelRatio, projection) { if (this.url_ === undefined) { return null; @@ -116796,7 +100978,7 @@ ol.source.ImageWMS.prototype.getImageInternal = 'FORMAT': 'image/png', 'TRANSPARENT': true }; - goog.object.extend(params, this.params_); + ol.object.assign(params, this.params_); this.imageSize_[0] = Math.ceil(imageWidth * this.ratio_); this.imageSize_[1] = Math.ceil(imageHeight * this.ratio_); @@ -116809,8 +100991,8 @@ ol.source.ImageWMS.prototype.getImageInternal = this.renderedRevision_ = this.getRevision(); - goog.events.listen(this.image_, goog.events.EventType.CHANGE, - this.handleImageChange, false, this); + ol.events.listen(this.image_, ol.events.EventType.CHANGE, + this.handleImageChange, this); return this.image_; @@ -116836,17 +101018,14 @@ ol.source.ImageWMS.prototype.getImageLoadFunction = function() { * @return {string} Request URL. * @private */ -ol.source.ImageWMS.prototype.getRequestUrl_ = - function(extent, size, pixelRatio, projection, params) { +ol.source.ImageWMS.prototype.getRequestUrl_ = function(extent, size, pixelRatio, projection, params) { goog.asserts.assert(this.url_ !== undefined, 'url is defined'); params[this.v13_ ? 'CRS' : 'SRS'] = projection.getCode(); if (!('STYLES' in this.params_)) { - /* jshint -W053 */ - params['STYLES'] = new String(''); - /* jshint +W053 */ + params['STYLES'] = ''; } if (pixelRatio != 1) { @@ -116931,7 +101110,7 @@ ol.source.ImageWMS.prototype.setUrl = function(url) { * @api stable */ ol.source.ImageWMS.prototype.updateParams = function(params) { - goog.object.extend(this.params_, params); + ol.object.assign(this.params_, params); this.updateV13_(); this.image_ = null; this.changed(); @@ -116942,67 +101121,9 @@ ol.source.ImageWMS.prototype.updateParams = function(params) { * @private */ ol.source.ImageWMS.prototype.updateV13_ = function() { - var version = - goog.object.get(this.params_, 'VERSION', ol.DEFAULT_WMS_VERSION); - this.v13_ = goog.string.compareVersions(version, '1.3') >= 0; -}; - -goog.provide('ol.source.XYZ'); - -goog.require('ol.source.TileImage'); - - - -/** - * @classdesc - * Layer source for tile data with URLs in a set XYZ format that are - * defined in a URL template. By default, this follows the widely-used - * Google grid where `x` 0 and `y` 0 are in the top left. Grids like - * TMS where `x` 0 and `y` 0 are in the bottom left can be used by - * using the `{-y}` placeholder in the URL template, so long as the - * source does not have a custom tile grid. In this case, - * {@link ol.source.TileImage} can be used with a `tileUrlFunction` - * such as: - * - * tileUrlFunction: function(coordinate) { - * return 'http://mapserver.com/' + coordinate[0] + '/' + - * coordinate[1] + '/' + coordinate[2] + '.png'; - * } - * - * - * @constructor - * @extends {ol.source.TileImage} - * @param {olx.source.XYZOptions} options XYZ options. - * @api stable - */ -ol.source.XYZ = function(options) { - var projection = options.projection !== undefined ? - options.projection : 'EPSG:3857'; - - var tileGrid = options.tileGrid !== undefined ? options.tileGrid : - ol.tilegrid.createXYZ({ - extent: ol.tilegrid.extentFromProjection(projection), - maxZoom: options.maxZoom, - tileSize: options.tileSize - }); - - goog.base(this, { - attributions: options.attributions, - crossOrigin: options.crossOrigin, - logo: options.logo, - projection: projection, - reprojectionErrorThreshold: options.reprojectionErrorThreshold, - tileGrid: tileGrid, - tileLoadFunction: options.tileLoadFunction, - tilePixelRatio: options.tilePixelRatio, - tileUrlFunction: options.tileUrlFunction, - url: options.url, - urls: options.urls, - wrapX: options.wrapX !== undefined ? options.wrapX : true - }); - + var version = this.params_['VERSION'] || ol.DEFAULT_WMS_VERSION; + this.v13_ = ol.string.compareVersions(version, '1.3') >= 0; }; -goog.inherits(ol.source.XYZ, ol.source.TileImage); goog.provide('ol.source.OSM'); @@ -117010,7 +101131,6 @@ goog.require('ol.Attribution'); goog.require('ol.source.XYZ'); - /** * @classdesc * Layer source for the OpenStreetMap tile server. @@ -117039,8 +101159,9 @@ ol.source.OSM = function(opt_options) { goog.base(this, { attributions: attributions, + cacheSize: options.cacheSize, crossOrigin: crossOrigin, - opaque: true, + opaque: options.opaque !== undefined ? options.opaque : true, maxZoom: options.maxZoom !== undefined ? options.maxZoom : 19, reprojectionErrorThreshold: options.reprojectionErrorThreshold, tileLoadFunction: options.tileLoadFunction, @@ -117073,7 +101194,6 @@ goog.require('ol.source.OSM'); goog.require('ol.source.XYZ'); - /** * @classdesc * Layer source for the MapQuest tile server. @@ -117104,11 +101224,12 @@ ol.source.MapQuest = function(opt_options) { goog.base(this, { attributions: layerConfig.attributions, + cacheSize: options.cacheSize, crossOrigin: 'anonymous', logo: 'https://developer.mapquest.com/content/osm/mq_logo.png', maxZoom: layerConfig.maxZoom, reprojectionErrorThreshold: options.reprojectionErrorThreshold, - opaque: true, + opaque: layerConfig.opaque, tileLoadFunction: options.tileLoadFunction, url: url }); @@ -117127,11 +101248,12 @@ ol.source.MapQuest.TILE_ATTRIBUTION = new ol.Attribution({ /** - * @type {Object.<string, {maxZoom: number, attributions: (Array.<ol.Attribution>)}>} + * @type {Object.<string, {maxZoom: number, opaque: boolean, attributions: (Array.<ol.Attribution>)}>} */ ol.source.MapQuestConfig = { 'osm': { maxZoom: 19, + opaque: true, attributions: [ ol.source.MapQuest.TILE_ATTRIBUTION, ol.source.OSM.ATTRIBUTION @@ -117139,6 +101261,7 @@ ol.source.MapQuestConfig = { }, 'sat': { maxZoom: 18, + opaque: true, attributions: [ ol.source.MapQuest.TILE_ATTRIBUTION, new ol.Attribution({ @@ -117149,6 +101272,7 @@ ol.source.MapQuestConfig = { }, 'hyb': { maxZoom: 18, + opaque: false, attributions: [ ol.source.MapQuest.TILE_ATTRIBUTION, ol.source.OSM.ATTRIBUTION @@ -117183,16 +101307,32 @@ var Processor = _dereq_('./processor'); exports.Processor = Processor; },{"./processor":2}],2:[function(_dereq_,module,exports){ -/* eslint-disable dot-notation */ +var newImageData = _dereq_('./util').newImageData; /** - * Create a function for running operations. + * Create a function for running operations. This function is serialized for + * use in a worker. * @param {function(Array, Object):*} operation The operation. * @return {function(Object):ArrayBuffer} A function that takes an object with * buffers, meta, imageOps, width, and height properties and returns an array * buffer. */ function createMinion(operation) { + var workerHasImageData = true; + try { + new ImageData(10, 10); + } catch (_) { + workerHasImageData = false; + } + + function newWorkerImageData(data, width, height) { + if (workerHasImageData) { + return new ImageData(data, width, height); + } else { + return {data: data, width: width, height: height}; + } + } + return function(data) { // bracket notation for minification support var buffers = data['buffers']; @@ -117208,7 +101348,7 @@ function createMinion(operation) { if (imageOps) { var images = new Array(numBuffers); for (b = 0; b < numBuffers; ++b) { - images[b] = new ImageData( + images[b] = newWorkerImageData( new Uint8ClampedArray(buffers[b]), width, height); } output = operation(images, meta).data; @@ -117242,7 +101382,7 @@ function createMinion(operation) { /** * Create a worker for running operations. * @param {Object} config Configuration. - * @param {function(Object)} onMessage Called with a message event. + * @param {function(MessageEvent)} onMessage Called with a message event. * @return {Worker} The worker. */ function createWorker(config, onMessage) { @@ -117251,12 +101391,10 @@ function createWorker(config, onMessage) { }); var lines = lib.concat([ - 'var __minion__ = (' + createMinion.toString() + ')(', - config.operation.toString(), - ');', - 'self.addEventListener("message", function(__event__) {', - 'var buffer = __minion__(__event__.data);', - 'self.postMessage({buffer: buffer, meta: __event__.data.meta}, [buffer]);', + 'var __minion__ = (' + createMinion.toString() + ')(', config.operation.toString(), ');', + 'self.addEventListener("message", function(event) {', + ' var buffer = __minion__(event.data);', + ' self.postMessage({buffer: buffer, meta: event.data.meta}, [buffer]);', '});' ]); @@ -117270,7 +101408,7 @@ function createWorker(config, onMessage) { /** * Create a faux worker for running operations. * @param {Object} config Configuration. - * @param {function(Object)} onMessage Called with a message event. + * @param {function(MessageEvent)} onMessage Called with a message event. * @return {Object} The faux worker. */ function createFauxWorker(config, onMessage) { @@ -117278,7 +101416,7 @@ function createFauxWorker(config, onMessage) { return { postMessage: function(data) { setTimeout(function() { - onMessage({data: {buffer: minion(data), meta: data.meta}}); + onMessage({'data': {'buffer': minion(data), 'meta': data['meta']}}); }, 0); } }; @@ -117399,7 +101537,7 @@ Processor.prototype._dispatch = function() { /** * Handle messages from the worker. * @param {number} index The worker index. - * @param {Object} event The message event. + * @param {MessageEvent} event The message event. */ Processor.prototype._onWorkerMessage = function(index, event) { if (this._destroyed) { @@ -117438,12 +101576,34 @@ Processor.prototype._resolveJob = function() { this._job = null; this._dataLookup = {}; job.callback(null, - new ImageData(data, job.inputs[0].width, job.inputs[0].height), meta); + newImageData(data, job.inputs[0].width, job.inputs[0].height), meta); this._dispatch(); }; module.exports = Processor; +},{"./util":3}],3:[function(_dereq_,module,exports){ +var hasImageData = true; +try { + new ImageData(10, 10); +} catch (_) { + hasImageData = false; +} + +var context = document.createElement('canvas').getContext('2d'); + +function newImageData(data, width, height) { + if (hasImageData) { + return new ImageData(data, width, height); + } else { + var imageData = context.createImageData(width, height); + imageData.data.set(data); + return imageData; + } +} + +exports.newImageData = newImageData; + },{}]},{},[1])(1) }); ol.ext.pixelworks = module.exports; @@ -117454,18 +101614,18 @@ goog.provide('ol.source.RasterEvent'); goog.provide('ol.source.RasterEventType'); goog.require('goog.asserts'); -goog.require('goog.events'); -goog.require('goog.events.Event'); -goog.require('goog.events.EventType'); -goog.require('goog.object'); goog.require('goog.vec.Mat4'); goog.require('ol.ImageCanvas'); goog.require('ol.TileQueue'); goog.require('ol.dom'); +goog.require('ol.events'); +goog.require('ol.events.Event'); +goog.require('ol.events.EventType'); goog.require('ol.ext.pixelworks'); goog.require('ol.extent'); goog.require('ol.layer.Image'); goog.require('ol.layer.Tile'); +goog.require('ol.object'); goog.require('ol.raster.OperationType'); goog.require('ol.renderer.canvas.ImageLayer'); goog.require('ol.renderer.canvas.TileLayer'); @@ -117474,7 +101634,6 @@ goog.require('ol.source.State'); goog.require('ol.source.Tile'); - /** * @classdesc * A source that transforms data from any number of input sources using an array @@ -117483,6 +101642,7 @@ goog.require('ol.source.Tile'); * * @constructor * @extends {ol.source.Image} + * @fires ol.source.RasterEvent * @param {olx.source.RasterOptions} options Options. * @api */ @@ -117514,8 +101674,8 @@ ol.source.Raster = function(options) { this.renderers_ = ol.source.Raster.createRenderers_(options.sources); for (var r = 0, rr = this.renderers_.length; r < rr; ++r) { - goog.events.listen(this.renderers_[r], goog.events.EventType.CHANGE, - this.changed, false, this); + ol.events.listen(this.renderers_[r], ol.events.EventType.CHANGE, + this.changed, this); } /** @@ -117529,8 +101689,10 @@ ol.source.Raster = function(options) { * @type {ol.TileQueue} */ this.tileQueue_ = new ol.TileQueue( - function() { return 1; }, - goog.bind(this.changed, this)); + function() { + return 1; + }, + this.changed.bind(this)); var layerStatesArray = ol.source.Raster.getLayerStatesArray_(this.renderers_); var layerStates = {}; @@ -117540,7 +101702,7 @@ ol.source.Raster = function(options) { /** * The most recently rendered state. - * @type {?ol.source.Raster.RenderedState} + * @type {?ol.SourceRasterRenderedState} * @private */ this.renderedState_ = null; @@ -117618,14 +101780,13 @@ ol.source.Raster.prototype.setOperation = function(operation, opt_lib) { * @return {olx.FrameState} The updated frame state. * @private */ -ol.source.Raster.prototype.updateFrameState_ = - function(extent, resolution, projection) { +ol.source.Raster.prototype.updateFrameState_ = function(extent, resolution, projection) { var frameState = /** @type {olx.FrameState} */ ( - goog.object.clone(this.frameState_)); + ol.object.assign({}, this.frameState_)); frameState.viewState = /** @type {olx.ViewState} */ ( - goog.object.clone(frameState.viewState)); + ol.object.assign({}, frameState.viewState)); var center = ol.extent.getCenter(extent); var width = Math.round(ol.extent.getWidth(extent) / resolution); @@ -117663,22 +101824,22 @@ ol.source.Raster.prototype.isDirty_ = function(extent, resolution) { /** * @inheritDoc */ -ol.source.Raster.prototype.getImage = - function(extent, resolution, pixelRatio, projection) { +ol.source.Raster.prototype.getImage = function(extent, resolution, pixelRatio, projection) { if (!this.allSourcesReady_()) { return null; } - if (!this.isDirty_(extent, resolution)) { + var currentExtent = extent.slice(); + if (!this.isDirty_(currentExtent, resolution)) { return this.renderedImageCanvas_; } var context = this.canvasContext_; var canvas = context.canvas; - var width = Math.round(ol.extent.getWidth(extent) / resolution); - var height = Math.round(ol.extent.getHeight(extent) / resolution); + var width = Math.round(ol.extent.getWidth(currentExtent) / resolution); + var height = Math.round(ol.extent.getHeight(currentExtent) / resolution); if (width !== canvas.width || height !== canvas.height) { @@ -117686,16 +101847,16 @@ ol.source.Raster.prototype.getImage = canvas.height = height; } - var frameState = this.updateFrameState_(extent, resolution, projection); + var frameState = this.updateFrameState_(currentExtent, resolution, projection); var imageCanvas = new ol.ImageCanvas( - extent, resolution, 1, this.getAttributions(), canvas, + currentExtent, resolution, 1, this.getAttributions(), canvas, this.composeFrame_.bind(this, frameState)); this.renderedImageCanvas_ = imageCanvas; this.renderedState_ = { - extent: extent, + extent: currentExtent, resolution: resolution, revision: this.getRevision() }; @@ -117764,8 +101925,7 @@ ol.source.Raster.prototype.composeFrame_ = function(frameState, callback) { * @param {Object} data The user data. * @private */ -ol.source.Raster.prototype.onWorkerComplete_ = - function(frameState, callback, err, output, data) { +ol.source.Raster.prototype.onWorkerComplete_ = function(frameState, callback, err, output, data) { if (err) { callback(err); return; @@ -117791,45 +101951,28 @@ ol.source.Raster.prototype.onWorkerComplete_ = * Get image data from a renderer. * @param {ol.renderer.canvas.Layer} renderer Layer renderer. * @param {olx.FrameState} frameState The frame state. - * @param {ol.layer.LayerState} layerState The layer state. + * @param {ol.LayerState} layerState The layer state. * @return {ImageData} The image data. * @private */ ol.source.Raster.getImageData_ = function(renderer, frameState, layerState) { - renderer.prepareFrame(frameState, layerState); - // We should be able to call renderer.composeFrame(), but this is inefficient - // for tiled sources (we've already rendered to an intermediate canvas in the - // prepareFrame call and we don't need to render again to the output canvas). - // TODO: make all canvas renderers render to a single canvas - var image = renderer.getImage(); - if (!image) { + if (!renderer.prepareFrame(frameState, layerState)) { return null; } - var imageTransform = renderer.getImageTransform(); - var dx = Math.round(goog.vec.Mat4.getElement(imageTransform, 0, 3)); - var dy = Math.round(goog.vec.Mat4.getElement(imageTransform, 1, 3)); var width = frameState.size[0]; var height = frameState.size[1]; - if (image instanceof Image) { - if (!ol.source.Raster.context_) { + if (!ol.source.Raster.context_) { + ol.source.Raster.context_ = ol.dom.createCanvasContext2D(width, height); + } else { + var canvas = ol.source.Raster.context_.canvas; + if (canvas.width !== width || canvas.height !== height) { ol.source.Raster.context_ = ol.dom.createCanvasContext2D(width, height); } else { - var canvas = ol.source.Raster.context_.canvas; - if (canvas.width !== width || canvas.height !== height) { - ol.source.Raster.context_ = ol.dom.createCanvasContext2D(width, height); - } else { - ol.source.Raster.context_.clearRect(0, 0, width, height); - } + ol.source.Raster.context_.clearRect(0, 0, width, height); } - var dw = Math.round( - image.width * goog.vec.Mat4.getElement(imageTransform, 0, 0)); - var dh = Math.round( - image.height * goog.vec.Mat4.getElement(imageTransform, 1, 1)); - ol.source.Raster.context_.drawImage(image, dx, dy, dw, dh); - return ol.source.Raster.context_.getImageData(0, 0, width, height); - } else { - return image.getContext('2d').getImageData(-dx, -dy, width, height); } + renderer.composeFrame(frameState, layerState, ol.source.Raster.context_); + return ol.source.Raster.context_.getImageData(0, 0, width, height); }; @@ -117844,7 +101987,7 @@ ol.source.Raster.context_ = null; /** * Get a list of layer states from a list of renderers. * @param {Array.<ol.renderer.canvas.Layer>} renderers Layer renderers. - * @return {Array.<ol.layer.LayerState>} The layer states. + * @return {Array.<ol.LayerState>} The layer states. * @private */ ol.source.Raster.getLayerStatesArray_ = function(renderers) { @@ -117914,21 +102057,12 @@ ol.source.Raster.createTileRenderer_ = function(source) { /** - * @typedef {{revision: number, - * resolution: number, - * extent: ol.Extent}} - */ -ol.source.Raster.RenderedState; - - - -/** * @classdesc * Events emitted by {@link ol.source.Raster} instances are instances of this * type. * * @constructor - * @extends {goog.events.Event} + * @extends {ol.events.Event} * @implements {oli.source.RasterEvent} * @param {string} type Type. * @param {olx.FrameState} frameState The frame state. @@ -117960,7 +102094,7 @@ ol.source.RasterEvent = function(type, frameState, data) { this.data = data; }; -goog.inherits(ol.source.RasterEvent, goog.events.Event); +goog.inherits(ol.source.RasterEvent, ol.events.Event); /** @@ -118054,13 +102188,12 @@ ol.source.StamenProviderConfig = { maxZoom: 20 }, 'watercolor': { - minZoom: 3, + minZoom: 1, maxZoom: 16 } }; - /** * @classdesc * Layer source for the Stamen tile server. @@ -118088,10 +102221,10 @@ ol.source.Stamen = function(options) { goog.base(this, { attributions: ol.source.Stamen.ATTRIBUTIONS, + cacheSize: options.cacheSize, crossOrigin: 'anonymous', maxZoom: providerConfig.maxZoom, - // FIXME uncomment the following when tilegrid supports minZoom - //minZoom: providerConfig.minZoom, + minZoom: providerConfig.minZoom, opaque: layerConfig.opaque, reprojectionErrorThreshold: options.reprojectionErrorThreshold, tileLoadFunction: options.tileLoadFunction, @@ -118118,20 +102251,17 @@ ol.source.Stamen.ATTRIBUTIONS = [ goog.provide('ol.source.TileArcGISRest'); goog.require('goog.asserts'); -goog.require('goog.math'); -goog.require('goog.object'); -goog.require('goog.string'); goog.require('goog.uri.utils'); goog.require('ol'); -goog.require('ol.TileCoord'); goog.require('ol.extent'); +goog.require('ol.object'); +goog.require('ol.math'); goog.require('ol.proj'); goog.require('ol.size'); goog.require('ol.source.TileImage'); goog.require('ol.tilecoord'); - /** * @classdesc * Layer source for tile data from ArcGIS Rest services. Map and Image @@ -118150,17 +102280,15 @@ ol.source.TileArcGISRest = function(opt_options) { var options = opt_options || {}; - var params = options.params !== undefined ? options.params : {}; - goog.base(this, { attributions: options.attributions, + cacheSize: options.cacheSize, crossOrigin: options.crossOrigin, logo: options.logo, projection: options.projection, reprojectionErrorThreshold: options.reprojectionErrorThreshold, tileGrid: options.tileGrid, tileLoadFunction: options.tileLoadFunction, - tileUrlFunction: goog.bind(this.tileUrlFunction_, this), url: options.url, urls: options.urls, wrapX: options.wrapX !== undefined ? options.wrapX : true @@ -118168,9 +102296,9 @@ ol.source.TileArcGISRest = function(opt_options) { /** * @private - * @type {Object} + * @type {!Object} */ - this.params_ = params; + this.params_ = options.params || {}; /** * @private @@ -118203,8 +102331,7 @@ ol.source.TileArcGISRest.prototype.getParams = function() { * @return {string|undefined} Request URL. * @private */ -ol.source.TileArcGISRest.prototype.getRequestUrl_ = - function(tileCoord, tileSize, tileExtent, +ol.source.TileArcGISRest.prototype.getRequestUrl_ = function(tileCoord, tileSize, tileExtent, pixelRatio, projection, params) { var urls = this.urls; @@ -118227,55 +102354,32 @@ ol.source.TileArcGISRest.prototype.getRequestUrl_ = if (urls.length == 1) { url = urls[0]; } else { - var index = goog.math.modulo(ol.tilecoord.hash(tileCoord), urls.length); + var index = ol.math.modulo(ol.tilecoord.hash(tileCoord), urls.length); url = urls[index]; } - if (!goog.string.endsWith(url, '/')) { - url = url + '/'; - } - - // If a MapServer, use export. If an ImageServer, use exportImage. - if (goog.string.endsWith(url, 'MapServer/')) { - url = url + 'export'; - } - else if (goog.string.endsWith(url, 'ImageServer/')) { - url = url + 'exportImage'; - } - else { + var modifiedUrl = url + .replace(/MapServer\/?$/, 'MapServer/export') + .replace(/ImageServer\/?$/, 'ImageServer/exportImage'); + if (modifiedUrl == url) { goog.asserts.fail('Unknown Rest Service', url); } - - return goog.uri.utils.appendParamsFromMap(url, params); + return goog.uri.utils.appendParamsFromMap(modifiedUrl, params); }; /** - * @param {number} z Z. - * @param {number} pixelRatio Pixel ratio. - * @param {ol.proj.Projection} projection Projection. - * @return {ol.Size} Size. + * @inheritDoc */ -ol.source.TileArcGISRest.prototype.getTilePixelSize = - function(z, pixelRatio, projection) { - var tileSize = goog.base(this, 'getTilePixelSize', z, pixelRatio, projection); - if (pixelRatio == 1) { - return tileSize; - } else { - return ol.size.scale(tileSize, pixelRatio, this.tmpSize); - } +ol.source.TileArcGISRest.prototype.getTilePixelRatio = function(pixelRatio) { + return pixelRatio; }; /** - * @param {ol.TileCoord} tileCoord Tile coordinate. - * @param {number} pixelRatio Pixel ratio. - * @param {ol.proj.Projection} projection Projection. - * @return {string|undefined} Tile URL. - * @private + * @inheritDoc */ -ol.source.TileArcGISRest.prototype.tileUrlFunction_ = - function(tileCoord, pixelRatio, projection) { +ol.source.TileArcGISRest.prototype.fixedTileUrlFunction = function(tileCoord, pixelRatio, projection) { var tileGrid = this.getTileGrid(); if (!tileGrid) { @@ -118301,7 +102405,7 @@ ol.source.TileArcGISRest.prototype.tileUrlFunction_ = 'FORMAT': 'PNG32', 'TRANSPARENT': true }; - goog.object.extend(baseParams, this.params_); + ol.object.assign(baseParams, this.params_); return this.getRequestUrl_(tileCoord, tileSize, tileExtent, pixelRatio, projection, baseParams); @@ -118314,20 +102418,17 @@ ol.source.TileArcGISRest.prototype.tileUrlFunction_ = * @api stable */ ol.source.TileArcGISRest.prototype.updateParams = function(params) { - goog.object.extend(this.params_, params); + ol.object.assign(this.params_, params); this.changed(); }; goog.provide('ol.source.TileDebug'); goog.require('ol.Tile'); -goog.require('ol.TileCoord'); goog.require('ol.TileState'); goog.require('ol.dom'); goog.require('ol.size'); goog.require('ol.source.Tile'); -goog.require('ol.tilecoord'); - /** @@ -118395,7 +102496,6 @@ ol.DebugTile_.prototype.getImage = function(opt_context) { }; - /** * @classdesc * A pseudo tile source, which does not fetch tiles from a server, but renders @@ -118433,8 +102533,8 @@ ol.source.TileDebug.prototype.getTile = function(z, x, y) { var tileSize = ol.size.toSize(this.tileGrid.getTileSize(z)); var tileCoord = [z, x, y]; var textTileCoord = this.getTileCoordForTileUrlFunction(tileCoord); - var text = !textTileCoord ? '' : ol.tilecoord.toString( - this.getTileCoordForTileUrlFunction(textTileCoord)); + var text = !textTileCoord ? '' : + this.getTileCoordForTileUrlFunction(textTileCoord).toString(); var tile = new ol.DebugTile_(tileCoord, tileSize, text); this.tileCache.set(tileCoordKey, tile); return tile; @@ -118451,17 +102551,16 @@ goog.provide('ol.source.TileJSON'); goog.provide('ol.tilejson'); goog.require('goog.asserts'); -goog.require('goog.net.Jsonp'); goog.require('ol.Attribution'); goog.require('ol.TileRange'); goog.require('ol.TileUrlFunction'); goog.require('ol.extent'); +goog.require('ol.net'); goog.require('ol.proj'); goog.require('ol.source.State'); goog.require('ol.source.TileImage'); - /** * @classdesc * Layer source for tile data in TileJSON format. @@ -118473,8 +102572,15 @@ goog.require('ol.source.TileImage'); */ ol.source.TileJSON = function(options) { + /** + * @type {TileJSON} + * @private + */ + this.tileJSON_ = null; + goog.base(this, { attributions: options.attributions, + cacheSize: options.cacheSize, crossOrigin: options.crossOrigin, projection: ol.proj.get('EPSG:3857'), reprojectionErrorThreshold: options.reprojectionErrorThreshold, @@ -118483,15 +102589,61 @@ ol.source.TileJSON = function(options) { wrapX: options.wrapX !== undefined ? options.wrapX : true }); - var request = new goog.net.Jsonp(options.url); - request.send(undefined, goog.bind(this.handleTileJSONResponse, this), - goog.bind(this.handleTileJSONError, this)); + if (options.jsonp) { + ol.net.jsonp(options.url, this.handleTileJSONResponse.bind(this), + this.handleTileJSONError.bind(this)); + } else { + var client = new XMLHttpRequest(); + client.addEventListener('load', this.onXHRLoad_.bind(this)); + client.addEventListener('error', this.onXHRError_.bind(this)); + client.open('GET', options.url); + client.send(); + } }; goog.inherits(ol.source.TileJSON, ol.source.TileImage); /** + * @private + * @param {Event} event The load event. + */ +ol.source.TileJSON.prototype.onXHRLoad_ = function(event) { + var client = /** @type {XMLHttpRequest} */ (event.target); + if (client.status >= 200 && client.status < 300) { + var response; + try { + response = /** @type {TileJSON} */(JSON.parse(client.responseText)); + } catch (err) { + this.handleTileJSONError(); + return; + } + this.handleTileJSONResponse(response); + } else { + this.handleTileJSONError(); + } +}; + + +/** + * @private + * @param {Event} event The error event. + */ +ol.source.TileJSON.prototype.onXHRError_ = function(event) { + this.handleTileJSONError(); +}; + + +/** + * @return {TileJSON} The tilejson object. + * @api + */ +ol.source.TileJSON.prototype.getTileJSON = function() { + return this.tileJSON_; +}; + + +/** * @protected * @param {TileJSON} tileJSON Tile JSON. */ @@ -118540,7 +102692,7 @@ ol.source.TileJSON.prototype.handleTileJSONResponse = function(tileJSON) { }) ]); } - + this.tileJSON_ = tileJSON; this.setState(ol.source.State.READY); }; @@ -118557,20 +102709,19 @@ goog.provide('ol.source.TileUTFGrid'); goog.require('goog.asserts'); goog.require('goog.async.nextTick'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.net.Jsonp'); goog.require('ol.Attribution'); goog.require('ol.Tile'); goog.require('ol.TileState'); goog.require('ol.TileUrlFunction'); +goog.require('ol.events'); +goog.require('ol.events.EventType'); goog.require('ol.extent'); +goog.require('ol.net'); goog.require('ol.proj'); goog.require('ol.source.State'); goog.require('ol.source.Tile'); - /** * @classdesc * Layer source for UTFGrid interaction data loaded from TileJSON format. @@ -118605,13 +102756,63 @@ ol.source.TileUTFGrid = function(options) { */ this.template_ = undefined; - var request = new goog.net.Jsonp(options.url); - request.send(undefined, goog.bind(this.handleTileJSONResponse, this)); + /** + * @private + * @type {boolean} + */ + this.jsonp_ = options.jsonp || false; + + if (options.url) { + if (this.jsonp_) { + ol.net.jsonp(options.url, this.handleTileJSONResponse.bind(this), + this.handleTileJSONError.bind(this)); + } else { + var client = new XMLHttpRequest(); + client.addEventListener('load', this.onXHRLoad_.bind(this)); + client.addEventListener('error', this.onXHRError_.bind(this)); + client.open('GET', options.url); + client.send(); + } + } else if (options.tileJSON) { + this.handleTileJSONResponse(options.tileJSON); + } else { + goog.asserts.fail('Either url or tileJSON options must be provided'); + } }; goog.inherits(ol.source.TileUTFGrid, ol.source.Tile); /** + * @private + * @param {Event} event The load event. + */ +ol.source.TileUTFGrid.prototype.onXHRLoad_ = function(event) { + var client = /** @type {XMLHttpRequest} */ (event.target); + if (client.status >= 200 && client.status < 300) { + var response; + try { + response = /** @type {TileJSON} */(JSON.parse(client.responseText)); + } catch (err) { + this.handleTileJSONError(); + return; + } + this.handleTileJSONResponse(response); + } else { + this.handleTileJSONError(); + } +}; + + +/** + * @private + * @param {Event} event The error event. + */ +ol.source.TileUTFGrid.prototype.onXHRError_ = function(event) { + this.handleTileJSONError(); +}; + + +/** * Return the template from TileJSON. * @return {string|undefined} The template from TileJSON. * @api @@ -118627,7 +102828,7 @@ ol.source.TileUTFGrid.prototype.getTemplate = function() { * in case of an error). * @param {ol.Coordinate} coordinate Coordinate. * @param {number} resolution Resolution. - * @param {function(this: T, Object)} callback Callback. + * @param {function(this: T, *)} callback Callback. * @param {T=} opt_this The object to use as `this` in the callback. * @param {boolean=} opt_request If `true` the callback is always async. * The tile data is requested if not yet loaded. @@ -118655,6 +102856,14 @@ ol.source.TileUTFGrid.prototype.forDataAtCoordinateAndResolution = function( /** + * @protected + */ +ol.source.TileUTFGrid.prototype.handleTileJSONError = function() { + this.setState(ol.source.State.ERROR); +}; + + +/** * TODO: very similar to ol.source.TileJSON#handleTileJSONResponse * @protected * @param {TileJSON} tileJSON Tile JSON. @@ -118721,8 +102930,7 @@ ol.source.TileUTFGrid.prototype.handleTileJSONResponse = function(tileJSON) { /** * @inheritDoc */ -ol.source.TileUTFGrid.prototype.getTile = - function(z, x, y, pixelRatio, projection) { +ol.source.TileUTFGrid.prototype.getTile = function(z, x, y, pixelRatio, projection) { var tileCoordKey = this.getKeyZXY(z, x, y); if (this.tileCache.containsKey(tileCoordKey)) { return /** @type {!ol.Tile} */ (this.tileCache.get(tileCoordKey)); @@ -118737,7 +102945,8 @@ ol.source.TileUTFGrid.prototype.getTile = tileUrl !== undefined ? ol.TileState.IDLE : ol.TileState.EMPTY, tileUrl !== undefined ? tileUrl : '', this.tileGrid.getTileCoordExtent(tileCoord), - this.preemptive_); + this.preemptive_, + this.jsonp_); this.tileCache.set(tileCoordKey, tile); return tile; } @@ -118755,7 +102964,6 @@ ol.source.TileUTFGrid.prototype.useTile = function(z, x, y) { }; - /** * @constructor * @extends {ol.Tile} @@ -118764,10 +102972,10 @@ ol.source.TileUTFGrid.prototype.useTile = function(z, x, y) { * @param {string} src Image source URI. * @param {ol.Extent} extent Extent of the tile. * @param {boolean} preemptive Load the tile when visible (before it's needed). + * @param {boolean} jsonp Load the tile as a script. * @private */ -ol.source.TileUTFGridTile_ = - function(tileCoord, state, src, extent, preemptive) { +ol.source.TileUTFGridTile_ = function(tileCoord, state, src, extent, preemptive, jsonp) { goog.base(this, tileCoord, state); @@ -118806,6 +103014,14 @@ ol.source.TileUTFGridTile_ = * @type {Object.<string, Object>|undefined} */ this.data_ = null; + + + /** + * @private + * @type {boolean} + */ + this.jsonp_ = jsonp; + }; goog.inherits(ol.source.TileUTFGridTile_, ol.Tile); @@ -118824,10 +103040,10 @@ ol.source.TileUTFGridTile_.prototype.getImage = function(opt_context) { /** * Synchronously returns data at given coordinate (if available). * @param {ol.Coordinate} coordinate Coordinate. - * @return {Object} + * @return {*} The data. */ ol.source.TileUTFGridTile_.prototype.getData = function(coordinate) { - if (!this.grid_ || !this.keys_ || !this.data_) { + if (!this.grid_ || !this.keys_) { return null; } var xRelative = (coordinate[0] - this.extent_[0]) / @@ -118837,7 +103053,7 @@ ol.source.TileUTFGridTile_.prototype.getData = function(coordinate) { var row = this.grid_[Math.floor((1 - yRelative) * this.grid_.length)]; - if (!goog.isString(row)) { + if (typeof row !== 'string') { return null; } @@ -118850,7 +103066,16 @@ ol.source.TileUTFGridTile_.prototype.getData = function(coordinate) { } code -= 32; - return (code in this.keys_) ? this.data_[this.keys_[code]] : null; + var data = null; + if (code in this.keys_) { + var id = this.keys_[code]; + if (this.data_ && id in this.data_) { + data = this.data_[id]; + } else { + data = id; + } + } + return data; }; @@ -118858,18 +103083,17 @@ ol.source.TileUTFGridTile_.prototype.getData = function(coordinate) { * Calls the callback (synchronously by default) with the available data * for given coordinate (or `null` if not yet loaded). * @param {ol.Coordinate} coordinate Coordinate. - * @param {function(this: T, Object)} callback Callback. + * @param {function(this: T, *)} callback Callback. * @param {T=} opt_this The object to use as `this` in the callback. * @param {boolean=} opt_request If `true` the callback is always async. * The tile data is requested if not yet loaded. * @template T */ -ol.source.TileUTFGridTile_.prototype.forDataAtCoordinate = - function(coordinate, callback, opt_this, opt_request) { +ol.source.TileUTFGridTile_.prototype.forDataAtCoordinate = function(coordinate, callback, opt_this, opt_request) { if (this.state == ol.TileState.IDLE && opt_request === true) { - goog.events.listenOnce(this, goog.events.EventType.CHANGE, function(e) { + ol.events.listenOnce(this, ol.events.EventType.CHANGE, function(e) { callback.call(opt_this, this.getData(coordinate)); - }, false, this); + }, this); this.loadInternal_(); } else { if (opt_request === true) { @@ -118901,7 +103125,7 @@ ol.source.TileUTFGridTile_.prototype.handleError_ = function() { /** - * @param {!UTFGridJSON} json + * @param {!UTFGridJSON} json UTFGrid data. * @private */ ol.source.TileUTFGridTile_.prototype.handleLoad_ = function(json) { @@ -118920,14 +103144,51 @@ ol.source.TileUTFGridTile_.prototype.handleLoad_ = function(json) { ol.source.TileUTFGridTile_.prototype.loadInternal_ = function() { if (this.state == ol.TileState.IDLE) { this.state = ol.TileState.LOADING; - var request = new goog.net.Jsonp(this.src_); - request.send(undefined, goog.bind(this.handleLoad_, this), - goog.bind(this.handleError_, this)); + if (this.jsonp_) { + ol.net.jsonp(this.src_, this.handleLoad_.bind(this), + this.handleError_.bind(this)); + } else { + var client = new XMLHttpRequest(); + client.addEventListener('load', this.onXHRLoad_.bind(this)); + client.addEventListener('error', this.onXHRError_.bind(this)); + client.open('GET', this.src_); + client.send(); + } } }; /** + * @private + * @param {Event} event The load event. + */ +ol.source.TileUTFGridTile_.prototype.onXHRLoad_ = function(event) { + var client = /** @type {XMLHttpRequest} */ (event.target); + if (client.status >= 200 && client.status < 300) { + var response; + try { + response = /** @type {!UTFGridJSON} */(JSON.parse(client.responseText)); + } catch (err) { + this.handleError_(); + return; + } + this.handleLoad_(response); + } else { + this.handleError_(); + } +}; + + +/** + * @private + * @param {Event} event The error event. + */ +ol.source.TileUTFGridTile_.prototype.onXHRError_ = function(event) { + this.handleError_(); +}; + + +/** * Load not yet loaded URI. */ ol.source.TileUTFGridTile_.prototype.load = function() { @@ -118943,20 +103204,18 @@ ol.source.TileUTFGridTile_.prototype.load = function() { goog.provide('ol.source.TileWMS'); goog.require('goog.asserts'); -goog.require('goog.math'); -goog.require('goog.object'); -goog.require('goog.string'); goog.require('goog.uri.utils'); goog.require('ol'); -goog.require('ol.TileCoord'); goog.require('ol.extent'); +goog.require('ol.object'); +goog.require('ol.math'); goog.require('ol.proj'); goog.require('ol.size'); goog.require('ol.source.TileImage'); goog.require('ol.source.wms'); goog.require('ol.source.wms.ServerType'); goog.require('ol.tilecoord'); - +goog.require('ol.string'); /** @@ -118972,12 +103231,13 @@ ol.source.TileWMS = function(opt_options) { var options = opt_options || {}; - var params = options.params !== undefined ? options.params : {}; + var params = options.params || {}; - var transparent = goog.object.get(params, 'TRANSPARENT', true); + var transparent = 'TRANSPARENT' in params ? params['TRANSPARENT'] : true; goog.base(this, { attributions: options.attributions, + cacheSize: options.cacheSize, crossOrigin: options.crossOrigin, logo: options.logo, opaque: !transparent, @@ -118985,7 +103245,6 @@ ol.source.TileWMS = function(opt_options) { reprojectionErrorThreshold: options.reprojectionErrorThreshold, tileGrid: options.tileGrid, tileLoadFunction: options.tileLoadFunction, - tileUrlFunction: goog.bind(this.tileUrlFunction_, this), url: options.url, urls: options.urls, wrapX: options.wrapX !== undefined ? options.wrapX : true @@ -118999,7 +103258,7 @@ ol.source.TileWMS = function(opt_options) { /** * @private - * @type {Object} + * @type {!Object} */ this.params_ = params; @@ -119036,6 +103295,7 @@ ol.source.TileWMS = function(opt_options) { this.tmpExtent_ = ol.extent.createEmpty(); this.updateV13_(); + this.setKey(this.getKeyForParams_()); }; goog.inherits(ol.source.TileWMS, ol.source.TileImage); @@ -119055,8 +103315,7 @@ goog.inherits(ol.source.TileWMS, ol.source.TileImage); * @return {string|undefined} GetFeatureInfo URL. * @api stable */ -ol.source.TileWMS.prototype.getGetFeatureInfoUrl = - function(coordinate, resolution, projection, params) { +ol.source.TileWMS.prototype.getGetFeatureInfoUrl = function(coordinate, resolution, projection, params) { goog.asserts.assert(!('VERSION' in params), 'key VERSION is not allowed in params'); @@ -119095,7 +103354,7 @@ ol.source.TileWMS.prototype.getGetFeatureInfoUrl = 'TRANSPARENT': true, 'QUERY_LAYERS': this.params_['LAYERS'] }; - goog.object.extend(baseParams, this.params_, params); + ol.object.assign(baseParams, this.params_, params); var x = Math.floor((coordinate[0] - tileExtent[0]) / tileResolution); var y = Math.floor((tileExtent[3] - coordinate[1]) / tileResolution); @@ -119111,7 +103370,7 @@ ol.source.TileWMS.prototype.getGetFeatureInfoUrl = /** * @inheritDoc */ -ol.source.TileWMS.prototype.getGutter = function() { +ol.source.TileWMS.prototype.getGutterInternal = function() { return this.gutter_; }; @@ -119145,8 +103404,7 @@ ol.source.TileWMS.prototype.getParams = function() { * @return {string|undefined} Request URL. * @private */ -ol.source.TileWMS.prototype.getRequestUrl_ = - function(tileCoord, tileSize, tileExtent, +ol.source.TileWMS.prototype.getRequestUrl_ = function(tileCoord, tileSize, tileExtent, pixelRatio, projection, params) { var urls = this.urls; @@ -119160,9 +103418,7 @@ ol.source.TileWMS.prototype.getRequestUrl_ = params[this.v13_ ? 'CRS' : 'SRS'] = projection.getCode(); if (!('STYLES' in this.params_)) { - /* jshint -W053 */ - params['STYLES'] = new String(''); - /* jshint +W053 */ + params['STYLES'] = ''; } if (pixelRatio != 1) { @@ -119205,7 +103461,7 @@ ol.source.TileWMS.prototype.getRequestUrl_ = if (urls.length == 1) { url = urls[0]; } else { - var index = goog.math.modulo(ol.tilecoord.hash(tileCoord), urls.length); + var index = ol.math.modulo(ol.tilecoord.hash(tileCoord), urls.length); url = urls[index]; } return goog.uri.utils.appendParamsFromMap(url, params); @@ -119213,19 +103469,10 @@ ol.source.TileWMS.prototype.getRequestUrl_ = /** - * @param {number} z Z. - * @param {number} pixelRatio Pixel ratio. - * @param {ol.proj.Projection} projection Projection. - * @return {ol.Size} Size. + * @inheritDoc */ -ol.source.TileWMS.prototype.getTilePixelSize = - function(z, pixelRatio, projection) { - var tileSize = goog.base(this, 'getTilePixelSize', z, pixelRatio, projection); - if (pixelRatio == 1 || !this.hidpi_ || this.serverType_ === undefined) { - return tileSize; - } else { - return ol.size.scale(tileSize, pixelRatio, this.tmpSize); - } +ol.source.TileWMS.prototype.getTilePixelRatio = function(pixelRatio) { + return (!this.hidpi_ || this.serverType_ === undefined) ? 1 : pixelRatio; }; @@ -119243,24 +103490,28 @@ ol.source.TileWMS.prototype.resetCoordKeyPrefix_ = function() { } } - var key; - for (key in this.params_) { - res[i++] = key + '-' + this.params_[key]; - } - this.coordKeyPrefix_ = res.join('#'); }; /** - * @param {ol.TileCoord} tileCoord Tile coordinate. - * @param {number} pixelRatio Pixel ratio. - * @param {ol.proj.Projection} projection Projection. - * @return {string|undefined} Tile URL. * @private + * @return {string} The key for the current params. + */ +ol.source.TileWMS.prototype.getKeyForParams_ = function() { + var i = 0; + var res = []; + for (var key in this.params_) { + res[i++] = key + '-' + this.params_[key]; + } + return res.join('/'); +}; + + +/** + * @inheritDoc */ -ol.source.TileWMS.prototype.tileUrlFunction_ = - function(tileCoord, pixelRatio, projection) { +ol.source.TileWMS.prototype.fixedTileUrlFunction = function(tileCoord, pixelRatio, projection) { var tileGrid = this.getTileGrid(); if (!tileGrid) { @@ -119298,7 +103549,7 @@ ol.source.TileWMS.prototype.tileUrlFunction_ = 'FORMAT': 'image/png', 'TRANSPARENT': true }; - goog.object.extend(baseParams, this.params_); + ol.object.assign(baseParams, this.params_); return this.getRequestUrl_(tileCoord, tileSize, tileExtent, pixelRatio, projection, baseParams); @@ -119311,10 +103562,10 @@ ol.source.TileWMS.prototype.tileUrlFunction_ = * @api stable */ ol.source.TileWMS.prototype.updateParams = function(params) { - goog.object.extend(this.params_, params); + ol.object.assign(this.params_, params); this.resetCoordKeyPrefix_(); this.updateV13_(); - this.changed(); + this.setKey(this.getKeyForParams_()); }; @@ -119322,9 +103573,8 @@ ol.source.TileWMS.prototype.updateParams = function(params) { * @private */ ol.source.TileWMS.prototype.updateV13_ = function() { - var version = - goog.object.get(this.params_, 'VERSION', ol.DEFAULT_WMS_VERSION); - this.v13_ = goog.string.compareVersions(version, '1.3') >= 0; + var version = this.params_['VERSION'] || ol.DEFAULT_WMS_VERSION; + this.v13_ = ol.string.compareVersions(version, '1.3') >= 0; }; goog.provide('ol.tilegrid.WMTS'); @@ -119334,7 +103584,6 @@ goog.require('ol.proj'); goog.require('ol.tilegrid.TileGrid'); - /** * @classdesc * Set the grid pattern for sources accessing WMTS tiled-image servers. @@ -119403,8 +103652,7 @@ ol.tilegrid.WMTS.prototype.getMatrixIds = function() { * @return {ol.tilegrid.WMTS} WMTS tileGrid instance. * @api */ -ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet = - function(matrixSet, opt_extent) { +ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet = function(matrixSet, opt_extent) { /** @type {!Array.<number>} */ var resolutions = []; @@ -119467,14 +103715,12 @@ ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet = goog.provide('ol.source.WMTS'); goog.provide('ol.source.WMTSRequestEncoding'); -goog.require('goog.array'); goog.require('goog.asserts'); -goog.require('goog.object'); goog.require('goog.uri.utils'); goog.require('ol.TileUrlFunction'); -goog.require('ol.TileUrlFunctionType'); goog.require('ol.array'); goog.require('ol.extent'); +goog.require('ol.object'); goog.require('ol.proj'); goog.require('ol.source.TileImage'); goog.require('ol.tilegrid.WMTS'); @@ -119491,7 +103737,6 @@ ol.source.WMTSRequestEncoding = { }; - /** * @classdesc * Layer source for tile data from WMTS servers. @@ -119527,13 +103772,6 @@ ol.source.WMTS = function(options) { * @private * @type {string} */ - this.dimensionsKey_ = ''; - this.resetDimensionsKey_(); - - /** - * @private - * @type {string} - */ this.layer_ = options.layer; /** @@ -119579,7 +103817,7 @@ ol.source.WMTS = function(options) { }; if (requestEncoding == ol.source.WMTSRequestEncoding.KVP) { - goog.object.extend(context, { + ol.object.assign(context, { 'Service': 'WMTS', 'Request': 'GetTile', 'Version': this.version_, @@ -119621,7 +103859,7 @@ ol.source.WMTS = function(options) { 'TileCol': tileCoord[1], 'TileRow': -tileCoord[2] - 1 }; - goog.object.extend(localContext, dimensions); + ol.object.assign(localContext, dimensions); var url = template; if (requestEncoding == ol.source.WMTSRequestEncoding.KVP) { url = goog.uri.utils.appendParamsFromMap(url, localContext); @@ -119642,6 +103880,7 @@ ol.source.WMTS = function(options) { goog.base(this, { attributions: options.attributions, + cacheSize: options.cacheSize, crossOrigin: options.crossOrigin, logo: options.logo, projection: options.projection, @@ -119655,6 +103894,8 @@ ol.source.WMTS = function(options) { wrapX: options.wrapX !== undefined ? options.wrapX : false }); + this.setKey(this.getKeyForDimensions_()); + }; goog.inherits(ol.source.WMTS, ol.source.TileImage); @@ -119682,14 +103923,6 @@ ol.source.WMTS.prototype.getFormat = function() { /** - * @inheritDoc - */ -ol.source.WMTS.prototype.getKeyParams = function() { - return this.dimensionsKey_; -}; - - -/** * Return the layer of the WMTS source. * @return {string} Layer. * @api @@ -119741,14 +103974,15 @@ ol.source.WMTS.prototype.getVersion = function() { /** * @private + * @return {string} The key for the current dimensions. */ -ol.source.WMTS.prototype.resetDimensionsKey_ = function() { +ol.source.WMTS.prototype.getKeyForDimensions_ = function() { var i = 0; var res = []; for (var key in this.dimensions_) { res[i++] = key + '-' + this.dimensions_[key]; } - this.dimensionsKey_ = res.join('/'); + return res.join('/'); }; @@ -119758,9 +103992,8 @@ ol.source.WMTS.prototype.resetDimensionsKey_ = function() { * @api */ ol.source.WMTS.prototype.updateDimensions = function(dimensions) { - goog.object.extend(this.dimensions_, dimensions); - this.resetDimensionsKey_(); - this.changed(); + ol.object.assign(this.dimensions_, dimensions); + this.setKey(this.getKeyForDimensions_()); }; @@ -119794,7 +104027,7 @@ ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) { 'config "layer" must not be null'); var layers = wmtsCap['Contents']['Layer']; - var l = goog.array.find(layers, function(elt, index, array) { + var l = ol.array.find(layers, function(elt, index, array) { return elt['Identifier'] == config['layer']; }); goog.asserts.assert(l, 'found a matching layer in Contents/Layer'); @@ -119805,9 +104038,9 @@ ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) { var idx, matrixSet; if (l['TileMatrixSetLink'].length > 1) { if ('projection' in config) { - idx = goog.array.findIndex(l['TileMatrixSetLink'], + idx = ol.array.findIndex(l['TileMatrixSetLink'], function(elt, index, array) { - var tileMatrixSet = goog.array.find(tileMatrixSets, function(el) { + var tileMatrixSet = ol.array.find(tileMatrixSets, function(el) { return el['Identifier'] == elt['TileMatrixSet']; }); return tileMatrixSet['SupportedCRS'].replace( @@ -119815,7 +104048,7 @@ ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) { ) == config['projection']; }); } else { - idx = goog.array.findIndex(l['TileMatrixSetLink'], + idx = ol.array.findIndex(l['TileMatrixSetLink'], function(elt, index, array) { return elt['TileMatrixSet'] == config['matrixSet']; }); @@ -119835,7 +104068,7 @@ ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) { if ('format' in config) { format = config['format']; } - idx = goog.array.findIndex(l['Style'], function(elt, index, array) { + idx = ol.array.findIndex(l['Style'], function(elt, index, array) { if ('style' in config) { return elt['Title'] == config['style']; } else { @@ -119864,7 +104097,7 @@ ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) { } var matrixSets = wmtsCap['Contents']['TileMatrixSet']; - var matrixSetObj = goog.array.find(matrixSets, function(elt, index, array) { + var matrixSetObj = ol.array.find(matrixSets, function(elt, index, array) { return elt['Identifier'] == matrixSet; }); goog.asserts.assert(matrixSetObj, @@ -119924,7 +104157,7 @@ ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) { var gets = wmtsCap['OperationsMetadata']['GetTile']['DCP']['HTTP']['Get']; for (var i = 0, ii = gets.length; i < ii; ++i) { - var constraint = goog.array.find(gets[i]['Constraint'], + var constraint = ol.array.find(gets[i]['Constraint'], function(elt, index, array) { return elt['name'] == 'GetEncoding'; }); @@ -119957,7 +104190,6 @@ goog.provide('ol.source.Zoomify'); goog.require('goog.asserts'); goog.require('ol'); goog.require('ol.ImageTile'); -goog.require('ol.TileCoord'); goog.require('ol.TileState'); goog.require('ol.dom'); goog.require('ol.extent'); @@ -119975,7 +104207,6 @@ ol.source.ZoomifyTierSizeCalculation = { }; - /** * @classdesc * Layer source for tile data in Zoomify format. @@ -120076,6 +104307,7 @@ ol.source.Zoomify = function(opt_options) { goog.base(this, { attributions: options.attributions, + cacheSize: options.cacheSize, crossOrigin: options.crossOrigin, logo: options.logo, reprojectionErrorThreshold: options.reprojectionErrorThreshold, @@ -120088,7 +104320,6 @@ ol.source.Zoomify = function(opt_options) { goog.inherits(ol.source.Zoomify, ol.source.TileImage); - /** * @constructor * @extends {ol.ImageTile} @@ -120146,21 +104377,8 @@ goog.provide('ol.style.Atlas'); goog.provide('ol.style.AtlasManager'); goog.require('goog.asserts'); -goog.require('goog.functions'); -goog.require('goog.object'); goog.require('ol'); - - -/** - * Provides information for an image inside an atlas manager. - * `offsetX` and `offsetY` is the position of the image inside - * the atlas image `image` and the position of the hit-detection image - * inside the hit-detection atlas image `hitImage`. - * @typedef {{offsetX: number, offsetY: number, image: HTMLCanvasElement, - * hitImage: HTMLCanvasElement}} - */ -ol.style.AtlasManagerInfo; - +goog.require('ol.dom'); /** @@ -120314,8 +104532,7 @@ ol.style.AtlasManager.prototype.mergeInfos_ = function(info, hitInfo) { * @return {?ol.style.AtlasManagerInfo} The position and atlas image for the * entry, or `null` if the image is too big. */ -ol.style.AtlasManager.prototype.add = - function(id, width, height, +ol.style.AtlasManager.prototype.add = function(id, width, height, renderCallback, opt_renderHitCallback, opt_this) { if (width + this.space_ > this.maxSize_ || height + this.space_ > this.maxSize_) { @@ -120333,7 +104550,7 @@ ol.style.AtlasManager.prototype.add = // the hit-detection atlas, to make sure that the offset is the same for // the original image and the hit-detection image. var renderHitCallback = opt_renderHitCallback !== undefined ? - opt_renderHitCallback : goog.functions.NULL; + opt_renderHitCallback : ol.nullFunction /** @type {?ol.style.AtlasInfo} */ var hitInfo = this.add_(true, @@ -120357,8 +104574,7 @@ ol.style.AtlasManager.prototype.add = * @return {?ol.style.AtlasInfo} The position and atlas image for the entry, * or `null` if the image is too big. */ -ol.style.AtlasManager.prototype.add_ = - function(isHitAtlas, id, width, height, +ol.style.AtlasManager.prototype.add_ = function(isHitAtlas, id, width, height, renderCallback, opt_this) { var atlases = (isHitAtlas) ? this.hitAtlases_ : this.atlases_; var atlas, info, i, ii; @@ -120389,16 +104605,6 @@ ol.style.AtlasManager.prototype.add_ = /** - * Provides information for an image inside an atlas. - * `offsetX` and `offsetY` are the position of the image inside - * the atlas image `image`. - * @typedef {{offsetX: number, offsetY: number, image: HTMLCanvasElement}} - */ -ol.style.AtlasInfo; - - - -/** * This class facilitates the creation of image atlases. * * Images added to an atlas will be rendered onto a single @@ -120425,7 +104631,7 @@ ol.style.Atlas = function(size, space) { /** * @private - * @type {Array.<ol.style.Atlas.Block>} + * @type {Array.<ol.style.AtlasBlock>} */ this.emptyBlocks_ = [{x: 0, y: 0, width: size, height: size}]; @@ -120437,29 +104643,24 @@ ol.style.Atlas = function(size, space) { /** * @private - * @type {HTMLCanvasElement} + * @type {CanvasRenderingContext2D} */ - this.canvas_ = /** @type {HTMLCanvasElement} */ - (document.createElement('CANVAS')); - this.canvas_.width = size; - this.canvas_.height = size; + this.context_ = ol.dom.createCanvasContext2D(size, size); /** * @private - * @type {CanvasRenderingContext2D} + * @type {HTMLCanvasElement} */ - this.context_ = /** @type {CanvasRenderingContext2D} */ - (this.canvas_.getContext('2d')); + this.canvas_ = this.context_.canvas; }; /** * @param {string} id The identifier of the entry to check. - * @return {?ol.style.AtlasInfo} + * @return {?ol.style.AtlasInfo} The atlas info. */ ol.style.Atlas.prototype.get = function(id) { - return /** @type {?ol.style.AtlasInfo} */ ( - goog.object.get(this.entries_, id, null)); + return this.entries_[id] || null; }; @@ -120473,8 +104674,7 @@ ol.style.Atlas.prototype.get = function(id) { * `renderCallback`. * @return {?ol.style.AtlasInfo} The position and atlas image for the entry. */ -ol.style.Atlas.prototype.add = - function(id, width, height, renderCallback, opt_this) { +ol.style.Atlas.prototype.add = function(id, width, height, renderCallback, opt_this) { var block, i, ii; for (i = 0, ii = this.emptyBlocks_.length; i < ii; ++i) { block = this.emptyBlocks_[i]; @@ -120507,18 +104707,17 @@ ol.style.Atlas.prototype.add = /** * @private * @param {number} index The index of the block. - * @param {ol.style.Atlas.Block} block The block to split. + * @param {ol.style.AtlasBlock} block The block to split. * @param {number} width The width of the entry to insert. * @param {number} height The height of the entry to insert. */ -ol.style.Atlas.prototype.split_ = - function(index, block, width, height) { +ol.style.Atlas.prototype.split_ = function(index, block, width, height) { var deltaWidth = block.width - width; var deltaHeight = block.height - height; - /** @type {ol.style.Atlas.Block} */ + /** @type {ol.style.AtlasBlock} */ var newBlock1; - /** @type {ol.style.Atlas.Block} */ + /** @type {ol.style.AtlasBlock} */ var newBlock2; if (deltaWidth > deltaHeight) { @@ -120567,11 +104766,10 @@ ol.style.Atlas.prototype.split_ = * blocks (that are potentially smaller) are filled first. * @private * @param {number} index The index of the block to remove. - * @param {ol.style.Atlas.Block} newBlock1 The 1st block to add. - * @param {ol.style.Atlas.Block} newBlock2 The 2nd block to add. + * @param {ol.style.AtlasBlock} newBlock1 The 1st block to add. + * @param {ol.style.AtlasBlock} newBlock2 The 2nd block to add. */ -ol.style.Atlas.prototype.updateBlocks_ = - function(index, newBlock1, newBlock2) { +ol.style.Atlas.prototype.updateBlocks_ = function(index, newBlock1, newBlock2) { var args = [index, 1]; if (newBlock1.width > 0 && newBlock1.height > 0) { args.push(newBlock1); @@ -120582,20 +104780,15 @@ ol.style.Atlas.prototype.updateBlocks_ = this.emptyBlocks_.splice.apply(this.emptyBlocks_, args); }; - -/** - * @typedef {{x: number, y: number, width: number, height: number}} - */ -ol.style.Atlas.Block; - goog.provide('ol.style.RegularShape'); goog.require('goog.asserts'); goog.require('ol'); goog.require('ol.color'); +goog.require('ol.colorlike'); +goog.require('ol.dom'); goog.require('ol.has'); goog.require('ol.render.canvas'); -goog.require('ol.structs.IHasChecksum'); goog.require('ol.style.AtlasManager'); goog.require('ol.style.Fill'); goog.require('ol.style.Image'); @@ -120603,7 +104796,6 @@ goog.require('ol.style.ImageState'); goog.require('ol.style.Stroke'); - /** * @classdesc * Set regular shape style for vector features. The resulting shape will be @@ -120613,7 +104805,6 @@ goog.require('ol.style.Stroke'); * @constructor * @param {olx.style.RegularShapeOptions} options Options. * @extends {ol.style.Image} - * @implements {ol.structs.IHasChecksum} * @api */ ol.style.RegularShape = function(options) { @@ -120716,9 +104907,15 @@ ol.style.RegularShape = function(options) { var snapToPixel = options.snapToPixel !== undefined ? options.snapToPixel : true; + /** + * @type {boolean} + */ + var rotateWithView = options.rotateWithView !== undefined ? + options.rotateWithView : false; + goog.base(this, { opacity: 1, - rotateWithView: false, + rotateWithView: rotateWithView, rotation: options.rotation !== undefined ? options.rotation : 0, scale: 1, snapToPixel: snapToPixel @@ -120875,22 +105072,8 @@ ol.style.RegularShape.prototype.unlistenImageChange = ol.nullFunction; /** - * @typedef {{ - * strokeStyle: (string|undefined), - * strokeWidth: number, - * size: number, - * lineCap: string, - * lineDash: Array.<number>, - * lineJoin: string, - * miterLimit: number - * }} - */ -ol.style.RegularShape.RenderOptions; - - -/** * @private - * @param {ol.style.AtlasManager|undefined} atlasManager + * @param {ol.style.AtlasManager|undefined} atlasManager An atlas manager. */ ol.style.RegularShape.prototype.render_ = function(atlasManager) { var imageSize; @@ -120927,7 +105110,7 @@ ol.style.RegularShape.prototype.render_ = function(atlasManager) { var size = 2 * (this.radius_ + strokeWidth) + 1; - /** @type {ol.style.RegularShape.RenderOptions} */ + /** @type {ol.style.RegularShapeRenderOptions} */ var renderOptions = { strokeStyle: strokeStyle, strokeWidth: strokeWidth, @@ -120940,18 +105123,13 @@ ol.style.RegularShape.prototype.render_ = function(atlasManager) { if (atlasManager === undefined) { // no atlas manager is used, create a new canvas - this.canvas_ = /** @type {HTMLCanvasElement} */ - (document.createElement('CANVAS')); - - this.canvas_.height = size; - this.canvas_.width = size; + var context = ol.dom.createCanvasContext2D(size, size); + this.canvas_ = context.canvas; // canvas.width and height are rounded to the closest integer size = this.canvas_.width; imageSize = size; - var context = /** @type {CanvasRenderingContext2D} */ - (this.canvas_.getContext('2d')); this.draw_(renderOptions, context, 0, 0); this.createHitDetectionCanvas_(renderOptions); @@ -120964,12 +105142,12 @@ ol.style.RegularShape.prototype.render_ = function(atlasManager) { if (hasCustomHitDetectionImage) { // render the hit-detection image into a separate atlas image renderHitDetectionCallback = - goog.bind(this.drawHitDetectionCanvas_, this, renderOptions); + this.drawHitDetectionCanvas_.bind(this, renderOptions); } var id = this.getChecksum(); var info = atlasManager.add( - id, size, size, goog.bind(this.draw_, this, renderOptions), + id, size, size, this.draw_.bind(this, renderOptions), renderHitDetectionCallback); goog.asserts.assert(info, 'shape size is too large'); @@ -120995,8 +105173,8 @@ ol.style.RegularShape.prototype.render_ = function(atlasManager) { /** * @private - * @param {ol.style.RegularShape.RenderOptions} renderOptions - * @param {CanvasRenderingContext2D} context + * @param {ol.style.RegularShapeRenderOptions} renderOptions Render options. + * @param {CanvasRenderingContext2D} context The rendering context. * @param {number} x The origin for the symbol (x). * @param {number} y The origin for the symbol (y). */ @@ -121020,7 +105198,7 @@ ol.style.RegularShape.prototype.draw_ = function(renderOptions, context, x, y) { } if (this.fill_) { - context.fillStyle = ol.color.asString(this.fill_.getColor()); + context.fillStyle = ol.colorlike.asColorLike(this.fill_.getColor()); context.fill(); } if (this.stroke_) { @@ -121040,10 +105218,9 @@ ol.style.RegularShape.prototype.draw_ = function(renderOptions, context, x, y) { /** * @private - * @param {ol.style.RegularShape.RenderOptions} renderOptions + * @param {ol.style.RegularShapeRenderOptions} renderOptions Render options. */ -ol.style.RegularShape.prototype.createHitDetectionCanvas_ = - function(renderOptions) { +ol.style.RegularShape.prototype.createHitDetectionCanvas_ = function(renderOptions) { this.hitDetectionImageSize_ = [renderOptions.size, renderOptions.size]; if (this.fill_) { this.hitDetectionCanvas_ = this.canvas_; @@ -121052,28 +105229,21 @@ ol.style.RegularShape.prototype.createHitDetectionCanvas_ = // if no fill style is set, create an extra hit-detection image with a // default fill style - this.hitDetectionCanvas_ = /** @type {HTMLCanvasElement} */ - (document.createElement('CANVAS')); - var canvas = this.hitDetectionCanvas_; - - canvas.height = renderOptions.size; - canvas.width = renderOptions.size; + var context = ol.dom.createCanvasContext2D(renderOptions.size, renderOptions.size); + this.hitDetectionCanvas_ = context.canvas; - var context = /** @type {CanvasRenderingContext2D} */ - (canvas.getContext('2d')); this.drawHitDetectionCanvas_(renderOptions, context, 0, 0); }; /** * @private - * @param {ol.style.RegularShape.RenderOptions} renderOptions - * @param {CanvasRenderingContext2D} context + * @param {ol.style.RegularShapeRenderOptions} renderOptions Render options. + * @param {CanvasRenderingContext2D} context The context. * @param {number} x The origin for the symbol (x). * @param {number} y The origin for the symbol (y). */ -ol.style.RegularShape.prototype.drawHitDetectionCanvas_ = - function(renderOptions, context, x, y) { +ol.style.RegularShape.prototype.drawHitDetectionCanvas_ = function(renderOptions, context, x, y) { // reset transform context.setTransform(1, 0, 0, 1, 0, 0); @@ -121107,7 +105277,7 @@ ol.style.RegularShape.prototype.drawHitDetectionCanvas_ = /** - * @inheritDoc + * @return {string} The checksum. */ ol.style.RegularShape.prototype.getChecksum = function() { var strokeChecksum = this.stroke_ ? @@ -121153,10 +105323,34 @@ ol.style.RegularShape.prototype.getChecksum = function() { // // This file has been auto-generated by GenJsDeps, please do not edit. -goog.addDependency('demos/editor/equationeditor.js', ['goog.demos.editor.EquationEditor'], ['goog.ui.equation.EquationEditorDialog']); -goog.addDependency('demos/editor/helloworld.js', ['goog.demos.editor.HelloWorld'], ['goog.dom', 'goog.dom.TagName', 'goog.editor.Plugin']); -goog.addDependency('demos/editor/helloworlddialog.js', ['goog.demos.editor.HelloWorldDialog', 'goog.demos.editor.HelloWorldDialog.OkEvent'], ['goog.dom.TagName', 'goog.events.Event', 'goog.string', 'goog.ui.editor.AbstractDialog', 'goog.ui.editor.AbstractDialog.Builder', 'goog.ui.editor.AbstractDialog.EventType']); -goog.addDependency('demos/editor/helloworlddialogplugin.js', ['goog.demos.editor.HelloWorldDialogPlugin', 'goog.demos.editor.HelloWorldDialogPlugin.Command'], ['goog.demos.editor.HelloWorldDialog', 'goog.dom.TagName', 'goog.editor.plugins.AbstractDialogPlugin', 'goog.editor.range', 'goog.functions', 'goog.ui.editor.AbstractDialog.EventType']); +goog.addDependency( + 'demos/editor/equationeditor.js', ['goog.demos.editor.EquationEditor'], + ['goog.ui.equation.EquationEditorDialog']); +goog.addDependency( + 'demos/editor/helloworld.js', ['goog.demos.editor.HelloWorld'], + ['goog.dom', 'goog.dom.TagName', 'goog.editor.Plugin']); +goog.addDependency( + 'demos/editor/helloworlddialog.js', + [ + 'goog.demos.editor.HelloWorldDialog', + 'goog.demos.editor.HelloWorldDialog.OkEvent' + ], + [ + 'goog.dom.TagName', 'goog.events.Event', 'goog.string', + 'goog.ui.editor.AbstractDialog', 'goog.ui.editor.AbstractDialog.Builder', + 'goog.ui.editor.AbstractDialog.EventType' + ]); +goog.addDependency( + 'demos/editor/helloworlddialogplugin.js', + [ + 'goog.demos.editor.HelloWorldDialogPlugin', + 'goog.demos.editor.HelloWorldDialogPlugin.Command' + ], + [ + 'goog.demos.editor.HelloWorldDialog', 'goog.dom.TagName', + 'goog.editor.plugins.AbstractDialogPlugin', 'goog.editor.range', + 'goog.functions', 'goog.ui.editor.AbstractDialog.EventType' + ]); /** * @fileoverview Custom exports file. @@ -121168,24 +105362,16 @@ goog.require('ol.Attribution'); goog.require('ol.Collection'); goog.require('ol.CollectionEvent'); goog.require('ol.CollectionEventType'); -goog.require('ol.Color'); -goog.require('ol.Coordinate'); -goog.require('ol.CoordinateFormatType'); goog.require('ol.DeviceOrientation'); goog.require('ol.DeviceOrientationProperty'); goog.require('ol.DragBoxEvent'); -goog.require('ol.Extent'); goog.require('ol.Feature'); -goog.require('ol.FeatureLoader'); -goog.require('ol.FeatureStyleFunction'); -goog.require('ol.FeatureUrlFunction'); goog.require('ol.Geolocation'); goog.require('ol.GeolocationProperty'); goog.require('ol.Graticule'); goog.require('ol.Image'); goog.require('ol.ImageTile'); goog.require('ol.Kinetic'); -goog.require('ol.LoadingStrategy'); goog.require('ol.Map'); goog.require('ol.MapBrowserEvent'); goog.require('ol.MapBrowserEvent.EventType'); @@ -121201,7 +105387,6 @@ goog.require('ol.Observable'); goog.require('ol.Overlay'); goog.require('ol.OverlayPositioning'); goog.require('ol.OverlayProperty'); -goog.require('ol.Size'); goog.require('ol.Sphere'); goog.require('ol.Tile'); goog.require('ol.TileState'); @@ -121211,6 +105396,7 @@ goog.require('ol.ViewHint'); goog.require('ol.ViewProperty'); goog.require('ol.animation'); goog.require('ol.color'); +goog.require('ol.colorlike'); goog.require('ol.control'); goog.require('ol.control.Attribution'); goog.require('ol.control.Control'); @@ -121226,7 +105412,7 @@ goog.require('ol.control.ZoomSlider'); goog.require('ol.control.ZoomToExtent'); goog.require('ol.coordinate'); goog.require('ol.easing'); -goog.require('ol.events.ConditionType'); +goog.require('ol.events.Event'); goog.require('ol.events.condition'); goog.require('ol.extent'); goog.require('ol.extent.Corner'); @@ -121252,6 +105438,25 @@ goog.require('ol.format.WKT'); goog.require('ol.format.WMSCapabilities'); goog.require('ol.format.WMSGetFeatureInfo'); goog.require('ol.format.WMTSCapabilities'); +goog.require('ol.format.ogc.filter'); +goog.require('ol.format.ogc.filter.And'); +goog.require('ol.format.ogc.filter.Bbox'); +goog.require('ol.format.ogc.filter.Comparison'); +goog.require('ol.format.ogc.filter.ComparisonBinary'); +goog.require('ol.format.ogc.filter.EqualTo'); +goog.require('ol.format.ogc.filter.Filter'); +goog.require('ol.format.ogc.filter.GreaterThan'); +goog.require('ol.format.ogc.filter.GreaterThanOrEqualTo'); +goog.require('ol.format.ogc.filter.IsBetween'); +goog.require('ol.format.ogc.filter.IsLike'); +goog.require('ol.format.ogc.filter.IsNull'); +goog.require('ol.format.ogc.filter.LessThan'); +goog.require('ol.format.ogc.filter.LessThanOrEqualTo'); +goog.require('ol.format.ogc.filter.Logical'); +goog.require('ol.format.ogc.filter.LogicalBinary'); +goog.require('ol.format.ogc.filter.Not'); +goog.require('ol.format.ogc.filter.NotEqualTo'); +goog.require('ol.format.ogc.filter.Or'); goog.require('ol.geom.Circle'); goog.require('ol.geom.Geometry'); goog.require('ol.geom.GeometryCollection'); @@ -121278,7 +105483,6 @@ goog.require('ol.interaction.DragZoom'); goog.require('ol.interaction.Draw'); goog.require('ol.interaction.DrawEvent'); goog.require('ol.interaction.DrawEventType'); -goog.require('ol.interaction.DrawGeometryFunctionType'); goog.require('ol.interaction.DrawMode'); goog.require('ol.interaction.Interaction'); goog.require('ol.interaction.InteractionProperty'); @@ -121293,7 +105497,6 @@ goog.require('ol.interaction.Pointer'); goog.require('ol.interaction.Select'); goog.require('ol.interaction.SelectEvent'); goog.require('ol.interaction.SelectEventType'); -goog.require('ol.interaction.SelectFilterFunction'); goog.require('ol.interaction.Snap'); goog.require('ol.interaction.SnapProperty'); goog.require('ol.interaction.Translate'); @@ -121304,7 +105507,6 @@ goog.require('ol.layer.Heatmap'); goog.require('ol.layer.Image'); goog.require('ol.layer.Layer'); goog.require('ol.layer.LayerProperty'); -goog.require('ol.layer.LayerState'); goog.require('ol.layer.Tile'); goog.require('ol.layer.Vector'); goog.require('ol.layer.VectorTile'); @@ -121312,7 +105514,6 @@ goog.require('ol.loadingstrategy'); goog.require('ol.proj'); goog.require('ol.proj.METERS_PER_UNIT'); goog.require('ol.proj.Projection'); -goog.require('ol.proj.ProjectionLike'); goog.require('ol.proj.Units'); goog.require('ol.proj.common'); goog.require('ol.render'); @@ -121324,8 +105525,10 @@ goog.require('ol.render.canvas.Immediate'); goog.require('ol.render.webgl.Immediate'); goog.require('ol.size'); goog.require('ol.source.BingMaps'); +goog.require('ol.source.CartoDB'); goog.require('ol.source.Cluster'); goog.require('ol.source.Image'); +goog.require('ol.source.ImageArcGISRest'); goog.require('ol.source.ImageCanvas'); goog.require('ol.source.ImageEvent'); goog.require('ol.source.ImageMapGuide'); @@ -121346,7 +105549,6 @@ goog.require('ol.source.TileDebug'); goog.require('ol.source.TileEvent'); goog.require('ol.source.TileImage'); goog.require('ol.source.TileJSON'); -goog.require('ol.source.TileOptions'); goog.require('ol.source.TileUTFGrid'); goog.require('ol.source.TileWMS'); goog.require('ol.source.UrlTile'); @@ -121362,7 +105564,6 @@ goog.require('ol.style.Atlas'); goog.require('ol.style.AtlasManager'); goog.require('ol.style.Circle'); goog.require('ol.style.Fill'); -goog.require('ol.style.GeometryFunction'); goog.require('ol.style.Icon'); goog.require('ol.style.IconAnchorUnits'); goog.require('ol.style.IconImageCache'); @@ -121372,7 +105573,6 @@ goog.require('ol.style.ImageState'); goog.require('ol.style.RegularShape'); goog.require('ol.style.Stroke'); goog.require('ol.style.Style'); -goog.require('ol.style.StyleFunction'); goog.require('ol.style.Text'); goog.require('ol.style.defaultGeometryFunction'); goog.require('ol.tilegrid.TileGrid'); @@ -121483,6 +105683,11 @@ goog.exportProperty( ol.Collection.prototype.setAt); goog.exportSymbol( + 'ol.colorlike.asColorLike', + ol.colorlike.asColorLike, + OPENLAYERS); + +goog.exportSymbol( 'ol.coordinate.add', ol.coordinate.add, OPENLAYERS); @@ -122088,16 +106293,6 @@ goog.exportProperty( ol.MapBrowserEvent.prototype.dragging); goog.exportProperty( - ol.MapBrowserEvent.prototype, - 'preventDefault', - ol.MapBrowserEvent.prototype.preventDefault); - -goog.exportProperty( - ol.MapBrowserEvent.prototype, - 'stopPropagation', - ol.MapBrowserEvent.prototype.stopPropagation); - -goog.exportProperty( ol.MapEvent.prototype, 'map', ol.MapEvent.prototype.map); @@ -122284,6 +106479,16 @@ goog.exportProperty( goog.exportProperty( ol.VectorTile.prototype, + 'setFeatures', + ol.VectorTile.prototype.setFeatures); + +goog.exportProperty( + ol.VectorTile.prototype, + 'setProjection', + ol.VectorTile.prototype.setProjection); + +goog.exportProperty( + ol.VectorTile.prototype, 'setLoader', ol.VectorTile.prototype.setLoader); @@ -122329,6 +106534,11 @@ goog.exportProperty( goog.exportProperty( ol.View.prototype, + 'getResolutions', + ol.View.prototype.getResolutions); + +goog.exportProperty( + ol.View.prototype, 'getRotation', ol.View.prototype.getRotation); @@ -122888,6 +107098,26 @@ goog.exportSymbol( OPENLAYERS); goog.exportSymbol( + 'ol.source.CartoDB', + ol.source.CartoDB, + OPENLAYERS); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'getConfig', + ol.source.CartoDB.prototype.getConfig); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'updateConfig', + ol.source.CartoDB.prototype.updateConfig); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'setConfig', + ol.source.CartoDB.prototype.setConfig); + +goog.exportSymbol( 'ol.source.Cluster', ol.source.Cluster, OPENLAYERS); @@ -122898,6 +107128,41 @@ goog.exportProperty( ol.source.Cluster.prototype.getSource); goog.exportSymbol( + 'ol.source.ImageArcGISRest', + ol.source.ImageArcGISRest, + OPENLAYERS); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'getParams', + ol.source.ImageArcGISRest.prototype.getParams); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'getImageLoadFunction', + ol.source.ImageArcGISRest.prototype.getImageLoadFunction); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'getUrl', + ol.source.ImageArcGISRest.prototype.getUrl); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'setImageLoadFunction', + ol.source.ImageArcGISRest.prototype.setImageLoadFunction); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'setUrl', + ol.source.ImageArcGISRest.prototype.setUrl); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'updateParams', + ol.source.ImageArcGISRest.prototype.updateParams); + +goog.exportSymbol( 'ol.source.ImageCanvas', ol.source.ImageCanvas, OPENLAYERS); @@ -123079,6 +107344,11 @@ goog.exportProperty( goog.exportProperty( ol.source.Source.prototype, + 'refresh', + ol.source.Source.prototype.refresh); + +goog.exportProperty( + ol.source.Source.prototype, 'setAttributions', ol.source.Source.prototype.setAttributions); @@ -123127,6 +107397,11 @@ goog.exportSymbol( ol.source.TileJSON, OPENLAYERS); +goog.exportProperty( + ol.source.TileJSON.prototype, + 'getTileJSON', + ol.source.TileJSON.prototype.getTileJSON); + goog.exportSymbol( 'ol.source.Tile', ol.source.Tile, @@ -123284,6 +107559,16 @@ goog.exportProperty( goog.exportProperty( ol.source.Vector.prototype, + 'getFormat', + ol.source.Vector.prototype.getFormat); + +goog.exportProperty( + ol.source.Vector.prototype, + 'getUrl', + ol.source.Vector.prototype.getUrl); + +goog.exportProperty( + ol.source.Vector.prototype, 'removeFeature', ol.source.Vector.prototype.removeFeature); @@ -123409,13 +107694,13 @@ goog.exportSymbol( goog.exportProperty( ol.render.webgl.Immediate.prototype, - 'drawAsync', - ol.render.webgl.Immediate.prototype.drawAsync); + 'setStyle', + ol.render.webgl.Immediate.prototype.setStyle); goog.exportProperty( ol.render.webgl.Immediate.prototype, - 'drawCircleGeometry', - ol.render.webgl.Immediate.prototype.drawCircleGeometry); + 'drawGeometry', + ol.render.webgl.Immediate.prototype.drawGeometry); goog.exportProperty( ol.render.webgl.Immediate.prototype, @@ -123423,120 +107708,25 @@ goog.exportProperty( ol.render.webgl.Immediate.prototype.drawFeature); goog.exportProperty( - ol.render.webgl.Immediate.prototype, - 'drawGeometryCollectionGeometry', - ol.render.webgl.Immediate.prototype.drawGeometryCollectionGeometry); - -goog.exportProperty( - ol.render.webgl.Immediate.prototype, - 'drawPointGeometry', - ol.render.webgl.Immediate.prototype.drawPointGeometry); - -goog.exportProperty( - ol.render.webgl.Immediate.prototype, - 'drawLineStringGeometry', - ol.render.webgl.Immediate.prototype.drawLineStringGeometry); - -goog.exportProperty( - ol.render.webgl.Immediate.prototype, - 'drawMultiLineStringGeometry', - ol.render.webgl.Immediate.prototype.drawMultiLineStringGeometry); - -goog.exportProperty( - ol.render.webgl.Immediate.prototype, - 'drawMultiPointGeometry', - ol.render.webgl.Immediate.prototype.drawMultiPointGeometry); - -goog.exportProperty( - ol.render.webgl.Immediate.prototype, - 'drawMultiPolygonGeometry', - ol.render.webgl.Immediate.prototype.drawMultiPolygonGeometry); - -goog.exportProperty( - ol.render.webgl.Immediate.prototype, - 'drawPolygonGeometry', - ol.render.webgl.Immediate.prototype.drawPolygonGeometry); - -goog.exportProperty( - ol.render.webgl.Immediate.prototype, - 'drawText', - ol.render.webgl.Immediate.prototype.drawText); - -goog.exportProperty( - ol.render.webgl.Immediate.prototype, - 'setFillStrokeStyle', - ol.render.webgl.Immediate.prototype.setFillStrokeStyle); - -goog.exportProperty( - ol.render.webgl.Immediate.prototype, - 'setImageStyle', - ol.render.webgl.Immediate.prototype.setImageStyle); - -goog.exportProperty( - ol.render.webgl.Immediate.prototype, - 'setTextStyle', - ol.render.webgl.Immediate.prototype.setTextStyle); + ol.render.canvas.Immediate.prototype, + 'drawCircle', + ol.render.canvas.Immediate.prototype.drawCircle); goog.exportProperty( ol.render.canvas.Immediate.prototype, - 'drawAsync', - ol.render.canvas.Immediate.prototype.drawAsync); + 'setStyle', + ol.render.canvas.Immediate.prototype.setStyle); goog.exportProperty( ol.render.canvas.Immediate.prototype, - 'drawCircleGeometry', - ol.render.canvas.Immediate.prototype.drawCircleGeometry); + 'drawGeometry', + ol.render.canvas.Immediate.prototype.drawGeometry); goog.exportProperty( ol.render.canvas.Immediate.prototype, 'drawFeature', ol.render.canvas.Immediate.prototype.drawFeature); -goog.exportProperty( - ol.render.canvas.Immediate.prototype, - 'drawPointGeometry', - ol.render.canvas.Immediate.prototype.drawPointGeometry); - -goog.exportProperty( - ol.render.canvas.Immediate.prototype, - 'drawMultiPointGeometry', - ol.render.canvas.Immediate.prototype.drawMultiPointGeometry); - -goog.exportProperty( - ol.render.canvas.Immediate.prototype, - 'drawLineStringGeometry', - ol.render.canvas.Immediate.prototype.drawLineStringGeometry); - -goog.exportProperty( - ol.render.canvas.Immediate.prototype, - 'drawMultiLineStringGeometry', - ol.render.canvas.Immediate.prototype.drawMultiLineStringGeometry); - -goog.exportProperty( - ol.render.canvas.Immediate.prototype, - 'drawPolygonGeometry', - ol.render.canvas.Immediate.prototype.drawPolygonGeometry); - -goog.exportProperty( - ol.render.canvas.Immediate.prototype, - 'drawMultiPolygonGeometry', - ol.render.canvas.Immediate.prototype.drawMultiPolygonGeometry); - -goog.exportProperty( - ol.render.canvas.Immediate.prototype, - 'setFillStrokeStyle', - ol.render.canvas.Immediate.prototype.setFillStrokeStyle); - -goog.exportProperty( - ol.render.canvas.Immediate.prototype, - 'setImageStyle', - ol.render.canvas.Immediate.prototype.setImageStyle); - -goog.exportProperty( - ol.render.canvas.Immediate.prototype, - 'setTextStyle', - ol.render.canvas.Immediate.prototype.setTextStyle); - goog.exportSymbol( 'ol.proj.common.add', ol.proj.common.add, @@ -123608,6 +107798,11 @@ goog.exportProperty( ol.proj.Projection.prototype.getPointResolution); goog.exportSymbol( + 'ol.proj.setProj4', + ol.proj.setProj4, + OPENLAYERS); + +goog.exportSymbol( 'ol.proj.addEquivalentProjections', ol.proj.addEquivalentProjections, OPENLAYERS); @@ -123638,6 +107833,11 @@ goog.exportSymbol( OPENLAYERS); goog.exportSymbol( + 'ol.proj.equivalent', + ol.proj.equivalent, + OPENLAYERS); + +goog.exportSymbol( 'ol.proj.getTransform', ol.proj.getTransform, OPENLAYERS); @@ -123864,11 +108064,6 @@ goog.exportProperty( goog.exportProperty( ol.layer.VectorTile.prototype, - 'getSource', - ol.layer.VectorTile.prototype.getSource); - -goog.exportProperty( - ol.layer.VectorTile.prototype, 'getUseInterimTilesOnError', ol.layer.VectorTile.prototype.getUseInterimTilesOnError); @@ -123922,6 +108117,11 @@ goog.exportProperty( 'coordinate', ol.DragBoxEvent.prototype.coordinate); +goog.exportProperty( + ol.DragBoxEvent.prototype, + 'mapBrowserEvent', + ol.DragBoxEvent.prototype.mapBrowserEvent); + goog.exportSymbol( 'ol.interaction.DragBox', ol.interaction.DragBox, @@ -124052,6 +108252,11 @@ goog.exportSymbol( ol.interaction.Modify.handleEvent, OPENLAYERS); +goog.exportProperty( + ol.interaction.Modify.prototype, + 'removePoint', + ol.interaction.Modify.prototype.removePoint); + goog.exportSymbol( 'ol.interaction.MouseWheelZoom', ol.interaction.MouseWheelZoom, @@ -124224,6 +108429,11 @@ goog.exportProperty( goog.exportProperty( ol.geom.Geometry.prototype, + 'rotate', + ol.geom.Geometry.prototype.rotate); + +goog.exportProperty( + ol.geom.Geometry.prototype, 'simplify', ol.geom.Geometry.prototype.simplify); @@ -124334,6 +108544,11 @@ goog.exportProperty( goog.exportProperty( ol.geom.LineString.prototype, + 'getCoordinateAt', + ol.geom.LineString.prototype.getCoordinateAt); + +goog.exportProperty( + ol.geom.LineString.prototype, 'getLength', ol.geom.LineString.prototype.getLength); @@ -124849,6 +109064,16 @@ goog.exportSymbol( goog.exportProperty( ol.format.MVT.prototype, + 'readFeatures', + ol.format.MVT.prototype.readFeatures); + +goog.exportProperty( + ol.format.MVT.prototype, + 'readProjection', + ol.format.MVT.prototype.readProjection); + +goog.exportProperty( + ol.format.MVT.prototype, 'setLayers', ol.format.MVT.prototype.setLayers); @@ -125033,6 +109258,151 @@ goog.exportProperty( ol.format.WMTSCapabilities.prototype.read); goog.exportSymbol( + 'ol.format.ogc.filter.and', + ol.format.ogc.filter.and, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.or', + ol.format.ogc.filter.or, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.not', + ol.format.ogc.filter.not, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.bbox', + ol.format.ogc.filter.bbox, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.equalTo', + ol.format.ogc.filter.equalTo, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.notEqualTo', + ol.format.ogc.filter.notEqualTo, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.lessThan', + ol.format.ogc.filter.lessThan, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.lessThanOrEqualTo', + ol.format.ogc.filter.lessThanOrEqualTo, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.greaterThan', + ol.format.ogc.filter.greaterThan, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.greaterThanOrEqualTo', + ol.format.ogc.filter.greaterThanOrEqualTo, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.isNull', + ol.format.ogc.filter.isNull, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.between', + ol.format.ogc.filter.between, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.like', + ol.format.ogc.filter.like, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.Filter', + ol.format.ogc.filter.Filter, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.And', + ol.format.ogc.filter.And, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.Or', + ol.format.ogc.filter.Or, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.Not', + ol.format.ogc.filter.Not, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.Bbox', + ol.format.ogc.filter.Bbox, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.Comparison', + ol.format.ogc.filter.Comparison, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.ComparisonBinary', + ol.format.ogc.filter.ComparisonBinary, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.EqualTo', + ol.format.ogc.filter.EqualTo, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.NotEqualTo', + ol.format.ogc.filter.NotEqualTo, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.LessThan', + ol.format.ogc.filter.LessThan, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.LessThanOrEqualTo', + ol.format.ogc.filter.LessThanOrEqualTo, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.GreaterThan', + ol.format.ogc.filter.GreaterThan, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.GreaterThanOrEqualTo', + ol.format.ogc.filter.GreaterThanOrEqualTo, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.IsNull', + ol.format.ogc.filter.IsNull, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.IsBetween', + ol.format.ogc.filter.IsBetween, + OPENLAYERS); + +goog.exportSymbol( + 'ol.format.ogc.filter.IsLike', + ol.format.ogc.filter.IsLike, + OPENLAYERS); + +goog.exportSymbol( 'ol.format.GML2', ol.format.GML2, OPENLAYERS); @@ -125143,6 +109513,31 @@ goog.exportSymbol( OPENLAYERS); goog.exportSymbol( + 'ol.events.condition.primaryAction', + ol.events.condition.primaryAction, + OPENLAYERS); + +goog.exportProperty( + ol.events.Event.prototype, + 'type', + ol.events.Event.prototype.type); + +goog.exportProperty( + ol.events.Event.prototype, + 'target', + ol.events.Event.prototype.target); + +goog.exportProperty( + ol.events.Event.prototype, + 'preventDefault', + ol.events.Event.prototype.preventDefault); + +goog.exportProperty( + ol.events.Event.prototype, + 'stopPropagation', + ol.events.Event.prototype.stopPropagation); + +goog.exportSymbol( 'ol.control.Attribution', ol.control.Attribution, OPENLAYERS); @@ -125328,6 +109723,26 @@ goog.exportSymbol( OPENLAYERS); goog.exportProperty( + ol.CollectionEvent.prototype, + 'type', + ol.CollectionEvent.prototype.type); + +goog.exportProperty( + ol.CollectionEvent.prototype, + 'target', + ol.CollectionEvent.prototype.target); + +goog.exportProperty( + ol.CollectionEvent.prototype, + 'preventDefault', + ol.CollectionEvent.prototype.preventDefault); + +goog.exportProperty( + ol.CollectionEvent.prototype, + 'stopPropagation', + ol.CollectionEvent.prototype.stopPropagation); + +goog.exportProperty( ol.Object.prototype, 'changed', ol.Object.prototype.changed); @@ -125693,6 +110108,26 @@ goog.exportProperty( ol.Map.prototype.unByKey); goog.exportProperty( + ol.MapEvent.prototype, + 'type', + ol.MapEvent.prototype.type); + +goog.exportProperty( + ol.MapEvent.prototype, + 'target', + ol.MapEvent.prototype.target); + +goog.exportProperty( + ol.MapEvent.prototype, + 'preventDefault', + ol.MapEvent.prototype.preventDefault); + +goog.exportProperty( + ol.MapEvent.prototype, + 'stopPropagation', + ol.MapEvent.prototype.stopPropagation); + +goog.exportProperty( ol.MapBrowserEvent.prototype, 'map', ol.MapBrowserEvent.prototype.map); @@ -125703,6 +110138,26 @@ goog.exportProperty( ol.MapBrowserEvent.prototype.frameState); goog.exportProperty( + ol.MapBrowserEvent.prototype, + 'type', + ol.MapBrowserEvent.prototype.type); + +goog.exportProperty( + ol.MapBrowserEvent.prototype, + 'target', + ol.MapBrowserEvent.prototype.target); + +goog.exportProperty( + ol.MapBrowserEvent.prototype, + 'preventDefault', + ol.MapBrowserEvent.prototype.preventDefault); + +goog.exportProperty( + ol.MapBrowserEvent.prototype, + 'stopPropagation', + ol.MapBrowserEvent.prototype.stopPropagation); + +goog.exportProperty( ol.MapBrowserPointerEvent.prototype, 'originalEvent', ol.MapBrowserPointerEvent.prototype.originalEvent); @@ -125743,6 +110198,36 @@ goog.exportProperty( ol.MapBrowserPointerEvent.prototype.frameState); goog.exportProperty( + ol.MapBrowserPointerEvent.prototype, + 'type', + ol.MapBrowserPointerEvent.prototype.type); + +goog.exportProperty( + ol.MapBrowserPointerEvent.prototype, + 'target', + ol.MapBrowserPointerEvent.prototype.target); + +goog.exportProperty( + ol.ObjectEvent.prototype, + 'type', + ol.ObjectEvent.prototype.type); + +goog.exportProperty( + ol.ObjectEvent.prototype, + 'target', + ol.ObjectEvent.prototype.target); + +goog.exportProperty( + ol.ObjectEvent.prototype, + 'preventDefault', + ol.ObjectEvent.prototype.preventDefault); + +goog.exportProperty( + ol.ObjectEvent.prototype, + 'stopPropagation', + ol.ObjectEvent.prototype.stopPropagation); + +goog.exportProperty( ol.Overlay.prototype, 'get', ol.Overlay.prototype.get); @@ -126129,6 +110614,11 @@ goog.exportProperty( goog.exportProperty( ol.source.Tile.prototype, + 'refresh', + ol.source.Tile.prototype.refresh); + +goog.exportProperty( + ol.source.Tile.prototype, 'setAttributions', ol.source.Tile.prototype.setAttributions); @@ -126204,6 +110694,11 @@ goog.exportProperty( goog.exportProperty( ol.source.UrlTile.prototype, + 'refresh', + ol.source.UrlTile.prototype.refresh); + +goog.exportProperty( + ol.source.UrlTile.prototype, 'getAttributions', ol.source.UrlTile.prototype.getAttributions); @@ -126334,6 +110829,11 @@ goog.exportProperty( goog.exportProperty( ol.source.TileImage.prototype, + 'refresh', + ol.source.TileImage.prototype.refresh); + +goog.exportProperty( + ol.source.TileImage.prototype, 'getAttributions', ol.source.TileImage.prototype.getAttributions); @@ -126474,6 +110974,11 @@ goog.exportProperty( goog.exportProperty( ol.source.BingMaps.prototype, + 'refresh', + ol.source.BingMaps.prototype.refresh); + +goog.exportProperty( + ol.source.BingMaps.prototype, 'getAttributions', ol.source.BingMaps.prototype.getAttributions); @@ -126563,6 +111068,296 @@ goog.exportProperty( ol.source.BingMaps.prototype.unByKey); goog.exportProperty( + ol.source.XYZ.prototype, + 'setRenderReprojectionEdges', + ol.source.XYZ.prototype.setRenderReprojectionEdges); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'setTileGridForProjection', + ol.source.XYZ.prototype.setTileGridForProjection); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'getTileLoadFunction', + ol.source.XYZ.prototype.getTileLoadFunction); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'getTileUrlFunction', + ol.source.XYZ.prototype.getTileUrlFunction); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'getUrls', + ol.source.XYZ.prototype.getUrls); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'setTileLoadFunction', + ol.source.XYZ.prototype.setTileLoadFunction); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'setTileUrlFunction', + ol.source.XYZ.prototype.setTileUrlFunction); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'setUrl', + ol.source.XYZ.prototype.setUrl); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'setUrls', + ol.source.XYZ.prototype.setUrls); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'getTileGrid', + ol.source.XYZ.prototype.getTileGrid); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'refresh', + ol.source.XYZ.prototype.refresh); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'getAttributions', + ol.source.XYZ.prototype.getAttributions); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'getLogo', + ol.source.XYZ.prototype.getLogo); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'getProjection', + ol.source.XYZ.prototype.getProjection); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'getState', + ol.source.XYZ.prototype.getState); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'setAttributions', + ol.source.XYZ.prototype.setAttributions); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'get', + ol.source.XYZ.prototype.get); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'getKeys', + ol.source.XYZ.prototype.getKeys); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'getProperties', + ol.source.XYZ.prototype.getProperties); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'set', + ol.source.XYZ.prototype.set); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'setProperties', + ol.source.XYZ.prototype.setProperties); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'unset', + ol.source.XYZ.prototype.unset); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'changed', + ol.source.XYZ.prototype.changed); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'dispatchEvent', + ol.source.XYZ.prototype.dispatchEvent); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'getRevision', + ol.source.XYZ.prototype.getRevision); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'on', + ol.source.XYZ.prototype.on); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'once', + ol.source.XYZ.prototype.once); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'un', + ol.source.XYZ.prototype.un); + +goog.exportProperty( + ol.source.XYZ.prototype, + 'unByKey', + ol.source.XYZ.prototype.unByKey); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'setRenderReprojectionEdges', + ol.source.CartoDB.prototype.setRenderReprojectionEdges); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'setTileGridForProjection', + ol.source.CartoDB.prototype.setTileGridForProjection); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'getTileLoadFunction', + ol.source.CartoDB.prototype.getTileLoadFunction); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'getTileUrlFunction', + ol.source.CartoDB.prototype.getTileUrlFunction); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'getUrls', + ol.source.CartoDB.prototype.getUrls); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'setTileLoadFunction', + ol.source.CartoDB.prototype.setTileLoadFunction); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'setTileUrlFunction', + ol.source.CartoDB.prototype.setTileUrlFunction); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'setUrl', + ol.source.CartoDB.prototype.setUrl); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'setUrls', + ol.source.CartoDB.prototype.setUrls); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'getTileGrid', + ol.source.CartoDB.prototype.getTileGrid); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'refresh', + ol.source.CartoDB.prototype.refresh); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'getAttributions', + ol.source.CartoDB.prototype.getAttributions); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'getLogo', + ol.source.CartoDB.prototype.getLogo); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'getProjection', + ol.source.CartoDB.prototype.getProjection); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'getState', + ol.source.CartoDB.prototype.getState); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'setAttributions', + ol.source.CartoDB.prototype.setAttributions); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'get', + ol.source.CartoDB.prototype.get); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'getKeys', + ol.source.CartoDB.prototype.getKeys); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'getProperties', + ol.source.CartoDB.prototype.getProperties); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'set', + ol.source.CartoDB.prototype.set); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'setProperties', + ol.source.CartoDB.prototype.setProperties); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'unset', + ol.source.CartoDB.prototype.unset); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'changed', + ol.source.CartoDB.prototype.changed); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'dispatchEvent', + ol.source.CartoDB.prototype.dispatchEvent); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'getRevision', + ol.source.CartoDB.prototype.getRevision); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'on', + ol.source.CartoDB.prototype.on); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'once', + ol.source.CartoDB.prototype.once); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'un', + ol.source.CartoDB.prototype.un); + +goog.exportProperty( + ol.source.CartoDB.prototype, + 'unByKey', + ol.source.CartoDB.prototype.unByKey); + +goog.exportProperty( ol.source.Vector.prototype, 'getAttributions', ol.source.Vector.prototype.getAttributions); @@ -126584,6 +111379,11 @@ goog.exportProperty( goog.exportProperty( ol.source.Vector.prototype, + 'refresh', + ol.source.Vector.prototype.refresh); + +goog.exportProperty( + ol.source.Vector.prototype, 'setAttributions', ol.source.Vector.prototype.setAttributions); @@ -126719,6 +111519,16 @@ goog.exportProperty( goog.exportProperty( ol.source.Cluster.prototype, + 'getFormat', + ol.source.Cluster.prototype.getFormat); + +goog.exportProperty( + ol.source.Cluster.prototype, + 'getUrl', + ol.source.Cluster.prototype.getUrl); + +goog.exportProperty( + ol.source.Cluster.prototype, 'removeFeature', ol.source.Cluster.prototype.removeFeature); @@ -126744,6 +111554,11 @@ goog.exportProperty( goog.exportProperty( ol.source.Cluster.prototype, + 'refresh', + ol.source.Cluster.prototype.refresh); + +goog.exportProperty( + ol.source.Cluster.prototype, 'setAttributions', ol.source.Cluster.prototype.setAttributions); @@ -126834,6 +111649,11 @@ goog.exportProperty( goog.exportProperty( ol.source.Image.prototype, + 'refresh', + ol.source.Image.prototype.refresh); + +goog.exportProperty( + ol.source.Image.prototype, 'setAttributions', ol.source.Image.prototype.setAttributions); @@ -126903,6 +111723,101 @@ goog.exportProperty( ol.source.Image.prototype.unByKey); goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'getAttributions', + ol.source.ImageArcGISRest.prototype.getAttributions); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'getLogo', + ol.source.ImageArcGISRest.prototype.getLogo); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'getProjection', + ol.source.ImageArcGISRest.prototype.getProjection); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'getState', + ol.source.ImageArcGISRest.prototype.getState); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'refresh', + ol.source.ImageArcGISRest.prototype.refresh); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'setAttributions', + ol.source.ImageArcGISRest.prototype.setAttributions); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'get', + ol.source.ImageArcGISRest.prototype.get); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'getKeys', + ol.source.ImageArcGISRest.prototype.getKeys); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'getProperties', + ol.source.ImageArcGISRest.prototype.getProperties); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'set', + ol.source.ImageArcGISRest.prototype.set); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'setProperties', + ol.source.ImageArcGISRest.prototype.setProperties); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'unset', + ol.source.ImageArcGISRest.prototype.unset); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'changed', + ol.source.ImageArcGISRest.prototype.changed); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'dispatchEvent', + ol.source.ImageArcGISRest.prototype.dispatchEvent); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'getRevision', + ol.source.ImageArcGISRest.prototype.getRevision); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'on', + ol.source.ImageArcGISRest.prototype.on); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'once', + ol.source.ImageArcGISRest.prototype.once); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'un', + ol.source.ImageArcGISRest.prototype.un); + +goog.exportProperty( + ol.source.ImageArcGISRest.prototype, + 'unByKey', + ol.source.ImageArcGISRest.prototype.unByKey); + +goog.exportProperty( ol.source.ImageCanvas.prototype, 'getAttributions', ol.source.ImageCanvas.prototype.getAttributions); @@ -126924,6 +111839,11 @@ goog.exportProperty( goog.exportProperty( ol.source.ImageCanvas.prototype, + 'refresh', + ol.source.ImageCanvas.prototype.refresh); + +goog.exportProperty( + ol.source.ImageCanvas.prototype, 'setAttributions', ol.source.ImageCanvas.prototype.setAttributions); @@ -127014,6 +111934,11 @@ goog.exportProperty( goog.exportProperty( ol.source.ImageMapGuide.prototype, + 'refresh', + ol.source.ImageMapGuide.prototype.refresh); + +goog.exportProperty( + ol.source.ImageMapGuide.prototype, 'setAttributions', ol.source.ImageMapGuide.prototype.setAttributions); @@ -127083,6 +112008,26 @@ goog.exportProperty( ol.source.ImageMapGuide.prototype.unByKey); goog.exportProperty( + ol.source.ImageEvent.prototype, + 'type', + ol.source.ImageEvent.prototype.type); + +goog.exportProperty( + ol.source.ImageEvent.prototype, + 'target', + ol.source.ImageEvent.prototype.target); + +goog.exportProperty( + ol.source.ImageEvent.prototype, + 'preventDefault', + ol.source.ImageEvent.prototype.preventDefault); + +goog.exportProperty( + ol.source.ImageEvent.prototype, + 'stopPropagation', + ol.source.ImageEvent.prototype.stopPropagation); + +goog.exportProperty( ol.source.ImageStatic.prototype, 'getAttributions', ol.source.ImageStatic.prototype.getAttributions); @@ -127104,6 +112049,11 @@ goog.exportProperty( goog.exportProperty( ol.source.ImageStatic.prototype, + 'refresh', + ol.source.ImageStatic.prototype.refresh); + +goog.exportProperty( + ol.source.ImageStatic.prototype, 'setAttributions', ol.source.ImageStatic.prototype.setAttributions); @@ -127194,6 +112144,11 @@ goog.exportProperty( goog.exportProperty( ol.source.ImageVector.prototype, + 'refresh', + ol.source.ImageVector.prototype.refresh); + +goog.exportProperty( + ol.source.ImageVector.prototype, 'setAttributions', ol.source.ImageVector.prototype.setAttributions); @@ -127284,6 +112239,11 @@ goog.exportProperty( goog.exportProperty( ol.source.ImageWMS.prototype, + 'refresh', + ol.source.ImageWMS.prototype.refresh); + +goog.exportProperty( + ol.source.ImageWMS.prototype, 'setAttributions', ol.source.ImageWMS.prototype.setAttributions); @@ -127353,146 +112313,6 @@ goog.exportProperty( ol.source.ImageWMS.prototype.unByKey); goog.exportProperty( - ol.source.XYZ.prototype, - 'setRenderReprojectionEdges', - ol.source.XYZ.prototype.setRenderReprojectionEdges); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'setTileGridForProjection', - ol.source.XYZ.prototype.setTileGridForProjection); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'getTileLoadFunction', - ol.source.XYZ.prototype.getTileLoadFunction); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'getTileUrlFunction', - ol.source.XYZ.prototype.getTileUrlFunction); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'getUrls', - ol.source.XYZ.prototype.getUrls); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'setTileLoadFunction', - ol.source.XYZ.prototype.setTileLoadFunction); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'setTileUrlFunction', - ol.source.XYZ.prototype.setTileUrlFunction); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'setUrl', - ol.source.XYZ.prototype.setUrl); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'setUrls', - ol.source.XYZ.prototype.setUrls); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'getTileGrid', - ol.source.XYZ.prototype.getTileGrid); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'getAttributions', - ol.source.XYZ.prototype.getAttributions); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'getLogo', - ol.source.XYZ.prototype.getLogo); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'getProjection', - ol.source.XYZ.prototype.getProjection); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'getState', - ol.source.XYZ.prototype.getState); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'setAttributions', - ol.source.XYZ.prototype.setAttributions); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'get', - ol.source.XYZ.prototype.get); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'getKeys', - ol.source.XYZ.prototype.getKeys); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'getProperties', - ol.source.XYZ.prototype.getProperties); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'set', - ol.source.XYZ.prototype.set); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'setProperties', - ol.source.XYZ.prototype.setProperties); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'unset', - ol.source.XYZ.prototype.unset); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'changed', - ol.source.XYZ.prototype.changed); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'dispatchEvent', - ol.source.XYZ.prototype.dispatchEvent); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'getRevision', - ol.source.XYZ.prototype.getRevision); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'on', - ol.source.XYZ.prototype.on); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'once', - ol.source.XYZ.prototype.once); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'un', - ol.source.XYZ.prototype.un); - -goog.exportProperty( - ol.source.XYZ.prototype, - 'unByKey', - ol.source.XYZ.prototype.unByKey); - -goog.exportProperty( ol.source.MapQuest.prototype, 'setRenderReprojectionEdges', ol.source.MapQuest.prototype.setRenderReprojectionEdges); @@ -127544,6 +112364,11 @@ goog.exportProperty( goog.exportProperty( ol.source.MapQuest.prototype, + 'refresh', + ol.source.MapQuest.prototype.refresh); + +goog.exportProperty( + ol.source.MapQuest.prototype, 'getAttributions', ol.source.MapQuest.prototype.getAttributions); @@ -127684,6 +112509,11 @@ goog.exportProperty( goog.exportProperty( ol.source.OSM.prototype, + 'refresh', + ol.source.OSM.prototype.refresh); + +goog.exportProperty( + ol.source.OSM.prototype, 'getAttributions', ol.source.OSM.prototype.getAttributions); @@ -127794,6 +112624,11 @@ goog.exportProperty( goog.exportProperty( ol.source.Raster.prototype, + 'refresh', + ol.source.Raster.prototype.refresh); + +goog.exportProperty( + ol.source.Raster.prototype, 'setAttributions', ol.source.Raster.prototype.setAttributions); @@ -127863,6 +112698,26 @@ goog.exportProperty( ol.source.Raster.prototype.unByKey); goog.exportProperty( + ol.source.RasterEvent.prototype, + 'type', + ol.source.RasterEvent.prototype.type); + +goog.exportProperty( + ol.source.RasterEvent.prototype, + 'target', + ol.source.RasterEvent.prototype.target); + +goog.exportProperty( + ol.source.RasterEvent.prototype, + 'preventDefault', + ol.source.RasterEvent.prototype.preventDefault); + +goog.exportProperty( + ol.source.RasterEvent.prototype, + 'stopPropagation', + ol.source.RasterEvent.prototype.stopPropagation); + +goog.exportProperty( ol.source.Stamen.prototype, 'setRenderReprojectionEdges', ol.source.Stamen.prototype.setRenderReprojectionEdges); @@ -127914,6 +112769,11 @@ goog.exportProperty( goog.exportProperty( ol.source.Stamen.prototype, + 'refresh', + ol.source.Stamen.prototype.refresh); + +goog.exportProperty( + ol.source.Stamen.prototype, 'getAttributions', ol.source.Stamen.prototype.getAttributions); @@ -128054,6 +112914,11 @@ goog.exportProperty( goog.exportProperty( ol.source.TileArcGISRest.prototype, + 'refresh', + ol.source.TileArcGISRest.prototype.refresh); + +goog.exportProperty( + ol.source.TileArcGISRest.prototype, 'getAttributions', ol.source.TileArcGISRest.prototype.getAttributions); @@ -128149,6 +113014,11 @@ goog.exportProperty( goog.exportProperty( ol.source.TileDebug.prototype, + 'refresh', + ol.source.TileDebug.prototype.refresh); + +goog.exportProperty( + ol.source.TileDebug.prototype, 'getAttributions', ol.source.TileDebug.prototype.getAttributions); @@ -128289,6 +113159,11 @@ goog.exportProperty( goog.exportProperty( ol.source.TileJSON.prototype, + 'refresh', + ol.source.TileJSON.prototype.refresh); + +goog.exportProperty( + ol.source.TileJSON.prototype, 'getAttributions', ol.source.TileJSON.prototype.getAttributions); @@ -128378,12 +113253,37 @@ goog.exportProperty( ol.source.TileJSON.prototype.unByKey); goog.exportProperty( + ol.source.TileEvent.prototype, + 'type', + ol.source.TileEvent.prototype.type); + +goog.exportProperty( + ol.source.TileEvent.prototype, + 'target', + ol.source.TileEvent.prototype.target); + +goog.exportProperty( + ol.source.TileEvent.prototype, + 'preventDefault', + ol.source.TileEvent.prototype.preventDefault); + +goog.exportProperty( + ol.source.TileEvent.prototype, + 'stopPropagation', + ol.source.TileEvent.prototype.stopPropagation); + +goog.exportProperty( ol.source.TileUTFGrid.prototype, 'getTileGrid', ol.source.TileUTFGrid.prototype.getTileGrid); goog.exportProperty( ol.source.TileUTFGrid.prototype, + 'refresh', + ol.source.TileUTFGrid.prototype.refresh); + +goog.exportProperty( + ol.source.TileUTFGrid.prototype, 'getAttributions', ol.source.TileUTFGrid.prototype.getAttributions); @@ -128524,6 +113424,11 @@ goog.exportProperty( goog.exportProperty( ol.source.TileWMS.prototype, + 'refresh', + ol.source.TileWMS.prototype.refresh); + +goog.exportProperty( + ol.source.TileWMS.prototype, 'getAttributions', ol.source.TileWMS.prototype.getAttributions); @@ -128613,6 +113518,26 @@ goog.exportProperty( ol.source.TileWMS.prototype.unByKey); goog.exportProperty( + ol.source.VectorEvent.prototype, + 'type', + ol.source.VectorEvent.prototype.type); + +goog.exportProperty( + ol.source.VectorEvent.prototype, + 'target', + ol.source.VectorEvent.prototype.target); + +goog.exportProperty( + ol.source.VectorEvent.prototype, + 'preventDefault', + ol.source.VectorEvent.prototype.preventDefault); + +goog.exportProperty( + ol.source.VectorEvent.prototype, + 'stopPropagation', + ol.source.VectorEvent.prototype.stopPropagation); + +goog.exportProperty( ol.source.VectorTile.prototype, 'getTileLoadFunction', ol.source.VectorTile.prototype.getTileLoadFunction); @@ -128654,6 +113579,11 @@ goog.exportProperty( goog.exportProperty( ol.source.VectorTile.prototype, + 'refresh', + ol.source.VectorTile.prototype.refresh); + +goog.exportProperty( + ol.source.VectorTile.prototype, 'getAttributions', ol.source.VectorTile.prototype.getAttributions); @@ -128794,6 +113724,11 @@ goog.exportProperty( goog.exportProperty( ol.source.WMTS.prototype, + 'refresh', + ol.source.WMTS.prototype.refresh); + +goog.exportProperty( + ol.source.WMTS.prototype, 'getAttributions', ol.source.WMTS.prototype.getAttributions); @@ -128934,6 +113869,11 @@ goog.exportProperty( goog.exportProperty( ol.source.Zoomify.prototype, + 'refresh', + ol.source.Zoomify.prototype.refresh); + +goog.exportProperty( + ol.source.Zoomify.prototype, 'getAttributions', ol.source.Zoomify.prototype.getAttributions); @@ -129518,6 +114458,46 @@ goog.exportProperty( ol.renderer.canvas.VectorTileLayer.prototype.unByKey); goog.exportProperty( + ol.render.Event.prototype, + 'type', + ol.render.Event.prototype.type); + +goog.exportProperty( + ol.render.Event.prototype, + 'target', + ol.render.Event.prototype.target); + +goog.exportProperty( + ol.render.Event.prototype, + 'preventDefault', + ol.render.Event.prototype.preventDefault); + +goog.exportProperty( + ol.render.Event.prototype, + 'stopPropagation', + ol.render.Event.prototype.stopPropagation); + +goog.exportProperty( + ol.pointer.PointerEvent.prototype, + 'type', + ol.pointer.PointerEvent.prototype.type); + +goog.exportProperty( + ol.pointer.PointerEvent.prototype, + 'target', + ol.pointer.PointerEvent.prototype.target); + +goog.exportProperty( + ol.pointer.PointerEvent.prototype, + 'preventDefault', + ol.pointer.PointerEvent.prototype.preventDefault); + +goog.exportProperty( + ol.pointer.PointerEvent.prototype, + 'stopPropagation', + ol.pointer.PointerEvent.prototype.stopPropagation); + +goog.exportProperty( ol.layer.Base.prototype, 'get', ol.layer.Base.prototype.get); @@ -130394,6 +115374,11 @@ goog.exportProperty( goog.exportProperty( ol.layer.VectorTile.prototype, + 'getSource', + ol.layer.VectorTile.prototype.getSource); + +goog.exportProperty( + ol.layer.VectorTile.prototype, 'getStyle', ol.layer.VectorTile.prototype.getStyle); @@ -130768,6 +115753,46 @@ goog.exportProperty( ol.interaction.DragAndDrop.prototype.unByKey); goog.exportProperty( + ol.interaction.DragAndDropEvent.prototype, + 'type', + ol.interaction.DragAndDropEvent.prototype.type); + +goog.exportProperty( + ol.interaction.DragAndDropEvent.prototype, + 'target', + ol.interaction.DragAndDropEvent.prototype.target); + +goog.exportProperty( + ol.interaction.DragAndDropEvent.prototype, + 'preventDefault', + ol.interaction.DragAndDropEvent.prototype.preventDefault); + +goog.exportProperty( + ol.interaction.DragAndDropEvent.prototype, + 'stopPropagation', + ol.interaction.DragAndDropEvent.prototype.stopPropagation); + +goog.exportProperty( + ol.DragBoxEvent.prototype, + 'type', + ol.DragBoxEvent.prototype.type); + +goog.exportProperty( + ol.DragBoxEvent.prototype, + 'target', + ol.DragBoxEvent.prototype.target); + +goog.exportProperty( + ol.DragBoxEvent.prototype, + 'preventDefault', + ol.DragBoxEvent.prototype.preventDefault); + +goog.exportProperty( + ol.DragBoxEvent.prototype, + 'stopPropagation', + ol.DragBoxEvent.prototype.stopPropagation); + +goog.exportProperty( ol.interaction.Pointer.prototype, 'getActive', ol.interaction.Pointer.prototype.getActive); @@ -131253,6 +116278,26 @@ goog.exportProperty( ol.interaction.DragZoom.prototype.unByKey); goog.exportProperty( + ol.interaction.DrawEvent.prototype, + 'type', + ol.interaction.DrawEvent.prototype.type); + +goog.exportProperty( + ol.interaction.DrawEvent.prototype, + 'target', + ol.interaction.DrawEvent.prototype.target); + +goog.exportProperty( + ol.interaction.DrawEvent.prototype, + 'preventDefault', + ol.interaction.DrawEvent.prototype.preventDefault); + +goog.exportProperty( + ol.interaction.DrawEvent.prototype, + 'stopPropagation', + ol.interaction.DrawEvent.prototype.stopPropagation); + +goog.exportProperty( ol.interaction.Draw.prototype, 'getActive', ol.interaction.Draw.prototype.getActive); @@ -131493,6 +116538,26 @@ goog.exportProperty( ol.interaction.KeyboardZoom.prototype.unByKey); goog.exportProperty( + ol.interaction.ModifyEvent.prototype, + 'type', + ol.interaction.ModifyEvent.prototype.type); + +goog.exportProperty( + ol.interaction.ModifyEvent.prototype, + 'target', + ol.interaction.ModifyEvent.prototype.target); + +goog.exportProperty( + ol.interaction.ModifyEvent.prototype, + 'preventDefault', + ol.interaction.ModifyEvent.prototype.preventDefault); + +goog.exportProperty( + ol.interaction.ModifyEvent.prototype, + 'stopPropagation', + ol.interaction.ModifyEvent.prototype.stopPropagation); + +goog.exportProperty( ol.interaction.Modify.prototype, 'getActive', ol.interaction.Modify.prototype.getActive); @@ -131813,6 +116878,26 @@ goog.exportProperty( ol.interaction.PinchZoom.prototype.unByKey); goog.exportProperty( + ol.interaction.SelectEvent.prototype, + 'type', + ol.interaction.SelectEvent.prototype.type); + +goog.exportProperty( + ol.interaction.SelectEvent.prototype, + 'target', + ol.interaction.SelectEvent.prototype.target); + +goog.exportProperty( + ol.interaction.SelectEvent.prototype, + 'preventDefault', + ol.interaction.SelectEvent.prototype.preventDefault); + +goog.exportProperty( + ol.interaction.SelectEvent.prototype, + 'stopPropagation', + ol.interaction.SelectEvent.prototype.stopPropagation); + +goog.exportProperty( ol.interaction.Select.prototype, 'getActive', ol.interaction.Select.prototype.getActive); @@ -131973,6 +117058,26 @@ goog.exportProperty( ol.interaction.Snap.prototype.unByKey); goog.exportProperty( + ol.interaction.TranslateEvent.prototype, + 'type', + ol.interaction.TranslateEvent.prototype.type); + +goog.exportProperty( + ol.interaction.TranslateEvent.prototype, + 'target', + ol.interaction.TranslateEvent.prototype.target); + +goog.exportProperty( + ol.interaction.TranslateEvent.prototype, + 'preventDefault', + ol.interaction.TranslateEvent.prototype.preventDefault); + +goog.exportProperty( + ol.interaction.TranslateEvent.prototype, + 'stopPropagation', + ol.interaction.TranslateEvent.prototype.stopPropagation); + +goog.exportProperty( ol.interaction.Translate.prototype, 'getActive', ol.interaction.Translate.prototype.getActive); @@ -132129,6 +117234,11 @@ goog.exportProperty( goog.exportProperty( ol.geom.SimpleGeometry.prototype, + 'rotate', + ol.geom.SimpleGeometry.prototype.rotate); + +goog.exportProperty( + ol.geom.SimpleGeometry.prototype, 'simplify', ol.geom.SimpleGeometry.prototype.simplify); @@ -132219,6 +117329,11 @@ goog.exportProperty( goog.exportProperty( ol.geom.Circle.prototype, + 'rotate', + ol.geom.Circle.prototype.rotate); + +goog.exportProperty( + ol.geom.Circle.prototype, 'getClosestPoint', ol.geom.Circle.prototype.getClosestPoint); @@ -132309,6 +117424,11 @@ goog.exportProperty( goog.exportProperty( ol.geom.GeometryCollection.prototype, + 'rotate', + ol.geom.GeometryCollection.prototype.rotate); + +goog.exportProperty( + ol.geom.GeometryCollection.prototype, 'simplify', ol.geom.GeometryCollection.prototype.simplify); @@ -132399,6 +117519,11 @@ goog.exportProperty( goog.exportProperty( ol.geom.LinearRing.prototype, + 'rotate', + ol.geom.LinearRing.prototype.rotate); + +goog.exportProperty( + ol.geom.LinearRing.prototype, 'getClosestPoint', ol.geom.LinearRing.prototype.getClosestPoint); @@ -132499,6 +117624,11 @@ goog.exportProperty( goog.exportProperty( ol.geom.LineString.prototype, + 'rotate', + ol.geom.LineString.prototype.rotate); + +goog.exportProperty( + ol.geom.LineString.prototype, 'getClosestPoint', ol.geom.LineString.prototype.getClosestPoint); @@ -132599,6 +117729,11 @@ goog.exportProperty( goog.exportProperty( ol.geom.MultiLineString.prototype, + 'rotate', + ol.geom.MultiLineString.prototype.rotate); + +goog.exportProperty( + ol.geom.MultiLineString.prototype, 'getClosestPoint', ol.geom.MultiLineString.prototype.getClosestPoint); @@ -132699,6 +117834,11 @@ goog.exportProperty( goog.exportProperty( ol.geom.MultiPoint.prototype, + 'rotate', + ol.geom.MultiPoint.prototype.rotate); + +goog.exportProperty( + ol.geom.MultiPoint.prototype, 'getClosestPoint', ol.geom.MultiPoint.prototype.getClosestPoint); @@ -132799,6 +117939,11 @@ goog.exportProperty( goog.exportProperty( ol.geom.MultiPolygon.prototype, + 'rotate', + ol.geom.MultiPolygon.prototype.rotate); + +goog.exportProperty( + ol.geom.MultiPolygon.prototype, 'getClosestPoint', ol.geom.MultiPolygon.prototype.getClosestPoint); @@ -132899,6 +118044,11 @@ goog.exportProperty( goog.exportProperty( ol.geom.Point.prototype, + 'rotate', + ol.geom.Point.prototype.rotate); + +goog.exportProperty( + ol.geom.Point.prototype, 'getClosestPoint', ol.geom.Point.prototype.getClosestPoint); @@ -132999,6 +118149,11 @@ goog.exportProperty( goog.exportProperty( ol.geom.Polygon.prototype, + 'rotate', + ol.geom.Polygon.prototype.rotate); + +goog.exportProperty( + ol.geom.Polygon.prototype, 'getClosestPoint', ol.geom.Polygon.prototype.getClosestPoint); @@ -133083,6 +118238,1176 @@ goog.exportProperty( ol.geom.Polygon.prototype.unByKey); goog.exportProperty( + ol.format.ogc.filter.Filter.prototype, + 'get', + ol.format.ogc.filter.Filter.prototype.get); + +goog.exportProperty( + ol.format.ogc.filter.Filter.prototype, + 'getKeys', + ol.format.ogc.filter.Filter.prototype.getKeys); + +goog.exportProperty( + ol.format.ogc.filter.Filter.prototype, + 'getProperties', + ol.format.ogc.filter.Filter.prototype.getProperties); + +goog.exportProperty( + ol.format.ogc.filter.Filter.prototype, + 'set', + ol.format.ogc.filter.Filter.prototype.set); + +goog.exportProperty( + ol.format.ogc.filter.Filter.prototype, + 'setProperties', + ol.format.ogc.filter.Filter.prototype.setProperties); + +goog.exportProperty( + ol.format.ogc.filter.Filter.prototype, + 'unset', + ol.format.ogc.filter.Filter.prototype.unset); + +goog.exportProperty( + ol.format.ogc.filter.Filter.prototype, + 'changed', + ol.format.ogc.filter.Filter.prototype.changed); + +goog.exportProperty( + ol.format.ogc.filter.Filter.prototype, + 'dispatchEvent', + ol.format.ogc.filter.Filter.prototype.dispatchEvent); + +goog.exportProperty( + ol.format.ogc.filter.Filter.prototype, + 'getRevision', + ol.format.ogc.filter.Filter.prototype.getRevision); + +goog.exportProperty( + ol.format.ogc.filter.Filter.prototype, + 'on', + ol.format.ogc.filter.Filter.prototype.on); + +goog.exportProperty( + ol.format.ogc.filter.Filter.prototype, + 'once', + ol.format.ogc.filter.Filter.prototype.once); + +goog.exportProperty( + ol.format.ogc.filter.Filter.prototype, + 'un', + ol.format.ogc.filter.Filter.prototype.un); + +goog.exportProperty( + ol.format.ogc.filter.Filter.prototype, + 'unByKey', + ol.format.ogc.filter.Filter.prototype.unByKey); + +goog.exportProperty( + ol.format.ogc.filter.Logical.prototype, + 'get', + ol.format.ogc.filter.Logical.prototype.get); + +goog.exportProperty( + ol.format.ogc.filter.Logical.prototype, + 'getKeys', + ol.format.ogc.filter.Logical.prototype.getKeys); + +goog.exportProperty( + ol.format.ogc.filter.Logical.prototype, + 'getProperties', + ol.format.ogc.filter.Logical.prototype.getProperties); + +goog.exportProperty( + ol.format.ogc.filter.Logical.prototype, + 'set', + ol.format.ogc.filter.Logical.prototype.set); + +goog.exportProperty( + ol.format.ogc.filter.Logical.prototype, + 'setProperties', + ol.format.ogc.filter.Logical.prototype.setProperties); + +goog.exportProperty( + ol.format.ogc.filter.Logical.prototype, + 'unset', + ol.format.ogc.filter.Logical.prototype.unset); + +goog.exportProperty( + ol.format.ogc.filter.Logical.prototype, + 'changed', + ol.format.ogc.filter.Logical.prototype.changed); + +goog.exportProperty( + ol.format.ogc.filter.Logical.prototype, + 'dispatchEvent', + ol.format.ogc.filter.Logical.prototype.dispatchEvent); + +goog.exportProperty( + ol.format.ogc.filter.Logical.prototype, + 'getRevision', + ol.format.ogc.filter.Logical.prototype.getRevision); + +goog.exportProperty( + ol.format.ogc.filter.Logical.prototype, + 'on', + ol.format.ogc.filter.Logical.prototype.on); + +goog.exportProperty( + ol.format.ogc.filter.Logical.prototype, + 'once', + ol.format.ogc.filter.Logical.prototype.once); + +goog.exportProperty( + ol.format.ogc.filter.Logical.prototype, + 'un', + ol.format.ogc.filter.Logical.prototype.un); + +goog.exportProperty( + ol.format.ogc.filter.Logical.prototype, + 'unByKey', + ol.format.ogc.filter.Logical.prototype.unByKey); + +goog.exportProperty( + ol.format.ogc.filter.LogicalBinary.prototype, + 'get', + ol.format.ogc.filter.LogicalBinary.prototype.get); + +goog.exportProperty( + ol.format.ogc.filter.LogicalBinary.prototype, + 'getKeys', + ol.format.ogc.filter.LogicalBinary.prototype.getKeys); + +goog.exportProperty( + ol.format.ogc.filter.LogicalBinary.prototype, + 'getProperties', + ol.format.ogc.filter.LogicalBinary.prototype.getProperties); + +goog.exportProperty( + ol.format.ogc.filter.LogicalBinary.prototype, + 'set', + ol.format.ogc.filter.LogicalBinary.prototype.set); + +goog.exportProperty( + ol.format.ogc.filter.LogicalBinary.prototype, + 'setProperties', + ol.format.ogc.filter.LogicalBinary.prototype.setProperties); + +goog.exportProperty( + ol.format.ogc.filter.LogicalBinary.prototype, + 'unset', + ol.format.ogc.filter.LogicalBinary.prototype.unset); + +goog.exportProperty( + ol.format.ogc.filter.LogicalBinary.prototype, + 'changed', + ol.format.ogc.filter.LogicalBinary.prototype.changed); + +goog.exportProperty( + ol.format.ogc.filter.LogicalBinary.prototype, + 'dispatchEvent', + ol.format.ogc.filter.LogicalBinary.prototype.dispatchEvent); + +goog.exportProperty( + ol.format.ogc.filter.LogicalBinary.prototype, + 'getRevision', + ol.format.ogc.filter.LogicalBinary.prototype.getRevision); + +goog.exportProperty( + ol.format.ogc.filter.LogicalBinary.prototype, + 'on', + ol.format.ogc.filter.LogicalBinary.prototype.on); + +goog.exportProperty( + ol.format.ogc.filter.LogicalBinary.prototype, + 'once', + ol.format.ogc.filter.LogicalBinary.prototype.once); + +goog.exportProperty( + ol.format.ogc.filter.LogicalBinary.prototype, + 'un', + ol.format.ogc.filter.LogicalBinary.prototype.un); + +goog.exportProperty( + ol.format.ogc.filter.LogicalBinary.prototype, + 'unByKey', + ol.format.ogc.filter.LogicalBinary.prototype.unByKey); + +goog.exportProperty( + ol.format.ogc.filter.And.prototype, + 'get', + ol.format.ogc.filter.And.prototype.get); + +goog.exportProperty( + ol.format.ogc.filter.And.prototype, + 'getKeys', + ol.format.ogc.filter.And.prototype.getKeys); + +goog.exportProperty( + ol.format.ogc.filter.And.prototype, + 'getProperties', + ol.format.ogc.filter.And.prototype.getProperties); + +goog.exportProperty( + ol.format.ogc.filter.And.prototype, + 'set', + ol.format.ogc.filter.And.prototype.set); + +goog.exportProperty( + ol.format.ogc.filter.And.prototype, + 'setProperties', + ol.format.ogc.filter.And.prototype.setProperties); + +goog.exportProperty( + ol.format.ogc.filter.And.prototype, + 'unset', + ol.format.ogc.filter.And.prototype.unset); + +goog.exportProperty( + ol.format.ogc.filter.And.prototype, + 'changed', + ol.format.ogc.filter.And.prototype.changed); + +goog.exportProperty( + ol.format.ogc.filter.And.prototype, + 'dispatchEvent', + ol.format.ogc.filter.And.prototype.dispatchEvent); + +goog.exportProperty( + ol.format.ogc.filter.And.prototype, + 'getRevision', + ol.format.ogc.filter.And.prototype.getRevision); + +goog.exportProperty( + ol.format.ogc.filter.And.prototype, + 'on', + ol.format.ogc.filter.And.prototype.on); + +goog.exportProperty( + ol.format.ogc.filter.And.prototype, + 'once', + ol.format.ogc.filter.And.prototype.once); + +goog.exportProperty( + ol.format.ogc.filter.And.prototype, + 'un', + ol.format.ogc.filter.And.prototype.un); + +goog.exportProperty( + ol.format.ogc.filter.And.prototype, + 'unByKey', + ol.format.ogc.filter.And.prototype.unByKey); + +goog.exportProperty( + ol.format.ogc.filter.Or.prototype, + 'get', + ol.format.ogc.filter.Or.prototype.get); + +goog.exportProperty( + ol.format.ogc.filter.Or.prototype, + 'getKeys', + ol.format.ogc.filter.Or.prototype.getKeys); + +goog.exportProperty( + ol.format.ogc.filter.Or.prototype, + 'getProperties', + ol.format.ogc.filter.Or.prototype.getProperties); + +goog.exportProperty( + ol.format.ogc.filter.Or.prototype, + 'set', + ol.format.ogc.filter.Or.prototype.set); + +goog.exportProperty( + ol.format.ogc.filter.Or.prototype, + 'setProperties', + ol.format.ogc.filter.Or.prototype.setProperties); + +goog.exportProperty( + ol.format.ogc.filter.Or.prototype, + 'unset', + ol.format.ogc.filter.Or.prototype.unset); + +goog.exportProperty( + ol.format.ogc.filter.Or.prototype, + 'changed', + ol.format.ogc.filter.Or.prototype.changed); + +goog.exportProperty( + ol.format.ogc.filter.Or.prototype, + 'dispatchEvent', + ol.format.ogc.filter.Or.prototype.dispatchEvent); + +goog.exportProperty( + ol.format.ogc.filter.Or.prototype, + 'getRevision', + ol.format.ogc.filter.Or.prototype.getRevision); + +goog.exportProperty( + ol.format.ogc.filter.Or.prototype, + 'on', + ol.format.ogc.filter.Or.prototype.on); + +goog.exportProperty( + ol.format.ogc.filter.Or.prototype, + 'once', + ol.format.ogc.filter.Or.prototype.once); + +goog.exportProperty( + ol.format.ogc.filter.Or.prototype, + 'un', + ol.format.ogc.filter.Or.prototype.un); + +goog.exportProperty( + ol.format.ogc.filter.Or.prototype, + 'unByKey', + ol.format.ogc.filter.Or.prototype.unByKey); + +goog.exportProperty( + ol.format.ogc.filter.Not.prototype, + 'get', + ol.format.ogc.filter.Not.prototype.get); + +goog.exportProperty( + ol.format.ogc.filter.Not.prototype, + 'getKeys', + ol.format.ogc.filter.Not.prototype.getKeys); + +goog.exportProperty( + ol.format.ogc.filter.Not.prototype, + 'getProperties', + ol.format.ogc.filter.Not.prototype.getProperties); + +goog.exportProperty( + ol.format.ogc.filter.Not.prototype, + 'set', + ol.format.ogc.filter.Not.prototype.set); + +goog.exportProperty( + ol.format.ogc.filter.Not.prototype, + 'setProperties', + ol.format.ogc.filter.Not.prototype.setProperties); + +goog.exportProperty( + ol.format.ogc.filter.Not.prototype, + 'unset', + ol.format.ogc.filter.Not.prototype.unset); + +goog.exportProperty( + ol.format.ogc.filter.Not.prototype, + 'changed', + ol.format.ogc.filter.Not.prototype.changed); + +goog.exportProperty( + ol.format.ogc.filter.Not.prototype, + 'dispatchEvent', + ol.format.ogc.filter.Not.prototype.dispatchEvent); + +goog.exportProperty( + ol.format.ogc.filter.Not.prototype, + 'getRevision', + ol.format.ogc.filter.Not.prototype.getRevision); + +goog.exportProperty( + ol.format.ogc.filter.Not.prototype, + 'on', + ol.format.ogc.filter.Not.prototype.on); + +goog.exportProperty( + ol.format.ogc.filter.Not.prototype, + 'once', + ol.format.ogc.filter.Not.prototype.once); + +goog.exportProperty( + ol.format.ogc.filter.Not.prototype, + 'un', + ol.format.ogc.filter.Not.prototype.un); + +goog.exportProperty( + ol.format.ogc.filter.Not.prototype, + 'unByKey', + ol.format.ogc.filter.Not.prototype.unByKey); + +goog.exportProperty( + ol.format.ogc.filter.Bbox.prototype, + 'get', + ol.format.ogc.filter.Bbox.prototype.get); + +goog.exportProperty( + ol.format.ogc.filter.Bbox.prototype, + 'getKeys', + ol.format.ogc.filter.Bbox.prototype.getKeys); + +goog.exportProperty( + ol.format.ogc.filter.Bbox.prototype, + 'getProperties', + ol.format.ogc.filter.Bbox.prototype.getProperties); + +goog.exportProperty( + ol.format.ogc.filter.Bbox.prototype, + 'set', + ol.format.ogc.filter.Bbox.prototype.set); + +goog.exportProperty( + ol.format.ogc.filter.Bbox.prototype, + 'setProperties', + ol.format.ogc.filter.Bbox.prototype.setProperties); + +goog.exportProperty( + ol.format.ogc.filter.Bbox.prototype, + 'unset', + ol.format.ogc.filter.Bbox.prototype.unset); + +goog.exportProperty( + ol.format.ogc.filter.Bbox.prototype, + 'changed', + ol.format.ogc.filter.Bbox.prototype.changed); + +goog.exportProperty( + ol.format.ogc.filter.Bbox.prototype, + 'dispatchEvent', + ol.format.ogc.filter.Bbox.prototype.dispatchEvent); + +goog.exportProperty( + ol.format.ogc.filter.Bbox.prototype, + 'getRevision', + ol.format.ogc.filter.Bbox.prototype.getRevision); + +goog.exportProperty( + ol.format.ogc.filter.Bbox.prototype, + 'on', + ol.format.ogc.filter.Bbox.prototype.on); + +goog.exportProperty( + ol.format.ogc.filter.Bbox.prototype, + 'once', + ol.format.ogc.filter.Bbox.prototype.once); + +goog.exportProperty( + ol.format.ogc.filter.Bbox.prototype, + 'un', + ol.format.ogc.filter.Bbox.prototype.un); + +goog.exportProperty( + ol.format.ogc.filter.Bbox.prototype, + 'unByKey', + ol.format.ogc.filter.Bbox.prototype.unByKey); + +goog.exportProperty( + ol.format.ogc.filter.Comparison.prototype, + 'get', + ol.format.ogc.filter.Comparison.prototype.get); + +goog.exportProperty( + ol.format.ogc.filter.Comparison.prototype, + 'getKeys', + ol.format.ogc.filter.Comparison.prototype.getKeys); + +goog.exportProperty( + ol.format.ogc.filter.Comparison.prototype, + 'getProperties', + ol.format.ogc.filter.Comparison.prototype.getProperties); + +goog.exportProperty( + ol.format.ogc.filter.Comparison.prototype, + 'set', + ol.format.ogc.filter.Comparison.prototype.set); + +goog.exportProperty( + ol.format.ogc.filter.Comparison.prototype, + 'setProperties', + ol.format.ogc.filter.Comparison.prototype.setProperties); + +goog.exportProperty( + ol.format.ogc.filter.Comparison.prototype, + 'unset', + ol.format.ogc.filter.Comparison.prototype.unset); + +goog.exportProperty( + ol.format.ogc.filter.Comparison.prototype, + 'changed', + ol.format.ogc.filter.Comparison.prototype.changed); + +goog.exportProperty( + ol.format.ogc.filter.Comparison.prototype, + 'dispatchEvent', + ol.format.ogc.filter.Comparison.prototype.dispatchEvent); + +goog.exportProperty( + ol.format.ogc.filter.Comparison.prototype, + 'getRevision', + ol.format.ogc.filter.Comparison.prototype.getRevision); + +goog.exportProperty( + ol.format.ogc.filter.Comparison.prototype, + 'on', + ol.format.ogc.filter.Comparison.prototype.on); + +goog.exportProperty( + ol.format.ogc.filter.Comparison.prototype, + 'once', + ol.format.ogc.filter.Comparison.prototype.once); + +goog.exportProperty( + ol.format.ogc.filter.Comparison.prototype, + 'un', + ol.format.ogc.filter.Comparison.prototype.un); + +goog.exportProperty( + ol.format.ogc.filter.Comparison.prototype, + 'unByKey', + ol.format.ogc.filter.Comparison.prototype.unByKey); + +goog.exportProperty( + ol.format.ogc.filter.ComparisonBinary.prototype, + 'get', + ol.format.ogc.filter.ComparisonBinary.prototype.get); + +goog.exportProperty( + ol.format.ogc.filter.ComparisonBinary.prototype, + 'getKeys', + ol.format.ogc.filter.ComparisonBinary.prototype.getKeys); + +goog.exportProperty( + ol.format.ogc.filter.ComparisonBinary.prototype, + 'getProperties', + ol.format.ogc.filter.ComparisonBinary.prototype.getProperties); + +goog.exportProperty( + ol.format.ogc.filter.ComparisonBinary.prototype, + 'set', + ol.format.ogc.filter.ComparisonBinary.prototype.set); + +goog.exportProperty( + ol.format.ogc.filter.ComparisonBinary.prototype, + 'setProperties', + ol.format.ogc.filter.ComparisonBinary.prototype.setProperties); + +goog.exportProperty( + ol.format.ogc.filter.ComparisonBinary.prototype, + 'unset', + ol.format.ogc.filter.ComparisonBinary.prototype.unset); + +goog.exportProperty( + ol.format.ogc.filter.ComparisonBinary.prototype, + 'changed', + ol.format.ogc.filter.ComparisonBinary.prototype.changed); + +goog.exportProperty( + ol.format.ogc.filter.ComparisonBinary.prototype, + 'dispatchEvent', + ol.format.ogc.filter.ComparisonBinary.prototype.dispatchEvent); + +goog.exportProperty( + ol.format.ogc.filter.ComparisonBinary.prototype, + 'getRevision', + ol.format.ogc.filter.ComparisonBinary.prototype.getRevision); + +goog.exportProperty( + ol.format.ogc.filter.ComparisonBinary.prototype, + 'on', + ol.format.ogc.filter.ComparisonBinary.prototype.on); + +goog.exportProperty( + ol.format.ogc.filter.ComparisonBinary.prototype, + 'once', + ol.format.ogc.filter.ComparisonBinary.prototype.once); + +goog.exportProperty( + ol.format.ogc.filter.ComparisonBinary.prototype, + 'un', + ol.format.ogc.filter.ComparisonBinary.prototype.un); + +goog.exportProperty( + ol.format.ogc.filter.ComparisonBinary.prototype, + 'unByKey', + ol.format.ogc.filter.ComparisonBinary.prototype.unByKey); + +goog.exportProperty( + ol.format.ogc.filter.EqualTo.prototype, + 'get', + ol.format.ogc.filter.EqualTo.prototype.get); + +goog.exportProperty( + ol.format.ogc.filter.EqualTo.prototype, + 'getKeys', + ol.format.ogc.filter.EqualTo.prototype.getKeys); + +goog.exportProperty( + ol.format.ogc.filter.EqualTo.prototype, + 'getProperties', + ol.format.ogc.filter.EqualTo.prototype.getProperties); + +goog.exportProperty( + ol.format.ogc.filter.EqualTo.prototype, + 'set', + ol.format.ogc.filter.EqualTo.prototype.set); + +goog.exportProperty( + ol.format.ogc.filter.EqualTo.prototype, + 'setProperties', + ol.format.ogc.filter.EqualTo.prototype.setProperties); + +goog.exportProperty( + ol.format.ogc.filter.EqualTo.prototype, + 'unset', + ol.format.ogc.filter.EqualTo.prototype.unset); + +goog.exportProperty( + ol.format.ogc.filter.EqualTo.prototype, + 'changed', + ol.format.ogc.filter.EqualTo.prototype.changed); + +goog.exportProperty( + ol.format.ogc.filter.EqualTo.prototype, + 'dispatchEvent', + ol.format.ogc.filter.EqualTo.prototype.dispatchEvent); + +goog.exportProperty( + ol.format.ogc.filter.EqualTo.prototype, + 'getRevision', + ol.format.ogc.filter.EqualTo.prototype.getRevision); + +goog.exportProperty( + ol.format.ogc.filter.EqualTo.prototype, + 'on', + ol.format.ogc.filter.EqualTo.prototype.on); + +goog.exportProperty( + ol.format.ogc.filter.EqualTo.prototype, + 'once', + ol.format.ogc.filter.EqualTo.prototype.once); + +goog.exportProperty( + ol.format.ogc.filter.EqualTo.prototype, + 'un', + ol.format.ogc.filter.EqualTo.prototype.un); + +goog.exportProperty( + ol.format.ogc.filter.EqualTo.prototype, + 'unByKey', + ol.format.ogc.filter.EqualTo.prototype.unByKey); + +goog.exportProperty( + ol.format.ogc.filter.NotEqualTo.prototype, + 'get', + ol.format.ogc.filter.NotEqualTo.prototype.get); + +goog.exportProperty( + ol.format.ogc.filter.NotEqualTo.prototype, + 'getKeys', + ol.format.ogc.filter.NotEqualTo.prototype.getKeys); + +goog.exportProperty( + ol.format.ogc.filter.NotEqualTo.prototype, + 'getProperties', + ol.format.ogc.filter.NotEqualTo.prototype.getProperties); + +goog.exportProperty( + ol.format.ogc.filter.NotEqualTo.prototype, + 'set', + ol.format.ogc.filter.NotEqualTo.prototype.set); + +goog.exportProperty( + ol.format.ogc.filter.NotEqualTo.prototype, + 'setProperties', + ol.format.ogc.filter.NotEqualTo.prototype.setProperties); + +goog.exportProperty( + ol.format.ogc.filter.NotEqualTo.prototype, + 'unset', + ol.format.ogc.filter.NotEqualTo.prototype.unset); + +goog.exportProperty( + ol.format.ogc.filter.NotEqualTo.prototype, + 'changed', + ol.format.ogc.filter.NotEqualTo.prototype.changed); + +goog.exportProperty( + ol.format.ogc.filter.NotEqualTo.prototype, + 'dispatchEvent', + ol.format.ogc.filter.NotEqualTo.prototype.dispatchEvent); + +goog.exportProperty( + ol.format.ogc.filter.NotEqualTo.prototype, + 'getRevision', + ol.format.ogc.filter.NotEqualTo.prototype.getRevision); + +goog.exportProperty( + ol.format.ogc.filter.NotEqualTo.prototype, + 'on', + ol.format.ogc.filter.NotEqualTo.prototype.on); + +goog.exportProperty( + ol.format.ogc.filter.NotEqualTo.prototype, + 'once', + ol.format.ogc.filter.NotEqualTo.prototype.once); + +goog.exportProperty( + ol.format.ogc.filter.NotEqualTo.prototype, + 'un', + ol.format.ogc.filter.NotEqualTo.prototype.un); + +goog.exportProperty( + ol.format.ogc.filter.NotEqualTo.prototype, + 'unByKey', + ol.format.ogc.filter.NotEqualTo.prototype.unByKey); + +goog.exportProperty( + ol.format.ogc.filter.LessThan.prototype, + 'get', + ol.format.ogc.filter.LessThan.prototype.get); + +goog.exportProperty( + ol.format.ogc.filter.LessThan.prototype, + 'getKeys', + ol.format.ogc.filter.LessThan.prototype.getKeys); + +goog.exportProperty( + ol.format.ogc.filter.LessThan.prototype, + 'getProperties', + ol.format.ogc.filter.LessThan.prototype.getProperties); + +goog.exportProperty( + ol.format.ogc.filter.LessThan.prototype, + 'set', + ol.format.ogc.filter.LessThan.prototype.set); + +goog.exportProperty( + ol.format.ogc.filter.LessThan.prototype, + 'setProperties', + ol.format.ogc.filter.LessThan.prototype.setProperties); + +goog.exportProperty( + ol.format.ogc.filter.LessThan.prototype, + 'unset', + ol.format.ogc.filter.LessThan.prototype.unset); + +goog.exportProperty( + ol.format.ogc.filter.LessThan.prototype, + 'changed', + ol.format.ogc.filter.LessThan.prototype.changed); + +goog.exportProperty( + ol.format.ogc.filter.LessThan.prototype, + 'dispatchEvent', + ol.format.ogc.filter.LessThan.prototype.dispatchEvent); + +goog.exportProperty( + ol.format.ogc.filter.LessThan.prototype, + 'getRevision', + ol.format.ogc.filter.LessThan.prototype.getRevision); + +goog.exportProperty( + ol.format.ogc.filter.LessThan.prototype, + 'on', + ol.format.ogc.filter.LessThan.prototype.on); + +goog.exportProperty( + ol.format.ogc.filter.LessThan.prototype, + 'once', + ol.format.ogc.filter.LessThan.prototype.once); + +goog.exportProperty( + ol.format.ogc.filter.LessThan.prototype, + 'un', + ol.format.ogc.filter.LessThan.prototype.un); + +goog.exportProperty( + ol.format.ogc.filter.LessThan.prototype, + 'unByKey', + ol.format.ogc.filter.LessThan.prototype.unByKey); + +goog.exportProperty( + ol.format.ogc.filter.LessThanOrEqualTo.prototype, + 'get', + ol.format.ogc.filter.LessThanOrEqualTo.prototype.get); + +goog.exportProperty( + ol.format.ogc.filter.LessThanOrEqualTo.prototype, + 'getKeys', + ol.format.ogc.filter.LessThanOrEqualTo.prototype.getKeys); + +goog.exportProperty( + ol.format.ogc.filter.LessThanOrEqualTo.prototype, + 'getProperties', + ol.format.ogc.filter.LessThanOrEqualTo.prototype.getProperties); + +goog.exportProperty( + ol.format.ogc.filter.LessThanOrEqualTo.prototype, + 'set', + ol.format.ogc.filter.LessThanOrEqualTo.prototype.set); + +goog.exportProperty( + ol.format.ogc.filter.LessThanOrEqualTo.prototype, + 'setProperties', + ol.format.ogc.filter.LessThanOrEqualTo.prototype.setProperties); + +goog.exportProperty( + ol.format.ogc.filter.LessThanOrEqualTo.prototype, + 'unset', + ol.format.ogc.filter.LessThanOrEqualTo.prototype.unset); + +goog.exportProperty( + ol.format.ogc.filter.LessThanOrEqualTo.prototype, + 'changed', + ol.format.ogc.filter.LessThanOrEqualTo.prototype.changed); + +goog.exportProperty( + ol.format.ogc.filter.LessThanOrEqualTo.prototype, + 'dispatchEvent', + ol.format.ogc.filter.LessThanOrEqualTo.prototype.dispatchEvent); + +goog.exportProperty( + ol.format.ogc.filter.LessThanOrEqualTo.prototype, + 'getRevision', + ol.format.ogc.filter.LessThanOrEqualTo.prototype.getRevision); + +goog.exportProperty( + ol.format.ogc.filter.LessThanOrEqualTo.prototype, + 'on', + ol.format.ogc.filter.LessThanOrEqualTo.prototype.on); + +goog.exportProperty( + ol.format.ogc.filter.LessThanOrEqualTo.prototype, + 'once', + ol.format.ogc.filter.LessThanOrEqualTo.prototype.once); + +goog.exportProperty( + ol.format.ogc.filter.LessThanOrEqualTo.prototype, + 'un', + ol.format.ogc.filter.LessThanOrEqualTo.prototype.un); + +goog.exportProperty( + ol.format.ogc.filter.LessThanOrEqualTo.prototype, + 'unByKey', + ol.format.ogc.filter.LessThanOrEqualTo.prototype.unByKey); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThan.prototype, + 'get', + ol.format.ogc.filter.GreaterThan.prototype.get); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThan.prototype, + 'getKeys', + ol.format.ogc.filter.GreaterThan.prototype.getKeys); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThan.prototype, + 'getProperties', + ol.format.ogc.filter.GreaterThan.prototype.getProperties); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThan.prototype, + 'set', + ol.format.ogc.filter.GreaterThan.prototype.set); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThan.prototype, + 'setProperties', + ol.format.ogc.filter.GreaterThan.prototype.setProperties); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThan.prototype, + 'unset', + ol.format.ogc.filter.GreaterThan.prototype.unset); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThan.prototype, + 'changed', + ol.format.ogc.filter.GreaterThan.prototype.changed); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThan.prototype, + 'dispatchEvent', + ol.format.ogc.filter.GreaterThan.prototype.dispatchEvent); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThan.prototype, + 'getRevision', + ol.format.ogc.filter.GreaterThan.prototype.getRevision); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThan.prototype, + 'on', + ol.format.ogc.filter.GreaterThan.prototype.on); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThan.prototype, + 'once', + ol.format.ogc.filter.GreaterThan.prototype.once); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThan.prototype, + 'un', + ol.format.ogc.filter.GreaterThan.prototype.un); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThan.prototype, + 'unByKey', + ol.format.ogc.filter.GreaterThan.prototype.unByKey); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype, + 'get', + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype.get); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype, + 'getKeys', + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype.getKeys); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype, + 'getProperties', + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype.getProperties); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype, + 'set', + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype.set); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype, + 'setProperties', + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype.setProperties); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype, + 'unset', + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype.unset); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype, + 'changed', + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype.changed); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype, + 'dispatchEvent', + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype.dispatchEvent); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype, + 'getRevision', + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype.getRevision); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype, + 'on', + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype.on); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype, + 'once', + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype.once); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype, + 'un', + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype.un); + +goog.exportProperty( + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype, + 'unByKey', + ol.format.ogc.filter.GreaterThanOrEqualTo.prototype.unByKey); + +goog.exportProperty( + ol.format.ogc.filter.IsNull.prototype, + 'get', + ol.format.ogc.filter.IsNull.prototype.get); + +goog.exportProperty( + ol.format.ogc.filter.IsNull.prototype, + 'getKeys', + ol.format.ogc.filter.IsNull.prototype.getKeys); + +goog.exportProperty( + ol.format.ogc.filter.IsNull.prototype, + 'getProperties', + ol.format.ogc.filter.IsNull.prototype.getProperties); + +goog.exportProperty( + ol.format.ogc.filter.IsNull.prototype, + 'set', + ol.format.ogc.filter.IsNull.prototype.set); + +goog.exportProperty( + ol.format.ogc.filter.IsNull.prototype, + 'setProperties', + ol.format.ogc.filter.IsNull.prototype.setProperties); + +goog.exportProperty( + ol.format.ogc.filter.IsNull.prototype, + 'unset', + ol.format.ogc.filter.IsNull.prototype.unset); + +goog.exportProperty( + ol.format.ogc.filter.IsNull.prototype, + 'changed', + ol.format.ogc.filter.IsNull.prototype.changed); + +goog.exportProperty( + ol.format.ogc.filter.IsNull.prototype, + 'dispatchEvent', + ol.format.ogc.filter.IsNull.prototype.dispatchEvent); + +goog.exportProperty( + ol.format.ogc.filter.IsNull.prototype, + 'getRevision', + ol.format.ogc.filter.IsNull.prototype.getRevision); + +goog.exportProperty( + ol.format.ogc.filter.IsNull.prototype, + 'on', + ol.format.ogc.filter.IsNull.prototype.on); + +goog.exportProperty( + ol.format.ogc.filter.IsNull.prototype, + 'once', + ol.format.ogc.filter.IsNull.prototype.once); + +goog.exportProperty( + ol.format.ogc.filter.IsNull.prototype, + 'un', + ol.format.ogc.filter.IsNull.prototype.un); + +goog.exportProperty( + ol.format.ogc.filter.IsNull.prototype, + 'unByKey', + ol.format.ogc.filter.IsNull.prototype.unByKey); + +goog.exportProperty( + ol.format.ogc.filter.IsBetween.prototype, + 'get', + ol.format.ogc.filter.IsBetween.prototype.get); + +goog.exportProperty( + ol.format.ogc.filter.IsBetween.prototype, + 'getKeys', + ol.format.ogc.filter.IsBetween.prototype.getKeys); + +goog.exportProperty( + ol.format.ogc.filter.IsBetween.prototype, + 'getProperties', + ol.format.ogc.filter.IsBetween.prototype.getProperties); + +goog.exportProperty( + ol.format.ogc.filter.IsBetween.prototype, + 'set', + ol.format.ogc.filter.IsBetween.prototype.set); + +goog.exportProperty( + ol.format.ogc.filter.IsBetween.prototype, + 'setProperties', + ol.format.ogc.filter.IsBetween.prototype.setProperties); + +goog.exportProperty( + ol.format.ogc.filter.IsBetween.prototype, + 'unset', + ol.format.ogc.filter.IsBetween.prototype.unset); + +goog.exportProperty( + ol.format.ogc.filter.IsBetween.prototype, + 'changed', + ol.format.ogc.filter.IsBetween.prototype.changed); + +goog.exportProperty( + ol.format.ogc.filter.IsBetween.prototype, + 'dispatchEvent', + ol.format.ogc.filter.IsBetween.prototype.dispatchEvent); + +goog.exportProperty( + ol.format.ogc.filter.IsBetween.prototype, + 'getRevision', + ol.format.ogc.filter.IsBetween.prototype.getRevision); + +goog.exportProperty( + ol.format.ogc.filter.IsBetween.prototype, + 'on', + ol.format.ogc.filter.IsBetween.prototype.on); + +goog.exportProperty( + ol.format.ogc.filter.IsBetween.prototype, + 'once', + ol.format.ogc.filter.IsBetween.prototype.once); + +goog.exportProperty( + ol.format.ogc.filter.IsBetween.prototype, + 'un', + ol.format.ogc.filter.IsBetween.prototype.un); + +goog.exportProperty( + ol.format.ogc.filter.IsBetween.prototype, + 'unByKey', + ol.format.ogc.filter.IsBetween.prototype.unByKey); + +goog.exportProperty( + ol.format.ogc.filter.IsLike.prototype, + 'get', + ol.format.ogc.filter.IsLike.prototype.get); + +goog.exportProperty( + ol.format.ogc.filter.IsLike.prototype, + 'getKeys', + ol.format.ogc.filter.IsLike.prototype.getKeys); + +goog.exportProperty( + ol.format.ogc.filter.IsLike.prototype, + 'getProperties', + ol.format.ogc.filter.IsLike.prototype.getProperties); + +goog.exportProperty( + ol.format.ogc.filter.IsLike.prototype, + 'set', + ol.format.ogc.filter.IsLike.prototype.set); + +goog.exportProperty( + ol.format.ogc.filter.IsLike.prototype, + 'setProperties', + ol.format.ogc.filter.IsLike.prototype.setProperties); + +goog.exportProperty( + ol.format.ogc.filter.IsLike.prototype, + 'unset', + ol.format.ogc.filter.IsLike.prototype.unset); + +goog.exportProperty( + ol.format.ogc.filter.IsLike.prototype, + 'changed', + ol.format.ogc.filter.IsLike.prototype.changed); + +goog.exportProperty( + ol.format.ogc.filter.IsLike.prototype, + 'dispatchEvent', + ol.format.ogc.filter.IsLike.prototype.dispatchEvent); + +goog.exportProperty( + ol.format.ogc.filter.IsLike.prototype, + 'getRevision', + ol.format.ogc.filter.IsLike.prototype.getRevision); + +goog.exportProperty( + ol.format.ogc.filter.IsLike.prototype, + 'on', + ol.format.ogc.filter.IsLike.prototype.on); + +goog.exportProperty( + ol.format.ogc.filter.IsLike.prototype, + 'once', + ol.format.ogc.filter.IsLike.prototype.once); + +goog.exportProperty( + ol.format.ogc.filter.IsLike.prototype, + 'un', + ol.format.ogc.filter.IsLike.prototype.un); + +goog.exportProperty( + ol.format.ogc.filter.IsLike.prototype, + 'unByKey', + ol.format.ogc.filter.IsLike.prototype.unByKey); + +goog.exportProperty( ol.format.GML2.prototype, 'readFeatures', ol.format.GML2.prototype.readFeatures); diff --git a/chimere/static/ol3/ol.js b/chimere/static/ol3/ol.js index 49d2e32..c9bc673 100644 --- a/chimere/static/ol3/ol.js +++ b/chimere/static/ol3/ol.js @@ -1,6 +1,6 @@ // OpenLayers 3. See http://openlayers.org/ // License: https://raw.githubusercontent.com/openlayers/ol3/master/LICENSE.md -// Version: v3.12.1 +// Version: v3.16.0 (function (root, factory) { if (typeof exports === "object") { @@ -12,203 +12,183 @@ } }(this, function () { var OPENLAYERS = {}; - var l,aa=aa||{},ba=this;function ca(b){return void 0!==b}function u(b,c,d){b=b.split(".");d=d||ba;b[0]in d||!d.execScript||d.execScript("var "+b[0]);for(var e;b.length&&(e=b.shift());)!b.length&&ca(c)?d[e]=c:d[e]?d=d[e]:d=d[e]={}}function da(){}function ea(b){b.Yb=function(){return b.Pg?b.Pg:b.Pg=new b}} -function fa(b){var c=typeof b;if("object"==c)if(b){if(b instanceof Array)return"array";if(b instanceof Object)return c;var d=Object.prototype.toString.call(b);if("[object Window]"==d)return"object";if("[object Array]"==d||"number"==typeof b.length&&"undefined"!=typeof b.splice&&"undefined"!=typeof b.propertyIsEnumerable&&!b.propertyIsEnumerable("splice"))return"array";if("[object Function]"==d||"undefined"!=typeof b.call&&"undefined"!=typeof b.propertyIsEnumerable&&!b.propertyIsEnumerable("call"))return"function"}else return"null"; -else if("function"==c&&"undefined"==typeof b.call)return"object";return c}function ga(b){return"array"==fa(b)}function ha(b){var c=fa(b);return"array"==c||"object"==c&&"number"==typeof b.length}function ia(b){return"string"==typeof b}function ja(b){return"number"==typeof b}function ka(b){return"function"==fa(b)}function oa(b){var c=typeof b;return"object"==c&&null!=b||"function"==c}function w(b){return b[pa]||(b[pa]=++qa)}var pa="closure_uid_"+(1E9*Math.random()>>>0),qa=0; -function ra(b,c,d){return b.call.apply(b.bind,arguments)}function ta(b,c,d){if(!b)throw Error();if(2<arguments.length){var e=Array.prototype.slice.call(arguments,2);return function(){var d=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(d,e);return b.apply(c,d)}}return function(){return b.apply(c,arguments)}}function ua(b,c,d){ua=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?ra:ta;return ua.apply(null,arguments)} -function va(b,c){var d=Array.prototype.slice.call(arguments,1);return function(){var c=d.slice();c.push.apply(c,arguments);return b.apply(this,c)}}var wa=Date.now||function(){return+new Date};function y(b,c){function d(){}d.prototype=c.prototype;b.ca=c.prototype;b.prototype=new d;b.prototype.constructor=b;b.zp=function(b,d,g){for(var h=Array(arguments.length-2),k=2;k<arguments.length;k++)h[k-2]=arguments[k];return c.prototype[d].apply(b,h)}};var xa,ya;function za(){};function Aa(b){if(Error.captureStackTrace)Error.captureStackTrace(this,Aa);else{var c=Error().stack;c&&(this.stack=c)}b&&(this.message=String(b))}y(Aa,Error);Aa.prototype.name="CustomError";var Ba;function Ca(b,c){var d=b.length-c.length;return 0<=d&&b.indexOf(c,d)==d}function Da(b,c){for(var d=b.split("%s"),e="",f=Array.prototype.slice.call(arguments,1);f.length&&1<d.length;)e+=d.shift()+f.shift();return e+d.join("%s")}var Ea=String.prototype.trim?function(b){return b.trim()}:function(b){return b.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")}; -function Ga(b){if(!Ha.test(b))return b;-1!=b.indexOf("&")&&(b=b.replace(Ia,"&"));-1!=b.indexOf("<")&&(b=b.replace(Ja,"<"));-1!=b.indexOf(">")&&(b=b.replace(Ka,">"));-1!=b.indexOf('"')&&(b=b.replace(La,"""));-1!=b.indexOf("'")&&(b=b.replace(Ma,"'"));-1!=b.indexOf("\x00")&&(b=b.replace(Na,"�"));return b}var Ia=/&/g,Ja=/</g,Ka=/>/g,La=/"/g,Ma=/'/g,Na=/\x00/g,Ha=/[\x00&<>"']/,Oa=String.prototype.repeat?function(b,c){return b.repeat(c)}:function(b,c){return Array(c+1).join(b)}; -function Pa(b){b=ca(void 0)?b.toFixed(void 0):String(b);var c=b.indexOf(".");-1==c&&(c=b.length);return Oa("0",Math.max(0,2-c))+b} -function Qa(b,c){for(var d=0,e=Ea(String(b)).split("."),f=Ea(String(c)).split("."),g=Math.max(e.length,f.length),h=0;0==d&&h<g;h++){var k=e[h]||"",m=f[h]||"",n=RegExp("(\\d*)(\\D*)","g"),p=RegExp("(\\d*)(\\D*)","g");do{var q=n.exec(k)||["","",""],r=p.exec(m)||["","",""];if(0==q[0].length&&0==r[0].length)break;d=Ra(0==q[1].length?0:parseInt(q[1],10),0==r[1].length?0:parseInt(r[1],10))||Ra(0==q[2].length,0==r[2].length)||Ra(q[2],r[2])}while(0==d)}return d}function Ra(b,c){return b<c?-1:b>c?1:0};function Sa(b,c,d){return Math.min(Math.max(b,c),d)}var Ta=function(){var b;"cosh"in Math?b=Math.cosh:b=function(b){b=Math.exp(b);return(b+1/b)/2};return b}();function Va(b,c,d,e,f,g){var h=f-d,k=g-e;if(0!==h||0!==k){var m=((b-d)*h+(c-e)*k)/(h*h+k*k);1<m?(d=f,e=g):0<m&&(d+=h*m,e+=k*m)}return Wa(b,c,d,e)}function Wa(b,c,d,e){b=d-b;c=e-c;return b*b+c*c}function Xa(b){return b*Math.PI/180};function Ya(b){return function(c){if(c)return[Sa(c[0],b[0],b[2]),Sa(c[1],b[1],b[3])]}}function Za(b){return b};var $a=Array.prototype;function ab(b,c){return $a.indexOf.call(b,c,void 0)}function bb(b,c){$a.forEach.call(b,c,void 0)}function cb(b,c){return $a.filter.call(b,c,void 0)}function db(b,c){return $a.map.call(b,c,void 0)}function eb(b,c){return $a.some.call(b,c,void 0)}function fb(b,c){var d=gb(b,c,void 0);return 0>d?null:ia(b)?b.charAt(d):b[d]}function gb(b,c,d){for(var e=b.length,f=ia(b)?b.split(""):b,g=0;g<e;g++)if(g in f&&c.call(d,f[g],g,b))return g;return-1} -function hb(b,c){var d=ab(b,c),e;(e=0<=d)&&$a.splice.call(b,d,1);return e}function ib(b){return $a.concat.apply($a,arguments)}function jb(b){var c=b.length;if(0<c){for(var d=Array(c),e=0;e<c;e++)d[e]=b[e];return d}return[]}function kb(b,c){for(var d=1;d<arguments.length;d++){var e=arguments[d];if(ha(e)){var f=b.length||0,g=e.length||0;b.length=f+g;for(var h=0;h<g;h++)b[f+h]=e[h]}else b.push(e)}}function lb(b,c,d,e){$a.splice.apply(b,mb(arguments,1))} -function mb(b,c,d){return 2>=arguments.length?$a.slice.call(b,c):$a.slice.call(b,c,d)}function nb(b,c){b.sort(c||ob)}function pb(b){for(var c=qb,d=0;d<b.length;d++)b[d]={index:d,value:b[d]};var e=c||ob;nb(b,function(b,c){return e(b.value,c.value)||b.index-c.index});for(d=0;d<b.length;d++)b[d]=b[d].value}function rb(b,c){if(!ha(b)||!ha(c)||b.length!=c.length)return!1;for(var d=b.length,e=sb,f=0;f<d;f++)if(!e(b[f],c[f]))return!1;return!0}function ob(b,c){return b>c?1:b<c?-1:0} -function sb(b,c){return b===c}function tb(b){for(var c=[],d=0;d<arguments.length;d++){var e=arguments[d];if(ga(e))for(var f=0;f<e.length;f+=8192)for(var g=mb(e,f,f+8192),g=tb.apply(null,g),h=0;h<g.length;h++)c.push(g[h]);else c.push(e)}return c};function ub(b,c){return b>c?1:b<c?-1:0}function vb(b,c){return 0<=b.indexOf(c)}function wb(b,c,d){var e=b.length;if(b[0]<=c)return 0;if(!(c<=b[e-1]))if(0<d)for(d=1;d<e;++d){if(b[d]<c)return d-1}else if(0>d)for(d=1;d<e;++d){if(b[d]<=c)return d}else for(d=1;d<e;++d){if(b[d]==c)return d;if(b[d]<c)return b[d-1]-c<c-b[d]?d-1:d}return e-1};function xb(b){return function(c,d,e){if(void 0!==c)return c=wb(b,c,e),c=Sa(c+d,0,b.length-1),b[c]}}function yb(b,c,d){return function(e,f,g){if(void 0!==e)return e=Math.max(Math.floor(Math.log(c/e)/Math.log(b)+(0<g?0:0>g?1:.5))+f,0),void 0!==d&&(e=Math.min(e,d)),c/Math.pow(b,e)}};function zb(b){if(void 0!==b)return 0}function Ab(b,c){if(void 0!==b)return b+c}function Bb(b){var c=2*Math.PI/b;return function(b,e){if(void 0!==b)return b=Math.floor((b+e)/c+.5)*c}}function Cb(){var b=Xa(5);return function(c,d){if(void 0!==c)return Math.abs(c+d)<=b?0:c+d}};function Db(b,c,d){this.center=b;this.resolution=c;this.rotation=d};var Eb;a:{var Fb=ba.navigator;if(Fb){var Gb=Fb.userAgent;if(Gb){Eb=Gb;break a}}Eb=""}function Hb(b){return-1!=Eb.indexOf(b)};function Ib(b,c,d){for(var e in b)c.call(d,b[e],e,b)}function Jb(b,c){for(var d in b)if(c.call(void 0,b[d],d,b))return!0;return!1}function Kb(b){var c=0,d;for(d in b)c++;return c}function Lb(b){var c=[],d=0,e;for(e in b)c[d++]=b[e];return c}function Mb(b,c){for(var d in b)if(b[d]==c)return!0;return!1}function Ob(b,c){for(var d in b)if(c.call(void 0,b[d],d,b))return d}function Pb(b){for(var c in b)return!1;return!0}function Qb(b){for(var c in b)delete b[c]}function Rb(b,c,d){return c in b?b[c]:d} -function Sb(b,c){var d=[];return c in b?b[c]:b[c]=d}function Tb(b){var c={},d;for(d in b)c[d]=b[d];return c}function Ub(b){var c=fa(b);if("object"==c||"array"==c){if(ka(b.clone))return b.clone();var c="array"==c?[]:{},d;for(d in b)c[d]=Ub(b[d]);return c}return b}var Vb="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "); -function Wb(b,c){for(var d,e,f=1;f<arguments.length;f++){e=arguments[f];for(d in e)b[d]=e[d];for(var g=0;g<Vb.length;g++)d=Vb[g],Object.prototype.hasOwnProperty.call(e,d)&&(b[d]=e[d])}};var Xb=Hb("Opera")||Hb("OPR"),Yb=Hb("Trident")||Hb("MSIE"),Zb=Hb("Edge"),$b=Hb("Gecko")&&!(-1!=Eb.toLowerCase().indexOf("webkit")&&!Hb("Edge"))&&!(Hb("Trident")||Hb("MSIE"))&&!Hb("Edge"),ac=-1!=Eb.toLowerCase().indexOf("webkit")&&!Hb("Edge"),bc=Hb("Macintosh"),cc=Hb("Windows"),dc=Hb("Linux")||Hb("CrOS");function ec(){var b=Eb;if($b)return/rv\:([^\);]+)(\)|;)/.exec(b);if(Zb)return/Edge\/([\d\.]+)/.exec(b);if(Yb)return/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(b);if(ac)return/WebKit\/(\S+)/.exec(b)} -function fc(){var b=ba.document;return b?b.documentMode:void 0}var gc=function(){if(Xb&&ba.opera){var b;var c=ba.opera.version;try{b=c()}catch(d){b=c}return b}b="";(c=ec())&&(b=c?c[1]:"");return Yb&&(c=fc(),c>parseFloat(b))?String(c):b}(),hc={};function ic(b){return hc[b]||(hc[b]=0<=Qa(gc,b))}var jc=ba.document,kc=jc&&Yb?fc()||("CSS1Compat"==jc.compatMode?parseInt(gc,10):5):void 0;var lc=!Yb||9<=kc,mc=!Yb||9<=kc,nc=Yb&&!ic("9");!ac||ic("528");$b&&ic("1.9b")||Yb&&ic("8")||Xb&&ic("9.5")||ac&&ic("528");$b&&!ic("8")||Yb&&ic("9");function oc(){0!=pc&&(qc[w(this)]=this);this.na=this.na;this.va=this.va}var pc=0,qc={};oc.prototype.na=!1;oc.prototype.Fc=function(){if(!this.na&&(this.na=!0,this.Y(),0!=pc)){var b=w(this);delete qc[b]}};function rc(b,c){var d=va(sc,c);b.na?d.call(void 0):(b.va||(b.va=[]),b.va.push(ca(void 0)?ua(d,void 0):d))}oc.prototype.Y=function(){if(this.va)for(;this.va.length;)this.va.shift()()};function sc(b){b&&"function"==typeof b.Fc&&b.Fc()};function tc(b,c){this.type=b;this.g=this.target=c;this.j=!1;this.Th=!0}tc.prototype.b=function(){this.j=!0};tc.prototype.preventDefault=function(){this.Th=!1};function uc(b){b.b()}function vc(b){b.preventDefault()};function wc(b){wc[" "](b);return b}wc[" "]=da;function xc(b,c){tc.call(this,b?b.type:"");this.relatedTarget=this.g=this.target=null;this.G=this.i=this.button=this.screenY=this.screenX=this.clientY=this.clientX=this.offsetY=this.offsetX=0;this.B=this.c=this.f=this.o=!1;this.state=null;this.l=!1;this.a=null;if(b){var d=this.type=b.type,e=b.changedTouches?b.changedTouches[0]:null;this.target=b.target||b.srcElement;this.g=c;var f=b.relatedTarget;if(f){if($b){var g;a:{try{wc(f.nodeName);g=!0;break a}catch(h){}g=!1}g||(f=null)}}else"mouseover"==d? -f=b.fromElement:"mouseout"==d&&(f=b.toElement);this.relatedTarget=f;null===e?(this.offsetX=ac||void 0!==b.offsetX?b.offsetX:b.layerX,this.offsetY=ac||void 0!==b.offsetY?b.offsetY:b.layerY,this.clientX=void 0!==b.clientX?b.clientX:b.pageX,this.clientY=void 0!==b.clientY?b.clientY:b.pageY,this.screenX=b.screenX||0,this.screenY=b.screenY||0):(this.clientX=void 0!==e.clientX?e.clientX:e.pageX,this.clientY=void 0!==e.clientY?e.clientY:e.pageY,this.screenX=e.screenX||0,this.screenY=e.screenY||0);this.button= -b.button;this.i=b.keyCode||0;this.G=b.charCode||("keypress"==d?b.keyCode:0);this.o=b.ctrlKey;this.f=b.altKey;this.c=b.shiftKey;this.B=b.metaKey;this.l=bc?b.metaKey:b.ctrlKey;this.state=b.state;this.a=b;b.defaultPrevented&&this.preventDefault()}}y(xc,tc);var yc=[1,4,2];function zc(b){return(lc?0==b.a.button:"click"==b.type?!0:!!(b.a.button&yc[0]))&&!(ac&&bc&&b.o)}xc.prototype.b=function(){xc.ca.b.call(this);this.a.stopPropagation?this.a.stopPropagation():this.a.cancelBubble=!0}; -xc.prototype.preventDefault=function(){xc.ca.preventDefault.call(this);var b=this.a;if(b.preventDefault)b.preventDefault();else if(b.returnValue=!1,nc)try{if(b.ctrlKey||112<=b.keyCode&&123>=b.keyCode)b.keyCode=-1}catch(c){}};var Ac="closure_listenable_"+(1E6*Math.random()|0);function Bc(b){return!(!b||!b[Ac])}var Cc=0;function Dc(b,c,d,e,f){this.listener=b;this.a=null;this.src=c;this.type=d;this.bd=!!e;this.ke=f;this.key=++Cc;this.Uc=this.Vd=!1}function Ec(b){b.Uc=!0;b.listener=null;b.a=null;b.src=null;b.ke=null};function Fc(b){this.src=b;this.a={};this.f=0}Fc.prototype.add=function(b,c,d,e,f){var g=b.toString();b=this.a[g];b||(b=this.a[g]=[],this.f++);var h=Gc(b,c,e,f);-1<h?(c=b[h],d||(c.Vd=!1)):(c=new Dc(c,this.src,g,!!e,f),c.Vd=d,b.push(c));return c};Fc.prototype.remove=function(b,c,d,e){b=b.toString();if(!(b in this.a))return!1;var f=this.a[b];c=Gc(f,c,d,e);return-1<c?(Ec(f[c]),$a.splice.call(f,c,1),0==f.length&&(delete this.a[b],this.f--),!0):!1}; -function Hc(b,c){var d=c.type;if(!(d in b.a))return!1;var e=hb(b.a[d],c);e&&(Ec(c),0==b.a[d].length&&(delete b.a[d],b.f--));return e}function Ic(b,c,d,e,f){b=b.a[c.toString()];c=-1;b&&(c=Gc(b,d,e,f));return-1<c?b[c]:null}function Jc(b,c,d){var e=ca(c),f=e?c.toString():"",g=ca(d);return Jb(b.a,function(b){for(var c=0;c<b.length;++c)if(!(e&&b[c].type!=f||g&&b[c].bd!=d))return!0;return!1})} -function Gc(b,c,d,e){for(var f=0;f<b.length;++f){var g=b[f];if(!g.Uc&&g.listener==c&&g.bd==!!d&&g.ke==e)return f}return-1};var Kc="closure_lm_"+(1E6*Math.random()|0),Lc={},Mc=0;function D(b,c,d,e,f){if(ga(c)){for(var g=0;g<c.length;g++)D(b,c[g],d,e,f);return null}d=Nc(d);return Bc(b)?b.Ra(c,d,e,f):Oc(b,c,d,!1,e,f)} -function Oc(b,c,d,e,f,g){if(!c)throw Error("Invalid event type");var h=!!f,k=Pc(b);k||(b[Kc]=k=new Fc(b));d=k.add(c,d,e,f,g);if(d.a)return d;e=Rc();d.a=e;e.src=b;e.listener=d;if(b.addEventListener)b.addEventListener(c.toString(),e,h);else if(b.attachEvent)b.attachEvent(Sc(c.toString()),e);else throw Error("addEventListener and attachEvent are unavailable.");Mc++;return d} -function Rc(){var b=Tc,c=mc?function(d){return b.call(c.src,c.listener,d)}:function(d){d=b.call(c.src,c.listener,d);if(!d)return d};return c}function Uc(b,c,d,e,f){if(ga(c)){for(var g=0;g<c.length;g++)Uc(b,c[g],d,e,f);return null}d=Nc(d);return Bc(b)?b.yb.add(String(c),d,!0,e,f):Oc(b,c,d,!0,e,f)}function Vc(b,c,d,e,f){if(ga(c))for(var g=0;g<c.length;g++)Vc(b,c[g],d,e,f);else d=Nc(d),Bc(b)?b.Wf(c,d,e,f):b&&(b=Pc(b))&&(c=Ic(b,c,d,!!e,f))&&Wc(c)} -function Wc(b){if(ja(b)||!b||b.Uc)return!1;var c=b.src;if(Bc(c))return Hc(c.yb,b);var d=b.type,e=b.a;c.removeEventListener?c.removeEventListener(d,e,b.bd):c.detachEvent&&c.detachEvent(Sc(d),e);Mc--;(d=Pc(c))?(Hc(d,b),0==d.f&&(d.src=null,c[Kc]=null)):Ec(b);return!0}function Sc(b){return b in Lc?Lc[b]:Lc[b]="on"+b}function Xc(b,c,d,e){var f=!0;if(b=Pc(b))if(c=b.a[c.toString()])for(c=c.concat(),b=0;b<c.length;b++){var g=c[b];g&&g.bd==d&&!g.Uc&&(g=Yc(g,e),f=f&&!1!==g)}return f} -function Yc(b,c){var d=b.listener,e=b.ke||b.src;b.Vd&&Wc(b);return d.call(e,c)} -function Tc(b,c){if(b.Uc)return!0;if(!mc){var d;if(!(d=c))a:{d=["window","event"];for(var e=ba,f;f=d.shift();)if(null!=e[f])e=e[f];else{d=null;break a}d=e}f=d;d=new xc(f,this);e=!0;if(!(0>f.keyCode||void 0!=f.returnValue)){a:{var g=!1;if(0==f.keyCode)try{f.keyCode=-1;break a}catch(m){g=!0}if(g||void 0==f.returnValue)f.returnValue=!0}f=[];for(g=d.g;g;g=g.parentNode)f.push(g);for(var g=b.type,h=f.length-1;!d.j&&0<=h;h--){d.g=f[h];var k=Xc(f[h],g,!0,d),e=e&&k}for(h=0;!d.j&&h<f.length;h++)d.g=f[h],k= -Xc(f[h],g,!1,d),e=e&&k}return e}return Yc(b,new xc(c,this))}function Pc(b){b=b[Kc];return b instanceof Fc?b:null}var Zc="__closure_events_fn_"+(1E9*Math.random()>>>0);function Nc(b){if(ka(b))return b;b[Zc]||(b[Zc]=function(c){return b.handleEvent(c)});return b[Zc]};function $c(){oc.call(this);this.yb=new Fc(this);this.Od=this;this.gb=null}y($c,oc);$c.prototype[Ac]=!0;l=$c.prototype;l.addEventListener=function(b,c,d,e){D(this,b,c,d,e)};l.removeEventListener=function(b,c,d,e){Vc(this,b,c,d,e)}; -l.s=function(b){var c,d=this.gb;if(d)for(c=[];d;d=d.gb)c.push(d);var d=this.Od,e=b.type||b;if(ia(b))b=new tc(b,d);else if(b instanceof tc)b.target=b.target||d;else{var f=b;b=new tc(e,d);Wb(b,f)}var f=!0,g;if(c)for(var h=c.length-1;!b.j&&0<=h;h--)g=b.g=c[h],f=bd(g,e,!0,b)&&f;b.j||(g=b.g=d,f=bd(g,e,!0,b)&&f,b.j||(f=bd(g,e,!1,b)&&f));if(c)for(h=0;!b.j&&h<c.length;h++)g=b.g=c[h],f=bd(g,e,!1,b)&&f;return f}; -l.Y=function(){$c.ca.Y.call(this);if(this.yb){var b=this.yb,c=0,d;for(d in b.a){for(var e=b.a[d],f=0;f<e.length;f++)++c,Ec(e[f]);delete b.a[d];b.f--}}this.gb=null};l.Ra=function(b,c,d,e){return this.yb.add(String(b),c,!1,d,e)};l.Wf=function(b,c,d,e){return this.yb.remove(String(b),c,d,e)}; -function bd(b,c,d,e){c=b.yb.a[String(c)];if(!c)return!0;c=c.concat();for(var f=!0,g=0;g<c.length;++g){var h=c[g];if(h&&!h.Uc&&h.bd==d){var k=h.listener,m=h.ke||h.src;h.Vd&&Hc(b.yb,h);f=!1!==k.call(m,e)&&f}}return f&&0!=e.Th}function cd(b,c,d){return Jc(b.yb,ca(c)?String(c):void 0,d)};function dd(){$c.call(this);this.f=0}y(dd,$c);function ed(b){Wc(b)}l=dd.prototype;l.u=function(){++this.f;this.s("change")};l.L=function(){return this.f};l.H=function(b,c,d){return D(this,b,c,!1,d)};l.M=function(b,c,d){return Uc(this,b,c,!1,d)};l.K=function(b,c,d){Vc(this,b,c,!1,d)};l.N=ed;function fd(b,c,d){tc.call(this,b);this.key=c;this.oldValue=d}y(fd,tc);function gd(b){dd.call(this);w(this);this.G={};void 0!==b&&this.I(b)}y(gd,dd);var hd={};function id(b){return hd.hasOwnProperty(b)?hd[b]:hd[b]="change:"+b}l=gd.prototype;l.get=function(b){var c;this.G.hasOwnProperty(b)&&(c=this.G[b]);return c};l.P=function(){return Object.keys(this.G)};l.R=function(){var b={},c;for(c in this.G)b[c]=this.G[c];return b}; -function jd(b,c,d){var e;e=id(c);b.s(new fd(e,c,d));b.s(new fd("propertychange",c,d))}l.set=function(b,c,d){d?this.G[b]=c:(d=this.G[b],this.G[b]=c,d!==c&&jd(this,b,d))};l.I=function(b,c){for(var d in b)this.set(d,b[d],c)};l.S=function(b,c){if(b in this.G){var d=this.G[b];delete this.G[b];c||jd(this,b,d)}};function kd(b,c,d){void 0===d&&(d=[0,0]);d[0]=b[0]+2*c;d[1]=b[1]+2*c;return d}function ld(b,c,d){void 0===d&&(d=[0,0]);d[0]=b[0]*c+.5|0;d[1]=b[1]*c+.5|0;return d}function md(b,c){if(ga(b))return b;void 0===c?c=[b,b]:(c[0]=b,c[1]=b);return c};function nd(b,c){var d=b%c;return 0>d*c?d+c:d}function od(b,c,d){return b+d*(c-b)};function pd(b,c){b[0]+=c[0];b[1]+=c[1];return b}function qd(b,c){var d=b[0],e=b[1],f=c[0],g=c[1],h=f[0],f=f[1],k=g[0],g=g[1],m=k-h,n=g-f,d=0===m&&0===n?0:(m*(d-h)+n*(e-f))/(m*m+n*n||0);0>=d||(1<=d?(h=k,f=g):(h+=d*m,f+=d*n));return[h,f]}function rd(b,c){var d=nd(b+180,360)-180,e=Math.abs(Math.round(3600*d));return Math.floor(e/3600)+"\u00b0 "+Pa(Math.floor(e/60%60))+"\u2032 "+Pa(Math.floor(e%60))+"\u2033 "+c.charAt(0>d?1:0)} -function sd(b,c,d){return b?c.replace("{x}",b[0].toFixed(d)).replace("{y}",b[1].toFixed(d)):""}function td(b,c){for(var d=!0,e=b.length-1;0<=e;--e)if(b[e]!=c[e]){d=!1;break}return d}function ud(b,c){var d=Math.cos(c),e=Math.sin(c),f=b[1]*d+b[0]*e;b[0]=b[0]*d-b[1]*e;b[1]=f;return b}function vd(b,c){var d=b[0]-c[0],e=b[1]-c[1];return d*d+e*e}function wd(b,c){return vd(b,qd(b,c))}function xd(b,c){return sd(b,"{x}, {y}",c)};function yd(b){this.length=b.length||b;for(var c=0;c<this.length;c++)this[c]=b[c]||0}yd.prototype.a=4;yd.prototype.set=function(b,c){c=c||0;for(var d=0;d<b.length&&c+d<this.length;d++)this[c+d]=b[d]};yd.prototype.toString=Array.prototype.join;"undefined"==typeof Float32Array&&(yd.BYTES_PER_ELEMENT=4,yd.prototype.BYTES_PER_ELEMENT=yd.prototype.a,yd.prototype.set=yd.prototype.set,yd.prototype.toString=yd.prototype.toString,u("Float32Array",yd,void 0));function zd(b){this.length=b.length||b;for(var c=0;c<this.length;c++)this[c]=b[c]||0}zd.prototype.a=8;zd.prototype.set=function(b,c){c=c||0;for(var d=0;d<b.length&&c+d<this.length;d++)this[c+d]=b[d]};zd.prototype.toString=Array.prototype.join;if("undefined"==typeof Float64Array){try{zd.BYTES_PER_ELEMENT=8}catch(b){}zd.prototype.BYTES_PER_ELEMENT=zd.prototype.a;zd.prototype.set=zd.prototype.set;zd.prototype.toString=zd.prototype.toString;u("Float64Array",zd,void 0)};function Ad(b,c,d,e,f){b[0]=c;b[1]=d;b[2]=e;b[3]=f};function Bd(){var b=Array(16);Cd(b,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);return b}function Dd(){var b=Array(16);Cd(b,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);return b}function Cd(b,c,d,e,f,g,h,k,m,n,p,q,r,t,x,z,A){b[0]=c;b[1]=d;b[2]=e;b[3]=f;b[4]=g;b[5]=h;b[6]=k;b[7]=m;b[8]=n;b[9]=p;b[10]=q;b[11]=r;b[12]=t;b[13]=x;b[14]=z;b[15]=A} -function Ed(b,c){b[0]=c[0];b[1]=c[1];b[2]=c[2];b[3]=c[3];b[4]=c[4];b[5]=c[5];b[6]=c[6];b[7]=c[7];b[8]=c[8];b[9]=c[9];b[10]=c[10];b[11]=c[11];b[12]=c[12];b[13]=c[13];b[14]=c[14];b[15]=c[15]}function Fd(b){b[0]=1;b[1]=0;b[2]=0;b[3]=0;b[4]=0;b[5]=1;b[6]=0;b[7]=0;b[8]=0;b[9]=0;b[10]=1;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1} -function Gd(b,c,d){var e=b[0],f=b[1],g=b[2],h=b[3],k=b[4],m=b[5],n=b[6],p=b[7],q=b[8],r=b[9],t=b[10],x=b[11],z=b[12],A=b[13],B=b[14];b=b[15];var v=c[0],L=c[1],M=c[2],J=c[3],C=c[4],sa=c[5],la=c[6],K=c[7],ma=c[8],Ua=c[9],Nb=c[10],na=c[11],Fa=c[12],ad=c[13],Qc=c[14];c=c[15];d[0]=e*v+k*L+q*M+z*J;d[1]=f*v+m*L+r*M+A*J;d[2]=g*v+n*L+t*M+B*J;d[3]=h*v+p*L+x*M+b*J;d[4]=e*C+k*sa+q*la+z*K;d[5]=f*C+m*sa+r*la+A*K;d[6]=g*C+n*sa+t*la+B*K;d[7]=h*C+p*sa+x*la+b*K;d[8]=e*ma+k*Ua+q*Nb+z*na;d[9]=f*ma+m*Ua+r*Nb+A*na;d[10]= -g*ma+n*Ua+t*Nb+B*na;d[11]=h*ma+p*Ua+x*Nb+b*na;d[12]=e*Fa+k*ad+q*Qc+z*c;d[13]=f*Fa+m*ad+r*Qc+A*c;d[14]=g*Fa+n*ad+t*Qc+B*c;d[15]=h*Fa+p*ad+x*Qc+b*c} -function Hd(b,c){var d=b[0],e=b[1],f=b[2],g=b[3],h=b[4],k=b[5],m=b[6],n=b[7],p=b[8],q=b[9],r=b[10],t=b[11],x=b[12],z=b[13],A=b[14],B=b[15],v=d*k-e*h,L=d*m-f*h,M=d*n-g*h,J=e*m-f*k,C=e*n-g*k,sa=f*n-g*m,la=p*z-q*x,K=p*A-r*x,ma=p*B-t*x,Ua=q*A-r*z,Nb=q*B-t*z,na=r*B-t*A,Fa=v*na-L*Nb+M*Ua+J*ma-C*K+sa*la;0!=Fa&&(Fa=1/Fa,c[0]=(k*na-m*Nb+n*Ua)*Fa,c[1]=(-e*na+f*Nb-g*Ua)*Fa,c[2]=(z*sa-A*C+B*J)*Fa,c[3]=(-q*sa+r*C-t*J)*Fa,c[4]=(-h*na+m*ma-n*K)*Fa,c[5]=(d*na-f*ma+g*K)*Fa,c[6]=(-x*sa+A*M-B*L)*Fa,c[7]=(p*sa-r*M+t* -L)*Fa,c[8]=(h*Nb-k*ma+n*la)*Fa,c[9]=(-d*Nb+e*ma-g*la)*Fa,c[10]=(x*C-z*M+B*v)*Fa,c[11]=(-p*C+q*M-t*v)*Fa,c[12]=(-h*Ua+k*K-m*la)*Fa,c[13]=(d*Ua-e*K+f*la)*Fa,c[14]=(-x*J+z*L-A*v)*Fa,c[15]=(p*J-q*L+r*v)*Fa)}function Id(b,c,d){var e=b[1]*c+b[5]*d+0*b[9]+b[13],f=b[2]*c+b[6]*d+0*b[10]+b[14],g=b[3]*c+b[7]*d+0*b[11]+b[15];b[12]=b[0]*c+b[4]*d+0*b[8]+b[12];b[13]=e;b[14]=f;b[15]=g} -function Jd(b,c,d){Cd(b,b[0]*c,b[1]*c,b[2]*c,b[3]*c,b[4]*d,b[5]*d,b[6]*d,b[7]*d,1*b[8],1*b[9],1*b[10],1*b[11],b[12],b[13],b[14],b[15])}function Kd(b,c){var d=b[0],e=b[1],f=b[2],g=b[3],h=b[4],k=b[5],m=b[6],n=b[7],p=Math.cos(c),q=Math.sin(c);b[0]=d*p+h*q;b[1]=e*p+k*q;b[2]=f*p+m*q;b[3]=g*p+n*q;b[4]=d*-q+h*p;b[5]=e*-q+k*p;b[6]=f*-q+m*p;b[7]=g*-q+n*p}new Float64Array(3);new Float64Array(3);new Float64Array(4);new Float64Array(4);new Float64Array(4);new Float64Array(16);function Ld(b){for(var c=Md(),d=0,e=b.length;d<e;++d)Nd(c,b[d]);return c}function Od(b,c,d){var e=Math.min.apply(null,b),f=Math.min.apply(null,c);b=Math.max.apply(null,b);c=Math.max.apply(null,c);return Pd(e,f,b,c,d)}function Qd(b,c,d){return d?(d[0]=b[0]-c,d[1]=b[1]-c,d[2]=b[2]+c,d[3]=b[3]+c,d):[b[0]-c,b[1]-c,b[2]+c,b[3]+c]}function Rd(b,c){return c?(c[0]=b[0],c[1]=b[1],c[2]=b[2],c[3]=b[3],c):b.slice()} -function Sd(b,c,d){c=c<b[0]?b[0]-c:b[2]<c?c-b[2]:0;b=d<b[1]?b[1]-d:b[3]<d?d-b[3]:0;return c*c+b*b}function Td(b,c){return Ud(b,c[0],c[1])}function Vd(b,c){return b[0]<=c[0]&&c[2]<=b[2]&&b[1]<=c[1]&&c[3]<=b[3]}function Ud(b,c,d){return b[0]<=c&&c<=b[2]&&b[1]<=d&&d<=b[3]}function Wd(b,c){var d=b[1],e=b[2],f=b[3],g=c[0],h=c[1],k=0;g<b[0]?k=k|16:g>e&&(k=k|4);h<d?k|=8:h>f&&(k|=2);0===k&&(k=1);return k}function Md(){return[Infinity,Infinity,-Infinity,-Infinity]} -function Pd(b,c,d,e,f){return f?(f[0]=b,f[1]=c,f[2]=d,f[3]=e,f):[b,c,d,e]}function Xd(b,c){var d=b[0],e=b[1];return Pd(d,e,d,e,c)}function Yd(b,c,d,e,f){f=Pd(Infinity,Infinity,-Infinity,-Infinity,f);return Zd(f,b,c,d,e)}function ae(b,c){return b[0]==c[0]&&b[2]==c[2]&&b[1]==c[1]&&b[3]==c[3]}function be(b,c){c[0]<b[0]&&(b[0]=c[0]);c[2]>b[2]&&(b[2]=c[2]);c[1]<b[1]&&(b[1]=c[1]);c[3]>b[3]&&(b[3]=c[3]);return b} -function Nd(b,c){c[0]<b[0]&&(b[0]=c[0]);c[0]>b[2]&&(b[2]=c[0]);c[1]<b[1]&&(b[1]=c[1]);c[1]>b[3]&&(b[3]=c[1])}function Zd(b,c,d,e,f){for(;d<e;d+=f){var g=b,h=c[d],k=c[d+1];g[0]=Math.min(g[0],h);g[1]=Math.min(g[1],k);g[2]=Math.max(g[2],h);g[3]=Math.max(g[3],k)}return b}function ce(b,c,d){var e;return(e=c.call(d,de(b)))||(e=c.call(d,ee(b)))||(e=c.call(d,fe(b)))?e:(e=c.call(d,ge(b)))?e:!1}function he(b){var c=0;ie(b)||(c=je(b)*ke(b));return c}function de(b){return[b[0],b[1]]} -function ee(b){return[b[2],b[1]]}function le(b){return[(b[0]+b[2])/2,(b[1]+b[3])/2]}function me(b,c,d,e){var f=c*e[0]/2;e=c*e[1]/2;c=Math.cos(d);d=Math.sin(d);f=[-f,-f,f,f];e=[-e,e,-e,e];var g,h,k;for(g=0;4>g;++g)h=f[g],k=e[g],f[g]=b[0]+h*c-k*d,e[g]=b[1]+h*d+k*c;return Od(f,e,void 0)}function ke(b){return b[3]-b[1]}function ne(b,c,d){d=d?d:Md();oe(b,c)&&(d[0]=b[0]>c[0]?b[0]:c[0],d[1]=b[1]>c[1]?b[1]:c[1],d[2]=b[2]<c[2]?b[2]:c[2],d[3]=b[3]<c[3]?b[3]:c[3]);return d}function ge(b){return[b[0],b[3]]} -function fe(b){return[b[2],b[3]]}function je(b){return b[2]-b[0]}function oe(b,c){return b[0]<=c[2]&&b[2]>=c[0]&&b[1]<=c[3]&&b[3]>=c[1]}function ie(b){return b[2]<b[0]||b[3]<b[1]}function pe(b,c){var d=(b[2]-b[0])/2*(c-1),e=(b[3]-b[1])/2*(c-1);b[0]-=d;b[2]+=d;b[1]-=e;b[3]+=e}function qe(b,c,d){b=[b[0],b[1],b[0],b[3],b[2],b[1],b[2],b[3]];c(b,b,2);return Od([b[0],b[2],b[4],b[6]],[b[1],b[3],b[5],b[7]],d)};function re(b){return function(){return b}}var se=re(!1),te=re(!0),ue=re(null);function ve(b){return b}function we(b){var c;c=c||0;return function(){return b.apply(this,Array.prototype.slice.call(arguments,0,c))}}function xe(b){var c=arguments,d=c.length;return function(){for(var b,f=0;f<d;f++)b=c[f].apply(this,arguments);return b}}function ye(b){var c=arguments,d=c.length;return function(){for(var b=0;b<d;b++)if(!c[b].apply(this,arguments))return!1;return!0}};/* + var l,aa=this;function t(a,c,d){a=a.split(".");d=d||aa;a[0]in d||!d.execScript||d.execScript("var "+a[0]);for(var e;a.length&&(e=a.shift());)a.length||void 0===c?d[e]?d=d[e]:d=d[e]={}:d[e]=c}function ba(a){a.Ub=function(){return a.Og?a.Og:a.Og=new a}} +function ca(a){var c=typeof a;if("object"==c)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return c;var d=Object.prototype.toString.call(a);if("[object Window]"==d)return"object";if("[object Array]"==d||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==d||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null"; +else if("function"==c&&"undefined"==typeof a.call)return"object";return c}function da(a){var c=ca(a);return"array"==c||"object"==c&&"number"==typeof a.length}function ea(a){return"string"==typeof a}function fa(a){return"number"==typeof a}function ga(a){return"function"==ca(a)}function ha(a){var c=typeof a;return"object"==c&&null!=a||"function"==c}function w(a){return a[ia]||(a[ia]=++ja)}var ia="closure_uid_"+(1E9*Math.random()>>>0),ja=0;function ka(a,c,d){return a.call.apply(a.bind,arguments)} +function la(a,c,d){if(!a)throw Error();if(2<arguments.length){var e=Array.prototype.slice.call(arguments,2);return function(){var d=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(d,e);return a.apply(c,d)}}return function(){return a.apply(c,arguments)}}function ma(a,c,d){ma=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?ka:la;return ma.apply(null,arguments)} +function y(a,c){function d(){}d.prototype=c.prototype;a.ia=c.prototype;a.prototype=new d;a.prototype.constructor=a;a.Lp=function(a,d,g){for(var h=Array(arguments.length-2),k=2;k<arguments.length;k++)h[k-2]=arguments[k];return c.prototype[d].apply(a,h)}};var na,oa;function pa(){}var qa=Function("return this")();var ra;var sa=String.prototype.trim?function(a){return a.trim()}:function(a){return a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")};function ta(a){if(!va.test(a))return a;-1!=a.indexOf("&")&&(a=a.replace(wa,"&"));-1!=a.indexOf("<")&&(a=a.replace(xa,"<"));-1!=a.indexOf(">")&&(a=a.replace(ya,">"));-1!=a.indexOf('"')&&(a=a.replace(za,"""));-1!=a.indexOf("'")&&(a=a.replace(Aa,"'"));-1!=a.indexOf("\x00")&&(a=a.replace(Ba,"�"));return a}var wa=/&/g,xa=/</g,ya=/>/g,za=/"/g,Aa=/'/g,Ba=/\x00/g,va=/[\x00&<>"']/; +function Ca(a,c){return a<c?-1:a>c?1:0};function Da(a,c,d){return Math.min(Math.max(a,c),d)}var Ea=function(){var a;"cosh"in Math?a=Math.cosh:a=function(a){a=Math.exp(a);return(a+1/a)/2};return a}();function Fa(a,c,d,e,f,g){var h=f-d,k=g-e;if(0!==h||0!==k){var m=((a-d)*h+(c-e)*k)/(h*h+k*k);1<m?(d=f,e=g):0<m&&(d+=h*m,e+=k*m)}return Ga(a,c,d,e)}function Ga(a,c,d,e){a=d-a;c=e-c;return a*a+c*c}function Ha(a){return a*Math.PI/180}function Ja(a,c){var d=a%c;return 0>d*c?d+c:d}function La(a,c,d){return a+d*(c-a)};function Ma(a){return function(c){if(c)return[Da(c[0],a[0],a[2]),Da(c[1],a[1],a[3])]}}function Na(a){return a};function Oa(a,c,d){this.center=a;this.resolution=c;this.rotation=d};var Pa="function"===typeof Object.assign?Object.assign:function(a,c){if(void 0===a||null===a)throw new TypeError("Cannot convert undefined or null to object");for(var d=Object(a),e=1,f=arguments.length;e<f;++e){var g=arguments[e];if(void 0!==g&&null!==g)for(var h in g)g.hasOwnProperty(h)&&(d[h]=g[h])}return d};function Qa(a){for(var c in a)delete a[c]}function Ra(a){var c=[],d;for(d in a)c.push(a[d]);return c}function Sa(a){for(var c in a)return!1;return!c};var Ua="olm_"+(1E4*Math.random()|0);function Va(a){function c(c){var e=a.listener,f=a.jg||a.target;a.lg&&Xa(a);return e.call(f,c)}return a.kg=c}function Ya(a,c,d,e){for(var f,g=0,h=a.length;g<h;++g)if(f=a[g],f.listener===c&&f.jg===d)return e&&(f.deleteIndex=g),f}function Za(a,c){var d=a[Ua];return d?d[c]:void 0}function $a(a){var c=a[Ua];c||(c=a[Ua]={});return c} +function ab(a,c){var d=Za(a,c);if(d){for(var e=0,f=d.length;e<f;++e)a.removeEventListener(c,d[e].kg),Qa(d[e]);d.length=0;if(d=a[Ua])delete d[c],0===Object.keys(d).length&&delete a[Ua]}}function C(a,c,d,e,f){var g=$a(a),h=g[c];h||(h=g[c]=[]);(g=Ya(h,d,e,!1))?f||(g.lg=!1):(g={jg:e,lg:!!f,listener:d,target:a,type:c},a.addEventListener(c,Va(g)),h.push(g));return g}function bb(a,c,d,e){return C(a,c,d,e,!0)}function cb(a,c,d,e){(a=Za(a,c))&&(d=Ya(a,d,e,!0))&&Xa(d)} +function Xa(a){if(a&&a.target){a.target.removeEventListener(a.type,a.kg);var c=Za(a.target,a.type);if(c){var d="deleteIndex"in a?a.deleteIndex:c.indexOf(a);-1!==d&&c.splice(d,1);0===c.length&&ab(a.target,a.type)}Qa(a)}}function db(a){var c=$a(a),d;for(d in c)ab(a,d)};function eb(){}eb.prototype.Cb=!1;function fb(a){a.Cb||(a.Cb=!0,a.fa())}eb.prototype.fa=pa;function gb(a,c){this.type=a;this.target=c||null}gb.prototype.preventDefault=gb.prototype.stopPropagation=function(){this.no=!0};function hb(a){a.stopPropagation()}function ib(a){a.preventDefault()};function jb(){this.Qa={};this.ya={};this.va={}}y(jb,eb);jb.prototype.addEventListener=function(a,c){var d=this.va[a];d||(d=this.va[a]=[]);-1===d.indexOf(c)&&d.push(c)}; +jb.prototype.b=function(a){var c="string"===typeof a?new gb(a):a;a=c.type;c.target=this;var d=this.va[a],e;if(d){a in this.ya||(this.ya[a]=0,this.Qa[a]=0);++this.ya[a];for(var f=0,g=d.length;f<g;++f)if(!1===d[f].call(this,c)||c.no){e=!1;break}--this.ya[a];if(0===this.ya[a]){c=this.Qa[a];for(delete this.Qa[a];c--;)this.removeEventListener(a,pa);delete this.ya[a]}return e}};jb.prototype.fa=function(){db(this)};function lb(a,c){return c?c in a.va:0<Object.keys(a.va).length} +jb.prototype.removeEventListener=function(a,c){var d=this.va[a];if(d){var e=d.indexOf(c);a in this.Qa?(d[e]=pa,++this.Qa[a]):(d.splice(e,1),0===d.length&&delete this.va[a])}};function mb(){jb.call(this);this.g=0}y(mb,jb);function nb(a){if(Array.isArray(a))for(var c=0,d=a.length;c<d;++c)Xa(a[c]);else Xa(a)}l=mb.prototype;l.u=function(){++this.g;this.b("change")};l.H=function(){return this.g};l.D=function(a,c,d){if(Array.isArray(a)){for(var e=a.length,f=Array(e),g=0;g<e;++g)f[g]=C(this,a[g],c,d);return f}return C(this,a,c,d)};l.I=function(a,c,d){if(Array.isArray(a)){for(var e=a.length,f=Array(e),g=0;g<e;++g)f[g]=bb(this,a[g],c,d);return f}return bb(this,a,c,d)}; +l.G=function(a,c,d){if(Array.isArray(a))for(var e=0,f=a.length;e<f;++e)cb(this,a[e],c,d);else cb(this,a,c,d)};l.J=nb;function ob(a,c,d){gb.call(this,a);this.key=c;this.oldValue=d}y(ob,gb);function pb(a){mb.call(this);w(this);this.U={};void 0!==a&&this.C(a)}y(pb,mb);var qb={};function rb(a){return qb.hasOwnProperty(a)?qb[a]:qb[a]="change:"+a}l=pb.prototype;l.get=function(a){var c;this.U.hasOwnProperty(a)&&(c=this.U[a]);return c};l.K=function(){return Object.keys(this.U)};l.L=function(){return Pa({},this.U)};function sb(a,c,d){var e;e=rb(c);a.b(new ob(e,c,d));a.b(new ob("propertychange",c,d))} +l.set=function(a,c,d){d?this.U[a]=c:(d=this.U[a],this.U[a]=c,d!==c&&sb(this,a,d))};l.C=function(a,c){for(var d in a)this.set(d,a[d],c)};l.P=function(a,c){if(a in this.U){var d=this.U[a];delete this.U[a];c||sb(this,a,d)}};function tb(a,c){return a>c?1:a<c?-1:0}function ub(a,c){return 0<=a.indexOf(c)}function vb(a,c,d){var e=a.length;if(a[0]<=c)return 0;if(!(c<=a[e-1]))if(0<d)for(d=1;d<e;++d){if(a[d]<c)return d-1}else if(0>d)for(d=1;d<e;++d){if(a[d]<=c)return d}else for(d=1;d<e;++d){if(a[d]==c)return d;if(a[d]<c)return a[d-1]-c<c-a[d]?d-1:d}return e-1}function wb(a){return a.reduce(function(a,d){return Array.isArray(d)?a.concat(wb(d)):a.concat(d)},[])} +function xb(a,c){var d,e=da(c)?c:[c],f=e.length;for(d=0;d<f;d++)a[a.length]=e[d]}function yb(a,c){var d=a.indexOf(c),e=-1<d;e&&a.splice(d,1);return e}function zb(a,c){for(var d=a.length>>>0,e,f=0;f<d;f++)if(e=a[f],c(e,f,a))return e;return null}function Ab(a,c){var d=a.length;if(d!==c.length)return!1;for(var e=0;e<d;e++)if(a[e]!==c[e])return!1;return!0} +function Bb(a){var c=Cb,d=a.length,e=Array(a.length),f;for(f=0;f<d;f++)e[f]={index:f,value:a[f]};e.sort(function(a,d){return c(a.value,d.value)||a.index-d.index});for(f=0;f<a.length;f++)a[f]=e[f].value}function Db(a,c){var d;return a.every(function(e,f){d=f;return!c(e,f,a)})?-1:d};function Eb(a){return function(c,d,e){if(void 0!==c)return c=vb(a,c,e),c=Da(c+d,0,a.length-1),a[c]}}function Fb(a,c,d){return function(e,f,g){if(void 0!==e)return e=Math.max(Math.floor(Math.log(c/e)/Math.log(a)+(0<g?0:0>g?1:.5))+f,0),void 0!==d&&(e=Math.min(e,d)),c/Math.pow(a,e)}};function Gb(a){if(void 0!==a)return 0}function Hb(a,c){if(void 0!==a)return a+c}function Ib(a){var c=2*Math.PI/a;return function(a,e){if(void 0!==a)return a=Math.floor((a+e)/c+.5)*c}}function Jb(){var a=Ha(5);return function(c,d){if(void 0!==c)return Math.abs(c+d)<=a?0:c+d}};function Kb(a,c){var d=void 0!==c?a.toFixed(c):""+a,e=d.indexOf("."),e=-1===e?d.length:e;return 2<e?d:Array(3-e).join("0")+d}function Lb(a){a=(""+a).split(".");for(var c=["1","3"],d=0;d<Math.max(a.length,c.length);d++){var e=parseInt(a[d]||"0",10),f=parseInt(c[d]||"0",10);if(e>f)return 1;if(f>e)return-1}return 0};function Mb(a,c){a[0]+=c[0];a[1]+=c[1];return a}function Nb(a,c){var d=a[0],e=a[1],f=c[0],g=c[1],h=f[0],f=f[1],k=g[0],g=g[1],m=k-h,n=g-f,d=0===m&&0===n?0:(m*(d-h)+n*(e-f))/(m*m+n*n||0);0>=d||(1<=d?(h=k,f=g):(h+=d*m,f+=d*n));return[h,f]}function Ob(a,c,d){a=Ja(a+180,360)-180;var e=Math.abs(3600*a);return Math.floor(e/3600)+"\u00b0 "+Kb(Math.floor(e/60%60))+"\u2032 "+Kb(e%60,d||0)+"\u2033 "+c.charAt(0>a?1:0)} +function Pb(a,c,d){return a?c.replace("{x}",a[0].toFixed(d)).replace("{y}",a[1].toFixed(d)):""}function Qb(a,c){for(var d=!0,e=a.length-1;0<=e;--e)if(a[e]!=c[e]){d=!1;break}return d}function Rb(a,c){var d=Math.cos(c),e=Math.sin(c),f=a[1]*d+a[0]*e;a[0]=a[0]*d-a[1]*e;a[1]=f;return a}function Sb(a,c){var d=a[0]-c[0],e=a[1]-c[1];return d*d+e*e}function Tb(a,c){return Sb(a,Nb(a,c))}function Ub(a,c){return Pb(a,"{x}, {y}",c)};function Vb(a){for(var c=Wb(),d=0,e=a.length;d<e;++d)Xb(c,a[d]);return c}function Yb(a,c,d){return d?(d[0]=a[0]-c,d[1]=a[1]-c,d[2]=a[2]+c,d[3]=a[3]+c,d):[a[0]-c,a[1]-c,a[2]+c,a[3]+c]}function Zb(a,c){return c?(c[0]=a[0],c[1]=a[1],c[2]=a[2],c[3]=a[3],c):a.slice()}function $b(a,c,d){c=c<a[0]?a[0]-c:a[2]<c?c-a[2]:0;a=d<a[1]?a[1]-d:a[3]<d?d-a[3]:0;return c*c+a*a}function ac(a,c){return bc(a,c[0],c[1])}function cc(a,c){return a[0]<=c[0]&&c[2]<=a[2]&&a[1]<=c[1]&&c[3]<=a[3]} +function bc(a,c,d){return a[0]<=c&&c<=a[2]&&a[1]<=d&&d<=a[3]}function dc(a,c){var d=a[1],e=a[2],f=a[3],g=c[0],h=c[1],k=0;g<a[0]?k=k|16:g>e&&(k=k|4);h<d?k|=8:h>f&&(k|=2);0===k&&(k=1);return k}function Wb(){return[Infinity,Infinity,-Infinity,-Infinity]}function ec(a,c,d,e,f){return f?(f[0]=a,f[1]=c,f[2]=d,f[3]=e,f):[a,c,d,e]}function fc(a,c){var d=a[0],e=a[1];return ec(d,e,d,e,c)}function gc(a,c,d,e,f){f=ec(Infinity,Infinity,-Infinity,-Infinity,f);return hc(f,a,c,d,e)} +function ic(a,c){return a[0]==c[0]&&a[2]==c[2]&&a[1]==c[1]&&a[3]==c[3]}function jc(a,c){c[0]<a[0]&&(a[0]=c[0]);c[2]>a[2]&&(a[2]=c[2]);c[1]<a[1]&&(a[1]=c[1]);c[3]>a[3]&&(a[3]=c[3]);return a}function Xb(a,c){c[0]<a[0]&&(a[0]=c[0]);c[0]>a[2]&&(a[2]=c[0]);c[1]<a[1]&&(a[1]=c[1]);c[1]>a[3]&&(a[3]=c[1])}function hc(a,c,d,e,f){for(;d<e;d+=f){var g=a,h=c[d],k=c[d+1];g[0]=Math.min(g[0],h);g[1]=Math.min(g[1],k);g[2]=Math.max(g[2],h);g[3]=Math.max(g[3],k)}return a} +function kc(a,c,d){var e;return(e=c.call(d,lc(a)))||(e=c.call(d,mc(a)))||(e=c.call(d,nc(a)))?e:(e=c.call(d,oc(a)))?e:!1}function pc(a){var c=0;qc(a)||(c=rc(a)*sc(a));return c}function lc(a){return[a[0],a[1]]}function mc(a){return[a[2],a[1]]}function tc(a){return[(a[0]+a[2])/2,(a[1]+a[3])/2]} +function uc(a,c,d,e,f){var g=c*e[0]/2;e=c*e[1]/2;c=Math.cos(d);var h=Math.sin(d);d=g*c;g*=h;c*=e;var k=e*h,m=a[0],n=a[1];a=m-d+k;e=m-d-k;h=m+d-k;d=m+d+k;var k=n-g-c,m=n-g+c,p=n+g+c,g=n+g-c;return ec(Math.min(a,e,h,d),Math.min(k,m,p,g),Math.max(a,e,h,d),Math.max(k,m,p,g),f)}function sc(a){return a[3]-a[1]}function vc(a,c,d){d=d?d:Wb();wc(a,c)&&(d[0]=a[0]>c[0]?a[0]:c[0],d[1]=a[1]>c[1]?a[1]:c[1],d[2]=a[2]<c[2]?a[2]:c[2],d[3]=a[3]<c[3]?a[3]:c[3]);return d}function oc(a){return[a[0],a[3]]} +function nc(a){return[a[2],a[3]]}function rc(a){return a[2]-a[0]}function wc(a,c){return a[0]<=c[2]&&a[2]>=c[0]&&a[1]<=c[3]&&a[3]>=c[1]}function qc(a){return a[2]<a[0]||a[3]<a[1]}function yc(a,c){var d=(a[2]-a[0])/2*(c-1),e=(a[3]-a[1])/2*(c-1);a[0]-=d;a[2]+=d;a[1]-=e;a[3]+=e} +function zc(a,c,d){a=[a[0],a[1],a[0],a[3],a[2],a[1],a[2],a[3]];c(a,a,2);var e=[a[0],a[2],a[4],a[6]],f=[a[1],a[3],a[5],a[7]];c=Math.min.apply(null,e);a=Math.min.apply(null,f);e=Math.max.apply(null,e);f=Math.max.apply(null,f);return ec(c,a,e,f,d)};function Ac(){return!0}function Bc(){return!1};/* Latitude/longitude spherical geodesy formulae taken from http://www.movable-type.co.uk/scripts/latlong.html Licensed under CC-BY-3.0. */ -function ze(b){this.radius=b}ze.prototype.f=function(b){for(var c=0,d=b.length,e=b[d-1][0],f=b[d-1][1],g=0;g<d;g++)var h=b[g][0],k=b[g][1],c=c+Xa(h-e)*(2+Math.sin(Xa(f))+Math.sin(Xa(k))),e=h,f=k;return c*this.radius*this.radius/2};ze.prototype.a=function(b,c){var d=Xa(b[1]),e=Xa(c[1]),f=(e-d)/2,g=Xa(c[0]-b[0])/2,d=Math.sin(f)*Math.sin(f)+Math.sin(g)*Math.sin(g)*Math.cos(d)*Math.cos(e);return 2*this.radius*Math.atan2(Math.sqrt(d),Math.sqrt(1-d))}; -ze.prototype.offset=function(b,c,d){var e=Xa(b[1]);c/=this.radius;var f=Math.asin(Math.sin(e)*Math.cos(c)+Math.cos(e)*Math.sin(c)*Math.cos(d));return[180*(Xa(b[0])+Math.atan2(Math.sin(d)*Math.sin(c)*Math.cos(e),Math.cos(c)-Math.sin(e)*Math.sin(f)))/Math.PI,180*f/Math.PI]};var Ae=new ze(6370997);var Be={};Be.degrees=2*Math.PI*Ae.radius/360;Be.ft=.3048;Be.m=1;Be["us-ft"]=1200/3937; -function Ce(b){this.a=b.code;this.f=b.units;this.i=void 0!==b.extent?b.extent:null;this.j=void 0!==b.worldExtent?b.worldExtent:null;this.g=void 0!==b.axisOrientation?b.axisOrientation:"enu";this.c=void 0!==b.global?b.global:!1;this.b=!(!this.c||!this.i);this.o=void 0!==b.getPointResolution?b.getPointResolution:this.hk;this.l=null;var c=De,d=b.code;if("function"==typeof proj4&&void 0===c[d]){var e=proj4.defs(d);if(void 0!==e){void 0!==e.axis&&void 0===b.axisOrientation&&(this.g=e.axis);void 0===b.units&& -(b=e.units,void 0===e.to_meter||void 0!==b&&void 0!==Be[b]||(b=e.to_meter.toString(),Be[b]=e.to_meter),this.f=b);for(var f in c)b=proj4.defs(f),void 0!==b&&(c=Ee(f),b===e?Fe([c,this]):(b=proj4(f,d),Ge(c,this,b.forward,b.inverse)))}}}l=Ce.prototype;l.Jj=function(){return this.a};l.J=function(){return this.i};l.Am=function(){return this.f};l.Kc=function(){return Be[this.f]};l.tk=function(){return this.j};function He(b){return b.g}l.gl=function(){return this.c}; -l.No=function(b){this.c=b;this.b=!(!b||!this.i)};l.Bm=function(b){this.i=b;this.b=!(!this.c||!b)};l.Vo=function(b){this.j=b};l.Mo=function(b){this.o=b};l.hk=function(b,c){if("degrees"==this.f)return b;var d=Ie(this,Ee("EPSG:4326")),e=[c[0]-b/2,c[1],c[0]+b/2,c[1],c[0],c[1]-b/2,c[0],c[1]+b/2],e=d(e,e,2),d=Ae.a(e.slice(0,2),e.slice(2,4)),e=Ae.a(e.slice(4,6),e.slice(6,8)),e=(d+e)/2,d=this.Kc();void 0!==d&&(e/=d);return e};l.getPointResolution=function(b,c){return this.o(b,c)};var De={},Je={}; -function Fe(b){Ke(b);b.forEach(function(c){b.forEach(function(b){c!==b&&Le(c,b,Me)})})}function Ne(){var b=Oe,c=Pe,d=Qe;Re.forEach(function(e){b.forEach(function(b){Le(e,b,c);Le(b,e,d)})})}function Se(b){De[b.a]=b;Le(b,b,Me)}function Ke(b){var c=[];b.forEach(function(b){c.push(Se(b))})}function Te(b){return b?ia(b)?Ee(b):b:Ee("EPSG:3857")}function Le(b,c,d){b=b.a;c=c.a;b in Je||(Je[b]={});Je[b][c]=d}function Ge(b,c,d,e){b=Ee(b);c=Ee(c);Le(b,c,Ue(d));Le(c,b,Ue(e))} -function Ue(b){return function(c,d,e){var f=c.length;e=void 0!==e?e:2;d=void 0!==d?d:Array(f);var g,h;for(h=0;h<f;h+=e)for(g=b([c[h],c[h+1]]),d[h]=g[0],d[h+1]=g[1],g=e-1;2<=g;--g)d[h+g]=c[h+g];return d}}function Ee(b){var c;b instanceof Ce?c=b:ia(b)?(c=De[b],void 0===c&&"function"==typeof proj4&&void 0!==proj4.defs(b)&&(c=new Ce({code:b}),Se(c))):c=null;return c}function Ve(b,c){if(b===c)return!0;var d=b.f===c.f;return b.a===c.a?d:Ie(b,c)===Me&&d} -function We(b,c){var d=Ee(b),e=Ee(c);return Ie(d,e)}function Ie(b,c){var d=b.a,e=c.a,f;d in Je&&e in Je[d]&&(f=Je[d][e]);void 0===f&&(f=Xe);return f}function Xe(b,c){if(void 0!==c&&b!==c){for(var d=0,e=b.length;d<e;++d)c[d]=b[d];b=c}return b}function Me(b,c){var d;if(void 0!==c){d=0;for(var e=b.length;d<e;++d)c[d]=b[d];d=c}else d=b.slice();return d}function Ye(b,c,d){return We(c,d)(b,void 0,b.length)}function Ze(b,c,d){c=We(c,d);return qe(b,c)};function $e(){gd.call(this);this.B=Md();this.v=-1;this.i={};this.o=this.j=0}y($e,gd);l=$e.prototype;l.qb=function(b,c){var d=c?c:[NaN,NaN];this.nb(b[0],b[1],d,Infinity);return d};l.og=function(b){return this.uc(b[0],b[1])};l.uc=se;l.J=function(b){this.v!=this.f&&(this.B=this.Wd(this.B),this.v=this.f);var c=this.B;b?(b[0]=c[0],b[1]=c[1],b[2]=c[2],b[3]=c[3]):b=c;return b};l.xb=function(b){return this.td(b*b)};l.lb=function(b,c){this.pc(We(b,c));return this};function af(b,c,d,e,f,g){var h=f[0],k=f[1],m=f[4],n=f[5],p=f[12];f=f[13];for(var q=g?g:[],r=0;c<d;c+=e){var t=b[c],x=b[c+1];q[r++]=h*t+m*x+p;q[r++]=k*t+n*x+f}g&&q.length!=r&&(q.length=r);return q};function bf(){$e.call(this);this.b="XY";this.a=2;this.A=null}y(bf,$e);function cf(b){if("XY"==b)return 2;if("XYZ"==b||"XYM"==b)return 3;if("XYZM"==b)return 4}l=bf.prototype;l.uc=se;l.Wd=function(b){return Yd(this.A,0,this.A.length,this.a,b)};l.Kb=function(){return this.A.slice(0,this.a)};l.ia=function(){return this.A};l.Lb=function(){return this.A.slice(this.A.length-this.a)};l.Mb=function(){return this.b}; -l.td=function(b){this.o!=this.f&&(Qb(this.i),this.j=0,this.o=this.f);if(0>b||0!==this.j&&b<=this.j)return this;var c=b.toString();if(this.i.hasOwnProperty(c))return this.i[c];var d=this.Lc(b);if(d.ia().length<this.A.length)return this.i[c]=d;this.j=b;return this};l.Lc=function(){return this};l.ra=function(){return this.a};function df(b,c,d){b.a=cf(c);b.b=c;b.A=d} -function ef(b,c,d,e){if(c)d=cf(c);else{for(c=0;c<e;++c){if(0===d.length){b.b="XY";b.a=2;return}d=d[0]}d=d.length;c=2==d?"XY":3==d?"XYZ":4==d?"XYZM":void 0}b.b=c;b.a=d}l.pc=function(b){this.A&&(b(this.A,this.A,this.a),this.u())};l.Pc=function(b,c){var d=this.ia();if(d){var e=d.length,f=this.ra(),g=d?d:[],h=0,k,m;for(k=0;k<e;k+=f)for(g[h++]=d[k]+b,g[h++]=d[k+1]+c,m=k+2;m<k+f;++m)g[h++]=d[m];d&&g.length!=h&&(g.length=h);this.u()}};function ff(b,c,d,e){for(var f=0,g=b[d-e],h=b[d-e+1];c<d;c+=e)var k=b[c],m=b[c+1],f=f+(h*k-g*m),g=k,h=m;return f/2}function gf(b,c,d,e){var f=0,g,h;g=0;for(h=d.length;g<h;++g){var k=d[g],f=f+ff(b,c,k,e);c=k}return f};function hf(b,c,d,e,f,g,h){var k=b[c],m=b[c+1],n=b[d]-k,p=b[d+1]-m;if(0!==n||0!==p)if(g=((f-k)*n+(g-m)*p)/(n*n+p*p),1<g)c=d;else if(0<g){for(f=0;f<e;++f)h[f]=od(b[c+f],b[d+f],g);h.length=e;return}for(f=0;f<e;++f)h[f]=b[c+f];h.length=e}function jf(b,c,d,e,f){var g=b[c],h=b[c+1];for(c+=e;c<d;c+=e){var k=b[c],m=b[c+1],g=Wa(g,h,k,m);g>f&&(f=g);g=k;h=m}return f}function kf(b,c,d,e,f){var g,h;g=0;for(h=d.length;g<h;++g){var k=d[g];f=jf(b,c,k,e,f);c=k}return f} -function lf(b,c,d,e,f,g,h,k,m,n,p){if(c==d)return n;var q;if(0===f){q=Wa(h,k,b[c],b[c+1]);if(q<n){for(p=0;p<e;++p)m[p]=b[c+p];m.length=e;return q}return n}for(var r=p?p:[NaN,NaN],t=c+e;t<d;)if(hf(b,t-e,t,e,h,k,r),q=Wa(h,k,r[0],r[1]),q<n){n=q;for(p=0;p<e;++p)m[p]=r[p];m.length=e;t+=e}else t+=e*Math.max((Math.sqrt(q)-Math.sqrt(n))/f|0,1);if(g&&(hf(b,d-e,c,e,h,k,r),q=Wa(h,k,r[0],r[1]),q<n)){n=q;for(p=0;p<e;++p)m[p]=r[p];m.length=e}return n} -function mf(b,c,d,e,f,g,h,k,m,n,p){p=p?p:[NaN,NaN];var q,r;q=0;for(r=d.length;q<r;++q){var t=d[q];n=lf(b,c,t,e,f,g,h,k,m,n,p);c=t}return n};function nf(b,c){var d=0,e,f;e=0;for(f=c.length;e<f;++e)b[d++]=c[e];return d}function of(b,c,d,e){var f,g;f=0;for(g=d.length;f<g;++f){var h=d[f],k;for(k=0;k<e;++k)b[c++]=h[k]}return c}function pf(b,c,d,e,f){f=f?f:[];var g=0,h,k;h=0;for(k=d.length;h<k;++h)c=of(b,c,d[h],e),f[g++]=c;f.length=g;return f};function qf(b,c,d,e,f){f=void 0!==f?f:[];for(var g=0;c<d;c+=e)f[g++]=b.slice(c,c+e);f.length=g;return f}function rf(b,c,d,e,f){f=void 0!==f?f:[];var g=0,h,k;h=0;for(k=d.length;h<k;++h){var m=d[h];f[g++]=qf(b,c,m,e,f[g]);c=m}f.length=g;return f};function tf(b,c,d,e,f,g,h){var k=(d-c)/e;if(3>k){for(;c<d;c+=e)g[h++]=b[c],g[h++]=b[c+1];return h}var m=Array(k);m[0]=1;m[k-1]=1;d=[c,d-e];for(var n=0,p;0<d.length;){var q=d.pop(),r=d.pop(),t=0,x=b[r],z=b[r+1],A=b[q],B=b[q+1];for(p=r+e;p<q;p+=e){var v=Va(b[p],b[p+1],x,z,A,B);v>t&&(n=p,t=v)}t>f&&(m[(n-c)/e]=1,r+e<n&&d.push(r,n),n+e<q&&d.push(n,q))}for(p=0;p<k;++p)m[p]&&(g[h++]=b[c+p*e],g[h++]=b[c+p*e+1]);return h} -function uf(b,c,d,e,f,g,h,k){var m,n;m=0;for(n=d.length;m<n;++m){var p=d[m];a:{var q=b,r=p,t=e,x=f,z=g;if(c!=r){var A=x*Math.round(q[c]/x),B=x*Math.round(q[c+1]/x);c+=t;z[h++]=A;z[h++]=B;var v=void 0,L=void 0;do if(v=x*Math.round(q[c]/x),L=x*Math.round(q[c+1]/x),c+=t,c==r){z[h++]=v;z[h++]=L;break a}while(v==A&&L==B);for(;c<r;){var M,J;M=x*Math.round(q[c]/x);J=x*Math.round(q[c+1]/x);c+=t;if(M!=v||J!=L){var C=v-A,sa=L-B,la=M-A,K=J-B;C*K==sa*la&&(0>C&&la<C||C==la||0<C&&la>C)&&(0>sa&&K<sa||sa==K||0<sa&& -K>sa)||(z[h++]=v,z[h++]=L,A=v,B=L);v=M;L=J}}z[h++]=v;z[h++]=L}}k.push(h);c=p}return h};function vf(b,c){bf.call(this);this.g=this.l=-1;this.la(b,c)}y(vf,bf);l=vf.prototype;l.clone=function(){var b=new vf(null);wf(b,this.b,this.A.slice());return b};l.nb=function(b,c,d,e){if(e<Sd(this.J(),b,c))return e;this.g!=this.f&&(this.l=Math.sqrt(jf(this.A,0,this.A.length,this.a,0)),this.g=this.f);return lf(this.A,0,this.A.length,this.a,this.l,!0,b,c,d,e)};l.bm=function(){return ff(this.A,0,this.A.length,this.a)};l.Z=function(){return qf(this.A,0,this.A.length,this.a)}; -l.Lc=function(b){var c=[];c.length=tf(this.A,0,this.A.length,this.a,b,c,0);b=new vf(null);wf(b,"XY",c);return b};l.W=function(){return"LinearRing"};l.la=function(b,c){b?(ef(this,c,b,1),this.A||(this.A=[]),this.A.length=of(this.A,0,b,this.a),this.u()):wf(this,"XY",null)};function wf(b,c,d){df(b,c,d);b.u()};function E(b,c){bf.call(this);this.la(b,c)}y(E,bf);l=E.prototype;l.clone=function(){var b=new E(null);b.ba(this.b,this.A.slice());return b};l.nb=function(b,c,d,e){var f=this.A;b=Wa(b,c,f[0],f[1]);if(b<e){e=this.a;for(c=0;c<e;++c)d[c]=f[c];d.length=e;return b}return e};l.Z=function(){return this.A?this.A.slice():[]};l.Wd=function(b){return Xd(this.A,b)};l.W=function(){return"Point"};l.Ea=function(b){return Ud(b,this.A[0],this.A[1])}; -l.la=function(b,c){b?(ef(this,c,b,0),this.A||(this.A=[]),this.A.length=nf(this.A,b),this.u()):this.ba("XY",null)};l.ba=function(b,c){df(this,b,c);this.u()};function xf(b,c,d,e,f){return!ce(f,function(f){return!yf(b,c,d,e,f[0],f[1])})}function yf(b,c,d,e,f,g){for(var h=!1,k=b[d-e],m=b[d-e+1];c<d;c+=e){var n=b[c],p=b[c+1];m>g!=p>g&&f<(n-k)*(g-m)/(p-m)+k&&(h=!h);k=n;m=p}return h}function zf(b,c,d,e,f,g){if(0===d.length||!yf(b,c,d[0],e,f,g))return!1;var h;c=1;for(h=d.length;c<h;++c)if(yf(b,d[c-1],d[c],e,f,g))return!1;return!0};function Af(b,c,d,e,f,g,h){var k,m,n,p,q,r=f[g+1],t=[],x=d[0];n=b[x-e];q=b[x-e+1];for(k=c;k<x;k+=e){p=b[k];m=b[k+1];if(r<=q&&m<=r||q<=r&&r<=m)n=(r-q)/(m-q)*(p-n)+n,t.push(n);n=p;q=m}x=NaN;q=-Infinity;t.sort(ub);n=t[0];k=1;for(m=t.length;k<m;++k){p=t[k];var z=Math.abs(p-n);z>q&&(n=(n+p)/2,zf(b,c,d,e,n,r)&&(x=n,q=z));n=p}isNaN(x)&&(x=f[g]);return h?(h.push(x,r),h):[x,r]};function Bf(b,c,d,e,f,g){for(var h=[b[c],b[c+1]],k=[],m;c+e<d;c+=e){k[0]=b[c+e];k[1]=b[c+e+1];if(m=f.call(g,h,k))return m;h[0]=k[0];h[1]=k[1]}return!1};function Cf(b,c,d,e,f){var g=Zd(Md(),b,c,d,e);return oe(f,g)?Vd(f,g)||g[0]>=f[0]&&g[2]<=f[2]||g[1]>=f[1]&&g[3]<=f[3]?!0:Bf(b,c,d,e,function(b,c){var d=!1,e=Wd(f,b),g=Wd(f,c);if(1===e||1===g)d=!0;else{var q=f[0],r=f[1],t=f[2],x=f[3],z=c[0],A=c[1],B=(A-b[1])/(z-b[0]);g&2&&!(e&2)&&(d=z-(A-x)/B,d=d>=q&&d<=t);d||!(g&4)||e&4||(d=A-(z-t)*B,d=d>=r&&d<=x);d||!(g&8)||e&8||(d=z-(A-r)/B,d=d>=q&&d<=t);d||!(g&16)||e&16||(d=A-(z-q)*B,d=d>=r&&d<=x)}return d}):!1} -function Df(b,c,d,e,f){var g=d[0];if(!(Cf(b,c,g,e,f)||yf(b,c,g,e,f[0],f[1])||yf(b,c,g,e,f[0],f[3])||yf(b,c,g,e,f[2],f[1])||yf(b,c,g,e,f[2],f[3])))return!1;if(1===d.length)return!0;c=1;for(g=d.length;c<g;++c)if(xf(b,d[c-1],d[c],e,f))return!1;return!0};function Ef(b,c,d,e){for(var f=0,g=b[d-e],h=b[d-e+1];c<d;c+=e)var k=b[c],m=b[c+1],f=f+(k-g)*(m+h),g=k,h=m;return 0<f}function Ff(b,c,d,e){var f=0;e=void 0!==e?e:!1;var g,h;g=0;for(h=c.length;g<h;++g){var k=c[g],f=Ef(b,f,k,d);if(0===g){if(e&&f||!e&&!f)return!1}else if(e&&!f||!e&&f)return!1;f=k}return!0} -function Gf(b,c,d,e,f){f=void 0!==f?f:!1;var g,h;g=0;for(h=d.length;g<h;++g){var k=d[g],m=Ef(b,c,k,e);if(0===g?f&&m||!f&&!m:f&&!m||!f&&m)for(var m=b,n=k,p=e;c<n-p;){var q;for(q=0;q<p;++q){var r=m[c+q];m[c+q]=m[n-p+q];m[n-p+q]=r}c+=p;n-=p}c=k}return c}function Hf(b,c,d,e){var f=0,g,h;g=0;for(h=c.length;g<h;++g)f=Gf(b,f,c[g],d,e);return f};function F(b,c){bf.call(this);this.g=[];this.C=-1;this.D=null;this.T=this.O=this.U=-1;this.l=null;this.la(b,c)}y(F,bf);l=F.prototype;l.oj=function(b){this.A?kb(this.A,b.ia()):this.A=b.ia().slice();this.g.push(this.A.length);this.u()};l.clone=function(){var b=new F(null);b.ba(this.b,this.A.slice(),this.g.slice());return b}; -l.nb=function(b,c,d,e){if(e<Sd(this.J(),b,c))return e;this.O!=this.f&&(this.U=Math.sqrt(kf(this.A,0,this.g,this.a,0)),this.O=this.f);return mf(this.A,0,this.g,this.a,this.U,!0,b,c,d,e)};l.uc=function(b,c){return zf(this.bc(),0,this.g,this.a,b,c)};l.em=function(){return gf(this.bc(),0,this.g,this.a)};l.Z=function(b){var c;void 0!==b?(c=this.bc().slice(),Gf(c,0,this.g,this.a,b)):c=this.A;return rf(c,0,this.g,this.a)};l.zb=function(){return this.g}; -function If(b){if(b.C!=b.f){var c=le(b.J());b.D=Af(b.bc(),0,b.g,b.a,c,0);b.C=b.f}return b.D}l.Sj=function(){return new E(If(this))};l.Xj=function(){return this.g.length};l.Dg=function(b){if(0>b||this.g.length<=b)return null;var c=new vf(null);wf(c,this.b,this.A.slice(0===b?0:this.g[b-1],this.g[b]));return c};l.be=function(){var b=this.b,c=this.A,d=this.g,e=[],f=0,g,h;g=0;for(h=d.length;g<h;++g){var k=d[g],m=new vf(null);wf(m,b,c.slice(f,k));e.push(m);f=k}return e}; -l.bc=function(){if(this.T!=this.f){var b=this.A;Ff(b,this.g,this.a)?this.l=b:(this.l=b.slice(),this.l.length=Gf(this.l,0,this.g,this.a));this.T=this.f}return this.l};l.Lc=function(b){var c=[],d=[];c.length=uf(this.A,0,this.g,this.a,Math.sqrt(b),c,0,d);b=new F(null);b.ba("XY",c,d);return b};l.W=function(){return"Polygon"};l.Ea=function(b){return Df(this.bc(),0,this.g,this.a,b)}; -l.la=function(b,c){if(b){ef(this,c,b,2);this.A||(this.A=[]);var d=pf(this.A,0,b,this.a,this.g);this.A.length=0===d.length?0:d[d.length-1];this.u()}else this.ba("XY",null,this.g)};l.ba=function(b,c,d){df(this,b,c);this.g=d;this.u()};function Jf(b,c,d,e){var f=e?e:32;e=[];var g;for(g=0;g<f;++g)kb(e,b.offset(c,d,2*Math.PI*g/f));e.push(e[0],e[1]);b=new F(null);b.ba("XY",e,[e.length]);return b} -function Kf(b){var c=b[0],d=b[1],e=b[2];b=b[3];c=[c,d,c,b,e,b,e,d,c,d];d=new F(null);d.ba("XY",c,[c.length]);return d}function Lf(b,c,d){var e=c?c:32,f=b.ra();c=b.b;for(var g=new F(null,c),e=f*(e+1),f=[],h=0;h<e;h++)f[h]=0;g.ba(c,f,[f.length]);Mf(g,b.wd(),b.zf(),d);return g}function Mf(b,c,d,e){var f=b.ia(),g=b.b,h=b.ra(),k=b.zb(),m=f.length/h-1;e=e?e:0;for(var n,p,q=0;q<=m;++q)p=q*h,n=e+2*nd(q,m)*Math.PI/m,f[p]=c[0]+d*Math.cos(n),f[p+1]=c[1]+d*Math.sin(n);b.ba(g,f,k)};function Nf(b){gd.call(this);b=b||{};this.b=[0,0];var c={};c.center=void 0!==b.center?b.center:null;this.g=Te(b.projection);var d,e,f,g=void 0!==b.minZoom?b.minZoom:0;d=void 0!==b.maxZoom?b.maxZoom:28;var h=void 0!==b.zoomFactor?b.zoomFactor:2;if(void 0!==b.resolutions)d=b.resolutions,e=d[0],f=d[d.length-1],d=xb(d);else{e=Te(b.projection);f=e.J();var k=(f?Math.max(je(f),ke(f)):360*Be.degrees/Be[e.f])/256/Math.pow(2,0),m=k/Math.pow(2,28);e=b.maxResolution;void 0!==e?g=0:e=k/Math.pow(h,g);f=b.minResolution; -void 0===f&&(f=void 0!==b.maxZoom?void 0!==b.maxResolution?e/Math.pow(h,d):k/Math.pow(h,d):m);d=g+Math.floor(Math.log(e/f)/Math.log(h));f=e/Math.pow(h,d-g);d=yb(h,e,d-g)}this.a=e;this.j=f;this.c=g;g=void 0!==b.extent?Ya(b.extent):Za;(void 0!==b.enableRotation?b.enableRotation:1)?(e=b.constrainRotation,e=void 0===e||!0===e?Cb():!1===e?Ab:ja(e)?Bb(e):Ab):e=zb;this.i=new Db(g,d,e);void 0!==b.resolution?c.resolution=b.resolution:void 0!==b.zoom&&(c.resolution=this.constrainResolution(this.a,b.zoom-this.c)); -c.rotation=void 0!==b.rotation?b.rotation:0;this.I(c)}y(Nf,gd);l=Nf.prototype;l.Xd=function(b){return this.i.center(b)};l.constrainResolution=function(b,c,d){return this.i.resolution(b,c||0,d||0)};l.constrainRotation=function(b,c){return this.i.rotation(b,c||0)};l.Ua=function(){return this.get("center")};l.$c=function(b){var c=this.Ua(),d=this.$(),e=this.Fa();return me(c,d,e,b)};l.Ml=function(){return this.g};l.$=function(){return this.get("resolution")}; -function Of(b){var c=b.a,d=Math.log(c/b.j)/Math.log(2);return function(b){return c/Math.pow(2,b*d)}}l.Fa=function(){return this.get("rotation")};function Pf(b){var c=b.a,d=Math.log(c/b.j)/Math.log(2);return function(b){return Math.log(c/b)/Math.log(2)/d}}function Qf(b){var c=b.Ua(),d=b.g,e=b.$();b=b.Fa();return{center:[Math.round(c[0]/e)*e,Math.round(c[1]/e)*e],projection:void 0!==d?d:null,resolution:e,rotation:b}} -l.uk=function(){var b,c=this.$();if(void 0!==c){var d,e=0;do{d=this.constrainResolution(this.a,e);if(d==c){b=e;break}++e}while(d>this.j)}return void 0!==b?this.c+b:b}; -l.kf=function(b,c,d){b instanceof bf||(b=Kf(b));var e=d||{};d=void 0!==e.padding?e.padding:[0,0,0,0];var f=void 0!==e.constrainResolution?e.constrainResolution:!0,g=void 0!==e.nearest?e.nearest:!1,h;void 0!==e.minResolution?h=e.minResolution:void 0!==e.maxZoom?h=this.constrainResolution(this.a,e.maxZoom-this.c,0):h=0;var k=b.ia(),m=this.Fa(),e=Math.cos(-m),m=Math.sin(-m),n=Infinity,p=Infinity,q=-Infinity,r=-Infinity;b=b.ra();for(var t=0,x=k.length;t<x;t+=b)var z=k[t]*e-k[t+1]*m,A=k[t]*m+k[t+1]*e, -n=Math.min(n,z),p=Math.min(p,A),q=Math.max(q,z),r=Math.max(r,A);k=[n,p,q,r];c=[c[0]-d[1]-d[3],c[1]-d[0]-d[2]];c=Math.max(je(k)/c[0],ke(k)/c[1]);c=isNaN(c)?h:Math.max(c,h);f&&(h=this.constrainResolution(c,0,0),!g&&h<c&&(h=this.constrainResolution(h,-1,0)),c=h);this.Ub(c);m=-m;g=(n+q)/2+(d[1]-d[3])/2*c;d=(p+r)/2+(d[0]-d[2])/2*c;this.kb([g*e-d*m,d*e+g*m])}; -l.uj=function(b,c,d){var e=this.Fa(),f=Math.cos(-e),e=Math.sin(-e),g=b[0]*f-b[1]*e;b=b[1]*f+b[0]*e;var h=this.$(),g=g+(c[0]/2-d[0])*h;b+=(d[1]-c[1]/2)*h;e=-e;this.kb([g*f-b*e,b*f+g*e])};function Rf(b){return!!b.Ua()&&void 0!==b.$()}l.rotate=function(b,c){if(void 0!==c){var d,e=this.Ua();void 0!==e&&(d=[e[0]-c[0],e[1]-c[1]],ud(d,b-this.Fa()),pd(d,c));this.kb(d)}this.ue(b)};l.kb=function(b){this.set("center",b)};function Sf(b,c){b.b[1]+=c}l.Ub=function(b){this.set("resolution",b)}; -l.ue=function(b){this.set("rotation",b)};l.Wo=function(b){b=this.constrainResolution(this.a,b-this.c,0);this.Ub(b)};function Tf(b){return Math.pow(b,3)}function Uf(b){return 1-Tf(1-b)}function Vf(b){return 3*b*b-2*b*b*b}function Wf(b){return b}function Xf(b){return.5>b?Vf(2*b):1-Vf(2*(b-.5))};function Yf(b){var c=b.source,d=b.start?b.start:Date.now(),e=c[0],f=c[1],g=void 0!==b.duration?b.duration:1E3,h=b.easing?b.easing:Vf;return function(b,c){if(c.time<d)return c.animate=!0,c.viewHints[0]+=1,!0;if(c.time<d+g){var n=1-h((c.time-d)/g),p=e-c.viewState.center[0],q=f-c.viewState.center[1];c.animate=!0;c.viewState.center[0]+=n*p;c.viewState.center[1]+=n*q;c.viewHints[0]+=1;return!0}return!1}} -function Zf(b){var c=b.rotation?b.rotation:0,d=b.start?b.start:Date.now(),e=void 0!==b.duration?b.duration:1E3,f=b.easing?b.easing:Vf,g=b.anchor?b.anchor:null;return function(b,k){if(k.time<d)return k.animate=!0,k.viewHints[0]+=1,!0;if(k.time<d+e){var m=1-f((k.time-d)/e),m=(c-k.viewState.rotation)*m;k.animate=!0;k.viewState.rotation+=m;if(g){var n=k.viewState.center;n[0]-=g[0];n[1]-=g[1];ud(n,m);pd(n,g)}k.viewHints[0]+=1;return!0}return!1}} -function $f(b){var c=b.resolution,d=b.start?b.start:Date.now(),e=void 0!==b.duration?b.duration:1E3,f=b.easing?b.easing:Vf;return function(b,h){if(h.time<d)return h.animate=!0,h.viewHints[0]+=1,!0;if(h.time<d+e){var k=1-f((h.time-d)/e),m=c-h.viewState.resolution;h.animate=!0;h.viewState.resolution+=k*m;h.viewHints[0]+=1;return!0}return!1}};function ag(b,c,d,e){return void 0!==e?(e[0]=b,e[1]=c,e[2]=d,e):[b,c,d]}function bg(b,c,d){return b+"/"+c+"/"+d}function dg(b){var c=b[0],d=Array(c),e=1<<c-1,f,g;for(f=0;f<c;++f)g=48,b[1]&e&&(g+=1),b[2]&e&&(g+=2),d[f]=String.fromCharCode(g),e>>=1;return d.join("")}function eg(b){return bg(b[0],b[1],b[2])};function fg(b,c,d,e){this.a=b;this.c=c;this.f=d;this.b=e}fg.prototype.contains=function(b){return gg(this,b[1],b[2])};function hg(b,c){return b.a<=c.a&&c.c<=b.c&&b.f<=c.f&&c.b<=b.b}function gg(b,c,d){return b.a<=c&&c<=b.c&&b.f<=d&&d<=b.b}function ig(b,c){return b.a==c.a&&b.f==c.f&&b.c==c.c&&b.b==c.b}function jg(b){return b.b-b.f+1}function kg(b){return b.c-b.a+1}function lg(b,c){return b.a<=c.c&&b.c>=c.a&&b.f<=c.b&&b.b>=c.f};function mg(b){this.f=b.html;this.a=b.tileRanges?b.tileRanges:null}mg.prototype.b=function(){return this.f};function ng(b,c,d){tc.call(this,b,d);this.element=c}y(ng,tc);function og(b){gd.call(this);this.a=b?b:[];pg(this)}y(og,gd);l=og.prototype;l.clear=function(){for(;0<this.$b();)this.pop()};l.uf=function(b){var c,d;c=0;for(d=b.length;c<d;++c)this.push(b[c]);return this};l.forEach=function(b,c){this.a.forEach(b,c)};l.wl=function(){return this.a};l.item=function(b){return this.a[b]};l.$b=function(){return this.get("length")};l.le=function(b,c){lb(this.a,b,0,c);pg(this);this.s(new ng("add",c,this))}; -l.pop=function(){return this.Sf(this.$b()-1)};l.push=function(b){var c=this.a.length;this.le(c,b);return c};l.remove=function(b){var c=this.a,d,e;d=0;for(e=c.length;d<e;++d)if(c[d]===b)return this.Sf(d)};l.Sf=function(b){var c=this.a[b];$a.splice.call(this.a,b,1);pg(this);this.s(new ng("remove",c,this));return c};l.Jo=function(b,c){var d=this.$b();if(b<d)d=this.a[b],this.a[b]=c,this.s(new ng("remove",d,this)),this.s(new ng("add",c,this));else{for(;d<b;++d)this.le(d,void 0);this.le(b,c)}}; -function pg(b){b.set("length",b.a.length)};var qg=/^#(?:[0-9a-f]{3}){1,2}$/i,rg=/^(?:rgb)?\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2})\)$/i,sg=/^(?:rgba)?\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|1|0\.\d{0,10})\)$/i;function tg(b){return ga(b)?b:ug(b)}function vg(b){if(!ia(b)){var c=b[0];c!=(c|0)&&(c=c+.5|0);var d=b[1];d!=(d|0)&&(d=d+.5|0);var e=b[2];e!=(e|0)&&(e=e+.5|0);b="rgba("+c+","+d+","+e+","+b[3]+")"}return b} -var ug=function(){var b={},c=0;return function(d){var e;if(b.hasOwnProperty(d))e=b[d];else{if(1024<=c){e=0;for(var f in b)0===(e++&3)&&(delete b[f],--c)}var g,h;qg.exec(d)?(h=3==d.length-1?1:2,e=parseInt(d.substr(1+0*h,h),16),f=parseInt(d.substr(1+1*h,h),16),g=parseInt(d.substr(1+2*h,h),16),1==h&&(e=(e<<4)+e,f=(f<<4)+f,g=(g<<4)+g),e=[e,f,g,1]):(h=sg.exec(d))?(e=Number(h[1]),f=Number(h[2]),g=Number(h[3]),h=Number(h[4]),e=[e,f,g,h],e=wg(e,e)):(h=rg.exec(d))?(e=Number(h[1]),f=Number(h[2]),g=Number(h[3]), -e=[e,f,g,1],e=wg(e,e)):e=void 0;b[d]=e;++c}return e}}();function wg(b,c){var d=c||[];d[0]=Sa(b[0]+.5|0,0,255);d[1]=Sa(b[1]+.5|0,0,255);d[2]=Sa(b[2]+.5|0,0,255);d[3]=Sa(b[3],0,1);return d};var xg=!Yb||9<=kc;!$b&&!Yb||Yb&&9<=kc||$b&&ic("1.9.1");Yb&&ic("9");function yg(b,c){this.x=ca(b)?b:0;this.y=ca(c)?c:0}l=yg.prototype;l.clone=function(){return new yg(this.x,this.y)};l.ceil=function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this};l.floor=function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this};l.round=function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this};l.scale=function(b,c){var d=ja(c)?c:b;this.x*=b;this.y*=d;return this};function zg(b,c){this.width=b;this.height=c}l=zg.prototype;l.clone=function(){return new zg(this.width,this.height)};l.rj=function(){return this.width*this.height};l.La=function(){return!this.rj()};l.ceil=function(){this.width=Math.ceil(this.width);this.height=Math.ceil(this.height);return this};l.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};l.round=function(){this.width=Math.round(this.width);this.height=Math.round(this.height);return this}; -l.scale=function(b,c){var d=ja(c)?c:b;this.width*=b;this.height*=d;return this};function Ag(b){return b?new Bg(Cg(b)):Ba||(Ba=new Bg)}function Dg(b){var c=document;return ia(b)?c.getElementById(b):b}function Eg(b,c){Ib(c,function(c,e){"style"==e?b.style.cssText=c:"class"==e?b.className=c:"for"==e?b.htmlFor=c:Fg.hasOwnProperty(e)?b.setAttribute(Fg[e],c):0==e.lastIndexOf("aria-",0)||0==e.lastIndexOf("data-",0)?b.setAttribute(e,c):b[e]=c})} -var Fg={cellpadding:"cellPadding",cellspacing:"cellSpacing",colspan:"colSpan",frameborder:"frameBorder",height:"height",maxlength:"maxLength",role:"role",rowspan:"rowSpan",type:"type",usemap:"useMap",valign:"vAlign",width:"width"};function Gg(b){b=b.document.documentElement;return new zg(b.clientWidth,b.clientHeight)} -function Hg(b,c,d){var e=arguments,f=document,g=e[0],h=e[1];if(!xg&&h&&(h.name||h.type)){g=["<",g];h.name&&g.push(' name="',Ga(h.name),'"');if(h.type){g.push(' type="',Ga(h.type),'"');var k={};Wb(k,h);delete k.type;h=k}g.push(">");g=g.join("")}g=f.createElement(g);h&&(ia(h)?g.className=h:ga(h)?g.className=h.join(" "):Eg(g,h));2<e.length&&Ig(f,g,e);return g} -function Ig(b,c,d){function e(d){d&&c.appendChild(ia(d)?b.createTextNode(d):d)}for(var f=2;f<d.length;f++){var g=d[f];!ha(g)||oa(g)&&0<g.nodeType?e(g):bb(Jg(g)?jb(g):g,e)}}function Kg(b){for(var c;c=b.firstChild;)b.removeChild(c)}function Lg(b,c,d){b.insertBefore(c,b.childNodes[d]||null)}function Mg(b){b&&b.parentNode&&b.parentNode.removeChild(b)}function Ng(b,c){var d=c.parentNode;d&&d.replaceChild(b,c)} -function Og(b){if(ca(b.firstElementChild))b=b.firstElementChild;else for(b=b.firstChild;b&&1!=b.nodeType;)b=b.nextSibling;return b}function Pg(b,c){if(b.contains&&1==c.nodeType)return b==c||b.contains(c);if("undefined"!=typeof b.compareDocumentPosition)return b==c||Boolean(b.compareDocumentPosition(c)&16);for(;c&&b!=c;)c=c.parentNode;return c==b}function Cg(b){return 9==b.nodeType?b:b.ownerDocument||b.document} -function Jg(b){if(b&&"number"==typeof b.length){if(oa(b))return"function"==typeof b.item||"string"==typeof b.item;if(ka(b))return"function"==typeof b.item}return!1}function Bg(b){this.a=b||ba.document||document}Bg.prototype.I=Eg;function Qg(){return!0} -function Rg(b){var c=b.a;b=c.scrollingElement?c.scrollingElement:ac?c.body||c.documentElement:c.documentElement;c=c.parentWindow||c.defaultView;return Yb&&ic("10")&&c.pageYOffset!=b.scrollTop?new yg(b.scrollLeft,b.scrollTop):new yg(c.pageXOffset||b.scrollLeft,c.pageYOffset||b.scrollTop)}Bg.prototype.appendChild=function(b,c){b.appendChild(c)};Bg.prototype.contains=Pg;function Sg(b){if(b.classList)return b.classList;b=b.className;return ia(b)&&b.match(/\S+/g)||[]}function Tg(b,c){var d;b.classList?d=b.classList.contains(c):(d=Sg(b),d=0<=ab(d,c));return d}function Ug(b,c){b.classList?b.classList.add(c):Tg(b,c)||(b.className+=0<b.className.length?" "+c:c)}function Vg(b,c){b.classList?b.classList.remove(c):Tg(b,c)&&(b.className=cb(Sg(b),function(b){return b!=c}).join(" "))}function Wg(b,c){Tg(b,c)?Vg(b,c):Ug(b,c)};function Xg(b,c,d,e){this.top=b;this.right=c;this.bottom=d;this.left=e}l=Xg.prototype;l.clone=function(){return new Xg(this.top,this.right,this.bottom,this.left)};l.contains=function(b){return this&&b?b instanceof Xg?b.left>=this.left&&b.right<=this.right&&b.top>=this.top&&b.bottom<=this.bottom:b.x>=this.left&&b.x<=this.right&&b.y>=this.top&&b.y<=this.bottom:!1}; +function Cc(a){this.radius=a}Cc.prototype.a=function(a){for(var c=0,d=a.length,e=a[d-1][0],f=a[d-1][1],g=0;g<d;g++)var h=a[g][0],k=a[g][1],c=c+Ha(h-e)*(2+Math.sin(Ha(f))+Math.sin(Ha(k))),e=h,f=k;return c*this.radius*this.radius/2};Cc.prototype.b=function(a,c){var d=Ha(a[1]),e=Ha(c[1]),f=(e-d)/2,g=Ha(c[0]-a[0])/2,d=Math.sin(f)*Math.sin(f)+Math.sin(g)*Math.sin(g)*Math.cos(d)*Math.cos(e);return 2*this.radius*Math.atan2(Math.sqrt(d),Math.sqrt(1-d))}; +Cc.prototype.offset=function(a,c,d){var e=Ha(a[1]);c/=this.radius;var f=Math.asin(Math.sin(e)*Math.cos(c)+Math.cos(e)*Math.sin(c)*Math.cos(d));return[180*(Ha(a[0])+Math.atan2(Math.sin(d)*Math.sin(c)*Math.cos(e),Math.cos(c)-Math.sin(e)*Math.sin(f)))/Math.PI,180*f/Math.PI]};var Dc=new Cc(6370997);var Ec={};Ec.degrees=2*Math.PI*Dc.radius/360;Ec.ft=.3048;Ec.m=1;Ec["us-ft"]=1200/3937; +function Fc(a){this.eb=a.code;this.c=a.units;this.f=void 0!==a.extent?a.extent:null;this.i=void 0!==a.worldExtent?a.worldExtent:null;this.b=void 0!==a.axisOrientation?a.axisOrientation:"enu";this.g=void 0!==a.global?a.global:!1;this.a=!(!this.g||!this.f);this.o=void 0!==a.getPointResolution?a.getPointResolution:this.nk;this.l=null;this.j=a.metersPerUnit;var c=Gc,d=a.code,e=Hc||qa.proj4;if("function"==typeof e&&void 0===c[d]){var f=e.defs(d);if(void 0!==f){void 0!==f.axis&&void 0===a.axisOrientation&& +(this.b=f.axis);void 0===a.metersPerUnit&&(this.j=f.to_meter);void 0===a.units&&(this.c=f.units);for(var g in c)c=e.defs(g),void 0!==c&&(a=Ic(g),c===f?Jc([a,this]):(c=e(g,d),Kc(a,this,c.forward,c.inverse)))}}}l=Fc.prototype;l.Oj=function(){return this.eb};l.O=function(){return this.f};l.vb=function(){return this.c};l.Vb=function(){return this.j||Ec[this.c]};l.Ak=function(){return this.i};l.ll=function(){return this.g};l.Yo=function(a){this.g=a;this.a=!(!a||!this.f)}; +l.Gm=function(a){this.f=a;this.a=!(!this.g||!a)};l.gp=function(a){this.i=a};l.Xo=function(a){this.o=a};l.nk=function(a,c){if("degrees"==this.vb())return a;var d=Lc(this,Ic("EPSG:4326")),e=[c[0]-a/2,c[1],c[0]+a/2,c[1],c[0],c[1]-a/2,c[0],c[1]+a/2],e=d(e,e,2),d=Dc.b(e.slice(0,2),e.slice(2,4)),e=Dc.b(e.slice(4,6),e.slice(6,8)),e=(d+e)/2,d=this.Vb();void 0!==d&&(e/=d);return e};l.getPointResolution=function(a,c){return this.o(a,c)};var Gc={},Mc={},Hc=null; +function Jc(a){Nc(a);a.forEach(function(c){a.forEach(function(a){c!==a&&Oc(c,a,Qc)})})}function Rc(){var a=Sc,c=Tc,d=Uc;Vc.forEach(function(e){a.forEach(function(a){Oc(e,a,c);Oc(a,e,d)})})}function Wc(a){Gc[a.eb]=a;Oc(a,a,Qc)}function Nc(a){var c=[];a.forEach(function(a){c.push(Wc(a))})}function Xc(a){return a?"string"===typeof a?Ic(a):a:Ic("EPSG:3857")}function Oc(a,c,d){a=a.eb;c=c.eb;a in Mc||(Mc[a]={});Mc[a][c]=d}function Kc(a,c,d,e){a=Ic(a);c=Ic(c);Oc(a,c,Yc(d));Oc(c,a,Yc(e))} +function Yc(a){return function(c,d,e){var f=c.length;e=void 0!==e?e:2;d=void 0!==d?d:Array(f);var g,h;for(h=0;h<f;h+=e)for(g=a([c[h],c[h+1]]),d[h]=g[0],d[h+1]=g[1],g=e-1;2<=g;--g)d[h+g]=c[h+g];return d}}function Ic(a){var c;if(a instanceof Fc)c=a;else if("string"===typeof a){c=Gc[a];var d=Hc||qa.proj4;void 0===c&&"function"==typeof d&&void 0!==d.defs(a)&&(c=new Fc({code:a}),Wc(c))}else c=null;return c}function Zc(a,c){if(a===c)return!0;var d=a.vb()===c.vb();return a.eb===c.eb?d:Lc(a,c)===Qc&&d} +function $c(a,c){var d=Ic(a),e=Ic(c);return Lc(d,e)}function Lc(a,c){var d=a.eb,e=c.eb,f;d in Mc&&e in Mc[d]&&(f=Mc[d][e]);void 0===f&&(f=ad);return f}function ad(a,c){if(void 0!==c&&a!==c){for(var d=0,e=a.length;d<e;++d)c[d]=a[d];a=c}return a}function Qc(a,c){var d;if(void 0!==c){d=0;for(var e=a.length;d<e;++d)c[d]=a[d];d=c}else d=a.slice();return d}function bd(a,c,d){return $c(c,d)(a,void 0,a.length)}function cd(a,c,d){c=$c(c,d);return zc(a,c)};function dd(){pb.call(this);this.v=Wb();this.B=-1;this.l={};this.s=this.o=0}y(dd,pb);l=dd.prototype;l.ub=function(a,c){var d=c?c:[NaN,NaN];this.rb(a[0],a[1],d,Infinity);return d};l.og=function(a){return this.wc(a[0],a[1])};l.wc=Bc;l.O=function(a){this.B!=this.g&&(this.v=this.Jd(this.v),this.B=this.g);var c=this.v;a?(a[0]=c[0],a[1]=c[1],a[2]=c[2],a[3]=c[3]):a=c;return a};l.yb=function(a){return this.hd(a*a)};l.hb=function(a,c){this.mc($c(a,c));return this};function ed(a){this.length=a.length||a;for(var c=0;c<this.length;c++)this[c]=a[c]||0}ed.prototype.BYTES_PER_ELEMENT=4;ed.prototype.set=function(a,c){c=c||0;for(var d=0;d<a.length&&c+d<this.length;d++)this[c+d]=a[d]};ed.prototype.toString=Array.prototype.join;"undefined"==typeof Float32Array&&(ed.BYTES_PER_ELEMENT=4,ed.prototype.BYTES_PER_ELEMENT=ed.prototype.BYTES_PER_ELEMENT,ed.prototype.set=ed.prototype.set,ed.prototype.toString=ed.prototype.toString,t("Float32Array",ed,void 0));function fd(a){this.length=a.length||a;for(var c=0;c<this.length;c++)this[c]=a[c]||0}fd.prototype.BYTES_PER_ELEMENT=8;fd.prototype.set=function(a,c){c=c||0;for(var d=0;d<a.length&&c+d<this.length;d++)this[c+d]=a[d]};fd.prototype.toString=Array.prototype.join;if("undefined"==typeof Float64Array){try{fd.BYTES_PER_ELEMENT=8}catch(a){}fd.prototype.BYTES_PER_ELEMENT=fd.prototype.BYTES_PER_ELEMENT;fd.prototype.set=fd.prototype.set;fd.prototype.toString=fd.prototype.toString;t("Float64Array",fd,void 0)};function gd(a,c,d,e,f){a[0]=c;a[1]=d;a[2]=e;a[3]=f};function hd(){var a=Array(16);id(a,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);return a}function jd(){var a=Array(16);id(a,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);return a}function id(a,c,d,e,f,g,h,k,m,n,p,q,r,u,v,x,z){a[0]=c;a[1]=d;a[2]=e;a[3]=f;a[4]=g;a[5]=h;a[6]=k;a[7]=m;a[8]=n;a[9]=p;a[10]=q;a[11]=r;a[12]=u;a[13]=v;a[14]=x;a[15]=z} +function kd(a,c){a[0]=c[0];a[1]=c[1];a[2]=c[2];a[3]=c[3];a[4]=c[4];a[5]=c[5];a[6]=c[6];a[7]=c[7];a[8]=c[8];a[9]=c[9];a[10]=c[10];a[11]=c[11];a[12]=c[12];a[13]=c[13];a[14]=c[14];a[15]=c[15]}function ld(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=1;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=1;a[11]=0;a[12]=0;a[13]=0;a[14]=0;a[15]=1} +function md(a,c,d){var e=a[0],f=a[1],g=a[2],h=a[3],k=a[4],m=a[5],n=a[6],p=a[7],q=a[8],r=a[9],u=a[10],v=a[11],x=a[12],z=a[13],E=a[14];a=a[15];var B=c[0],A=c[1],G=c[2],O=c[3],L=c[4],R=c[5],Wa=c[6],J=c[7],ua=c[8],Ta=c[9],kb=c[10],Ka=c[11],Ia=c[12],xc=c[13],Pc=c[14];c=c[15];d[0]=e*B+k*A+q*G+x*O;d[1]=f*B+m*A+r*G+z*O;d[2]=g*B+n*A+u*G+E*O;d[3]=h*B+p*A+v*G+a*O;d[4]=e*L+k*R+q*Wa+x*J;d[5]=f*L+m*R+r*Wa+z*J;d[6]=g*L+n*R+u*Wa+E*J;d[7]=h*L+p*R+v*Wa+a*J;d[8]=e*ua+k*Ta+q*kb+x*Ka;d[9]=f*ua+m*Ta+r*kb+z*Ka;d[10]=g* +ua+n*Ta+u*kb+E*Ka;d[11]=h*ua+p*Ta+v*kb+a*Ka;d[12]=e*Ia+k*xc+q*Pc+x*c;d[13]=f*Ia+m*xc+r*Pc+z*c;d[14]=g*Ia+n*xc+u*Pc+E*c;d[15]=h*Ia+p*xc+v*Pc+a*c} +function nd(a,c){var d=a[0],e=a[1],f=a[2],g=a[3],h=a[4],k=a[5],m=a[6],n=a[7],p=a[8],q=a[9],r=a[10],u=a[11],v=a[12],x=a[13],z=a[14],E=a[15],B=d*k-e*h,A=d*m-f*h,G=d*n-g*h,O=e*m-f*k,L=e*n-g*k,R=f*n-g*m,Wa=p*x-q*v,J=p*z-r*v,ua=p*E-u*v,Ta=q*z-r*x,kb=q*E-u*x,Ka=r*E-u*z,Ia=B*Ka-A*kb+G*Ta+O*ua-L*J+R*Wa;0!=Ia&&(Ia=1/Ia,c[0]=(k*Ka-m*kb+n*Ta)*Ia,c[1]=(-e*Ka+f*kb-g*Ta)*Ia,c[2]=(x*R-z*L+E*O)*Ia,c[3]=(-q*R+r*L-u*O)*Ia,c[4]=(-h*Ka+m*ua-n*J)*Ia,c[5]=(d*Ka-f*ua+g*J)*Ia,c[6]=(-v*R+z*G-E*A)*Ia,c[7]=(p*R-r*G+u*A)*Ia, +c[8]=(h*kb-k*ua+n*Wa)*Ia,c[9]=(-d*kb+e*ua-g*Wa)*Ia,c[10]=(v*L-x*G+E*B)*Ia,c[11]=(-p*L+q*G-u*B)*Ia,c[12]=(-h*Ta+k*J-m*Wa)*Ia,c[13]=(d*Ta-e*J+f*Wa)*Ia,c[14]=(-v*O+x*A-z*B)*Ia,c[15]=(p*O-q*A+r*B)*Ia)}function od(a,c,d){var e=a[1]*c+a[5]*d+0*a[9]+a[13],f=a[2]*c+a[6]*d+0*a[10]+a[14],g=a[3]*c+a[7]*d+0*a[11]+a[15];a[12]=a[0]*c+a[4]*d+0*a[8]+a[12];a[13]=e;a[14]=f;a[15]=g} +function pd(a,c,d){id(a,a[0]*c,a[1]*c,a[2]*c,a[3]*c,a[4]*d,a[5]*d,a[6]*d,a[7]*d,1*a[8],1*a[9],1*a[10],1*a[11],a[12],a[13],a[14],a[15])}function qd(a,c){var d=a[0],e=a[1],f=a[2],g=a[3],h=a[4],k=a[5],m=a[6],n=a[7],p=Math.cos(c),q=Math.sin(c);a[0]=d*p+h*q;a[1]=e*p+k*q;a[2]=f*p+m*q;a[3]=g*p+n*q;a[4]=d*-q+h*p;a[5]=e*-q+k*p;a[6]=f*-q+m*p;a[7]=g*-q+n*p}new Float64Array(3);new Float64Array(3);new Float64Array(4);new Float64Array(4);new Float64Array(4);new Float64Array(16);function rd(a,c,d,e,f,g){var h=f[0],k=f[1],m=f[4],n=f[5],p=f[12];f=f[13];for(var q=g?g:[],r=0;c<d;c+=e){var u=a[c],v=a[c+1];q[r++]=h*u+m*v+p;q[r++]=k*u+n*v+f}g&&q.length!=r&&(q.length=r);return q};function sd(){dd.call(this);this.f="XY";this.a=2;this.A=null}y(sd,dd);function td(a){if("XY"==a)return 2;if("XYZ"==a||"XYM"==a)return 3;if("XYZM"==a)return 4}l=sd.prototype;l.wc=Bc;l.Jd=function(a){return gc(this.A,0,this.A.length,this.a,a)};l.Fb=function(){return this.A.slice(0,this.a)};l.ga=function(){return this.A};l.Gb=function(){return this.A.slice(this.A.length-this.a)};l.Hb=function(){return this.f}; +l.hd=function(a){this.s!=this.g&&(Qa(this.l),this.o=0,this.s=this.g);if(0>a||0!==this.o&&a<=this.o)return this;var c=a.toString();if(this.l.hasOwnProperty(c))return this.l[c];var d=this.Ic(a);if(d.ga().length<this.A.length)return this.l[c]=d;this.o=a;return this};l.Ic=function(){return this};l.ua=function(){return this.a};function ud(a,c,d){a.a=td(c);a.f=c;a.A=d} +function vd(a,c,d,e){if(c)d=td(c);else{for(c=0;c<e;++c){if(0===d.length){a.f="XY";a.a=2;return}d=d[0]}d=d.length;c=2==d?"XY":3==d?"XYZ":4==d?"XYZM":void 0}a.f=c;a.a=d}l.mc=function(a){this.A&&(a(this.A,this.A,this.a),this.u())};l.rotate=function(a,c){var d=this.ga();if(d){for(var e=d.length,f=this.ua(),g=d?d:[],h=Math.cos(a),k=Math.sin(a),m=c[0],n=c[1],p=0,q=0;q<e;q+=f){var r=d[q]-m,u=d[q+1]-n;g[p++]=m+r*h-u*k;g[p++]=n+r*k+u*h;for(r=q+2;r<q+f;++r)g[p++]=d[r]}d&&g.length!=p&&(g.length=p);this.u()}}; +l.Nc=function(a,c){var d=this.ga();if(d){var e=d.length,f=this.ua(),g=d?d:[],h=0,k,m;for(k=0;k<e;k+=f)for(g[h++]=d[k]+a,g[h++]=d[k+1]+c,m=k+2;m<k+f;++m)g[h++]=d[m];d&&g.length!=h&&(g.length=h);this.u()}};function wd(a,c,d,e){for(var f=0,g=a[d-e],h=a[d-e+1];c<d;c+=e)var k=a[c],m=a[c+1],f=f+(h*k-g*m),g=k,h=m;return f/2}function xd(a,c,d,e){var f=0,g,h;g=0;for(h=d.length;g<h;++g){var k=d[g],f=f+wd(a,c,k,e);c=k}return f};function yd(a,c,d,e,f,g,h){var k=a[c],m=a[c+1],n=a[d]-k,p=a[d+1]-m;if(0!==n||0!==p)if(g=((f-k)*n+(g-m)*p)/(n*n+p*p),1<g)c=d;else if(0<g){for(f=0;f<e;++f)h[f]=La(a[c+f],a[d+f],g);h.length=e;return}for(f=0;f<e;++f)h[f]=a[c+f];h.length=e}function zd(a,c,d,e,f){var g=a[c],h=a[c+1];for(c+=e;c<d;c+=e){var k=a[c],m=a[c+1],g=Ga(g,h,k,m);g>f&&(f=g);g=k;h=m}return f}function Ad(a,c,d,e,f){var g,h;g=0;for(h=d.length;g<h;++g){var k=d[g];f=zd(a,c,k,e,f);c=k}return f} +function Bd(a,c,d,e,f,g,h,k,m,n,p){if(c==d)return n;var q;if(0===f){q=Ga(h,k,a[c],a[c+1]);if(q<n){for(p=0;p<e;++p)m[p]=a[c+p];m.length=e;return q}return n}for(var r=p?p:[NaN,NaN],u=c+e;u<d;)if(yd(a,u-e,u,e,h,k,r),q=Ga(h,k,r[0],r[1]),q<n){n=q;for(p=0;p<e;++p)m[p]=r[p];m.length=e;u+=e}else u+=e*Math.max((Math.sqrt(q)-Math.sqrt(n))/f|0,1);if(g&&(yd(a,d-e,c,e,h,k,r),q=Ga(h,k,r[0],r[1]),q<n)){n=q;for(p=0;p<e;++p)m[p]=r[p];m.length=e}return n} +function Cd(a,c,d,e,f,g,h,k,m,n,p){p=p?p:[NaN,NaN];var q,r;q=0;for(r=d.length;q<r;++q){var u=d[q];n=Bd(a,c,u,e,f,g,h,k,m,n,p);c=u}return n};function Dd(a,c){var d=0,e,f;e=0;for(f=c.length;e<f;++e)a[d++]=c[e];return d}function Ed(a,c,d,e){var f,g;f=0;for(g=d.length;f<g;++f){var h=d[f],k;for(k=0;k<e;++k)a[c++]=h[k]}return c}function Fd(a,c,d,e,f){f=f?f:[];var g=0,h,k;h=0;for(k=d.length;h<k;++h)c=Ed(a,c,d[h],e),f[g++]=c;f.length=g;return f};function Gd(a,c,d,e,f){f=void 0!==f?f:[];for(var g=0;c<d;c+=e)f[g++]=a.slice(c,c+e);f.length=g;return f}function Hd(a,c,d,e,f){f=void 0!==f?f:[];var g=0,h,k;h=0;for(k=d.length;h<k;++h){var m=d[h];f[g++]=Gd(a,c,m,e,f[g]);c=m}f.length=g;return f};function Id(a,c,d,e,f,g,h){var k=(d-c)/e;if(3>k){for(;c<d;c+=e)g[h++]=a[c],g[h++]=a[c+1];return h}var m=Array(k);m[0]=1;m[k-1]=1;d=[c,d-e];for(var n=0,p;0<d.length;){var q=d.pop(),r=d.pop(),u=0,v=a[r],x=a[r+1],z=a[q],E=a[q+1];for(p=r+e;p<q;p+=e){var B=Fa(a[p],a[p+1],v,x,z,E);B>u&&(n=p,u=B)}u>f&&(m[(n-c)/e]=1,r+e<n&&d.push(r,n),n+e<q&&d.push(n,q))}for(p=0;p<k;++p)m[p]&&(g[h++]=a[c+p*e],g[h++]=a[c+p*e+1]);return h} +function Jd(a,c,d,e,f,g,h,k){var m,n;m=0;for(n=d.length;m<n;++m){var p=d[m];a:{var q=a,r=p,u=e,v=f,x=g;if(c!=r){var z=v*Math.round(q[c]/v),E=v*Math.round(q[c+1]/v);c+=u;x[h++]=z;x[h++]=E;var B=void 0,A=void 0;do if(B=v*Math.round(q[c]/v),A=v*Math.round(q[c+1]/v),c+=u,c==r){x[h++]=B;x[h++]=A;break a}while(B==z&&A==E);for(;c<r;){var G,O;G=v*Math.round(q[c]/v);O=v*Math.round(q[c+1]/v);c+=u;if(G!=B||O!=A){var L=B-z,R=A-E,Wa=G-z,J=O-E;L*J==R*Wa&&(0>L&&Wa<L||L==Wa||0<L&&Wa>L)&&(0>R&&J<R||R==J||0<R&&J>R)|| +(x[h++]=B,x[h++]=A,z=B,E=A);B=G;A=O}}x[h++]=B;x[h++]=A}}k.push(h);c=p}return h};function Kd(a,c){sd.call(this);this.i=this.j=-1;this.ma(a,c)}y(Kd,sd);l=Kd.prototype;l.clone=function(){var a=new Kd(null);Ld(a,this.f,this.A.slice());return a};l.rb=function(a,c,d,e){if(e<$b(this.O(),a,c))return e;this.i!=this.g&&(this.j=Math.sqrt(zd(this.A,0,this.A.length,this.a,0)),this.i=this.g);return Bd(this.A,0,this.A.length,this.a,this.j,!0,a,c,d,e)};l.hm=function(){return wd(this.A,0,this.A.length,this.a)};l.Z=function(){return Gd(this.A,0,this.A.length,this.a)}; +l.Ic=function(a){var c=[];c.length=Id(this.A,0,this.A.length,this.a,a,c,0);a=new Kd(null);Ld(a,"XY",c);return a};l.X=function(){return"LinearRing"};l.ma=function(a,c){a?(vd(this,c,a,1),this.A||(this.A=[]),this.A.length=Ed(this.A,0,a,this.a),this.u()):Ld(this,"XY",null)};function Ld(a,c,d){ud(a,c,d);a.u()};function D(a,c){sd.call(this);this.ma(a,c)}y(D,sd);l=D.prototype;l.clone=function(){var a=new D(null);a.ba(this.f,this.A.slice());return a};l.rb=function(a,c,d,e){var f=this.A;a=Ga(a,c,f[0],f[1]);if(a<e){e=this.a;for(c=0;c<e;++c)d[c]=f[c];d.length=e;return a}return e};l.Z=function(){return this.A?this.A.slice():[]};l.Jd=function(a){return fc(this.A,a)};l.X=function(){return"Point"};l.Ia=function(a){return bc(a,this.A[0],this.A[1])}; +l.ma=function(a,c){a?(vd(this,c,a,0),this.A||(this.A=[]),this.A.length=Dd(this.A,a),this.u()):this.ba("XY",null)};l.ba=function(a,c){ud(this,a,c);this.u()};function Md(a,c,d,e,f){return!kc(f,function(f){return!Nd(a,c,d,e,f[0],f[1])})}function Nd(a,c,d,e,f,g){for(var h=!1,k=a[d-e],m=a[d-e+1];c<d;c+=e){var n=a[c],p=a[c+1];m>g!=p>g&&f<(n-k)*(g-m)/(p-m)+k&&(h=!h);k=n;m=p}return h}function Od(a,c,d,e,f,g){if(0===d.length||!Nd(a,c,d[0],e,f,g))return!1;var h;c=1;for(h=d.length;c<h;++c)if(Nd(a,d[c-1],d[c],e,f,g))return!1;return!0};function Pd(a,c,d,e,f,g,h){var k,m,n,p,q,r=f[g+1],u=[],v=d[0];n=a[v-e];q=a[v-e+1];for(k=c;k<v;k+=e){p=a[k];m=a[k+1];if(r<=q&&m<=r||q<=r&&r<=m)n=(r-q)/(m-q)*(p-n)+n,u.push(n);n=p;q=m}v=NaN;q=-Infinity;u.sort(tb);n=u[0];k=1;for(m=u.length;k<m;++k){p=u[k];var x=Math.abs(p-n);x>q&&(n=(n+p)/2,Od(a,c,d,e,n,r)&&(v=n,q=x));n=p}isNaN(v)&&(v=f[g]);return h?(h.push(v,r),h):[v,r]};function Qd(a,c,d,e,f,g){for(var h=[a[c],a[c+1]],k=[],m;c+e<d;c+=e){k[0]=a[c+e];k[1]=a[c+e+1];if(m=f.call(g,h,k))return m;h[0]=k[0];h[1]=k[1]}return!1};function Rd(a,c,d,e,f){var g=hc(Wb(),a,c,d,e);return wc(f,g)?cc(f,g)||g[0]>=f[0]&&g[2]<=f[2]||g[1]>=f[1]&&g[3]<=f[3]?!0:Qd(a,c,d,e,function(a,c){var d=!1,e=dc(f,a),g=dc(f,c);if(1===e||1===g)d=!0;else{var q=f[0],r=f[1],u=f[2],v=f[3],x=c[0],z=c[1],E=(z-a[1])/(x-a[0]);g&2&&!(e&2)&&(d=x-(z-v)/E,d=d>=q&&d<=u);d||!(g&4)||e&4||(d=z-(x-u)*E,d=d>=r&&d<=v);d||!(g&8)||e&8||(d=x-(z-r)/E,d=d>=q&&d<=u);d||!(g&16)||e&16||(d=z-(x-q)*E,d=d>=r&&d<=v)}return d}):!1} +function Sd(a,c,d,e,f){var g=d[0];if(!(Rd(a,c,g,e,f)||Nd(a,c,g,e,f[0],f[1])||Nd(a,c,g,e,f[0],f[3])||Nd(a,c,g,e,f[2],f[1])||Nd(a,c,g,e,f[2],f[3])))return!1;if(1===d.length)return!0;c=1;for(g=d.length;c<g;++c)if(Md(a,d[c-1],d[c],e,f))return!1;return!0};function Td(a,c,d,e){for(var f=0,g=a[d-e],h=a[d-e+1];c<d;c+=e)var k=a[c],m=a[c+1],f=f+(k-g)*(m+h),g=k,h=m;return 0<f}function Ud(a,c,d,e){var f=0;e=void 0!==e?e:!1;var g,h;g=0;for(h=c.length;g<h;++g){var k=c[g],f=Td(a,f,k,d);if(0===g){if(e&&f||!e&&!f)return!1}else if(e&&!f||!e&&f)return!1;f=k}return!0} +function Vd(a,c,d,e,f){f=void 0!==f?f:!1;var g,h;g=0;for(h=d.length;g<h;++g){var k=d[g],m=Td(a,c,k,e);if(0===g?f&&m||!f&&!m:f&&!m||!f&&m)for(var m=a,n=k,p=e;c<n-p;){var q;for(q=0;q<p;++q){var r=m[c+q];m[c+q]=m[n-p+q];m[n-p+q]=r}c+=p;n-=p}c=k}return c}function Wd(a,c,d,e){var f=0,g,h;g=0;for(h=c.length;g<h;++g)f=Vd(a,f,c[g],d,e);return f};function F(a,c){sd.call(this);this.i=[];this.M=-1;this.N=null;this.T=this.R=this.S=-1;this.j=null;this.ma(a,c)}y(F,sd);l=F.prototype;l.tj=function(a){this.A?xb(this.A,a.ga()):this.A=a.ga().slice();this.i.push(this.A.length);this.u()};l.clone=function(){var a=new F(null);a.ba(this.f,this.A.slice(),this.i.slice());return a}; +l.rb=function(a,c,d,e){if(e<$b(this.O(),a,c))return e;this.R!=this.g&&(this.S=Math.sqrt(Ad(this.A,0,this.i,this.a,0)),this.R=this.g);return Cd(this.A,0,this.i,this.a,this.S,!0,a,c,d,e)};l.wc=function(a,c){return Od(this.Kb(),0,this.i,this.a,a,c)};l.km=function(){return xd(this.Kb(),0,this.i,this.a)};l.Z=function(a){var c;void 0!==a?(c=this.Kb().slice(),Vd(c,0,this.i,this.a,a)):c=this.A;return Hd(c,0,this.i,this.a)};l.zb=function(){return this.i}; +function Xd(a){if(a.M!=a.g){var c=tc(a.O());a.N=Pd(a.Kb(),0,a.i,a.a,c,0);a.M=a.g}return a.N}l.Yj=function(){return new D(Xd(this))};l.ck=function(){return this.i.length};l.Cg=function(a){if(0>a||this.i.length<=a)return null;var c=new Kd(null);Ld(c,this.f,this.A.slice(0===a?0:this.i[a-1],this.i[a]));return c};l.Pd=function(){var a=this.f,c=this.A,d=this.i,e=[],f=0,g,h;g=0;for(h=d.length;g<h;++g){var k=d[g],m=new Kd(null);Ld(m,a,c.slice(f,k));e.push(m);f=k}return e}; +l.Kb=function(){if(this.T!=this.g){var a=this.A;Ud(a,this.i,this.a)?this.j=a:(this.j=a.slice(),this.j.length=Vd(this.j,0,this.i,this.a));this.T=this.g}return this.j};l.Ic=function(a){var c=[],d=[];c.length=Jd(this.A,0,this.i,this.a,Math.sqrt(a),c,0,d);a=new F(null);a.ba("XY",c,d);return a};l.X=function(){return"Polygon"};l.Ia=function(a){return Sd(this.Kb(),0,this.i,this.a,a)}; +l.ma=function(a,c){if(a){vd(this,c,a,2);this.A||(this.A=[]);var d=Fd(this.A,0,a,this.a,this.i);this.A.length=0===d.length?0:d[d.length-1];this.u()}else this.ba("XY",null,this.i)};l.ba=function(a,c,d){ud(this,a,c);this.i=d;this.u()};function Yd(a,c,d,e){var f=e?e:32;e=[];var g;for(g=0;g<f;++g)xb(e,a.offset(c,d,2*Math.PI*g/f));e.push(e[0],e[1]);a=new F(null);a.ba("XY",e,[e.length]);return a} +function Zd(a){var c=a[0],d=a[1],e=a[2];a=a[3];c=[c,d,c,a,e,a,e,d,c,d];d=new F(null);d.ba("XY",c,[c.length]);return d}function $d(a,c,d){var e=c?c:32,f=a.ua();c=a.f;for(var g=new F(null,c),e=f*(e+1),f=Array(e),h=0;h<e;h++)f[h]=0;g.ba(c,f,[f.length]);ae(g,a.ld(),a.sf(),d);return g}function ae(a,c,d,e){var f=a.ga(),g=a.f,h=a.ua(),k=a.zb(),m=f.length/h-1;e=e?e:0;for(var n,p,q=0;q<=m;++q)p=q*h,n=e+2*Ja(q,m)*Math.PI/m,f[p]=c[0]+d*Math.cos(n),f[p+1]=c[1]+d*Math.sin(n);a.ba(g,f,k)};function be(a){pb.call(this);a=a||{};this.f=[0,0];var c={};c.center=void 0!==a.center?a.center:null;this.i=Xc(a.projection);var d,e,f,g=void 0!==a.minZoom?a.minZoom:0;d=void 0!==a.maxZoom?a.maxZoom:28;var h=void 0!==a.zoomFactor?a.zoomFactor:2;if(void 0!==a.resolutions)d=a.resolutions,e=d[0],f=d[d.length-1],d=Eb(d);else{e=Xc(a.projection);f=e.O();var k=(f?Math.max(rc(f),sc(f)):360*Ec.degrees/e.Vb())/256/Math.pow(2,0),m=k/Math.pow(2,28);e=a.maxResolution;void 0!==e?g=0:e=k/Math.pow(h,g);f=a.minResolution; +void 0===f&&(f=void 0!==a.maxZoom?void 0!==a.maxResolution?e/Math.pow(h,d):k/Math.pow(h,d):m);d=g+Math.floor(Math.log(e/f)/Math.log(h));f=e/Math.pow(h,d-g);d=Fb(h,e,d-g)}this.a=e;this.o=f;this.j=a.resolutions;this.c=g;g=void 0!==a.extent?Ma(a.extent):Na;(void 0!==a.enableRotation?a.enableRotation:1)?(e=a.constrainRotation,e=void 0===e||!0===e?Jb():!1===e?Hb:fa(e)?Ib(e):Hb):e=Gb;this.l=new Oa(g,d,e);void 0!==a.resolution?c.resolution=a.resolution:void 0!==a.zoom&&(c.resolution=this.constrainResolution(this.a, +a.zoom-this.c));c.rotation=void 0!==a.rotation?a.rotation:0;this.C(c)}y(be,pb);l=be.prototype;l.Kd=function(a){return this.l.center(a)};l.constrainResolution=function(a,c,d){return this.l.resolution(a,c||0,d||0)};l.constrainRotation=function(a,c){return this.l.rotation(a,c||0)};l.bb=function(){return this.get("center")};function ce(a,c){return void 0!==c?(c[0]=a.f[0],c[1]=a.f[1],c):a.f.slice()}l.Fc=function(a){var c=this.bb(),d=this.$(),e=this.Ka();return uc(c,d,e,a)};l.Rl=function(){return this.i}; +l.$=function(){return this.get("resolution")};l.Sl=function(){return this.j};function de(a,c){return Math.max(rc(a)/c[0],sc(a)/c[1])}function ee(a){var c=a.a,d=Math.log(c/a.o)/Math.log(2);return function(a){return c/Math.pow(2,a*d)}}l.Ka=function(){return this.get("rotation")};function fe(a){var c=a.a,d=Math.log(c/a.o)/Math.log(2);return function(a){return Math.log(c/a)/Math.log(2)/d}} +l.V=function(){var a=this.bb(),c=this.i,d=this.$(),e=this.Ka();return{center:[Math.round(a[0]/d)*d,Math.round(a[1]/d)*d],projection:void 0!==c?c:null,resolution:d,rotation:e}};l.Bk=function(){var a,c=this.$();if(void 0!==c){var d,e=0;do{d=this.constrainResolution(this.a,e);if(d==c){a=e;break}++e}while(d>this.o)}return void 0!==a?this.c+a:a}; +l.Ze=function(a,c,d){a instanceof sd||(a=Zd(a));var e=d||{};d=void 0!==e.padding?e.padding:[0,0,0,0];var f=void 0!==e.constrainResolution?e.constrainResolution:!0,g=void 0!==e.nearest?e.nearest:!1,h;void 0!==e.minResolution?h=e.minResolution:void 0!==e.maxZoom?h=this.constrainResolution(this.a,e.maxZoom-this.c,0):h=0;var k=a.ga(),m=this.Ka(),e=Math.cos(-m),m=Math.sin(-m),n=Infinity,p=Infinity,q=-Infinity,r=-Infinity;a=a.ua();for(var u=0,v=k.length;u<v;u+=a)var x=k[u]*e-k[u+1]*m,z=k[u]*m+k[u+1]*e, +n=Math.min(n,x),p=Math.min(p,z),q=Math.max(q,x),r=Math.max(r,z);c=de([n,p,q,r],[c[0]-d[1]-d[3],c[1]-d[0]-d[2]]);c=isNaN(c)?h:Math.max(c,h);f&&(h=this.constrainResolution(c,0,0),!g&&h<c&&(h=this.constrainResolution(h,-1,0)),c=h);this.Qb(c);m=-m;g=(n+q)/2+(d[1]-d[3])/2*c;d=(p+r)/2+(d[0]-d[2])/2*c;this.jb([g*e-d*m,d*e+g*m])}; +l.Aj=function(a,c,d){var e=this.Ka(),f=Math.cos(-e),e=Math.sin(-e),g=a[0]*f-a[1]*e;a=a[1]*f+a[0]*e;var h=this.$(),g=g+(c[0]/2-d[0])*h;a+=(d[1]-c[1]/2)*h;e=-e;this.jb([g*f-a*e,a*f+g*e])};function ge(a){return!!a.bb()&&void 0!==a.$()}l.rotate=function(a,c){if(void 0!==c){var d,e=this.bb();void 0!==e&&(d=[e[0]-c[0],e[1]-c[1]],Rb(d,a-this.Ka()),Mb(d,c));this.jb(d)}this.de(a)};l.jb=function(a){this.set("center",a)};function he(a,c){a.f[1]+=c}l.Qb=function(a){this.set("resolution",a)}; +l.de=function(a){this.set("rotation",a)};l.hp=function(a){a=this.constrainResolution(this.a,a-this.c,0);this.Qb(a)};function ie(a){return Math.pow(a,3)}function je(a){return 1-ie(1-a)}function ke(a){return 3*a*a-2*a*a*a}function le(a){return a}function me(a){return.5>a?ke(2*a):1-ke(2*(a-.5))};function ne(a){var c=a.source,d=a.start?a.start:Date.now(),e=c[0],f=c[1],g=void 0!==a.duration?a.duration:1E3,h=a.easing?a.easing:ke;return function(a,c){if(c.time<d)return c.animate=!0,c.viewHints[0]+=1,!0;if(c.time<d+g){var n=1-h((c.time-d)/g),p=e-c.viewState.center[0],q=f-c.viewState.center[1];c.animate=!0;c.viewState.center[0]+=n*p;c.viewState.center[1]+=n*q;c.viewHints[0]+=1;return!0}return!1}} +function oe(a){var c=a.rotation?a.rotation:0,d=a.start?a.start:Date.now(),e=void 0!==a.duration?a.duration:1E3,f=a.easing?a.easing:ke,g=a.anchor?a.anchor:null;return function(a,k){if(k.time<d)return k.animate=!0,k.viewHints[0]+=1,!0;if(k.time<d+e){var m=1-f((k.time-d)/e),m=(c-k.viewState.rotation)*m;k.animate=!0;k.viewState.rotation+=m;if(g){var n=k.viewState.center;n[0]-=g[0];n[1]-=g[1];Rb(n,m);Mb(n,g)}k.viewHints[0]+=1;return!0}return!1}} +function pe(a){var c=a.resolution,d=a.start?a.start:Date.now(),e=void 0!==a.duration?a.duration:1E3,f=a.easing?a.easing:ke;return function(a,h){if(h.time<d)return h.animate=!0,h.viewHints[0]+=1,!0;if(h.time<d+e){var k=1-f((h.time-d)/e),m=c-h.viewState.resolution;h.animate=!0;h.viewState.resolution+=k*m;h.viewHints[0]+=1;return!0}return!1}};function qe(a,c,d,e){this.b=a;this.a=c;this.g=d;this.f=e}qe.prototype.contains=function(a){return re(this,a[1],a[2])};function re(a,c,d){return a.b<=c&&c<=a.a&&a.g<=d&&d<=a.f}function se(a,c){return a.b==c.b&&a.g==c.g&&a.a==c.a&&a.f==c.f}function te(a,c){return a.b<=c.a&&a.a>=c.b&&a.g<=c.f&&a.f>=c.g};function ue(a){this.a=a.html;this.b=a.tileRanges?a.tileRanges:null}ue.prototype.g=function(){return this.a};function ve(a,c,d){gb.call(this,a,d);this.element=c}y(ve,gb);function we(a){pb.call(this);this.a=a?a:[];xe(this)}y(we,pb);l=we.prototype;l.clear=function(){for(;0<this.Zb();)this.pop()};l.lf=function(a){var c,d;c=0;for(d=a.length;c<d;++c)this.push(a[c]);return this};l.forEach=function(a,c){this.a.forEach(a,c)};l.Cl=function(){return this.a};l.item=function(a){return this.a[a]};l.Zb=function(){return this.get("length")};l.Zd=function(a,c){this.a.splice(a,0,c);xe(this);this.b(new ve("add",c,this))}; +l.pop=function(){return this.Nf(this.Zb()-1)};l.push=function(a){var c=this.a.length;this.Zd(c,a);return c};l.remove=function(a){var c=this.a,d,e;d=0;for(e=c.length;d<e;++d)if(c[d]===a)return this.Nf(d)};l.Nf=function(a){var c=this.a[a];this.a.splice(a,1);xe(this);this.b(new ve("remove",c,this));return c};l.To=function(a,c){var d=this.Zb();if(a<d)d=this.a[a],this.a[a]=c,this.b(new ve("remove",d,this)),this.b(new ve("add",c,this));else{for(;d<a;++d)this.Zd(d,void 0);this.Zd(a,c)}}; +function xe(a){a.set("length",a.a.length)};var ye=Array.prototype.forEach?function(a,c,d){Array.prototype.forEach.call(a,c,d)}:function(a,c,d){for(var e=a.length,f=ea(a)?a.split(""):a,g=0;g<e;g++)g in f&&c.call(d,f[g],g,a)};function ze(a){return Array.prototype.concat.apply(Array.prototype,arguments)}function Ae(a){var c=a.length;if(0<c){for(var d=Array(c),e=0;e<c;e++)d[e]=a[e];return d}return[]}function Be(a,c,d){return 2>=arguments.length?Array.prototype.slice.call(a,c):Array.prototype.slice.call(a,c,d)};var Ce=/^#(?:[0-9a-f]{3}){1,2}$/i,De=/^(?:rgb)?\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2})\)$/i,Ee=/^(?:rgba)?\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|1|0\.\d{0,10})\)$/i;function Fe(a){return Array.isArray(a)?a:Ge(a)}function He(a){if("string"!==typeof a){var c=a[0];c!=(c|0)&&(c=c+.5|0);var d=a[1];d!=(d|0)&&(d=d+.5|0);var e=a[2];e!=(e|0)&&(e=e+.5|0);a="rgba("+c+","+d+","+e+","+(void 0===a[3]?1:a[3])+")"}return a} +var Ge=function(){var a={},c=0;return function(d){var e;if(a.hasOwnProperty(d))e=a[d];else{if(1024<=c){e=0;for(var f in a)0===(e++&3)&&(delete a[f],--c)}var g,h;Ce.exec(d)?(h=3==d.length-1?1:2,e=parseInt(d.substr(1+0*h,h),16),f=parseInt(d.substr(1+1*h,h),16),g=parseInt(d.substr(1+2*h,h),16),1==h&&(e=(e<<4)+e,f=(f<<4)+f,g=(g<<4)+g),e=[e,f,g,1]):(h=Ee.exec(d))?(e=Number(h[1]),f=Number(h[2]),g=Number(h[3]),h=Number(h[4]),e=[e,f,g,h],e=Ie(e,e)):(h=De.exec(d))?(e=Number(h[1]),f=Number(h[2]),g=Number(h[3]), +e=[e,f,g,1],e=Ie(e,e)):e=void 0;a[d]=e;++c}return e}}();function Ie(a,c){var d=c||[];d[0]=Da(a[0]+.5|0,0,255);d[1]=Da(a[1]+.5|0,0,255);d[2]=Da(a[2]+.5|0,0,255);d[3]=Da(a[3],0,1);return d};function Je(a){return"string"===typeof a||a instanceof CanvasPattern||a instanceof CanvasGradient?a:He(a)};var Ke;a:{var Le=aa.navigator;if(Le){var Me=Le.userAgent;if(Me){Ke=Me;break a}}Ke=""}function Ne(a){return-1!=Ke.indexOf(a)};function Oe(a,c){for(var d in a)c.call(void 0,a[d],d,a)}var Pe="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" ");function Qe(a,c){for(var d,e,f=1;f<arguments.length;f++){e=arguments[f];for(d in e)a[d]=e[d];for(var g=0;g<Pe.length;g++)d=Pe[g],Object.prototype.hasOwnProperty.call(e,d)&&(a[d]=e[d])}};var Re=Ne("Opera")||Ne("OPR"),Se=Ne("Trident")||Ne("MSIE"),Te=Ne("Edge"),Ue=Ne("Gecko")&&!(-1!=Ke.toLowerCase().indexOf("webkit")&&!Ne("Edge"))&&!(Ne("Trident")||Ne("MSIE"))&&!Ne("Edge"),Ve=-1!=Ke.toLowerCase().indexOf("webkit")&&!Ne("Edge");function We(){var a=aa.document;return a?a.documentMode:void 0}var Xe; +a:{var Ye="",$e=function(){var a=Ke;if(Ue)return/rv\:([^\);]+)(\)|;)/.exec(a);if(Te)return/Edge\/([\d\.]+)/.exec(a);if(Se)return/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(a);if(Ve)return/WebKit\/(\S+)/.exec(a);if(Re)return/(?:Version)[ \/]?(\S+)/.exec(a)}();$e&&(Ye=$e?$e[1]:"");if(Se){var af=We();if(null!=af&&af>parseFloat(Ye)){Xe=String(af);break a}}Xe=Ye}var bf={}; +function cf(a){var c;if(!(c=bf[a])){c=0;for(var d=sa(String(Xe)).split("."),e=sa(String(a)).split("."),f=Math.max(d.length,e.length),g=0;0==c&&g<f;g++){var h=d[g]||"",k=e[g]||"",m=RegExp("(\\d*)(\\D*)","g"),n=RegExp("(\\d*)(\\D*)","g");do{var p=m.exec(h)||["","",""],q=n.exec(k)||["","",""];if(0==p[0].length&&0==q[0].length)break;c=Ca(0==p[1].length?0:parseInt(p[1],10),0==q[1].length?0:parseInt(q[1],10))||Ca(0==p[2].length,0==q[2].length)||Ca(p[2],q[2])}while(0==c)}c=bf[a]=0<=c}return c} +var df=aa.document,ef=df&&Se?We()||("CSS1Compat"==df.compatMode?parseInt(Xe,10):5):void 0;var ff=!Se||9<=Number(ef);!Ue&&!Se||Se&&9<=Number(ef)||Ue&&cf("1.9.1");Se&&cf("9");function gf(a,c){this.x=void 0!==a?a:0;this.y=void 0!==c?c:0}l=gf.prototype;l.clone=function(){return new gf(this.x,this.y)};l.ceil=function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this};l.floor=function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this};l.round=function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this};l.scale=function(a,c){var d=fa(c)?c:a;this.x*=a;this.y*=d;return this};function hf(a,c){this.width=a;this.height=c}l=hf.prototype;l.clone=function(){return new hf(this.width,this.height)};l.wj=function(){return this.width*this.height};l.Sa=function(){return!this.wj()};l.ceil=function(){this.width=Math.ceil(this.width);this.height=Math.ceil(this.height);return this};l.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};l.round=function(){this.width=Math.round(this.width);this.height=Math.round(this.height);return this}; +l.scale=function(a,c){var d=fa(c)?c:a;this.width*=a;this.height*=d;return this};function jf(a){return a?new kf(lf(a)):ra||(ra=new kf)}function mf(a){var c=document;return ea(a)?c.getElementById(a):a}function nf(a,c){Oe(c,function(c,e){"style"==e?a.style.cssText=c:"class"==e?a.className=c:"for"==e?a.htmlFor=c:of.hasOwnProperty(e)?a.setAttribute(of[e],c):0==e.lastIndexOf("aria-",0)||0==e.lastIndexOf("data-",0)?a.setAttribute(e,c):a[e]=c})} +var of={cellpadding:"cellPadding",cellspacing:"cellSpacing",colspan:"colSpan",frameborder:"frameBorder",height:"height",maxlength:"maxLength",nonce:"nonce",role:"role",rowspan:"rowSpan",type:"type",usemap:"useMap",valign:"vAlign",width:"width"}; +function pf(a,c,d){var e=arguments,f=document,g=e[0],h=e[1];if(!ff&&h&&(h.name||h.type)){g=["<",g];h.name&&g.push(' name="',ta(h.name),'"');if(h.type){g.push(' type="',ta(h.type),'"');var k={};Qe(k,h);delete k.type;h=k}g.push(">");g=g.join("")}g=f.createElement(g);h&&(ea(h)?g.className=h:"array"==ca(h)?g.className=h.join(" "):nf(g,h));2<e.length&&qf(f,g,e);return g} +function qf(a,c,d){function e(d){d&&c.appendChild(ea(d)?a.createTextNode(d):d)}for(var f=2;f<d.length;f++){var g=d[f];!da(g)||ha(g)&&0<g.nodeType?e(g):ye(rf(g)?Ae(g):g,e)}}function sf(a){for(var c;c=a.firstChild;)a.removeChild(c)}function tf(a,c,d){a.insertBefore(c,a.childNodes[d]||null)}function uf(a){a&&a.parentNode&&a.parentNode.removeChild(a)}function vf(a,c){var d=c.parentNode;d&&d.replaceChild(a,c)} +function wf(a,c){if(!a||!c)return!1;if(a.contains&&1==c.nodeType)return a==c||a.contains(c);if("undefined"!=typeof a.compareDocumentPosition)return a==c||!!(a.compareDocumentPosition(c)&16);for(;c&&a!=c;)c=c.parentNode;return c==a}function lf(a){return 9==a.nodeType?a:a.ownerDocument||a.document}function rf(a){if(a&&"number"==typeof a.length){if(ha(a))return"function"==typeof a.item||"string"==typeof a.item;if(ga(a))return"function"==typeof a.item}return!1} +function kf(a){this.b=a||aa.document||document}kf.prototype.C=nf;kf.prototype.createElement=function(a){return this.b.createElement(a)};kf.prototype.appendChild=function(a,c){a.appendChild(c)};kf.prototype.contains=wf;function xf(a,c,d,e){this.top=a;this.right=c;this.bottom=d;this.left=e}l=xf.prototype;l.clone=function(){return new xf(this.top,this.right,this.bottom,this.left)};l.contains=function(a){return this&&a?a instanceof xf?a.left>=this.left&&a.right<=this.right&&a.top>=this.top&&a.bottom<=this.bottom:a.x>=this.left&&a.x<=this.right&&a.y>=this.top&&a.y<=this.bottom:!1}; l.ceil=function(){this.top=Math.ceil(this.top);this.right=Math.ceil(this.right);this.bottom=Math.ceil(this.bottom);this.left=Math.ceil(this.left);return this};l.floor=function(){this.top=Math.floor(this.top);this.right=Math.floor(this.right);this.bottom=Math.floor(this.bottom);this.left=Math.floor(this.left);return this};l.round=function(){this.top=Math.round(this.top);this.right=Math.round(this.right);this.bottom=Math.round(this.bottom);this.left=Math.round(this.left);return this}; -l.scale=function(b,c){var d=ja(c)?c:b;this.left*=b;this.right*=b;this.top*=d;this.bottom*=d;return this};function Yg(b,c,d,e){this.left=b;this.top=c;this.width=d;this.height=e}l=Yg.prototype;l.clone=function(){return new Yg(this.left,this.top,this.width,this.height)};l.contains=function(b){return b instanceof Yg?this.left<=b.left&&this.left+this.width>=b.left+b.width&&this.top<=b.top&&this.top+this.height>=b.top+b.height:b.x>=this.left&&b.x<=this.left+this.width&&b.y>=this.top&&b.y<=this.top+this.height}; -l.distance=function(b){var c=b.x<this.left?this.left-b.x:Math.max(b.x-(this.left+this.width),0);b=b.y<this.top?this.top-b.y:Math.max(b.y-(this.top+this.height),0);return Math.sqrt(c*c+b*b)};l.ceil=function(){this.left=Math.ceil(this.left);this.top=Math.ceil(this.top);this.width=Math.ceil(this.width);this.height=Math.ceil(this.height);return this};l.floor=function(){this.left=Math.floor(this.left);this.top=Math.floor(this.top);this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this}; -l.round=function(){this.left=Math.round(this.left);this.top=Math.round(this.top);this.width=Math.round(this.width);this.height=Math.round(this.height);return this};l.scale=function(b,c){var d=ja(c)?c:b;this.left*=b;this.width*=b;this.top*=d;this.height*=d;return this};function Zg(b,c){var d=Cg(b);return d.defaultView&&d.defaultView.getComputedStyle&&(d=d.defaultView.getComputedStyle(b,null))?d[c]||d.getPropertyValue(c)||"":""}function $g(b,c){return Zg(b,c)||(b.currentStyle?b.currentStyle[c]:null)||b.style&&b.style[c]}function ah(b,c,d){var e;c instanceof yg?(e=c.x,c=c.y):(e=c,c=d);b.style.left=bh(e);b.style.top=bh(c)} -function ch(b){var c;try{c=b.getBoundingClientRect()}catch(d){return{left:0,top:0,right:0,bottom:0}}Yb&&b.ownerDocument.body&&(b=b.ownerDocument,c.left-=b.documentElement.clientLeft+b.body.clientLeft,c.top-=b.documentElement.clientTop+b.body.clientTop);return c}function dh(b){if(1==b.nodeType)return b=ch(b),new yg(b.left,b.top);b=b.changedTouches?b.changedTouches[0]:b;return new yg(b.clientX,b.clientY)}function bh(b){"number"==typeof b&&(b=b+"px");return b} -function eh(b){var c=fh;if("none"!=$g(b,"display"))return c(b);var d=b.style,e=d.display,f=d.visibility,g=d.position;d.visibility="hidden";d.position="absolute";d.display="inline";b=c(b);d.display=e;d.position=g;d.visibility=f;return b}function fh(b){var c=b.offsetWidth,d=b.offsetHeight,e=ac&&!c&&!d;return ca(c)&&!e||!b.getBoundingClientRect?new zg(c,d):(b=ch(b),new zg(b.right-b.left,b.bottom-b.top))}function gh(b,c){b.style.display=c?"":"none"} -function hh(b,c,d,e){if(/^\d+px?$/.test(c))return parseInt(c,10);var f=b.style[d],g=b.runtimeStyle[d];b.runtimeStyle[d]=b.currentStyle[d];b.style[d]=c;c=b.style[e];b.style[d]=f;b.runtimeStyle[d]=g;return c}function ih(b,c){var d=b.currentStyle?b.currentStyle[c]:null;return d?hh(b,d,"left","pixelLeft"):0} -function jh(b,c){if(Yb){var d=ih(b,c+"Left"),e=ih(b,c+"Right"),f=ih(b,c+"Top"),g=ih(b,c+"Bottom");return new Xg(f,e,g,d)}d=Zg(b,c+"Left");e=Zg(b,c+"Right");f=Zg(b,c+"Top");g=Zg(b,c+"Bottom");return new Xg(parseFloat(f),parseFloat(e),parseFloat(g),parseFloat(d))}var kh={thin:2,medium:4,thick:6};function lh(b,c){if("none"==(b.currentStyle?b.currentStyle[c+"Style"]:null))return 0;var d=b.currentStyle?b.currentStyle[c+"Width"]:null;return d in kh?kh[d]:hh(b,d,"left","pixelLeft")} -function mh(b){if(Yb&&!(9<=kc)){var c=lh(b,"borderLeft"),d=lh(b,"borderRight"),e=lh(b,"borderTop");b=lh(b,"borderBottom");return new Xg(e,d,b,c)}c=Zg(b,"borderLeftWidth");d=Zg(b,"borderRightWidth");e=Zg(b,"borderTopWidth");b=Zg(b,"borderBottomWidth");return new Xg(parseFloat(e),parseFloat(d),parseFloat(b),parseFloat(c))};function nh(b,c,d){tc.call(this,b);this.map=c;this.frameState=void 0!==d?d:null}y(nh,tc);function oh(b){gd.call(this);this.element=b.element?b.element:null;this.a=this.U=null;this.o=[];this.render=b.render?b.render:za;b.target&&this.c(b.target)}y(oh,gd);oh.prototype.Y=function(){Mg(this.element);oh.ca.Y.call(this)};oh.prototype.g=function(){return this.a}; -oh.prototype.setMap=function(b){this.a&&Mg(this.element);0<this.o.length&&(this.o.forEach(Wc),this.o.length=0);if(this.a=b)(this.U?this.U:b.j).appendChild(this.element),this.render!==za&&this.o.push(D(b,"postrender",this.render,!1,this)),b.render()};oh.prototype.c=function(b){this.U=Dg(b)};function ph(){this.b=0;this.c={};this.f=this.a=null}l=ph.prototype;l.clear=function(){this.b=0;this.c={};this.f=this.a=null};function qh(b,c){return b.c.hasOwnProperty(c)}l.forEach=function(b,c){for(var d=this.a;d;)b.call(c,d.mc,d.oe,this),d=d.sb};l.get=function(b){b=this.c[b];if(b===this.f)return b.mc;b===this.a?(this.a=this.a.sb,this.a.hc=null):(b.sb.hc=b.hc,b.hc.sb=b.sb);b.sb=null;b.hc=this.f;this.f=this.f.sb=b;return b.mc};l.qc=function(){return this.b}; -l.P=function(){var b=Array(this.b),c=0,d;for(d=this.f;d;d=d.hc)b[c++]=d.oe;return b};l.sc=function(){var b=Array(this.b),c=0,d;for(d=this.f;d;d=d.hc)b[c++]=d.mc;return b};l.pop=function(){var b=this.a;delete this.c[b.oe];b.sb&&(b.sb.hc=null);this.a=b.sb;this.a||(this.f=null);--this.b;return b.mc};l.replace=function(b,c){this.get(b);this.c[b].mc=c};l.set=function(b,c){var d={oe:b,sb:null,hc:this.f,mc:c};this.f?this.f.sb=d:this.a=d;this.f=d;this.c[b]=d;++this.b};function rh(b){ph.call(this);this.g=void 0!==b?b:2048}y(rh,ph);function sh(b){return b.qc()>b.g}function th(b,c){for(var d,e;sh(b)&&!(d=b.a.mc,e=d.a[0].toString(),e in c&&c[e].contains(d.a));)b.pop().Fc()};function uh(b,c){$c.call(this);this.a=b;this.state=c;this.f=null;this.key=""}y(uh,$c);function vh(b){b.s("change")}uh.prototype.$a=function(){return w(this).toString()};uh.prototype.g=function(){return this.a};function wh(b){gd.call(this);this.b=Ee(b.projection);this.i=void 0!==b.attributions?b.attributions:null;this.U=b.logo;this.B=void 0!==b.state?b.state:"ready";this.O=void 0!==b.wrapX?b.wrapX:!1}y(wh,gd);l=wh.prototype;l.ye=za;l.sa=function(){return this.i};l.qa=function(){return this.U};l.ta=function(){return this.b};l.ua=function(){return this.B};function xh(b){return b.O}l.ma=function(b){this.i=b;this.u()};function yh(b,c){b.B=c;b.u()};function zh(b){this.minZoom=void 0!==b.minZoom?b.minZoom:0;this.a=b.resolutions;this.maxZoom=this.a.length-1;this.b=void 0!==b.origin?b.origin:null;this.g=null;void 0!==b.origins&&(this.g=b.origins);var c=b.extent;void 0===c||this.b||this.g||(this.b=ge(c));this.i=null;void 0!==b.tileSizes&&(this.i=b.tileSizes);this.l=void 0!==b.tileSize?b.tileSize:this.i?null:256;this.G=void 0!==c?c:null;this.f=null;void 0!==b.sizes?this.f=b.sizes.map(function(b){return new fg(Math.min(0,b[0]),Math.max(b[0]-1,-1), -Math.min(0,b[1]),Math.max(b[1]-1,-1))},this):c&&Ah(this,c);this.c=[0,0]}var Bh=[0,0,0];function Ch(b,c,d,e,f){f=b.Aa(c,f);for(c=c[0]-1;c>=b.minZoom;){if(d.call(null,c,Dh(b,f,c,e)))return!0;--c}return!1}l=zh.prototype;l.J=function(){return this.G};l.Eg=function(){return this.maxZoom};l.Fg=function(){return this.minZoom};l.Da=function(b){return this.b?this.b:this.g[b]};l.$=function(b){return this.a[b]};l.zh=function(){return this.a}; -function Eh(b,c,d,e){return c[0]<b.maxZoom?(e=b.Aa(c,e),Dh(b,e,c[0]+1,d)):null}function Fh(b,c,d,e){Gh(b,c[0],c[1],d,!1,Bh);var f=Bh[1],g=Bh[2];Gh(b,c[2],c[3],d,!0,Bh);b=Bh[1];c=Bh[2];void 0!==e?(e.a=f,e.c=b,e.f=g,e.b=c):e=new fg(f,b,g,c);return e}function Dh(b,c,d,e){d=b.$(d);return Fh(b,c,d,e)}function Hh(b,c){var d=b.Da(c[0]),e=b.$(c[0]),f=md(b.Ka(c[0]),b.c);return[d[0]+(c[1]+.5)*f[0]*e,d[1]+(c[2]+.5)*f[1]*e]} -l.Aa=function(b,c){var d=this.Da(b[0]),e=this.$(b[0]),f=md(this.Ka(b[0]),this.c),g=d[0]+b[1]*f[0]*e,d=d[1]+b[2]*f[1]*e;return Pd(g,d,g+f[0]*e,d+f[1]*e,c)};l.fe=function(b,c,d){return Gh(this,b[0],b[1],c,!1,d)};function Gh(b,c,d,e,f,g){var h=Ih(b,e),k=e/b.$(h),m=b.Da(h);b=md(b.Ka(h),b.c);c=k*Math.floor((c-m[0])/e+(f?.5:0))/b[0];d=k*Math.floor((d-m[1])/e+(f?0:.5))/b[1];f?(c=Math.ceil(c)-1,d=Math.ceil(d)-1):(c=Math.floor(c),d=Math.floor(d));return ag(h,c,d,g)} -l.ge=function(b,c,d){c=this.$(c);return Gh(this,b[0],b[1],c,!1,d)};l.Ka=function(b){return this.l?this.l:this.i[b]};function Ih(b,c){var d=wb(b.a,c,0);return Sa(d,b.minZoom,b.maxZoom)}function Ah(b,c){for(var d=b.a.length,e=Array(d),f=b.minZoom;f<d;++f)e[f]=Dh(b,c,f);b.f=e}function Jh(b){var c=b.l;if(!c){var c=Kh(b),d=Lh(c,void 0,void 0),c=new zh({extent:c,origin:ge(c),resolutions:d,tileSize:void 0});b.l=c}return c} -function Mh(b){var c={};Wb(c,void 0!==b?b:{});void 0===c.extent&&(c.extent=Ee("EPSG:3857").J());c.resolutions=Lh(c.extent,c.maxZoom,c.tileSize);delete c.maxZoom;return new zh(c)}function Lh(b,c,d){c=void 0!==c?c:42;var e=ke(b);b=je(b);d=md(void 0!==d?d:256);d=Math.max(b/d[0],e/d[1]);c+=1;e=Array(c);for(b=0;b<c;++b)e[b]=d/Math.pow(2,b);return e}function Kh(b){b=Ee(b);var c=b.J();c||(b=180*Be.degrees/b.Kc(),c=Pd(-b,-b,b,b));return c};function Nh(b){wh.call(this,{attributions:b.attributions,extent:b.extent,logo:b.logo,projection:b.projection,state:b.state,wrapX:b.wrapX});this.pa=void 0!==b.opaque?b.opaque:!1;this.v=void 0!==b.tilePixelRatio?b.tilePixelRatio:1;this.tileGrid=void 0!==b.tileGrid?b.tileGrid:null;this.a=new rh(b.df);this.c=[0,0]}y(Nh,wh);l=Nh.prototype;l.qh=function(){return sh(this.a)};l.rh=function(b,c){var d=this.ud(b);d&&th(d,c)}; -function Oh(b,c,d,e,f){c=b.ud(c);if(!c)return!1;for(var g=!0,h,k,m=e.a;m<=e.c;++m)for(var n=e.f;n<=e.b;++n)h=b.Ab(d,m,n),k=!1,qh(c,h)&&(h=c.get(h),(k=2===h.state)&&(k=!1!==f(h))),k||(g=!1);return g}l.ae=function(){return 0};l.Cg=function(){return""};l.Ab=bg;l.Ha=function(){return this.tileGrid};l.ib=function(b){return this.tileGrid?this.tileGrid:Jh(b)};l.ud=function(b){var c=this.b;return c&&!Ve(c,b)?null:this.a};l.Qb=function(b,c,d){c=this.ib(d);return ld(md(c.Ka(b),this.c),this.v,this.c)}; -function Ph(b,c,d){var e=void 0!==d?d:b.b;d=b.ib(e);if(b.O&&e.c){var f=c;c=f[0];b=Hh(d,f);e=Kh(e);Td(e,b)?c=f:(f=je(e),b[0]+=f*Math.ceil((e[0]-b[0])/f),c=d.ge(b,c))}f=c[0];e=c[1];b=c[2];if(d.minZoom>f||f>d.maxZoom)d=!1;else{var g=d.J();d=(d=g?Dh(d,g,f):d.f?d.f[f]:null)?gg(d,e,b):!0}return d?c:null}l.Yf=za;function Qh(b,c){tc.call(this,b);this.tile=c}y(Qh,tc);function Rh(b){b=b?b:{};this.C=document.createElement("UL");this.B=document.createElement("LI");this.C.appendChild(this.B);gh(this.B,!1);this.b=void 0!==b.collapsed?b.collapsed:!0;this.j=void 0!==b.collapsible?b.collapsible:!0;this.j||(this.b=!1);var c=b.className?b.className:"ol-attribution",d=b.tipLabel?b.tipLabel:"Attributions",e=b.collapseLabel?b.collapseLabel:"\u00bb";this.D=ia(e)?Hg("SPAN",{},e):e;e=b.label?b.label:"i";this.O=ia(e)?Hg("SPAN",{},e):e;d=Hg("BUTTON",{type:"button",title:d},this.j&& -!this.b?this.D:this.O);D(d,"click",this.Pl,!1,this);c=Hg("DIV",c+" ol-unselectable ol-control"+(this.b&&this.j?" ol-collapsed":"")+(this.j?"":" ol-uncollapsible"),this.C,d);oh.call(this,{element:c,render:b.render?b.render:Sh,target:b.target});this.v=!0;this.l={};this.i={};this.T={}}y(Rh,oh); -function Sh(b){if(b=b.frameState){var c,d,e,f,g,h,k,m,n,p,q,r=b.layerStatesArray,t=Tb(b.attributions),x={},z=b.viewState.projection;d=0;for(c=r.length;d<c;d++)if(h=r[d].layer.ea())if(p=w(h).toString(),n=h.i)for(e=0,f=n.length;e<f;e++)if(k=n[e],m=w(k).toString(),!(m in t)){if(g=b.usedTiles[p]){var A=h.ib(z);a:{q=k;var B=z;if(q.a){var v=void 0,L=void 0,M=void 0,J=void 0;for(J in g)if(J in q.a)for(var M=g[J],C,v=0,L=q.a[J].length;v<L;++v){C=q.a[J][v];if(lg(C,M)){q=!0;break a}var sa=Dh(A,B.J(),parseInt(J, -10)),la=kg(sa);if(M.a<sa.a||M.c>sa.c)if(lg(C,new fg(nd(M.a,la),nd(M.c,la),M.f,M.b))||kg(M)>la&&lg(C,sa)){q=!0;break a}}q=!1}else q=!0}}else q=!1;q?(m in x&&delete x[m],t[m]=k):x[m]=k}c=[t,x];d=c[0];c=c[1];for(var K in this.l)K in d?(this.i[K]||(gh(this.l[K],!0),this.i[K]=!0),delete d[K]):K in c?(this.i[K]&&(gh(this.l[K],!1),delete this.i[K]),delete c[K]):(Mg(this.l[K]),delete this.l[K],delete this.i[K]);for(K in d)e=document.createElement("LI"),e.innerHTML=d[K].f,this.C.appendChild(e),this.l[K]=e, -this.i[K]=!0;for(K in c)e=document.createElement("LI"),e.innerHTML=c[K].f,gh(e,!1),this.C.appendChild(e),this.l[K]=e;K=!Pb(this.i)||!Pb(b.logos);this.v!=K&&(gh(this.element,K),this.v=K);K&&Pb(this.i)?Ug(this.element,"ol-logo-only"):Vg(this.element,"ol-logo-only");var ma;b=b.logos;K=this.T;for(ma in K)ma in b||(Mg(K[ma]),delete K[ma]);for(var Ua in b)Ua in K||(ma=new Image,ma.src=Ua,d=b[Ua],""===d?d=ma:(d=Hg("A",{href:d}),d.appendChild(ma)),this.B.appendChild(d),K[Ua]=d);gh(this.B,!Pb(b))}else this.v&& -(gh(this.element,!1),this.v=!1)}l=Rh.prototype;l.Pl=function(b){b.preventDefault();Th(this)};function Th(b){Wg(b.element,"ol-collapsed");b.b?Ng(b.D,b.O):Ng(b.O,b.D);b.b=!b.b}l.Ol=function(){return this.j};l.Rl=function(b){this.j!==b&&(this.j=b,Wg(this.element,"ol-uncollapsible"),!b&&this.b&&Th(this))};l.Ql=function(b){this.j&&this.b!==b&&Th(this)};l.Nl=function(){return this.b};function Uh(b){b=b?b:{};var c=b.className?b.className:"ol-rotate",d=b.label?b.label:"\u21e7";this.b=null;ia(d)?this.b=Hg("SPAN","ol-compass",d):(this.b=d,Ug(this.b,"ol-compass"));d=Hg("BUTTON",{"class":c+"-reset",type:"button",title:b.tipLabel?b.tipLabel:"Reset rotation"},this.b);D(d,"click",Uh.prototype.v,!1,this);c=Hg("DIV",c+" ol-unselectable ol-control",d);d=b.render?b.render:Vh;this.j=b.resetNorth?b.resetNorth:void 0;oh.call(this,{element:c,render:d,target:b.target});this.l=void 0!==b.duration? -b.duration:250;this.i=void 0!==b.autoHide?b.autoHide:!0;this.B=void 0;this.i&&Ug(this.element,"ol-hidden")}y(Uh,oh);Uh.prototype.v=function(b){b.preventDefault();if(void 0!==this.j)this.j();else{b=this.a;var c=b.aa();if(c){var d=c.Fa();void 0!==d&&(0<this.l&&(d%=2*Math.PI,d<-Math.PI&&(d+=2*Math.PI),d>Math.PI&&(d-=2*Math.PI),b.Na(Zf({rotation:d,duration:this.l,easing:Uf}))),c.ue(0))}}}; -function Vh(b){if(b=b.frameState){b=b.viewState.rotation;if(b!=this.B){var c="rotate("+b+"rad)";if(this.i){var d=this.element;0===b?Ug(d,"ol-hidden"):Vg(d,"ol-hidden")}this.b.style.msTransform=c;this.b.style.webkitTransform=c;this.b.style.transform=c}this.B=b}};function Wh(b){b=b?b:{};var c=b.className?b.className:"ol-zoom",d=b.delta?b.delta:1,e=b.zoomOutLabel?b.zoomOutLabel:"\u2212",f=b.zoomOutTipLabel?b.zoomOutTipLabel:"Zoom out",g=Hg("BUTTON",{"class":c+"-in",type:"button",title:b.zoomInTipLabel?b.zoomInTipLabel:"Zoom in"},b.zoomInLabel?b.zoomInLabel:"+");D(g,"click",va(Wh.prototype.i,d),!1,this);e=Hg("BUTTON",{"class":c+"-out",type:"button",title:f},e);D(e,"click",va(Wh.prototype.i,-d),!1,this);c=Hg("DIV",c+" ol-unselectable ol-control",g,e);oh.call(this, -{element:c,target:b.target});this.b=void 0!==b.duration?b.duration:250}y(Wh,oh);Wh.prototype.i=function(b,c){c.preventDefault();var d=this.a,e=d.aa();if(e){var f=e.$();f&&(0<this.b&&d.Na($f({resolution:f,duration:this.b,easing:Uf})),d=e.constrainResolution(f,b),e.Ub(d))}};function Xh(b){b=b?b:{};var c=new og;(void 0!==b.zoom?b.zoom:1)&&c.push(new Wh(b.zoomOptions));(void 0!==b.rotate?b.rotate:1)&&c.push(new Uh(b.rotateOptions));(void 0!==b.attribution?b.attribution:1)&&c.push(new Rh(b.attributionOptions));return c};var Yh=ac?"webkitfullscreenchange":$b?"mozfullscreenchange":Yb?"MSFullscreenChange":"fullscreenchange";function Zh(){var b=Ag().a,c=b.body;return!!(c.webkitRequestFullscreen||c.mozRequestFullScreen&&b.mozFullScreenEnabled||c.msRequestFullscreen&&b.msFullscreenEnabled||c.requestFullscreen&&b.fullscreenEnabled)} -function $h(b){b.webkitRequestFullscreen?b.webkitRequestFullscreen():b.mozRequestFullScreen?b.mozRequestFullScreen():b.msRequestFullscreen?b.msRequestFullscreen():b.requestFullscreen&&b.requestFullscreen()}function ai(){var b=Ag().a;return!!(b.webkitIsFullScreen||b.mozFullScreen||b.msFullscreenElement||b.fullscreenElement)};function bi(b){b=b?b:{};this.b=b.className?b.className:"ol-full-screen";var c=b.label?b.label:"\u2922";this.i=ia(c)?document.createTextNode(c):c;c=b.labelActive?b.labelActive:"\u00d7";this.j=ia(c)?document.createTextNode(c):c;c=b.tipLabel?b.tipLabel:"Toggle full-screen";c=Hg("BUTTON",{"class":this.b+"-"+ai(),type:"button",title:c},this.i);D(c,"click",this.v,!1,this);D(ba.document,Yh,this.l,!1,this);var d=this.b+" ol-unselectable ol-control "+(Zh()?"":"ol-unsupported"),c=Hg("DIV",d,c);oh.call(this, -{element:c,target:b.target});this.B=void 0!==b.keys?b.keys:!1}y(bi,oh);bi.prototype.v=function(b){b.preventDefault();Zh()&&(b=this.a)&&(ai()?(b=Ag().a,b.webkitCancelFullScreen?b.webkitCancelFullScreen():b.mozCancelFullScreen?b.mozCancelFullScreen():b.msExitFullscreen?b.msExitFullscreen():b.exitFullscreen&&b.exitFullscreen()):(b=b.xf(),b=Dg(b),this.B?b.mozRequestFullScreenWithKeys?b.mozRequestFullScreenWithKeys():b.webkitRequestFullscreen?b.webkitRequestFullscreen():$h(b):$h(b)))}; -bi.prototype.l=function(){var b=this.b+"-true",c=this.b+"-false",d=Og(this.element),e=this.a;ai()?(Tg(d,c)&&(Vg(d,c),Ug(d,b)),Ng(this.j,this.i)):(Tg(d,b)&&(Vg(d,b),Ug(d,c)),Ng(this.i,this.j));e&&e.Vc()};function di(b){b=b?b:{};var c=Hg("DIV",b.className?b.className:"ol-mouse-position");oh.call(this,{element:c,render:b.render?b.render:ei,target:b.target});D(this,id("projection"),this.Sl,!1,this);b.coordinateFormat&&this.Wh(b.coordinateFormat);b.projection&&this.bh(Ee(b.projection));this.B=b.undefinedHTML?b.undefinedHTML:"";this.l=c.innerHTML;this.j=this.i=this.b=null}y(di,oh); -function ei(b){b=b.frameState;b?this.b!=b.viewState.projection&&(this.b=b.viewState.projection,this.i=null):this.b=null;fi(this,this.j)}l=di.prototype;l.Sl=function(){this.i=null};l.wg=function(){return this.get("coordinateFormat")};l.ah=function(){return this.get("projection")};l.Nk=function(b){this.j=this.a.$d(b.a);fi(this,this.j)};l.Ok=function(){fi(this,null);this.j=null}; -l.setMap=function(b){di.ca.setMap.call(this,b);b&&(b=b.a,this.o.push(D(b,"mousemove",this.Nk,!1,this),D(b,"mouseout",this.Ok,!1,this)))};l.Wh=function(b){this.set("coordinateFormat",b)};l.bh=function(b){this.set("projection",b)};function fi(b,c){var d=b.B;if(c&&b.b){if(!b.i){var e=b.ah();b.i=e?Ie(b.b,e):Xe}if(e=b.a.Ga(c))b.i(e,e),d=(d=b.wg())?d(e):e.toString()}b.l&&d==b.l||(b.element.innerHTML=d,b.l=d)};function gi(b,c,d){oc.call(this);this.xa=null;this.b=!1;this.i=b;this.g=d;this.a=c||window;this.f=ua(this.c,this)}y(gi,oc);gi.prototype.start=function(){hi(this);this.b=!1;var b=ii(this),c=ji(this);b&&!c&&this.a.mozRequestAnimationFrame?(this.xa=D(this.a,"MozBeforePaint",this.f),this.a.mozRequestAnimationFrame(null),this.b=!0):this.xa=b&&c?b.call(this.a,this.f):this.a.setTimeout(we(this.f),20)}; -function hi(b){if(null!=b.xa){var c=ii(b),d=ji(b);c&&!d&&b.a.mozRequestAnimationFrame?Wc(b.xa):c&&d?d.call(b.a,b.xa):b.a.clearTimeout(b.xa)}b.xa=null}gi.prototype.c=function(){this.b&&this.xa&&Wc(this.xa);this.xa=null;this.i.call(this.g,wa())};gi.prototype.Y=function(){hi(this);gi.ca.Y.call(this)};function ii(b){b=b.a;return b.requestAnimationFrame||b.webkitRequestAnimationFrame||b.mozRequestAnimationFrame||b.oRequestAnimationFrame||b.msRequestAnimationFrame||null} -function ji(b){b=b.a;return b.cancelAnimationFrame||b.cancelRequestAnimationFrame||b.webkitCancelRequestAnimationFrame||b.mozCancelRequestAnimationFrame||b.oCancelRequestAnimationFrame||b.msCancelRequestAnimationFrame||null};function ki(b){ba.setTimeout(function(){throw b;},0)}function li(b,c){var d=b;c&&(d=ua(b,c));d=mi(d);!ka(ba.setImmediate)||ba.Window&&ba.Window.prototype&&ba.Window.prototype.setImmediate==ba.setImmediate?(ni||(ni=oi()),ni(d)):ba.setImmediate(d)}var ni; -function oi(){var b=ba.MessageChannel;"undefined"===typeof b&&"undefined"!==typeof window&&window.postMessage&&window.addEventListener&&!Hb("Presto")&&(b=function(){var b=document.createElement("IFRAME");b.style.display="none";b.src="";document.documentElement.appendChild(b);var c=b.contentWindow,b=c.document;b.open();b.write("");b.close();var d="callImmediate"+Math.random(),e="file:"==c.location.protocol?"*":c.location.protocol+"//"+c.location.host,b=ua(function(b){if(("*"==e||b.origin==e)&&b.data== -d)this.port1.onmessage()},this);c.addEventListener("message",b,!1);this.port1={};this.port2={postMessage:function(){c.postMessage(d,e)}}});if("undefined"!==typeof b&&!Hb("Trident")&&!Hb("MSIE")){var c=new b,d={},e=d;c.port1.onmessage=function(){if(ca(d.next)){d=d.next;var b=d.ng;d.ng=null;b()}};return function(b){e.next={ng:b};e=e.next;c.port2.postMessage(0)}}return"undefined"!==typeof document&&"onreadystatechange"in document.createElement("SCRIPT")?function(b){var c=document.createElement("SCRIPT"); -c.onreadystatechange=function(){c.onreadystatechange=null;c.parentNode.removeChild(c);c=null;b();b=null};document.documentElement.appendChild(c)}:function(b){ba.setTimeout(b,0)}}var mi=ve;function pi(b,c){this.f={};this.a=[];this.b=0;var d=arguments.length;if(1<d){if(d%2)throw Error("Uneven number of arguments");for(var e=0;e<d;e+=2)this.set(arguments[e],arguments[e+1])}else if(b){if(b instanceof pi)e=b.P(),d=b.sc();else{var d=[],f=0;for(e in b)d[f++]=e;e=d;d=Lb(b)}for(f=0;f<e.length;f++)this.set(e[f],d[f])}}l=pi.prototype;l.qc=function(){return this.b};l.sc=function(){qi(this);for(var b=[],c=0;c<this.a.length;c++)b.push(this.f[this.a[c]]);return b};l.P=function(){qi(this);return this.a.concat()}; -l.La=function(){return 0==this.b};l.clear=function(){this.f={};this.b=this.a.length=0};l.remove=function(b){return ri(this.f,b)?(delete this.f[b],this.b--,this.a.length>2*this.b&&qi(this),!0):!1};function qi(b){if(b.b!=b.a.length){for(var c=0,d=0;c<b.a.length;){var e=b.a[c];ri(b.f,e)&&(b.a[d++]=e);c++}b.a.length=d}if(b.b!=b.a.length){for(var f={},d=c=0;c<b.a.length;)e=b.a[c],ri(f,e)||(b.a[d++]=e,f[e]=1),c++;b.a.length=d}}l.get=function(b,c){return ri(this.f,b)?this.f[b]:c}; -l.set=function(b,c){ri(this.f,b)||(this.b++,this.a.push(b));this.f[b]=c};l.forEach=function(b,c){for(var d=this.P(),e=0;e<d.length;e++){var f=d[e],g=this.get(f);b.call(c,g,f,this)}};l.clone=function(){return new pi(this)};function ri(b,c){return Object.prototype.hasOwnProperty.call(b,c)};function si(){this.a=wa()}new si;si.prototype.set=function(b){this.a=b};si.prototype.reset=function(){this.set(wa())};si.prototype.get=function(){return this.a};function ti(b){$c.call(this);this.a=b||window;this.f=D(this.a,"resize",this.c,!1,this);this.b=Gg(this.a||window)}y(ti,$c);ti.prototype.Y=function(){ti.ca.Y.call(this);this.f&&(Wc(this.f),this.f=null);this.b=this.a=null};ti.prototype.c=function(){var b=Gg(this.a||window),c=this.b;b==c||b&&c&&b.width==c.width&&b.height==c.height||(this.b=b,this.s("resize"))};function ui(b,c,d,e,f){if(!(Yb||Zb||ac&&ic("525")))return!0;if(bc&&f)return vi(b);if(f&&!e)return!1;ja(c)&&(c=wi(c));if(!d&&(17==c||18==c||bc&&91==c))return!1;if((ac||Zb)&&e&&d)switch(b){case 220:case 219:case 221:case 192:case 186:case 189:case 187:case 188:case 190:case 191:case 192:case 222:return!1}if(Yb&&e&&c==b)return!1;switch(b){case 13:return!0;case 27:return!(ac||Zb)}return vi(b)} -function vi(b){if(48<=b&&57>=b||96<=b&&106>=b||65<=b&&90>=b||(ac||Zb)&&0==b)return!0;switch(b){case 32:case 43:case 63:case 64:case 107:case 109:case 110:case 111:case 186:case 59:case 189:case 187:case 61:case 188:case 190:case 191:case 192:case 222:case 219:case 220:case 221:return!0;default:return!1}}function wi(b){if($b)b=xi(b);else if(bc&&ac)a:switch(b){case 93:b=91;break a}return b} -function xi(b){switch(b){case 61:return 187;case 59:return 186;case 173:return 189;case 224:return 91;case 0:return 224;default:return b}};function yi(b,c){$c.call(this);b&&zi(this,b,c)}y(yi,$c);l=yi.prototype;l.vd=null;l.me=null;l.rf=null;l.ne=null;l.jb=-1;l.Zb=-1;l.cf=!1; -var Ai={3:13,12:144,63232:38,63233:40,63234:37,63235:39,63236:112,63237:113,63238:114,63239:115,63240:116,63241:117,63242:118,63243:119,63244:120,63245:121,63246:122,63247:123,63248:44,63272:46,63273:36,63275:35,63276:33,63277:34,63289:144,63302:45},Bi={Up:38,Down:40,Left:37,Right:39,Enter:13,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,"U+007F":46,Home:36,End:35,PageUp:33,PageDown:34,Insert:45},Ci=Yb||Zb||ac&&ic("525"),Di=bc&&$b; -yi.prototype.a=function(b){if(ac||Zb)if(17==this.jb&&!b.o||18==this.jb&&!b.f||bc&&91==this.jb&&!b.B)this.Zb=this.jb=-1;-1==this.jb&&(b.o&&17!=b.i?this.jb=17:b.f&&18!=b.i?this.jb=18:b.B&&91!=b.i&&(this.jb=91));Ci&&!ui(b.i,this.jb,b.c,b.o,b.f)?this.handleEvent(b):(this.Zb=wi(b.i),Di&&(this.cf=b.f))};yi.prototype.f=function(b){this.Zb=this.jb=-1;this.cf=b.f}; -yi.prototype.handleEvent=function(b){var c=b.a,d,e,f=c.altKey;Yb&&"keypress"==b.type?(d=this.Zb,e=13!=d&&27!=d?c.keyCode:0):(ac||Zb)&&"keypress"==b.type?(d=this.Zb,e=0<=c.charCode&&63232>c.charCode&&vi(d)?c.charCode:0):Xb&&!ac?(d=this.Zb,e=vi(d)?c.keyCode:0):(d=c.keyCode||this.Zb,e=c.charCode||0,Di&&(f=this.cf),bc&&63==e&&224==d&&(d=191));var g=d=wi(d),h=c.keyIdentifier;d?63232<=d&&d in Ai?g=Ai[d]:25==d&&b.c&&(g=9):h&&h in Bi&&(g=Bi[h]);this.jb=g;b=new Ei(g,e,0,c);b.f=f;this.s(b)}; -function zi(b,c,d){b.ne&&Fi(b);b.vd=c;b.me=D(b.vd,"keypress",b,d);b.rf=D(b.vd,"keydown",b.a,d,b);b.ne=D(b.vd,"keyup",b.f,d,b)}function Fi(b){b.me&&(Wc(b.me),Wc(b.rf),Wc(b.ne),b.me=null,b.rf=null,b.ne=null);b.vd=null;b.jb=-1;b.Zb=-1}yi.prototype.Y=function(){yi.ca.Y.call(this);Fi(this)};function Ei(b,c,d,e){xc.call(this,e);this.type="key";this.i=b;this.G=c}y(Ei,xc);function Gi(b,c){$c.call(this);var d=this.a=b;(d=oa(d)&&1==d.nodeType?this.a:this.a?this.a.body:null)&&$g(d,"direction");this.f=D(this.a,$b?"DOMMouseScroll":"mousewheel",this,c)}y(Gi,$c); -Gi.prototype.handleEvent=function(b){var c=0,d=0;b=b.a;if("mousewheel"==b.type){c=1;if(Yb||ac&&(cc||ic("532.0")))c=40;d=Hi(-b.wheelDelta,c);c=ca(b.wheelDeltaX)?Hi(-b.wheelDeltaY,c):d}else d=b.detail,100<d?d=3:-100>d&&(d=-3),ca(b.axis)&&b.axis===b.HORIZONTAL_AXIS||(c=d);ja(this.b)&&(c=Math.min(Math.max(c,-this.b),this.b));d=new Ii(d,b,0,c);this.s(d)};function Hi(b,c){return ac&&(bc||dc)&&0!=b%c?b:b/c}Gi.prototype.Y=function(){Gi.ca.Y.call(this);Wc(this.f);this.f=null}; -function Ii(b,c,d,e){xc.call(this,c);this.type="mousewheel";this.detail=b;this.v=e}y(Ii,xc);function Ji(b,c,d){tc.call(this,b);this.a=c;b=d?d:{};this.buttons=Ki(b);this.pressure=Li(b,this.buttons);this.bubbles="bubbles"in b?b.bubbles:!1;this.cancelable="cancelable"in b?b.cancelable:!1;this.view="view"in b?b.view:null;this.detail="detail"in b?b.detail:null;this.screenX="screenX"in b?b.screenX:0;this.screenY="screenY"in b?b.screenY:0;this.clientX="clientX"in b?b.clientX:0;this.clientY="clientY"in b?b.clientY:0;this.button="button"in b?b.button:0;this.relatedTarget="relatedTarget"in b?b.relatedTarget: -null;this.pointerId="pointerId"in b?b.pointerId:0;this.width="width"in b?b.width:0;this.height="height"in b?b.height:0;this.pointerType="pointerType"in b?b.pointerType:"";this.isPrimary="isPrimary"in b?b.isPrimary:!1;c.preventDefault&&(this.preventDefault=function(){c.preventDefault()})}y(Ji,tc);function Ki(b){if(b.buttons||Mi)b=b.buttons;else switch(b.which){case 1:b=1;break;case 2:b=4;break;case 3:b=2;break;default:b=0}return b} -function Li(b,c){var d=0;b.pressure?d=b.pressure:d=c?.5:0;return d}var Mi=!1;try{Mi=1===(new MouseEvent("click",{buttons:1})).buttons}catch(b){};function Ni(b,c){var d=document.createElement("CANVAS");b&&(d.width=b);c&&(d.height=c);return d.getContext("2d")} -var Oi=function(){var b;return function(){if(void 0===b)if(ba.getComputedStyle){var c=document.createElement("P"),d,e={webkitTransform:"-webkit-transform",OTransform:"-o-transform",msTransform:"-ms-transform",MozTransform:"-moz-transform",transform:"transform"};document.body.appendChild(c);for(var f in e)f in c.style&&(c.style[f]="translate(1px,1px)",d=ba.getComputedStyle(c).getPropertyValue(e[f]));Mg(c);b=d&&"none"!==d}else b=!1;return b}}(),Pi=function(){var b;return function(){if(void 0===b)if(ba.getComputedStyle){var c= -document.createElement("P"),d,e={webkitTransform:"-webkit-transform",OTransform:"-o-transform",msTransform:"-ms-transform",MozTransform:"-moz-transform",transform:"transform"};document.body.appendChild(c);for(var f in e)f in c.style&&(c.style[f]="translate3d(1px,1px,1px)",d=ba.getComputedStyle(c).getPropertyValue(e[f]));Mg(c);b=d&&"none"!==d}else b=!1;return b}}(); -function Qi(b,c){var d=b.style;d.WebkitTransform=c;d.MozTransform=c;d.a=c;d.msTransform=c;d.transform=c;Yb&&ic("9.0")&&(b.style.transformOrigin="0 0")}function Ri(b,c){var d;if(Pi()){var e=Array(16);for(d=0;16>d;++d)e[d]=c[d].toFixed(6);Qi(b,"matrix3d("+e.join(",")+")")}else if(Oi()){var e=[c[0],c[1],c[4],c[5],c[12],c[13]],f=Array(6);for(d=0;6>d;++d)f[d]=e[d].toFixed(6);Qi(b,"matrix("+f.join(",")+")")}else b.style.left=Math.round(c[12])+"px",b.style.top=Math.round(c[13])+"px"};var Si=["experimental-webgl","webgl","webkit-3d","moz-webgl"];function Ti(b,c){var d,e,f=Si.length;for(e=0;e<f;++e)try{if(d=b.getContext(Si[e],c))return d}catch(g){}return null};var Ui,Vi=ba.devicePixelRatio||1,Wi=!1,Xi=function(){if(!("HTMLCanvasElement"in ba))return!1;try{var b=Ni();return b?(void 0!==b.setLineDash&&(Wi=!0),!0):!1}catch(c){return!1}}(),Yi="DeviceOrientationEvent"in ba,Zi="geolocation"in ba.navigator,$i="ontouchstart"in ba,aj="PointerEvent"in ba,bj=!!ba.navigator.msPointerEnabled,cj=!1,dj,ej=[]; -if("WebGLRenderingContext"in ba)try{var fj=Ti(document.createElement("CANVAS"),{failIfMajorPerformanceCaveat:!0});fj&&(cj=!0,dj=fj.getParameter(fj.MAX_TEXTURE_SIZE),ej=fj.getSupportedExtensions())}catch(b){}Ui=cj;ya=ej;xa=dj;function gj(b,c){this.a=b;this.g=c};function hj(b){gj.call(this,b,{mousedown:this.il,mousemove:this.jl,mouseup:this.ml,mouseover:this.ll,mouseout:this.kl});this.f=b.f;this.b=[]}y(hj,gj);function ij(b,c){for(var d=b.b,e=c.clientX,f=c.clientY,g=0,h=d.length,k;g<h&&(k=d[g]);g++){var m=Math.abs(f-k[1]);if(25>=Math.abs(e-k[0])&&25>=m)return!0}return!1}function jj(b){var c=kj(b,b.a),d=c.preventDefault;c.preventDefault=function(){b.preventDefault();d()};c.pointerId=1;c.isPrimary=!0;c.pointerType="mouse";return c}l=hj.prototype; -l.il=function(b){if(!ij(this,b)){(1).toString()in this.f&&this.cancel(b);var c=jj(b);this.f[(1).toString()]=b;lj(this.a,mj,c,b)}};l.jl=function(b){if(!ij(this,b)){var c=jj(b);lj(this.a,nj,c,b)}};l.ml=function(b){if(!ij(this,b)){var c=this.f[(1).toString()];c&&c.button===b.button&&(c=jj(b),lj(this.a,oj,c,b),delete this.f[(1).toString()])}};l.ll=function(b){if(!ij(this,b)){var c=jj(b);pj(this.a,c,b)}};l.kl=function(b){if(!ij(this,b)){var c=jj(b);qj(this.a,c,b)}}; -l.cancel=function(b){var c=jj(b);this.a.cancel(c,b);delete this.f[(1).toString()]};function rj(b){gj.call(this,b,{MSPointerDown:this.rl,MSPointerMove:this.sl,MSPointerUp:this.vl,MSPointerOut:this.tl,MSPointerOver:this.ul,MSPointerCancel:this.ql,MSGotPointerCapture:this.ol,MSLostPointerCapture:this.pl});this.f=b.f;this.b=["","unavailable","touch","pen","mouse"]}y(rj,gj);function sj(b,c){var d=c;ja(c.a.pointerType)&&(d=kj(c,c.a),d.pointerType=b.b[c.a.pointerType]);return d}l=rj.prototype;l.rl=function(b){this.f[b.a.pointerId.toString()]=b;var c=sj(this,b);lj(this.a,mj,c,b)}; -l.sl=function(b){var c=sj(this,b);lj(this.a,nj,c,b)};l.vl=function(b){var c=sj(this,b);lj(this.a,oj,c,b);delete this.f[b.a.pointerId.toString()]};l.tl=function(b){var c=sj(this,b);qj(this.a,c,b)};l.ul=function(b){var c=sj(this,b);pj(this.a,c,b)};l.ql=function(b){var c=sj(this,b);this.a.cancel(c,b);delete this.f[b.a.pointerId.toString()]};l.pl=function(b){this.a.s(new Ji("lostpointercapture",b,b.a))};l.ol=function(b){this.a.s(new Ji("gotpointercapture",b,b.a))};function tj(b){gj.call(this,b,{pointerdown:this.Vn,pointermove:this.Wn,pointerup:this.Zn,pointerout:this.Xn,pointerover:this.Yn,pointercancel:this.Un,gotpointercapture:this.vk,lostpointercapture:this.hl})}y(tj,gj);l=tj.prototype;l.Vn=function(b){uj(this.a,b)};l.Wn=function(b){uj(this.a,b)};l.Zn=function(b){uj(this.a,b)};l.Xn=function(b){uj(this.a,b)};l.Yn=function(b){uj(this.a,b)};l.Un=function(b){uj(this.a,b)};l.hl=function(b){uj(this.a,b)};l.vk=function(b){uj(this.a,b)};function vj(b,c){gj.call(this,b,{touchstart:this.ap,touchmove:this.$o,touchend:this.Zo,touchcancel:this.Yo});this.f=b.f;this.j=c;this.b=void 0;this.i=0;this.c=void 0}y(vj,gj);l=vj.prototype;l.Sh=function(){this.i=0;this.c=void 0}; -function wj(b,c,d){c=kj(c,d);c.pointerId=d.identifier+2;c.bubbles=!0;c.cancelable=!0;c.detail=b.i;c.button=0;c.buttons=1;c.width=d.webkitRadiusX||d.radiusX||0;c.height=d.webkitRadiusY||d.radiusY||0;c.pressure=d.webkitForce||d.force||.5;c.isPrimary=b.b===d.identifier;c.pointerType="touch";c.clientX=d.clientX;c.clientY=d.clientY;c.screenX=d.screenX;c.screenY=d.screenY;return c} -function xj(b,c,d){function e(){c.preventDefault()}var f=Array.prototype.slice.call(c.a.changedTouches),g=f.length,h,k;for(h=0;h<g;++h)k=wj(b,c,f[h]),k.preventDefault=e,d.call(b,c,k)} -l.ap=function(b){var c=b.a.touches,d=Object.keys(this.f),e=d.length;if(e>=c.length){var f=[],g,h,k;for(g=0;g<e;++g){h=d[g];k=this.f[h];var m;if(!(m=1==h))a:{m=c.length;for(var n=void 0,p=0;p<m;p++)if(n=c[p],n.identifier===h-2){m=!0;break a}m=!1}m||f.push(k.wc)}for(g=0;g<f.length;++g)this.ef(b,f[g])}c=Kb(this.f);if(0===c||1===c&&(1).toString()in this.f)this.b=b.a.changedTouches[0].identifier,void 0!==this.c&&ba.clearTimeout(this.c);yj(this,b);this.i++;xj(this,b,this.Qn)}; -l.Qn=function(b,c){this.f[c.pointerId]={target:c.target,wc:c,Ah:c.target};var d=this.a;c.bubbles=!0;lj(d,Aj,c,b);d=this.a;c.bubbles=!1;lj(d,Bj,c,b);lj(this.a,mj,c,b)};l.$o=function(b){b.preventDefault();xj(this,b,this.nl)};l.nl=function(b,c){var d=this.f[c.pointerId];if(d){var e=d.wc,f=d.Ah;lj(this.a,nj,c,b);e&&f!==c.target&&(e.relatedTarget=c.target,c.relatedTarget=f,e.target=f,c.target?(qj(this.a,e,b),pj(this.a,c,b)):(c.target=f,c.relatedTarget=null,this.ef(b,c)));d.wc=c;d.Ah=c.target}}; -l.Zo=function(b){yj(this,b);xj(this,b,this.bp)};l.bp=function(b,c){lj(this.a,oj,c,b);this.a.wc(c,b);var d=this.a;c.bubbles=!1;lj(d,Cj,c,b);delete this.f[c.pointerId];c.isPrimary&&(this.b=void 0,this.c=ba.setTimeout(ua(this.Sh,this),200))};l.Yo=function(b){xj(this,b,this.ef)};l.ef=function(b,c){this.a.cancel(c,b);this.a.wc(c,b);var d=this.a;c.bubbles=!1;lj(d,Cj,c,b);delete this.f[c.pointerId];c.isPrimary&&(this.b=void 0,this.c=ba.setTimeout(ua(this.Sh,this),200))}; -function yj(b,c){var d=b.j.b,e=c.a.changedTouches[0];if(b.b===e.identifier){var f=[e.clientX,e.clientY];d.push(f);ba.setTimeout(function(){hb(d,f)},2500)}};function Dj(b){$c.call(this);this.c=b;this.f={};this.b={};this.a=[];aj?Ej(this,new tj(this)):bj?Ej(this,new rj(this)):(b=new hj(this),Ej(this,b),$i&&Ej(this,new vj(this,b)));b=this.a.length;for(var c,d=0;d<b;d++)c=this.a[d],Fj(this,Object.keys(c.g))}y(Dj,$c);function Ej(b,c){var d=Object.keys(c.g);d&&(d.forEach(function(b){var d=c.g[b];d&&(this.b[b]=ua(d,c))},b),b.a.push(c))}Dj.prototype.g=function(b){var c=this.b[b.type];c&&c(b)}; -function Fj(b,c){c.forEach(function(b){D(this.c,b,this.g,!1,this)},b)}function Gj(b,c){c.forEach(function(b){Vc(this.c,b,this.g,!1,this)},b)}function kj(b,c){for(var d={},e,f=0,g=Hj.length;f<g;f++)e=Hj[f][0],d[e]=b[e]||c[e]||Hj[f][1];return d}Dj.prototype.wc=function(b,c){b.bubbles=!0;lj(this,Ij,b,c)};Dj.prototype.cancel=function(b,c){lj(this,Jj,b,c)};function qj(b,c,d){b.wc(c,d);var e=c.relatedTarget;e&&Pg(c.target,e)||(c.bubbles=!1,lj(b,Cj,c,d))} -function pj(b,c,d){c.bubbles=!0;lj(b,Aj,c,d);var e=c.relatedTarget;e&&Pg(c.target,e)||(c.bubbles=!1,lj(b,Bj,c,d))}function lj(b,c,d,e){b.s(new Ji(c,e,d))}function uj(b,c){b.s(new Ji(c.type,c,c.a))}Dj.prototype.Y=function(){for(var b=this.a.length,c,d=0;d<b;d++)c=this.a[d],Gj(this,Object.keys(c.g));Dj.ca.Y.call(this)}; -var nj="pointermove",mj="pointerdown",oj="pointerup",Aj="pointerover",Ij="pointerout",Bj="pointerenter",Cj="pointerleave",Jj="pointercancel",Hj=[["bubbles",!1],["cancelable",!1],["view",null],["detail",null],["screenX",0],["screenY",0],["clientX",0],["clientY",0],["ctrlKey",!1],["altKey",!1],["shiftKey",!1],["metaKey",!1],["button",0],["relatedTarget",null],["buttons",0],["pointerId",0],["width",0],["height",0],["pressure",0],["tiltX",0],["tiltY",0],["pointerType",""],["hwTimestamp",0],["isPrimary", -!1],["type",""],["target",null],["currentTarget",null],["which",0]];function Kj(b,c,d,e,f){nh.call(this,b,c,f);this.a=d;this.originalEvent=d.a;this.pixel=c.$d(this.originalEvent);this.coordinate=c.Ga(this.pixel);this.dragging=void 0!==e?e:!1}y(Kj,nh);Kj.prototype.preventDefault=function(){Kj.ca.preventDefault.call(this);this.a.preventDefault()};Kj.prototype.b=function(){Kj.ca.b.call(this);this.a.b()};function Lj(b,c,d,e,f){Kj.call(this,b,c,d.a,e,f);this.f=d}y(Lj,Kj); -function Mj(b){$c.call(this);this.b=b;this.i=0;this.j=!1;this.f=this.l=this.c=null;b=this.b.a;this.B=0;this.G={};this.g=new Dj(b);this.a=null;this.l=D(this.g,mj,this.Rk,!1,this);this.o=D(this.g,nj,this.xo,!1,this)}y(Mj,$c);function Nj(b,c){var d;d=new Lj(Oj,b.b,c);b.s(d);0!==b.i?(ba.clearTimeout(b.i),b.i=0,d=new Lj(Pj,b.b,c),b.s(d)):b.i=ba.setTimeout(ua(function(){this.i=0;var b=new Lj(Qj,this.b,c);this.s(b)},b),250)} -function Rj(b,c){c.type==Sj||c.type==Tj?delete b.G[c.pointerId]:c.type==Uj&&(b.G[c.pointerId]=!0);b.B=Kb(b.G)}l=Mj.prototype;l.Lg=function(b){Rj(this,b);var c=new Lj(Sj,this.b,b);this.s(c);!this.j&&0===b.button&&Nj(this,this.f);0===this.B&&(this.c.forEach(Wc),this.c=null,this.j=!1,this.f=null,sc(this.a),this.a=null)}; -l.Rk=function(b){Rj(this,b);var c=new Lj(Uj,this.b,b);this.s(c);this.f=b;this.c||(this.a=new Dj(document),this.c=[D(this.a,Vj,this.Il,!1,this),D(this.a,Sj,this.Lg,!1,this),D(this.g,Tj,this.Lg,!1,this)])};l.Il=function(b){if(b.clientX!=this.f.clientX||b.clientY!=this.f.clientY){this.j=!0;var c=new Lj(Wj,this.b,b,this.j);this.s(c)}b.preventDefault()};l.xo=function(b){this.s(new Lj(b.type,this.b,b,!(!this.f||b.clientX==this.f.clientX&&b.clientY==this.f.clientY)))}; -l.Y=function(){this.o&&(Wc(this.o),this.o=null);this.l&&(Wc(this.l),this.l=null);this.c&&(this.c.forEach(Wc),this.c=null);this.a&&(sc(this.a),this.a=null);this.g&&(sc(this.g),this.g=null);Mj.ca.Y.call(this)};var Qj="singleclick",Oj="click",Pj="dblclick",Wj="pointerdrag",Vj="pointermove",Uj="pointerdown",Sj="pointerup",Tj="pointercancel",Xj={up:Qj,jp:Oj,kp:Pj,np:Wj,qp:Vj,mp:Uj,tp:Sj,sp:"pointerover",rp:"pointerout",op:"pointerenter",pp:"pointerleave",lp:Tj};function Yj(b){gd.call(this);var c=Tb(b);c.opacity=void 0!==b.opacity?b.opacity:1;c.visible=void 0!==b.visible?b.visible:!0;c.zIndex=void 0!==b.zIndex?b.zIndex:0;c.maxResolution=void 0!==b.maxResolution?b.maxResolution:Infinity;c.minResolution=void 0!==b.minResolution?b.minResolution:0;this.I(c)}y(Yj,gd); -function Zj(b){var c=b.Rb(),d=b.pf(),e=b.rb(),f=b.J(),g=b.Sb(),h=b.Nb(),k=b.Ob();return{layer:b,opacity:Sa(c,0,1),O:d,visible:e,Bb:!0,extent:f,zIndex:g,maxResolution:h,minResolution:Math.max(k,0)}}l=Yj.prototype;l.J=function(){return this.get("extent")};l.Nb=function(){return this.get("maxResolution")};l.Ob=function(){return this.get("minResolution")};l.Rb=function(){return this.get("opacity")};l.rb=function(){return this.get("visible")};l.Sb=function(){return this.get("zIndex")}; -l.cc=function(b){this.set("extent",b)};l.kc=function(b){this.set("maxResolution",b)};l.lc=function(b){this.set("minResolution",b)};l.dc=function(b){this.set("opacity",b)};l.ec=function(b){this.set("visible",b)};l.fc=function(b){this.set("zIndex",b)};function ak(){};function bk(b,c,d,e,f,g){tc.call(this,b,c);this.vectorContext=d;this.frameState=e;this.context=f;this.glContext=g}y(bk,tc);function ck(b){var c=Tb(b);delete c.source;Yj.call(this,c);this.i=this.B=this.o=null;b.map&&this.setMap(b.map);D(this,id("source"),this.Xk,!1,this);this.zc(b.source?b.source:null)}y(ck,Yj);function dk(b,c){return b.visible&&c>=b.minResolution&&c<b.maxResolution}l=ck.prototype;l.of=function(b){b=b?b:[];b.push(Zj(this));return b};l.ea=function(){return this.get("source")||null};l.pf=function(){var b=this.ea();return b?b.B:"undefined"};l.zm=function(){this.u()}; -l.Xk=function(){this.i&&(Wc(this.i),this.i=null);var b=this.ea();b&&(this.i=D(b,"change",this.zm,!1,this));this.u()};l.setMap=function(b){Wc(this.o);this.o=null;b||this.u();Wc(this.B);this.B=null;b&&(this.o=D(b,"precompose",function(b){var d=Zj(this);d.Bb=!1;d.zIndex=Infinity;b.frameState.layerStatesArray.push(d);b.frameState.layerStates[w(this)]=d},!1,this),this.B=D(this,"change",b.render,!1,b),this.u())};l.zc=function(b){this.set("source",b)};function ek(b,c,d,e,f){$c.call(this);this.i=f;this.extent=b;this.b=d;this.resolution=c;this.state=e}y(ek,$c);function fk(b){b.s("change")}ek.prototype.J=function(){return this.extent};ek.prototype.$=function(){return this.resolution};function gk(b,c,d,e,f,g,h,k){Fd(b);0===c&&0===d||Id(b,c,d);1==e&&1==f||Jd(b,e,f);0!==g&&Kd(b,g);0===h&&0===k||Id(b,h,k);return b}function hk(b,c){return b[0]==c[0]&&b[1]==c[1]&&b[4]==c[4]&&b[5]==c[5]&&b[12]==c[12]&&b[13]==c[13]}function ik(b,c,d){var e=b[1],f=b[5],g=b[13],h=c[0];c=c[1];d[0]=b[0]*h+b[4]*c+b[12];d[1]=e*h+f*c+g;return d};function jk(b){dd.call(this);this.a=b}y(jk,dd);l=jk.prototype;l.ab=za;l.vc=function(b,c,d,e){b=b.slice();ik(c.pixelToCoordinateMatrix,b,b);if(this.ab(b,c,te,this))return d.call(e,this.a)};l.xe=se;l.cd=function(b,c,d){return function(e,f){return Oh(b,c,e,f,function(b){d[e]||(d[e]={});d[e][b.a.toString()]=b})}};l.Dm=function(b){2===b.target.state&&kk(this)};function lk(b,c){var d=c.state;2!=d&&3!=d&&D(c,"change",b.Dm,!1,b);0==d&&(c.load(),d=c.state);return 2==d} -function kk(b){var c=b.a;c.rb()&&"ready"==c.pf()&&b.u()}function mk(b,c){c.qh()&&b.postRenderFunctions.push(va(function(b,c,f){c=w(b).toString();b.rh(f.viewState.projection,f.usedTiles[c])},c))}function nk(b,c){if(c){var d,e,f;e=0;for(f=c.length;e<f;++e)d=c[e],b[w(d).toString()]=d}}function ok(b,c){var d=c.U;void 0!==d&&(ia(d)?b.logos[d]="":oa(d)&&(b.logos[d.src]=d.href))} -function pk(b,c,d,e){c=w(c).toString();d=d.toString();c in b?d in b[c]?(b=b[c][d],e.a<b.a&&(b.a=e.a),e.c>b.c&&(b.c=e.c),e.f<b.f&&(b.f=e.f),e.b>b.b&&(b.b=e.b)):b[c][d]=e:(b[c]={},b[c][d]=e)}function qk(b,c,d){return[c*(Math.round(b[0]/c)+d[0]%2/2),c*(Math.round(b[1]/c)+d[1]%2/2)]} -function rk(b,c,d,e,f,g,h,k,m,n){var p=w(c).toString();p in b.wantedTiles||(b.wantedTiles[p]={});var q=b.wantedTiles[p];b=b.tileQueue;var r=d.minZoom,t,x,z,A,B,v;for(v=h;v>=r;--v)for(x=Dh(d,g,v,x),z=d.$(v),A=x.a;A<=x.c;++A)for(B=x.f;B<=x.b;++B)h-v<=k?(t=c.Pb(v,A,B,e,f),0==t.state&&(q[eg(t.a)]=!0,t.$a()in b.b||b.c([t,p,Hh(d,t.a),z])),void 0!==m&&m.call(n,t)):c.Yf(v,A,B,f)};function sk(b){this.B=b.opacity;this.C=b.rotateWithView;this.G=b.rotation;this.j=b.scale;this.D=b.snapToPixel}l=sk.prototype;l.Be=function(){return this.B};l.de=function(){return this.C};l.Ce=function(){return this.G};l.De=function(){return this.j};l.ee=function(){return this.D};l.Ee=function(b){this.B=b};l.Fe=function(b){this.G=b};l.Ge=function(b){this.j=b};function tk(b){b=b||{};this.g=void 0!==b.anchor?b.anchor:[.5,.5];this.c=null;this.f=void 0!==b.anchorOrigin?b.anchorOrigin:"top-left";this.l=void 0!==b.anchorXUnits?b.anchorXUnits:"fraction";this.o=void 0!==b.anchorYUnits?b.anchorYUnits:"fraction";var c=void 0!==b.crossOrigin?b.crossOrigin:null,d=void 0!==b.img?b.img:null,e=void 0!==b.imgSize?b.imgSize:null,f=b.src;void 0!==f&&0!==f.length||!d||(f=d.src||w(d).toString());var g=void 0!==b.src?0:2,h=uk.Yb(),k=h.get(f,c);k||(k=new vk(d,f,e,c,g),h.set(f, -c,k));this.a=k;this.O=void 0!==b.offset?b.offset:[0,0];this.b=void 0!==b.offsetOrigin?b.offsetOrigin:"top-left";this.i=null;this.v=void 0!==b.size?b.size:null;sk.call(this,{opacity:void 0!==b.opacity?b.opacity:1,rotation:void 0!==b.rotation?b.rotation:0,scale:void 0!==b.scale?b.scale:1,snapToPixel:void 0!==b.snapToPixel?b.snapToPixel:!0,rotateWithView:void 0!==b.rotateWithView?b.rotateWithView:!1})}y(tk,sk);l=tk.prototype; -l.Xb=function(){if(this.c)return this.c;var b=this.g,c=this.Cb();if("fraction"==this.l||"fraction"==this.o){if(!c)return null;b=this.g.slice();"fraction"==this.l&&(b[0]*=c[0]);"fraction"==this.o&&(b[1]*=c[1])}if("top-left"!=this.f){if(!c)return null;b===this.g&&(b=this.g.slice());if("top-right"==this.f||"bottom-right"==this.f)b[0]=-b[0]+c[0];if("bottom-left"==this.f||"bottom-right"==this.f)b[1]=-b[1]+c[1]}return this.c=b};l.gc=function(){return this.a.a};l.rd=function(){return this.a.b};l.Cd=function(){return this.a.f}; -l.Ae=function(){var b=this.a;if(!b.g)if(b.l){var c=b.b[0],d=b.b[1],e=Ni(c,d);e.fillRect(0,0,c,d);b.g=e.canvas}else b.g=b.a;return b.g};l.Da=function(){if(this.i)return this.i;var b=this.O;if("top-left"!=this.b){var c=this.Cb(),d=this.a.b;if(!c||!d)return null;b=b.slice();if("top-right"==this.b||"bottom-right"==this.b)b[0]=d[0]-c[0]-b[0];if("bottom-left"==this.b||"bottom-right"==this.b)b[1]=d[1]-c[1]-b[1]}return this.i=b};l.hn=function(){return this.a.i};l.Cb=function(){return this.v?this.v:this.a.b}; -l.tf=function(b,c){return D(this.a,"change",b,!1,c)};l.load=function(){this.a.load()};l.Xf=function(b,c){Vc(this.a,"change",b,!1,c)};function vk(b,c,d,e,f){$c.call(this);this.g=null;this.a=b?b:new Image;null!==e&&(this.a.crossOrigin=e);this.c=null;this.f=f;this.b=d;this.i=c;this.l=!1;2==this.f&&wk(this)}y(vk,$c);function wk(b){var c=Ni(1,1);try{c.drawImage(b.a,0,0),c.getImageData(0,0,1,1)}catch(d){b.l=!0}}vk.prototype.j=function(){this.f=3;this.c.forEach(Wc);this.c=null;this.s("change")}; -vk.prototype.o=function(){this.f=2;this.b=[this.a.width,this.a.height];this.c.forEach(Wc);this.c=null;wk(this);this.s("change")};vk.prototype.load=function(){if(0==this.f){this.f=1;this.c=[Uc(this.a,"error",this.j,!1,this),Uc(this.a,"load",this.o,!1,this)];try{this.a.src=this.i}catch(b){this.j()}}};function uk(){this.a={};this.f=0}ea(uk);uk.prototype.clear=function(){this.a={};this.f=0};uk.prototype.get=function(b,c){var d=c+":"+b;return d in this.a?this.a[d]:null}; -uk.prototype.set=function(b,c,d){this.a[c+":"+b]=d;++this.f};function xk(b,c){oc.call(this);this.i=c;this.c={};this.G={}}y(xk,oc);function yk(b){var c=b.viewState,d=b.coordinateToPixelMatrix;gk(d,b.size[0]/2,b.size[1]/2,1/c.resolution,-1/c.resolution,-c.rotation,-c.center[0],-c.center[1]);Hd(d,b.pixelToCoordinateMatrix)}l=xk.prototype;l.Y=function(){Ib(this.c,sc);xk.ca.Y.call(this)}; -function zk(){var b=uk.Yb();if(32<b.f){var c=0,d,e;for(d in b.a){e=b.a[d];var f;if(f=0===(c++&3))Bc(e)?e=cd(e,void 0,void 0):(e=Pc(e),e=!!e&&Jc(e,void 0,void 0)),f=!e;f&&(delete b.a[d],--b.f)}}} -l.Bf=function(b,c,d,e,f,g){function h(b){var c=w(b).toString();if(!(c in p))return p[c]=!0,d.call(e,b,null)}var k,m=c.viewState,n=m.resolution,p={},q=m.projection,m=b;if(q.b){var q=q.J(),r=je(q),t=b[0];if(t<q[0]||t>q[2])m=[t+r*Math.ceil((q[0]-t)/r),b[1]]}q=c.layerStatesArray;for(r=q.length-1;0<=r;--r){var t=q[r],x=t.layer;if(dk(t,n)&&f.call(g,x)){var z=Ak(this,x);x.ea()&&(k=z.ab(xh(x.ea())?m:b,c,t.Bb?d:h,e));if(k)return k}}}; -l.lh=function(b,c,d,e,f,g){var h,k=c.viewState.resolution,m=c.layerStatesArray,n;for(n=m.length-1;0<=n;--n){h=m[n];var p=h.layer;if(dk(h,k)&&f.call(g,p)&&(h=Ak(this,p).vc(b,c,d,e)))return h}};l.mh=function(b,c,d,e){return void 0!==this.Bf(b,c,te,this,d,e)};function Ak(b,c){var d=w(c).toString();if(d in b.c)return b.c[d];var e=b.hf(c);b.c[d]=e;b.G[d]=D(e,"change",b.Hk,!1,b);return e}l.Hk=function(){this.i.render()};l.Ne=za; -l.Do=function(b,c){for(var d in this.c)if(!(c&&d in c.layerStates)){var e=d,f=this.c[e];delete this.c[e];Wc(this.G[e]);delete this.G[e];sc(f)}};function Bk(b,c){for(var d in b.c)if(!(d in c.layerStates)){c.postRenderFunctions.push(ua(b.Do,b));break}}function qb(b,c){return b.zIndex-c.zIndex};function Ck(b,c){this.o=b;this.i=c;this.a=[];this.f=[];this.b={}}Ck.prototype.clear=function(){this.a.length=0;this.f.length=0;Qb(this.b)};function Dk(b){var c=b.a,d=b.f,e=c[0];1==c.length?(c.length=0,d.length=0):(c[0]=c.pop(),d[0]=d.pop(),Ek(b,0));c=b.i(e);delete b.b[c];return e}Ck.prototype.c=function(b){var c=this.o(b);return Infinity!=c?(this.a.push(b),this.f.push(c),this.b[this.i(b)]=!0,Fk(this,0,this.a.length-1),!0):!1};Ck.prototype.qc=function(){return this.a.length}; -Ck.prototype.La=function(){return 0===this.a.length};function Ek(b,c){for(var d=b.a,e=b.f,f=d.length,g=d[c],h=e[c],k=c;c<f>>1;){var m=2*c+1,n=2*c+2,m=n<f&&e[n]<e[m]?n:m;d[c]=d[m];e[c]=e[m];c=m}d[c]=g;e[c]=h;Fk(b,k,c)}function Fk(b,c,d){var e=b.a;b=b.f;for(var f=e[d],g=b[d];d>c;){var h=d-1>>1;if(b[h]>g)e[d]=e[h],b[d]=b[h],d=h;else break}e[d]=f;b[d]=g} -function Gk(b){var c=b.o,d=b.a,e=b.f,f=0,g=d.length,h,k,m;for(k=0;k<g;++k)h=d[k],m=c(h),Infinity==m?delete b.b[b.i(h)]:(e[f]=m,d[f++]=h);d.length=f;e.length=f;for(c=(b.a.length>>1)-1;0<=c;c--)Ek(b,c)};function Hk(b,c){Ck.call(this,function(c){return b.apply(null,c)},function(b){return b[0].$a()});this.G=c;this.g=0;this.j={}}y(Hk,Ck);Hk.prototype.c=function(b){var c=Hk.ca.c.call(this,b);c&&D(b[0],"change",this.l,!1,this);return c};Hk.prototype.l=function(b){b=b.target;var c=b.state;if(2===c||3===c||4===c)Vc(b,"change",this.l,!1,this),b=b.$a(),b in this.j&&(delete this.j[b],--this.g),this.G()}; -function Ik(b,c,d){for(var e=0,f;b.g<c&&e<d&&0<b.qc();)f=Dk(b)[0],0===f.state&&(f.load(),b.j[f.$a()]=!0,++b.g,++e)};function Jk(b,c,d){this.c=b;this.b=c;this.i=d;this.a=[];this.f=this.g=0}function Kk(b,c){var d=b.c,e=b.f,f=b.b-e,g=Math.log(b.b/b.f)/b.c;return Yf({source:c,duration:g,easing:function(b){return e*(Math.exp(d*b*g)-1)/f}})};function Lk(b){gd.call(this);this.B=null;this.g(!0);this.handleEvent=b.handleEvent}y(Lk,gd);Lk.prototype.b=function(){return this.get("active")};Lk.prototype.i=function(){return this.B};Lk.prototype.g=function(b){this.set("active",b)};Lk.prototype.setMap=function(b){this.B=b};function Mk(b,c,d,e,f){if(void 0!==d){var g=c.Fa(),h=c.Ua();void 0!==g&&h&&f&&0<f&&(b.Na(Zf({rotation:g,duration:f,easing:Uf})),e&&b.Na(Yf({source:h,duration:f,easing:Uf})));c.rotate(d,e)}} -function Nk(b,c,d,e,f){var g=c.$();d=c.constrainResolution(g,d,0);Ok(b,c,d,e,f)}function Ok(b,c,d,e,f){if(d){var g=c.$(),h=c.Ua();void 0!==g&&h&&d!==g&&f&&0<f&&(b.Na($f({resolution:g,duration:f,easing:Uf})),e&&b.Na(Yf({source:h,duration:f,easing:Uf})));if(e){var k;b=c.Ua();f=c.$();void 0!==b&&void 0!==f&&(k=[e[0]-d*(e[0]-b[0])/f,e[1]-d*(e[1]-b[1])/f]);c.kb(k)}c.Ub(d)}};function Pk(b){b=b?b:{};this.a=b.delta?b.delta:1;Lk.call(this,{handleEvent:Qk});this.c=void 0!==b.duration?b.duration:250}y(Pk,Lk);function Qk(b){var c=!1,d=b.a;if(b.type==Pj){var c=b.map,e=b.coordinate,d=d.c?-this.a:this.a,f=c.aa();Nk(c,f,d,e,this.c);b.preventDefault();c=!0}return!c};function Rk(b){b=b.a;return b.f&&!b.l&&b.c}function Sk(b){return"pointermove"==b.type}function Tk(b){return b.type==Qj}function Uk(b){b=b.a;return!b.f&&!b.l&&!b.c}function Vk(b){b=b.a;return!b.f&&!b.l&&b.c}function Wk(b){b=b.a.target.tagName;return"INPUT"!==b&&"SELECT"!==b&&"TEXTAREA"!==b}function Xk(b){return"mouse"==b.f.pointerType};function Yk(b){b=b?b:{};Lk.call(this,{handleEvent:b.handleEvent?b.handleEvent:Zk});this.Cc=b.handleDownEvent?b.handleDownEvent:se;this.Yc=b.handleDragEvent?b.handleDragEvent:za;this.Xe=b.handleMoveEvent?b.handleMoveEvent:za;this.Ye=b.handleUpEvent?b.handleUpEvent:se;this.C=!1;this.fa={};this.j=[]}y(Yk,Lk);function $k(b){for(var c=b.length,d=0,e=0,f=0;f<c;f++)d+=b[f].clientX,e+=b[f].clientY;return[d/c,e/c]} -function Zk(b){if(!(b instanceof Lj))return!0;var c=!1,d=b.type;if(d===Uj||d===Wj||d===Sj)d=b.f,b.type==Sj?delete this.fa[d.pointerId]:b.type==Uj?this.fa[d.pointerId]=d:d.pointerId in this.fa&&(this.fa[d.pointerId]=d),this.j=Lb(this.fa);this.C&&(b.type==Wj?this.Yc(b):b.type==Sj&&(this.C=this.Ye(b)));b.type==Uj?(this.C=b=this.Cc(b),c=this.Ac(b)):b.type==Vj&&this.Xe(b);return!c}Yk.prototype.Ac=ve;function al(b){Yk.call(this,{handleDownEvent:bl,handleDragEvent:cl,handleUpEvent:dl});b=b?b:{};this.a=b.kinetic;this.c=this.l=null;this.v=b.condition?b.condition:Uk;this.o=!1}y(al,Yk);function cl(b){var c=$k(this.j);this.a&&this.a.a.push(c[0],c[1],Date.now());if(this.c){var d=this.c[0]-c[0],e=c[1]-this.c[1];b=b.map;var f=b.aa(),g=Qf(f),e=d=[d,e],h=g.resolution;e[0]*=h;e[1]*=h;ud(d,g.rotation);pd(d,g.center);d=f.Xd(d);b.render();f.kb(d)}this.c=c} -function dl(b){b=b.map;var c=b.aa();if(0===this.j.length){var d;if(d=!this.o&&this.a)if(d=this.a,6>d.a.length)d=!1;else{var e=Date.now()-d.i,f=d.a.length-3;if(d.a[f+2]<e)d=!1;else{for(var g=f-3;0<g&&d.a[g+2]>e;)g-=3;var e=d.a[f+2]-d.a[g+2],h=d.a[f]-d.a[g],f=d.a[f+1]-d.a[g+1];d.g=Math.atan2(f,h);d.f=Math.sqrt(h*h+f*f)/e;d=d.f>d.b}}d&&(d=this.a,d=(d.b-d.f)/d.c,f=this.a.g,g=c.Ua(),this.l=Kk(this.a,g),b.Na(this.l),g=b.Pa(g),d=b.Ga([g[0]-d*Math.cos(f),g[1]-d*Math.sin(f)]),d=c.Xd(d),c.kb(d));Sf(c,-1);b.render(); -return!1}this.c=null;return!0}function bl(b){if(0<this.j.length&&this.v(b)){var c=b.map,d=c.aa();this.c=null;this.C||Sf(d,1);c.render();this.l&&hb(c.O,this.l)&&(d.kb(b.frameState.viewState.center),this.l=null);this.a&&(b=this.a,b.a.length=0,b.g=0,b.f=0);this.o=1<this.j.length;return!0}return!1}al.prototype.Ac=se;function el(b){b=b?b:{};Yk.call(this,{handleDownEvent:fl,handleDragEvent:gl,handleUpEvent:hl});this.c=b.condition?b.condition:Rk;this.a=void 0;this.l=void 0!==b.duration?b.duration:250}y(el,Yk);function gl(b){if(Xk(b)){var c=b.map,d=c.Sa();b=b.pixel;d=Math.atan2(d[1]/2-b[1],b[0]-d[0]/2);if(void 0!==this.a){b=d-this.a;var e=c.aa(),f=e.Fa();c.render();Mk(c,e,f-b)}this.a=d}} -function hl(b){if(!Xk(b))return!0;b=b.map;var c=b.aa();Sf(c,-1);var d=c.Fa(),e=this.l,d=c.constrainRotation(d,0);Mk(b,c,d,void 0,e);return!1}function fl(b){return Xk(b)&&zc(b.a)&&this.c(b)?(b=b.map,Sf(b.aa(),1),b.render(),this.a=void 0,!0):!1}el.prototype.Ac=se;function il(b){this.c=null;this.f=document.createElement("div");this.f.style.position="absolute";this.f.className="ol-box "+b;this.b=this.g=this.a=null}y(il,oc);il.prototype.Y=function(){this.setMap(null);il.ca.Y.call(this)};function jl(b){var c=b.g,d=b.b;b=b.f.style;b.left=Math.min(c[0],d[0])+"px";b.top=Math.min(c[1],d[1])+"px";b.width=Math.abs(d[0]-c[0])+"px";b.height=Math.abs(d[1]-c[1])+"px"} -il.prototype.setMap=function(b){if(this.a){this.a.l.removeChild(this.f);var c=this.f.style;c.left=c.top=c.width=c.height="inherit"}(this.a=b)&&this.a.l.appendChild(this.f)};function kl(b){var c=b.g,d=b.b,c=[c,[c[0],d[1]],d,[d[0],c[1]]].map(b.a.Ga,b.a);c[4]=c[0].slice();b.c?b.c.la([c]):b.c=new F([c])}il.prototype.X=function(){return this.c};function ll(b,c){tc.call(this,b);this.coordinate=c}y(ll,tc);function ml(b){Yk.call(this,{handleDownEvent:nl,handleDragEvent:pl,handleUpEvent:ql});b=b?b:{};this.c=new il(b.className||"ol-dragbox");this.a=null;this.v=b.condition?b.condition:te}y(ml,Yk);function pl(b){if(Xk(b)){var c=this.c;b=b.pixel;c.g=this.a;c.b=b;kl(c);jl(c)}}ml.prototype.X=function(){return this.c.X()};ml.prototype.o=za; -function ql(b){if(!Xk(b))return!0;this.c.setMap(null);var c=b.pixel[0]-this.a[0],d=b.pixel[1]-this.a[1];64<=c*c+d*d&&(this.o(b),this.s(new ll("boxend",b.coordinate)));return!1}function nl(b){if(Xk(b)&&zc(b.a)&&this.v(b)){this.a=b.pixel;this.c.setMap(b.map);var c=this.c,d=this.a;c.g=this.a;c.b=d;kl(c);jl(c);this.s(new ll("boxstart",b.coordinate));return!0}return!1};function rl(b){b=b?b:{};var c=b.condition?b.condition:Vk;this.l=void 0!==b.duration?b.duration:200;ml.call(this,{condition:c,className:b.className||"ol-dragzoom"})}y(rl,ml);rl.prototype.o=function(){var b=this.B,c=b.aa(),d=b.Sa(),e=this.X().J(),d=c.constrainResolution(Math.max(je(e)/d[0],ke(e)/d[1])),f=c.$(),g=c.Ua();b.Na($f({resolution:f,duration:this.l,easing:Uf}));b.Na(Yf({source:g,duration:this.l,easing:Uf}));c.kb(le(e));c.Ub(d)};function sl(b){Lk.call(this,{handleEvent:tl});b=b||{};this.a=void 0!==b.condition?b.condition:ye(Uk,Wk);this.c=void 0!==b.duration?b.duration:100;this.j=void 0!==b.pixelDelta?b.pixelDelta:128}y(sl,Lk); -function tl(b){var c=!1;if("key"==b.type){var d=b.a.i;if(this.a(b)&&(40==d||37==d||39==d||38==d)){var e=b.map,c=e.aa(),f=c.$()*this.j,g=0,h=0;40==d?h=-f:37==d?g=-f:39==d?g=f:h=f;d=[g,h];ud(d,c.Fa());f=this.c;if(g=c.Ua())f&&0<f&&e.Na(Yf({source:g,duration:f,easing:Wf})),e=c.Xd([g[0]+d[0],g[1]+d[1]]),c.kb(e);b.preventDefault();c=!0}}return!c};function ul(b){Lk.call(this,{handleEvent:vl});b=b?b:{};this.c=b.condition?b.condition:Wk;this.a=b.delta?b.delta:1;this.j=void 0!==b.duration?b.duration:100}y(ul,Lk);function vl(b){var c=!1;if("key"==b.type){var d=b.a.G;if(this.c(b)&&(43==d||45==d)){c=b.map;d=43==d?this.a:-this.a;c.render();var e=c.aa();Nk(c,e,d,void 0,this.j);b.preventDefault();c=!0}}return!c};function wl(b){Lk.call(this,{handleEvent:xl});b=b||{};this.c=0;this.C=void 0!==b.duration?b.duration:250;this.o=void 0!==b.useAnchor?b.useAnchor:!0;this.a=null;this.l=this.j=void 0}y(wl,Lk);function xl(b){var c=!1;if("mousewheel"==b.type){var c=b.map,d=b.a;this.o&&(this.a=b.coordinate);this.c+=d.v;void 0===this.j&&(this.j=Date.now());d=Math.max(80-(Date.now()-this.j),0);ba.clearTimeout(this.l);this.l=ba.setTimeout(ua(this.v,this,c),d);b.preventDefault();c=!0}return!c} -wl.prototype.v=function(b){var c=Sa(this.c,-1,1),d=b.aa();b.render();Nk(b,d,-c,this.a,this.C);this.c=0;this.a=null;this.l=this.j=void 0};wl.prototype.D=function(b){this.o=b;b||(this.a=null)};function yl(b){Yk.call(this,{handleDownEvent:zl,handleDragEvent:Al,handleUpEvent:Bl});b=b||{};this.c=null;this.l=void 0;this.a=!1;this.o=0;this.D=void 0!==b.threshold?b.threshold:.3;this.v=void 0!==b.duration?b.duration:250}y(yl,Yk); -function Al(b){var c=0,d=this.j[0],e=this.j[1],d=Math.atan2(e.clientY-d.clientY,e.clientX-d.clientX);void 0!==this.l&&(c=d-this.l,this.o+=c,!this.a&&Math.abs(this.o)>this.D&&(this.a=!0));this.l=d;b=b.map;d=dh(b.a);e=$k(this.j);e[0]-=d.x;e[1]-=d.y;this.c=b.Ga(e);this.a&&(d=b.aa(),e=d.Fa(),b.render(),Mk(b,d,e+c,this.c))}function Bl(b){if(2>this.j.length){b=b.map;var c=b.aa();Sf(c,-1);if(this.a){var d=c.Fa(),e=this.c,f=this.v,d=c.constrainRotation(d,0);Mk(b,c,d,e,f)}return!1}return!0} -function zl(b){return 2<=this.j.length?(b=b.map,this.c=null,this.l=void 0,this.a=!1,this.o=0,this.C||Sf(b.aa(),1),b.render(),!0):!1}yl.prototype.Ac=se;function Cl(b){Yk.call(this,{handleDownEvent:Dl,handleDragEvent:El,handleUpEvent:Fl});b=b?b:{};this.c=null;this.o=void 0!==b.duration?b.duration:400;this.a=void 0;this.l=1}y(Cl,Yk);function El(b){var c=1,d=this.j[0],e=this.j[1],f=d.clientX-e.clientX,d=d.clientY-e.clientY,f=Math.sqrt(f*f+d*d);void 0!==this.a&&(c=this.a/f);this.a=f;1!=c&&(this.l=c);b=b.map;var f=b.aa(),d=f.$(),e=dh(b.a),g=$k(this.j);g[0]-=e.x;g[1]-=e.y;this.c=b.Ga(g);b.render();Ok(b,f,d*c,this.c)} -function Fl(b){if(2>this.j.length){b=b.map;var c=b.aa();Sf(c,-1);var d=c.$(),e=this.c,f=this.o,d=c.constrainResolution(d,0,this.l-1);Ok(b,c,d,e,f);return!1}return!0}function Dl(b){return 2<=this.j.length?(b=b.map,this.c=null,this.a=void 0,this.l=1,this.C||Sf(b.aa(),1),b.render(),!0):!1}Cl.prototype.Ac=se;function Gl(b){b=b?b:{};var c=new og,d=new Jk(-.005,.05,100);(void 0!==b.altShiftDragRotate?b.altShiftDragRotate:1)&&c.push(new el);(void 0!==b.doubleClickZoom?b.doubleClickZoom:1)&&c.push(new Pk({delta:b.zoomDelta,duration:b.zoomDuration}));(void 0!==b.dragPan?b.dragPan:1)&&c.push(new al({kinetic:d}));(void 0!==b.pinchRotate?b.pinchRotate:1)&&c.push(new yl);(void 0!==b.pinchZoom?b.pinchZoom:1)&&c.push(new Cl({duration:b.zoomDuration}));if(void 0!==b.keyboard?b.keyboard:1)c.push(new sl),c.push(new ul({delta:b.zoomDelta, -duration:b.zoomDuration}));(void 0!==b.mouseWheelZoom?b.mouseWheelZoom:1)&&c.push(new wl({duration:b.zoomDuration}));(void 0!==b.shiftDragZoom?b.shiftDragZoom:1)&&c.push(new rl({duration:b.zoomDuration}));return c};function Hl(b){var c=b||{};b=Tb(c);delete b.layers;c=c.layers;Yj.call(this,b);this.b=[];this.a={};D(this,id("layers"),this.Jk,!1,this);c?ga(c)&&(c=new og(c.slice())):c=new og;this.ih(c)}y(Hl,Yj);l=Hl.prototype;l.ie=function(){this.rb()&&this.u()}; -l.Jk=function(){this.b.forEach(Wc);this.b.length=0;var b=this.Qc();this.b.push(D(b,"add",this.Ik,!1,this),D(b,"remove",this.Kk,!1,this));Ib(this.a,function(b){b.forEach(Wc)});Qb(this.a);var b=b.a,c,d,e;c=0;for(d=b.length;c<d;c++)e=b[c],this.a[w(e).toString()]=[D(e,"propertychange",this.ie,!1,this),D(e,"change",this.ie,!1,this)];this.u()};l.Ik=function(b){b=b.element;var c=w(b).toString();this.a[c]=[D(b,"propertychange",this.ie,!1,this),D(b,"change",this.ie,!1,this)];this.u()}; -l.Kk=function(b){b=w(b.element).toString();this.a[b].forEach(Wc);delete this.a[b];this.u()};l.Qc=function(){return this.get("layers")};l.ih=function(b){this.set("layers",b)}; -l.of=function(b){var c=void 0!==b?b:[],d=c.length;this.Qc().forEach(function(b){b.of(c)});b=Zj(this);var e,f;for(e=c.length;d<e;d++)f=c[d],f.opacity*=b.opacity,f.visible=f.visible&&b.visible,f.maxResolution=Math.min(f.maxResolution,b.maxResolution),f.minResolution=Math.max(f.minResolution,b.minResolution),void 0!==b.extent&&(f.extent=void 0!==f.extent?ne(f.extent,b.extent):b.extent);return c};l.pf=function(){return"ready"};function Il(b){Ce.call(this,{code:b,units:"m",extent:Jl,global:!0,worldExtent:Kl})}y(Il,Ce);Il.prototype.getPointResolution=function(b,c){return b/Ta(c[1]/6378137)};var Ll=6378137*Math.PI,Jl=[-Ll,-Ll,Ll,Ll],Kl=[-180,-85,180,85],Oe="EPSG:3857 EPSG:102100 EPSG:102113 EPSG:900913 urn:ogc:def:crs:EPSG:6.18:3:3857 urn:ogc:def:crs:EPSG::3857 http://www.opengis.net/gml/srs/epsg.xml#3857".split(" ").map(function(b){return new Il(b)}); -function Pe(b,c,d){var e=b.length;d=1<d?d:2;void 0===c&&(2<d?c=b.slice():c=Array(e));for(var f=0;f<e;f+=d)c[f]=6378137*Math.PI*b[f]/180,c[f+1]=6378137*Math.log(Math.tan(Math.PI*(b[f+1]+90)/360));return c}function Qe(b,c,d){var e=b.length;d=1<d?d:2;void 0===c&&(2<d?c=b.slice():c=Array(e));for(var f=0;f<e;f+=d)c[f]=180*b[f]/(6378137*Math.PI),c[f+1]=360*Math.atan(Math.exp(b[f+1]/6378137))/Math.PI-90;return c};function Ml(b,c){Ce.call(this,{code:b,units:"degrees",extent:Nl,axisOrientation:c,global:!0,worldExtent:Nl})}y(Ml,Ce);Ml.prototype.getPointResolution=function(b){return b}; -var Nl=[-180,-90,180,90],Re=[new Ml("CRS:84"),new Ml("EPSG:4326","neu"),new Ml("urn:ogc:def:crs:EPSG::4326","neu"),new Ml("urn:ogc:def:crs:EPSG:6.6:4326","neu"),new Ml("urn:ogc:def:crs:OGC:1.3:CRS84"),new Ml("urn:ogc:def:crs:OGC:2:84"),new Ml("http://www.opengis.net/gml/srs/epsg.xml#4326","neu"),new Ml("urn:x-ogc:def:crs:EPSG:4326","neu")];function Ol(){Fe(Oe);Fe(Re);Ne()};function Pl(b){ck.call(this,b?b:{})}y(Pl,ck);function G(b){b=b?b:{};var c=Tb(b);delete c.preload;delete c.useInterimTilesOnError;ck.call(this,c);this.c(void 0!==b.preload?b.preload:0);this.g(void 0!==b.useInterimTilesOnError?b.useInterimTilesOnError:!0)}y(G,ck);G.prototype.a=function(){return this.get("preload")};G.prototype.c=function(b){this.set("preload",b)};G.prototype.b=function(){return this.get("useInterimTilesOnError")};G.prototype.g=function(b){this.set("useInterimTilesOnError",b)};var Ql=[0,0,0,1],Rl=[],Sl=[0,0,0,1];function Tl(b){b=b||{};this.a=void 0!==b.color?b.color:null;this.f=void 0}Tl.prototype.b=function(){return this.a};Tl.prototype.c=function(b){this.a=b;this.f=void 0};Tl.prototype.Jb=function(){void 0===this.f&&(this.f="f"+(this.a?vg(this.a):"-"));return this.f};function Ul(){this.f=-1};function Vl(){this.f=-1;this.f=64;this.a=Array(4);this.g=Array(this.f);this.c=this.b=0;this.reset()}y(Vl,Ul);Vl.prototype.reset=function(){this.a[0]=1732584193;this.a[1]=4023233417;this.a[2]=2562383102;this.a[3]=271733878;this.c=this.b=0}; -function Wl(b,c,d){d||(d=0);var e=Array(16);if(ia(c))for(var f=0;16>f;++f)e[f]=c.charCodeAt(d++)|c.charCodeAt(d++)<<8|c.charCodeAt(d++)<<16|c.charCodeAt(d++)<<24;else for(f=0;16>f;++f)e[f]=c[d++]|c[d++]<<8|c[d++]<<16|c[d++]<<24;c=b.a[0];d=b.a[1];var f=b.a[2],g=b.a[3],h=0,h=c+(g^d&(f^g))+e[0]+3614090360&4294967295;c=d+(h<<7&4294967295|h>>>25);h=g+(f^c&(d^f))+e[1]+3905402710&4294967295;g=c+(h<<12&4294967295|h>>>20);h=f+(d^g&(c^d))+e[2]+606105819&4294967295;f=g+(h<<17&4294967295|h>>>15);h=d+(c^f&(g^ +l.scale=function(a,c){var d=fa(c)?c:a;this.left*=a;this.right*=a;this.top*=d;this.bottom*=d;return this};function yf(a,c){var d=lf(a);return d.defaultView&&d.defaultView.getComputedStyle&&(d=d.defaultView.getComputedStyle(a,null))?d[c]||d.getPropertyValue(c)||"":""}function zf(a){var c;try{c=a.getBoundingClientRect()}catch(d){return{left:0,top:0,right:0,bottom:0}}Se&&a.ownerDocument.body&&(a=a.ownerDocument,c.left-=a.documentElement.clientLeft+a.body.clientLeft,c.top-=a.documentElement.clientTop+a.body.clientTop);return c} +function Af(a){var c=Bf;if("none"!=(yf(a,"display")||(a.currentStyle?a.currentStyle.display:null)||a.style&&a.style.display))return c(a);var d=a.style,e=d.display,f=d.visibility,g=d.position;d.visibility="hidden";d.position="absolute";d.display="inline";a=c(a);d.display=e;d.position=g;d.visibility=f;return a}function Bf(a){var c=a.offsetWidth,d=a.offsetHeight,e=Ve&&!c&&!d;return(void 0===c||e)&&a.getBoundingClientRect?(a=zf(a),new hf(a.right-a.left,a.bottom-a.top)):new hf(c,d)} +function Cf(a,c){a.style.display=c?"":"none"}function Df(a,c,d,e){if(/^\d+px?$/.test(c))return parseInt(c,10);var f=a.style[d],g=a.runtimeStyle[d];a.runtimeStyle[d]=a.currentStyle[d];a.style[d]=c;c=a.style[e];a.style[d]=f;a.runtimeStyle[d]=g;return c}function Ef(a,c){var d=a.currentStyle?a.currentStyle[c]:null;return d?Df(a,d,"left","pixelLeft"):0} +function Ff(a,c){if(Se){var d=Ef(a,c+"Left"),e=Ef(a,c+"Right"),f=Ef(a,c+"Top"),g=Ef(a,c+"Bottom");return new xf(f,e,g,d)}d=yf(a,c+"Left");e=yf(a,c+"Right");f=yf(a,c+"Top");g=yf(a,c+"Bottom");return new xf(parseFloat(f),parseFloat(e),parseFloat(g),parseFloat(d))}var Gf={thin:2,medium:4,thick:6};function Hf(a,c){if("none"==(a.currentStyle?a.currentStyle[c+"Style"]:null))return 0;var d=a.currentStyle?a.currentStyle[c+"Width"]:null;return d in Gf?Gf[d]:Df(a,d,"left","pixelLeft")};function If(a,c,d){gb.call(this,a);this.map=c;this.frameState=void 0!==d?d:null}y(If,gb);function Jf(a){pb.call(this);this.element=a.element?a.element:null;this.a=this.S=null;this.s=[];this.render=a.render?a.render:pa;a.target&&this.c(a.target)}y(Jf,pb);Jf.prototype.fa=function(){uf(this.element);Jf.ia.fa.call(this)};Jf.prototype.i=function(){return this.a}; +Jf.prototype.setMap=function(a){this.a&&uf(this.element);for(var c=0,d=this.s.length;c<d;++c)Xa(this.s[c]);this.s.length=0;if(this.a=a)(this.S?this.S:a.v).appendChild(this.element),this.render!==pa&&this.s.push(C(a,"postrender",this.render,this)),a.render()};Jf.prototype.c=function(a){this.S=mf(a)};function Kf(){this.g=0;this.f={};this.a=this.b=null}l=Kf.prototype;l.clear=function(){this.g=0;this.f={};this.a=this.b=null};function Lf(a,c){return a.f.hasOwnProperty(c)}l.forEach=function(a,c){for(var d=this.b;d;)a.call(c,d.kc,d.Yb,this),d=d.xb};l.get=function(a){a=this.f[a];if(a===this.a)return a.kc;a===this.b?(this.b=this.b.xb,this.b.fc=null):(a.xb.fc=a.fc,a.fc.xb=a.xb);a.xb=null;a.fc=this.a;this.a=this.a.xb=a;return a.kc};l.rc=function(){return this.g}; +l.K=function(){var a=Array(this.g),c=0,d;for(d=this.a;d;d=d.fc)a[c++]=d.Yb;return a};l.uc=function(){var a=Array(this.g),c=0,d;for(d=this.a;d;d=d.fc)a[c++]=d.kc;return a};l.pop=function(){var a=this.b;delete this.f[a.Yb];a.xb&&(a.xb.fc=null);this.b=a.xb;this.b||(this.a=null);--this.g;return a.kc};l.replace=function(a,c){this.get(a);this.f[a].kc=c};l.set=function(a,c){var d={Yb:a,xb:null,fc:this.a,kc:c};this.a?this.a.xb=d:this.b=d;this.a=d;this.f[a]=d;++this.g};function Mf(a,c,d,e){return void 0!==e?(e[0]=a,e[1]=c,e[2]=d,e):[a,c,d]}function Nf(a){var c=a[0],d=Array(c),e=1<<c-1,f,g;for(f=0;f<c;++f)g=48,a[1]&e&&(g+=1),a[2]&e&&(g+=2),d[f]=String.fromCharCode(g),e>>=1;return d.join("")};function Of(a){Kf.call(this);this.c=void 0!==a?a:2048}y(Of,Kf);function Pf(a){return a.rc()>a.c}Of.prototype.Gc=function(a){for(var c,d;Pf(this)&&!(c=this.b.kc,d=c.ja[0].toString(),d in a&&a[d].contains(c.ja));)fb(this.pop())};function Qf(a,c){jb.call(this);this.ja=a;this.state=c;this.a=null;this.key=""}y(Qf,jb);function Rf(a){a.b("change")}Qf.prototype.gb=function(){return w(this).toString()};Qf.prototype.i=function(){return this.ja};Qf.prototype.V=function(){return this.state};function Sf(a,c,d){void 0===d&&(d=[0,0]);d[0]=a[0]+2*c;d[1]=a[1]+2*c;return d}function Tf(a,c,d){void 0===d&&(d=[0,0]);d[0]=a[0]*c+.5|0;d[1]=a[1]*c+.5|0;return d}function Uf(a,c){if(Array.isArray(a))return a;void 0===c?c=[a,a]:(c[0]=a,c[1]=a);return c};function Vf(a){pb.call(this);this.f=Ic(a.projection);this.l=Wf(a.attributions);this.R=a.logo;this.wa=void 0!==a.state?a.state:"ready";this.N=void 0!==a.wrapX?a.wrapX:!1}y(Vf,pb);function Wf(a){if("string"===typeof a)return[new ue({html:a})];if(a instanceof ue)return[a];if(Array.isArray(a)){for(var c=a.length,d=Array(c),e=0;e<c;e++){var f=a[e];d[e]="string"===typeof f?new ue({html:f}):f}return d}return null}l=Vf.prototype;l.oa=pa;l.ra=function(){return this.l};l.qa=function(){return this.R};l.sa=function(){return this.f}; +l.V=function(){return this.wa};l.pa=function(){this.u()};l.ka=function(a){this.l=Wf(a);this.u()};function Xf(a,c){a.wa=c;a.u()};function Yf(a){this.minZoom=void 0!==a.minZoom?a.minZoom:0;this.b=a.resolutions;this.maxZoom=this.b.length-1;this.g=void 0!==a.origin?a.origin:null;this.c=null;void 0!==a.origins&&(this.c=a.origins);var c=a.extent;void 0===c||this.g||this.c||(this.g=oc(c));this.i=null;void 0!==a.tileSizes&&(this.i=a.tileSizes);this.o=void 0!==a.tileSize?a.tileSize:this.i?null:256;this.s=void 0!==c?c:null;this.a=null;this.f=[0,0];void 0!==a.sizes?this.a=a.sizes.map(function(a){return new qe(Math.min(0,a[0]),Math.max(a[0]- +1,-1),Math.min(0,a[1]),Math.max(a[1]-1,-1))},this):c&&Zf(this,c)}var $f=[0,0,0];function ag(a,c,d,e,f){f=a.Ba(c,f);for(c=c[0]-1;c>=a.minZoom;){if(d.call(null,c,bg(a,f,c,e)))return!0;--c}return!1}l=Yf.prototype;l.O=function(){return this.s};l.Dg=function(){return this.maxZoom};l.Eg=function(){return this.minZoom};l.Fa=function(a){return this.g?this.g:this.c[a]};l.$=function(a){return this.b[a]};l.Fh=function(){return this.b}; +function cg(a,c,d,e){return c[0]<a.maxZoom?(e=a.Ba(c,e),bg(a,e,c[0]+1,d)):null}function dg(a,c,d,e){eg(a,c[0],c[1],d,!1,$f);var f=$f[1],g=$f[2];eg(a,c[2],c[3],d,!0,$f);a=$f[1];c=$f[2];void 0!==e?(e.b=f,e.a=a,e.g=g,e.f=c):e=new qe(f,a,g,c);return e}function bg(a,c,d,e){d=a.$(d);return dg(a,c,d,e)}function fg(a,c){var d=a.Fa(c[0]),e=a.$(c[0]),f=Uf(a.Ha(c[0]),a.f);return[d[0]+(c[1]+.5)*f[0]*e,d[1]+(c[2]+.5)*f[1]*e]} +l.Ba=function(a,c){var d=this.Fa(a[0]),e=this.$(a[0]),f=Uf(this.Ha(a[0]),this.f),g=d[0]+a[1]*f[0]*e,d=d[1]+a[2]*f[1]*e;return ec(g,d,g+f[0]*e,d+f[1]*e,c)};l.Td=function(a,c,d){return eg(this,a[0],a[1],c,!1,d)};function eg(a,c,d,e,f,g){var h=gg(a,e),k=e/a.$(h),m=a.Fa(h);a=Uf(a.Ha(h),a.f);c=k*Math.floor((c-m[0])/e+(f?.5:0))/a[0];d=k*Math.floor((d-m[1])/e+(f?0:.5))/a[1];f?(c=Math.ceil(c)-1,d=Math.ceil(d)-1):(c=Math.floor(c),d=Math.floor(d));return Mf(h,c,d,g)} +l.kd=function(a,c,d){c=this.$(c);return eg(this,a[0],a[1],c,!1,d)};l.Ha=function(a){return this.o?this.o:this.i[a]};function gg(a,c,d){c=vb(a.b,c,d||0);return Da(c,a.minZoom,a.maxZoom)}function Zf(a,c){for(var d=a.b.length,e=Array(d),f=a.minZoom;f<d;++f)e[f]=bg(a,c,f);a.a=e}function hg(a){var c=a.l;if(!c){var c=ig(a),d=jg(c,void 0,void 0),c=new Yf({extent:c,origin:oc(c),resolutions:d,tileSize:void 0});a.l=c}return c} +function kg(a){var c={};Pa(c,void 0!==a?a:{});void 0===c.extent&&(c.extent=Ic("EPSG:3857").O());c.resolutions=jg(c.extent,c.maxZoom,c.tileSize);delete c.maxZoom;return new Yf(c)}function jg(a,c,d){c=void 0!==c?c:42;var e=sc(a);a=rc(a);d=Uf(void 0!==d?d:256);d=Math.max(a/d[0],e/d[1]);c+=1;e=Array(c);for(a=0;a<c;++a)e[a]=d/Math.pow(2,a);return e}function ig(a){a=Ic(a);var c=a.O();c||(a=180*Ec.degrees/a.Vb(),c=ec(-a,-a,a,a));return c};function lg(a){Vf.call(this,{attributions:a.attributions,extent:a.extent,logo:a.logo,projection:a.projection,state:a.state,wrapX:a.wrapX});this.ea=void 0!==a.opaque?a.opaque:!1;this.ta=void 0!==a.tilePixelRatio?a.tilePixelRatio:1;this.tileGrid=void 0!==a.tileGrid?a.tileGrid:null;this.a=new Of(a.cacheSize);this.o=[0,0];this.Yb=""}y(lg,Vf);l=lg.prototype;l.vh=function(){return Pf(this.a)};l.Gc=function(a,c){var d=this.jd(a);d&&d.Gc(c)}; +function mg(a,c,d,e,f){c=a.jd(c);if(!c)return!1;for(var g=!0,h,k,m=e.b;m<=e.a;++m)for(var n=e.g;n<=e.f;++n)h=a.Ab(d,m,n),k=!1,Lf(c,h)&&(h=c.get(h),(k=2===h.V())&&(k=!1!==f(h))),k||(g=!1);return g}l.Od=function(){return 0};function ng(a,c){a.Yb!==c&&(a.Yb=c,a.u())}l.Ab=function(a,c,d){return a+"/"+c+"/"+d};l.ef=function(){return this.ea};l.Ga=function(){return this.tileGrid};l.fb=function(a){return this.tileGrid?this.tileGrid:hg(a)};l.jd=function(a){var c=this.f;return c&&!Zc(c,a)?null:this.a}; +l.Xb=function(){return this.ta};l.Ud=function(a,c,d){d=this.fb(d);c=this.Xb(c);a=Uf(d.Ha(a),this.o);return 1==c?a:Tf(a,c,this.o)};function og(a,c,d){var e=void 0!==d?d:a.f;d=a.fb(e);if(a.N&&e.g){var f=c;c=f[0];a=fg(d,f);e=ig(e);ac(e,a)?c=f:(f=rc(e),a[0]+=f*Math.ceil((e[0]-a[0])/f),c=d.kd(a,c))}f=c[0];e=c[1];a=c[2];if(d.minZoom>f||f>d.maxZoom)d=!1;else{var g=d.O();d=(d=g?bg(d,g,f):d.a?d.a[f]:null)?re(d,e,a):!0}return d?c:null}l.pa=function(){this.a.clear();this.u()};l.Uf=pa; +function pg(a,c){gb.call(this,a);this.tile=c}y(pg,gb);function qg(a){a=a?a:{};this.M=document.createElement("UL");this.v=document.createElement("LI");this.M.appendChild(this.v);Cf(this.v,!1);this.f=void 0!==a.collapsed?a.collapsed:!0;this.o=void 0!==a.collapsible?a.collapsible:!0;this.o||(this.f=!1);var c=void 0!==a.className?a.className:"ol-attribution",d=void 0!==a.tipLabel?a.tipLabel:"Attributions",e=void 0!==a.collapseLabel?a.collapseLabel:"\u00bb";this.N="string"===typeof e?pf("SPAN",{},e):e;e=void 0!==a.label?a.label:"i";this.R="string"===typeof e? +pf("SPAN",{},e):e;d=pf("BUTTON",{type:"button",title:d},this.o&&!this.f?this.N:this.R);C(d,"click",this.Vl,this);c=pf("DIV",c+" ol-unselectable ol-control"+(this.f&&this.o?" ol-collapsed":"")+(this.o?"":" ol-uncollapsible"),this.M,d);Jf.call(this,{element:c,render:a.render?a.render:rg,target:a.target});this.B=!0;this.j={};this.l={};this.T={}}y(qg,Jf); +function rg(a){if(a=a.frameState){var c,d,e,f,g,h,k,m,n,p,q,r=a.layerStatesArray,u=Pa({},a.attributions),v={},x=a.viewState.projection;d=0;for(c=r.length;d<c;d++)if(h=r[d].layer.da())if(p=w(h).toString(),n=h.l)for(e=0,f=n.length;e<f;e++)if(k=n[e],m=w(k).toString(),!(m in u)){if(g=a.usedTiles[p]){var z=h.fb(x);a:{q=k;var E=x;if(q.b){var B=void 0,A=void 0,G=void 0,O=void 0;for(O in g)if(O in q.b)for(var G=g[O],L,B=0,A=q.b[O].length;B<A;++B){L=q.b[O][B];if(te(L,G)){q=!0;break a}var R=bg(z,ig(E),parseInt(O, +10)),Wa=R.a-R.b+1;if(G.b<R.b||G.a>R.a)if(te(L,new qe(Ja(G.b,Wa),Ja(G.a,Wa),G.g,G.f))||G.a-G.b+1>Wa&&te(L,R)){q=!0;break a}}q=!1}else q=!0}}else q=!1;q?(m in v&&delete v[m],u[m]=k):v[m]=k}c=[u,v];d=c[0];c=c[1];for(var J in this.j)J in d?(this.l[J]||(Cf(this.j[J],!0),this.l[J]=!0),delete d[J]):J in c?(this.l[J]&&(Cf(this.j[J],!1),delete this.l[J]),delete c[J]):(uf(this.j[J]),delete this.j[J],delete this.l[J]);for(J in d)e=document.createElement("LI"),e.innerHTML=d[J].a,this.M.appendChild(e),this.j[J]= +e,this.l[J]=!0;for(J in c)e=document.createElement("LI"),e.innerHTML=c[J].a,Cf(e,!1),this.M.appendChild(e),this.j[J]=e;J=!Sa(this.l)||!Sa(a.logos);this.B!=J&&(Cf(this.element,J),this.B=J);J&&Sa(this.l)?this.element.classList.add("ol-logo-only"):this.element.classList.remove("ol-logo-only");var ua;a=a.logos;J=this.T;for(ua in J)ua in a||(uf(J[ua]),delete J[ua]);for(var Ta in a)d=a[Ta],d instanceof HTMLElement&&(this.v.appendChild(d),J[Ta]=d),Ta in J||(ua=new Image,ua.src=Ta,""===d?d=ua:(d=pf("A",{href:d}), +d.appendChild(ua)),this.v.appendChild(d),J[Ta]=d);Cf(this.v,!Sa(a))}else this.B&&(Cf(this.element,!1),this.B=!1)}l=qg.prototype;l.Vl=function(a){a.preventDefault();sg(this)};function sg(a){a.element.classList.toggle("ol-collapsed");a.f?vf(a.N,a.R):vf(a.R,a.N);a.f=!a.f}l.Ul=function(){return this.o};l.Xl=function(a){this.o!==a&&(this.o=a,this.element.classList.toggle("ol-uncollapsible"),!a&&this.f&&sg(this))};l.Wl=function(a){this.o&&this.f!==a&&sg(this)};l.Tl=function(){return this.f};function tg(a){a=a?a:{};var c=void 0!==a.className?a.className:"ol-rotate",d=void 0!==a.label?a.label:"\u21e7";this.f=null;"string"===typeof d?this.f=pf("SPAN","ol-compass",d):(this.f=d,this.f.classList.add("ol-compass"));d=pf("BUTTON",{"class":c+"-reset",type:"button",title:a.tipLabel?a.tipLabel:"Reset rotation"},this.f);C(d,"click",tg.prototype.B,this);c=pf("DIV",c+" ol-unselectable ol-control",d);d=a.render?a.render:ug;this.o=a.resetNorth?a.resetNorth:void 0;Jf.call(this,{element:c,render:d,target:a.target}); +this.j=void 0!==a.duration?a.duration:250;this.l=void 0!==a.autoHide?a.autoHide:!0;this.v=void 0;this.l&&this.element.classList.add("ol-hidden")}y(tg,Jf);tg.prototype.B=function(a){a.preventDefault();if(void 0!==this.o)this.o();else{a=this.a;var c=a.aa();if(c){var d=c.Ka();void 0!==d&&(0<this.j&&(d%=2*Math.PI,d<-Math.PI&&(d+=2*Math.PI),d>Math.PI&&(d-=2*Math.PI),a.Va(oe({rotation:d,duration:this.j,easing:je}))),c.de(0))}}}; +function ug(a){if(a=a.frameState){a=a.viewState.rotation;if(a!=this.v){var c="rotate("+a+"rad)";if(this.l){var d=this.element.classList.contains("ol-hidden");d||0!==a?d&&0!==a&&this.element.classList.remove("ol-hidden"):this.element.classList.add("ol-hidden")}this.f.style.msTransform=c;this.f.style.webkitTransform=c;this.f.style.transform=c}this.v=a}};function vg(a){a=a?a:{};var c=void 0!==a.className?a.className:"ol-zoom",d=void 0!==a.delta?a.delta:1,e=void 0!==a.zoomOutLabel?a.zoomOutLabel:"\u2212",f=void 0!==a.zoomOutTipLabel?a.zoomOutTipLabel:"Zoom out",g=pf("BUTTON",{"class":c+"-in",type:"button",title:void 0!==a.zoomInTipLabel?a.zoomInTipLabel:"Zoom in"},void 0!==a.zoomInLabel?a.zoomInLabel:"+");C(g,"click",vg.prototype.l.bind(this,d));e=pf("BUTTON",{"class":c+"-out",type:"button",title:f},e);C(e,"click",vg.prototype.l.bind(this,-d));c=pf("DIV", +c+" ol-unselectable ol-control",g,e);Jf.call(this,{element:c,target:a.target});this.f=void 0!==a.duration?a.duration:250}y(vg,Jf);vg.prototype.l=function(a,c){c.preventDefault();var d=this.a,e=d.aa();if(e){var f=e.$();f&&(0<this.f&&d.Va(pe({resolution:f,duration:this.f,easing:je})),d=e.constrainResolution(f,a),e.Qb(d))}};function wg(a){a=a?a:{};var c=new we;(void 0!==a.zoom?a.zoom:1)&&c.push(new vg(a.zoomOptions));(void 0!==a.rotate?a.rotate:1)&&c.push(new tg(a.rotateOptions));(void 0!==a.attribution?a.attribution:1)&&c.push(new qg(a.attributionOptions));return c};var xg=Ve?"webkitfullscreenchange":Ue?"mozfullscreenchange":Se?"MSFullscreenChange":"fullscreenchange";function yg(){var a=jf().b,c=a.body;return!!(c.webkitRequestFullscreen||c.mozRequestFullScreen&&a.mozFullScreenEnabled||c.msRequestFullscreen&&a.msFullscreenEnabled||c.requestFullscreen&&a.fullscreenEnabled)} +function zg(a){a.webkitRequestFullscreen?a.webkitRequestFullscreen():a.mozRequestFullScreen?a.mozRequestFullScreen():a.msRequestFullscreen?a.msRequestFullscreen():a.requestFullscreen&&a.requestFullscreen()}function Ag(){var a=jf().b;return!!(a.webkitIsFullScreen||a.mozFullScreen||a.msFullscreenElement||a.fullscreenElement)};function Bg(a){a=a?a:{};this.f=void 0!==a.className?a.className:"ol-full-screen";var c=void 0!==a.label?a.label:"\u2922";this.l="string"===typeof c?document.createTextNode(c):c;c=void 0!==a.labelActive?a.labelActive:"\u00d7";this.o="string"===typeof c?document.createTextNode(c):c;c=a.tipLabel?a.tipLabel:"Toggle full-screen";c=pf("BUTTON",{"class":this.f+"-"+Ag(),type:"button",title:c},this.l);C(c,"click",this.M,this);var d=this.f+" ol-unselectable ol-control "+(yg()?"":"ol-unsupported"),c=pf("DIV", +d,c);Jf.call(this,{element:c,target:a.target});this.B=void 0!==a.keys?a.keys:!1;this.j=a.source}y(Bg,Jf); +Bg.prototype.M=function(a){a.preventDefault();yg()&&(a=this.a)&&(Ag()?(a=jf().b,a.webkitCancelFullScreen?a.webkitCancelFullScreen():a.mozCancelFullScreen?a.mozCancelFullScreen():a.msExitFullscreen?a.msExitFullscreen():a.exitFullscreen&&a.exitFullscreen()):(a=this.j?mf(this.j):a.tc(),this.B?a.mozRequestFullScreenWithKeys?a.mozRequestFullScreenWithKeys():a.webkitRequestFullscreen?a.webkitRequestFullscreen():zg(a):zg(a)))}; +Bg.prototype.v=function(){var a=this.element.firstElementChild,c=this.a;Ag()?(a.className=this.f+"-true",vf(this.o,this.l)):(a.className=this.f+"-false",vf(this.l,this.o));c&&c.Sc()};Bg.prototype.setMap=function(a){Bg.ia.setMap.call(this,a);a&&this.s.push(C(qa.document,xg,this.v,this))};function Cg(a){a=a?a:{};var c=document.createElement("DIV");c.className=void 0!==a.className?a.className:"ol-mouse-position";Jf.call(this,{element:c,render:a.render?a.render:Dg,target:a.target});C(this,rb("projection"),this.Yl,this);a.coordinateFormat&&this.$h(a.coordinateFormat);a.projection&&this.dh(Ic(a.projection));this.v=void 0!==a.undefinedHTML?a.undefinedHTML:"";this.j=c.innerHTML;this.o=this.l=this.f=null}y(Cg,Jf); +function Dg(a){a=a.frameState;a?this.f!=a.viewState.projection&&(this.f=a.viewState.projection,this.l=null):this.f=null;Eg(this,this.o)}l=Cg.prototype;l.Yl=function(){this.l=null};l.xg=function(){return this.get("coordinateFormat")};l.bh=function(){return this.get("projection")};l.Tk=function(a){this.o=this.a.Nd(a);Eg(this,this.o)};l.Uk=function(){Eg(this,null);this.o=null};l.setMap=function(a){Cg.ia.setMap.call(this,a);a&&(a=a.a,this.s.push(C(a,"mousemove",this.Tk,this),C(a,"mouseout",this.Uk,this)))}; +l.$h=function(a){this.set("coordinateFormat",a)};l.dh=function(a){this.set("projection",a)};function Eg(a,c){var d=a.v;if(c&&a.f){if(!a.l){var e=a.bh();a.l=e?Lc(a.f,e):ad}if(e=a.a.Ma(c))a.l(e,e),d=(d=a.xg())?d(e):e.toString()}a.j&&d==a.j||(a.element.innerHTML=d,a.j=d)};function Fg(a,c){var d=a;c&&(d=ma(a,c));!ga(aa.setImmediate)||aa.Window&&aa.Window.prototype&&!Ne("Edge")&&aa.Window.prototype.setImmediate==aa.setImmediate?(Gg||(Gg=Hg()),Gg(d)):aa.setImmediate(d)}var Gg; +function Hg(){var a=aa.MessageChannel;"undefined"===typeof a&&"undefined"!==typeof window&&window.postMessage&&window.addEventListener&&!Ne("Presto")&&(a=function(){var a=document.createElement("IFRAME");a.style.display="none";a.src="";document.documentElement.appendChild(a);var c=a.contentWindow,a=c.document;a.open();a.write("");a.close();var d="callImmediate"+Math.random(),e="file:"==c.location.protocol?"*":c.location.protocol+"//"+c.location.host,a=ma(function(a){if(("*"==e||a.origin==e)&&a.data== +d)this.port1.onmessage()},this);c.addEventListener("message",a,!1);this.port1={};this.port2={postMessage:function(){c.postMessage(d,e)}}});if("undefined"!==typeof a&&!Ne("Trident")&&!Ne("MSIE")){var c=new a,d={},e=d;c.port1.onmessage=function(){if(void 0!==d.next){d=d.next;var a=d.ng;d.ng=null;a()}};return function(a){e.next={ng:a};e=e.next;c.port2.postMessage(0)}}return"undefined"!==typeof document&&"onreadystatechange"in document.createElement("SCRIPT")?function(a){var c=document.createElement("SCRIPT"); +c.onreadystatechange=function(){c.onreadystatechange=null;c.parentNode.removeChild(c);c=null;a();a=null};document.documentElement.appendChild(c)}:function(a){aa.setTimeout(a,0)}};function Ig(a,c,d){gb.call(this,a);this.b=c;a=d?d:{};this.buttons=Jg(a);this.pressure=Kg(a,this.buttons);this.bubbles="bubbles"in a?a.bubbles:!1;this.cancelable="cancelable"in a?a.cancelable:!1;this.view="view"in a?a.view:null;this.detail="detail"in a?a.detail:null;this.screenX="screenX"in a?a.screenX:0;this.screenY="screenY"in a?a.screenY:0;this.clientX="clientX"in a?a.clientX:0;this.clientY="clientY"in a?a.clientY:0;this.button="button"in a?a.button:0;this.relatedTarget="relatedTarget"in a?a.relatedTarget: +null;this.pointerId="pointerId"in a?a.pointerId:0;this.width="width"in a?a.width:0;this.height="height"in a?a.height:0;this.pointerType="pointerType"in a?a.pointerType:"";this.isPrimary="isPrimary"in a?a.isPrimary:!1;c.preventDefault&&(this.preventDefault=function(){c.preventDefault()})}y(Ig,gb);function Jg(a){if(a.buttons||Lg)a=a.buttons;else switch(a.which){case 1:a=1;break;case 2:a=4;break;case 3:a=2;break;default:a=0}return a} +function Kg(a,c){var d=0;a.pressure?d=a.pressure:d=c?.5:0;return d}var Lg=!1;try{Lg=1===(new MouseEvent("click",{buttons:1})).buttons}catch(a){};function Mg(a,c){var d=document.createElement("CANVAS");a&&(d.width=a);c&&(d.height=c);return d.getContext("2d")} +var Ng=function(){var a;return function(){if(void 0===a){var c=document.createElement("P"),d,e={webkitTransform:"-webkit-transform",OTransform:"-o-transform",msTransform:"-ms-transform",MozTransform:"-moz-transform",transform:"transform"};document.body.appendChild(c);for(var f in e)f in c.style&&(c.style[f]="translate(1px,1px)",d=qa.getComputedStyle(c).getPropertyValue(e[f]));document.body.removeChild(c);a=d&&"none"!==d}return a}}(),Og=function(){var a;return function(){if(void 0===a){var c=document.createElement("P"), +d,e={webkitTransform:"-webkit-transform",OTransform:"-o-transform",msTransform:"-ms-transform",MozTransform:"-moz-transform",transform:"transform"};document.body.appendChild(c);for(var f in e)f in c.style&&(c.style[f]="translate3d(1px,1px,1px)",d=qa.getComputedStyle(c).getPropertyValue(e[f]));document.body.removeChild(c);a=d&&"none"!==d}return a}}(); +function Pg(a,c){var d=a.style;d.WebkitTransform=c;d.MozTransform=c;d.b=c;d.msTransform=c;d.transform=c;Se&&cf("9.0")&&(a.style.transformOrigin="0 0")}function Qg(a,c){var d;if(Og()){var e=Array(16);for(d=0;16>d;++d)e[d]=c[d].toFixed(6);Pg(a,"matrix3d("+e.join(",")+")")}else if(Ng()){var e=[c[0],c[1],c[4],c[5],c[12],c[13]],f=Array(6);for(d=0;6>d;++d)f[d]=e[d].toFixed(6);Pg(a,"matrix("+f.join(",")+")")}else a.style.left=Math.round(c[12])+"px",a.style.top=Math.round(c[13])+"px"};var Rg=["experimental-webgl","webgl","webkit-3d","moz-webgl"];function Sg(a,c){var d,e,f=Rg.length;for(e=0;e<f;++e)try{if(d=a.getContext(Rg[e],c))return d}catch(g){}return null};var Tg,Ug="undefined"!==typeof navigator?navigator.userAgent.toLowerCase():"",Vg=-1!==Ug.indexOf("firefox"),Wg=-1!==Ug.indexOf("safari")&&-1===Ug.indexOf("chrom"),Xg=-1!==Ug.indexOf("macintosh"),Yg=qa.devicePixelRatio||1,Zg=!1,$g=function(){if(!("HTMLCanvasElement"in qa))return!1;try{var a=Mg();return a?(void 0!==a.setLineDash&&(Zg=!0),!0):!1}catch(c){return!1}}(),ah="DeviceOrientationEvent"in qa,bh="geolocation"in qa.navigator,ch="ontouchstart"in qa,dh="PointerEvent"in qa,eh=!!qa.navigator.msPointerEnabled, +fh=!1,gh,hh=[];if("WebGLRenderingContext"in qa)try{var ih=Sg(document.createElement("CANVAS"),{failIfMajorPerformanceCaveat:!0});ih&&(fh=!0,gh=ih.getParameter(ih.MAX_TEXTURE_SIZE),hh=ih.getSupportedExtensions())}catch(a){}Tg=fh;oa=hh;na=gh;function jh(a,c){this.b=a;this.c=c};function kh(a){jh.call(this,a,{mousedown:this.nl,mousemove:this.ol,mouseup:this.rl,mouseover:this.ql,mouseout:this.pl});this.a=a.g;this.g=[]}y(kh,jh);function lh(a,c){for(var d=a.g,e=c.clientX,f=c.clientY,g=0,h=d.length,k;g<h&&(k=d[g]);g++){var m=Math.abs(f-k[1]);if(25>=Math.abs(e-k[0])&&25>=m)return!0}return!1}function mh(a){var c=nh(a,a),d=c.preventDefault;c.preventDefault=function(){a.preventDefault();d()};c.pointerId=1;c.isPrimary=!0;c.pointerType="mouse";return c}l=kh.prototype; +l.nl=function(a){if(!lh(this,a)){if((1).toString()in this.a){var c=mh(a);oh(this.b,ph,c,a);delete this.a[(1).toString()]}c=mh(a);this.a[(1).toString()]=a;oh(this.b,qh,c,a)}};l.ol=function(a){if(!lh(this,a)){var c=mh(a);oh(this.b,rh,c,a)}};l.rl=function(a){if(!lh(this,a)){var c=this.a[(1).toString()];c&&c.button===a.button&&(c=mh(a),oh(this.b,sh,c,a),delete this.a[(1).toString()])}};l.ql=function(a){if(!lh(this,a)){var c=mh(a);th(this.b,c,a)}}; +l.pl=function(a){if(!lh(this,a)){var c=mh(a);uh(this.b,c,a)}};function vh(a){jh.call(this,a,{MSPointerDown:this.wl,MSPointerMove:this.xl,MSPointerUp:this.Al,MSPointerOut:this.yl,MSPointerOver:this.zl,MSPointerCancel:this.vl,MSGotPointerCapture:this.tl,MSLostPointerCapture:this.ul});this.a=a.g;this.g=["","unavailable","touch","pen","mouse"]}y(vh,jh);function wh(a,c){var d=c;fa(c.pointerType)&&(d=nh(c,c),d.pointerType=a.g[c.pointerType]);return d}l=vh.prototype;l.wl=function(a){this.a[a.pointerId.toString()]=a;var c=wh(this,a);oh(this.b,qh,c,a)}; +l.xl=function(a){var c=wh(this,a);oh(this.b,rh,c,a)};l.Al=function(a){var c=wh(this,a);oh(this.b,sh,c,a);delete this.a[a.pointerId.toString()]};l.yl=function(a){var c=wh(this,a);uh(this.b,c,a)};l.zl=function(a){var c=wh(this,a);th(this.b,c,a)};l.vl=function(a){var c=wh(this,a);oh(this.b,ph,c,a);delete this.a[a.pointerId.toString()]};l.ul=function(a){this.b.b(new Ig("lostpointercapture",a,a))};l.tl=function(a){this.b.b(new Ig("gotpointercapture",a,a))};function xh(a){jh.call(this,a,{pointerdown:this.eo,pointermove:this.fo,pointerup:this.jo,pointerout:this.ho,pointerover:this.io,pointercancel:this.co,gotpointercapture:this.Ck,lostpointercapture:this.ml})}y(xh,jh);l=xh.prototype;l.eo=function(a){yh(this.b,a)};l.fo=function(a){yh(this.b,a)};l.jo=function(a){yh(this.b,a)};l.ho=function(a){yh(this.b,a)};l.io=function(a){yh(this.b,a)};l.co=function(a){yh(this.b,a)};l.ml=function(a){yh(this.b,a)};l.Ck=function(a){yh(this.b,a)};function zh(a,c){jh.call(this,a,{touchstart:this.mp,touchmove:this.lp,touchend:this.kp,touchcancel:this.jp});this.a=a.g;this.l=c;this.g=void 0;this.i=0;this.f=void 0}y(zh,jh);l=zh.prototype;l.Yh=function(){this.i=0;this.f=void 0}; +function Ah(a,c,d){c=nh(c,d);c.pointerId=d.identifier+2;c.bubbles=!0;c.cancelable=!0;c.detail=a.i;c.button=0;c.buttons=1;c.width=d.webkitRadiusX||d.radiusX||0;c.height=d.webkitRadiusY||d.radiusY||0;c.pressure=d.webkitForce||d.force||.5;c.isPrimary=a.g===d.identifier;c.pointerType="touch";c.clientX=d.clientX;c.clientY=d.clientY;c.screenX=d.screenX;c.screenY=d.screenY;return c} +function Bh(a,c,d){function e(){c.preventDefault()}var f=Array.prototype.slice.call(c.changedTouches),g=f.length,h,k;for(h=0;h<g;++h)k=Ah(a,c,f[h]),k.preventDefault=e,d.call(a,c,k)} +l.mp=function(a){var c=a.touches,d=Object.keys(this.a),e=d.length;if(e>=c.length){var f=[],g,h,k;for(g=0;g<e;++g){h=d[g];k=this.a[h];var m;if(!(m=1==h))a:{m=c.length;for(var n=void 0,p=0;p<m;p++)if(n=c[p],n.identifier===h-2){m=!0;break a}m=!1}m||f.push(k.out)}for(g=0;g<f.length;++g)this.Qe(a,f[g])}c=a.changedTouches[0];d=Object.keys(this.a).length;if(0===d||1===d&&(1).toString()in this.a)this.g=c.identifier,void 0!==this.f&&qa.clearTimeout(this.f);Ch(this,a);this.i++;Bh(this,a,this.Zn)}; +l.Zn=function(a,c){this.a[c.pointerId]={target:c.target,out:c,Gh:c.target};var d=this.b;c.bubbles=!0;oh(d,Dh,c,a);d=this.b;c.bubbles=!1;oh(d,Eh,c,a);oh(this.b,qh,c,a)};l.lp=function(a){a.preventDefault();Bh(this,a,this.sl)};l.sl=function(a,c){var d=this.a[c.pointerId];if(d){var e=d.out,f=d.Gh;oh(this.b,rh,c,a);e&&f!==c.target&&(e.relatedTarget=c.target,c.relatedTarget=f,e.target=f,c.target?(uh(this.b,e,a),th(this.b,c,a)):(c.target=f,c.relatedTarget=null,this.Qe(a,c)));d.out=c;d.Gh=c.target}}; +l.kp=function(a){Ch(this,a);Bh(this,a,this.np)};l.np=function(a,c){oh(this.b,sh,c,a);this.b.out(c,a);var d=this.b;c.bubbles=!1;oh(d,Fh,c,a);delete this.a[c.pointerId];c.isPrimary&&(this.g=void 0,this.f=qa.setTimeout(this.Yh.bind(this),200))};l.jp=function(a){Bh(this,a,this.Qe)};l.Qe=function(a,c){oh(this.b,ph,c,a);this.b.out(c,a);var d=this.b;c.bubbles=!1;oh(d,Fh,c,a);delete this.a[c.pointerId];c.isPrimary&&(this.g=void 0,this.f=qa.setTimeout(this.Yh.bind(this),200))}; +function Ch(a,c){var d=a.l.g,e=c.changedTouches[0];if(a.g===e.identifier){var f=[e.clientX,e.clientY];d.push(f);qa.setTimeout(function(){yb(d,f)},2500)}};function Gh(a){jb.call(this);this.i=a;this.g={};this.c={};this.a=[];dh?Hh(this,new xh(this)):eh?Hh(this,new vh(this)):(a=new kh(this),Hh(this,a),ch&&Hh(this,new zh(this,a)));a=this.a.length;for(var c,d=0;d<a;d++)c=this.a[d],Ih(this,Object.keys(c.c))}y(Gh,jb);function Hh(a,c){var d=Object.keys(c.c);d&&(d.forEach(function(a){var d=c.c[a];d&&(this.c[a]=d.bind(c))},a),a.a.push(c))}Gh.prototype.f=function(a){var c=this.c[a.type];c&&c(a)}; +function Ih(a,c){c.forEach(function(a){C(this.i,a,this.f,this)},a)}function Jh(a,c){c.forEach(function(a){cb(this.i,a,this.f,this)},a)}function nh(a,c){for(var d={},e,f=0,g=Kh.length;f<g;f++)e=Kh[f][0],d[e]=a[e]||c[e]||Kh[f][1];return d}Gh.prototype.out=function(a,c){a.bubbles=!0;oh(this,Lh,a,c)};function uh(a,c,d){a.out(c,d);var e=c.relatedTarget;e&&wf(c.target,e)||(c.bubbles=!1,oh(a,Fh,c,d))} +function th(a,c,d){c.bubbles=!0;oh(a,Dh,c,d);var e=c.relatedTarget;e&&wf(c.target,e)||(c.bubbles=!1,oh(a,Eh,c,d))}function oh(a,c,d,e){a.b(new Ig(c,e,d))}function yh(a,c){a.b(new Ig(c.type,c,c))}Gh.prototype.fa=function(){for(var a=this.a.length,c,d=0;d<a;d++)c=this.a[d],Jh(this,Object.keys(c.c));Gh.ia.fa.call(this)}; +var rh="pointermove",qh="pointerdown",sh="pointerup",Dh="pointerover",Lh="pointerout",Eh="pointerenter",Fh="pointerleave",ph="pointercancel",Kh=[["bubbles",!1],["cancelable",!1],["view",null],["detail",null],["screenX",0],["screenY",0],["clientX",0],["clientY",0],["ctrlKey",!1],["altKey",!1],["shiftKey",!1],["metaKey",!1],["button",0],["relatedTarget",null],["buttons",0],["pointerId",0],["width",0],["height",0],["pressure",0],["tiltX",0],["tiltY",0],["pointerType",""],["hwTimestamp",0],["isPrimary", +!1],["type",""],["target",null],["currentTarget",null],["which",0]];function Mh(a,c,d,e,f){If.call(this,a,c,f);this.originalEvent=d;this.pixel=c.Nd(d);this.coordinate=c.Ma(this.pixel);this.dragging=void 0!==e?e:!1}y(Mh,If);Mh.prototype.preventDefault=function(){Mh.ia.preventDefault.call(this);this.originalEvent.preventDefault()};Mh.prototype.stopPropagation=function(){Mh.ia.stopPropagation.call(this);this.originalEvent.stopPropagation()};function Nh(a,c,d,e,f){Mh.call(this,a,c,d.b,e,f);this.b=d}y(Nh,Mh); +function Oh(a){jb.call(this);this.f=a;this.l=0;this.o=!1;this.c=[];this.g=null;a=this.f.a;this.U=0;this.v={};this.i=new Gh(a);this.a=null;this.j=C(this.i,qh,this.Wk,this);this.s=C(this.i,rh,this.Ho,this)}y(Oh,jb);function Ph(a,c){var d;d=new Nh(Qh,a.f,c);a.b(d);0!==a.l?(qa.clearTimeout(a.l),a.l=0,d=new Nh(Rh,a.f,c),a.b(d)):a.l=qa.setTimeout(function(){this.l=0;var a=new Nh(Sh,this.f,c);this.b(a)}.bind(a),250)} +function Th(a,c){c.type==Uh||c.type==Vh?delete a.v[c.pointerId]:c.type==Wh&&(a.v[c.pointerId]=!0);a.U=Object.keys(a.v).length}l=Oh.prototype;l.Lg=function(a){Th(this,a);var c=new Nh(Uh,this.f,a);this.b(c);!this.o&&0===a.button&&Ph(this,this.g);0===this.U&&(this.c.forEach(Xa),this.c.length=0,this.o=!1,this.g=null,fb(this.a),this.a=null)}; +l.Wk=function(a){Th(this,a);var c=new Nh(Wh,this.f,a);this.b(c);this.g=a;0===this.c.length&&(this.a=new Gh(document),this.c.push(C(this.a,Xh,this.Ol,this),C(this.a,Uh,this.Lg,this),C(this.i,Vh,this.Lg,this)))};l.Ol=function(a){if(a.clientX!=this.g.clientX||a.clientY!=this.g.clientY){this.o=!0;var c=new Nh(Yh,this.f,a,this.o);this.b(c)}a.preventDefault()};l.Ho=function(a){this.b(new Nh(a.type,this.f,a,!(!this.g||a.clientX==this.g.clientX&&a.clientY==this.g.clientY)))}; +l.fa=function(){this.s&&(Xa(this.s),this.s=null);this.j&&(Xa(this.j),this.j=null);this.c.forEach(Xa);this.c.length=0;this.a&&(fb(this.a),this.a=null);this.i&&(fb(this.i),this.i=null);Oh.ia.fa.call(this)};var Sh="singleclick",Qh="click",Rh="dblclick",Yh="pointerdrag",Xh="pointermove",Wh="pointerdown",Uh="pointerup",Vh="pointercancel",Zh={Gp:Sh,vp:Qh,wp:Rh,zp:Yh,Cp:Xh,yp:Wh,Fp:Uh,Ep:"pointerover",Dp:"pointerout",Ap:"pointerenter",Bp:"pointerleave",xp:Vh};function $h(a){pb.call(this);var c=Pa({},a);c.opacity=void 0!==a.opacity?a.opacity:1;c.visible=void 0!==a.visible?a.visible:!0;c.zIndex=void 0!==a.zIndex?a.zIndex:0;c.maxResolution=void 0!==a.maxResolution?a.maxResolution:Infinity;c.minResolution=void 0!==a.minResolution?a.minResolution:0;this.C(c)}y($h,pb); +function ai(a){var c=a.Lb(),d=a.ff(),e=a.wb(),f=a.O(),g=a.Mb(),h=a.Ib(),k=a.Jb();return{layer:a,opacity:Da(c,0,1),R:d,visible:e,Lc:!0,extent:f,zIndex:g,maxResolution:h,minResolution:Math.max(k,0)}}l=$h.prototype;l.O=function(){return this.get("extent")};l.Ib=function(){return this.get("maxResolution")};l.Jb=function(){return this.get("minResolution")};l.Lb=function(){return this.get("opacity")};l.wb=function(){return this.get("visible")};l.Mb=function(){return this.get("zIndex")}; +l.ac=function(a){this.set("extent",a)};l.ic=function(a){this.set("maxResolution",a)};l.jc=function(a){this.set("minResolution",a)};l.bc=function(a){this.set("opacity",a)};l.cc=function(a){this.set("visible",a)};l.dc=function(a){this.set("zIndex",a)};function bi(){};function ci(a,c,d,e,f,g){gb.call(this,a,c);this.vectorContext=d;this.frameState=e;this.context=f;this.glContext=g}y(ci,gb);function di(a){var c=Pa({},a);delete c.source;$h.call(this,c);this.v=this.j=this.o=null;a.map&&this.setMap(a.map);C(this,rb("source"),this.bl,this);this.Ac(a.source?a.source:null)}y(di,$h);function ei(a,c){return a.visible&&c>=a.minResolution&&c<a.maxResolution}l=di.prototype;l.df=function(a){a=a?a:[];a.push(ai(this));return a};l.da=function(){return this.get("source")||null};l.ff=function(){var a=this.da();return a?a.V():"undefined"};l.Fm=function(){this.u()}; +l.bl=function(){this.v&&(Xa(this.v),this.v=null);var a=this.da();a&&(this.v=C(a,"change",this.Fm,this));this.u()};l.setMap=function(a){this.o&&(Xa(this.o),this.o=null);a||this.u();this.j&&(Xa(this.j),this.j=null);a&&(this.o=C(a,"precompose",function(a){var d=ai(this);d.Lc=!1;d.zIndex=Infinity;a.frameState.layerStatesArray.push(d);a.frameState.layerStates[w(this)]=d},this),this.j=C(this,"change",a.render,a),this.u())};l.Ac=function(a){this.set("source",a)};function fi(a,c,d,e,f){jb.call(this);this.l=f;this.extent=a;this.f=d;this.resolution=c;this.state=e}y(fi,jb);function gi(a){a.b("change")}fi.prototype.O=function(){return this.extent};fi.prototype.$=function(){return this.resolution};fi.prototype.V=function(){return this.state};function hi(a,c,d,e,f,g,h,k){ld(a);0===c&&0===d||od(a,c,d);1==e&&1==f||pd(a,e,f);0!==g&&qd(a,g);0===h&&0===k||od(a,h,k);return a}function ii(a,c){return a[0]==c[0]&&a[1]==c[1]&&a[4]==c[4]&&a[5]==c[5]&&a[12]==c[12]&&a[13]==c[13]}function ji(a,c,d){var e=a[1],f=a[5],g=a[13],h=c[0];c=c[1];d[0]=a[0]*h+a[4]*c+a[12];d[1]=e*h+f*c+g;return d};function ki(a){mb.call(this);this.a=a}y(ki,mb);l=ki.prototype;l.oa=pa;l.xc=function(a,c,d,e){a=a.slice();ji(c.pixelToCoordinateMatrix,a,a);if(this.oa(a,c,Ac,this))return d.call(e,this.a)};l.ge=Bc;l.Ld=function(a,c,d){return function(e,f){return mg(a,c,e,f,function(a){d[e]||(d[e]={});d[e][a.ja.toString()]=a})}};l.Im=function(a){2===a.target.V()&&li(this)};function mi(a,c){var d=c.V();2!=d&&3!=d&&C(c,"change",a.Im,a);0==d&&(c.load(),d=c.V());return 2==d} +function li(a){var c=a.a;c.wb()&&"ready"==c.ff()&&a.u()}function ni(a,c){c.vh()&&a.postRenderFunctions.push(function(a,c,f){c=w(a).toString();a.Gc(f.viewState.projection,f.usedTiles[c])}.bind(null,c))}function oi(a,c){if(c){var d,e,f;e=0;for(f=c.length;e<f;++e)d=c[e],a[w(d).toString()]=d}}function pi(a,c){var d=c.R;void 0!==d&&("string"===typeof d?a.logos[d]="":ha(d)&&(a.logos[d.src]=d.href))} +function qi(a,c,d,e){c=w(c).toString();d=d.toString();c in a?d in a[c]?(a=a[c][d],e.b<a.b&&(a.b=e.b),e.a>a.a&&(a.a=e.a),e.g<a.g&&(a.g=e.g),e.f>a.f&&(a.f=e.f)):a[c][d]=e:(a[c]={},a[c][d]=e)}function ri(a,c,d){return[c*(Math.round(a[0]/c)+d[0]%2/2),c*(Math.round(a[1]/c)+d[1]%2/2)]} +function si(a,c,d,e,f,g,h,k,m,n){var p=w(c).toString();p in a.wantedTiles||(a.wantedTiles[p]={});var q=a.wantedTiles[p];a=a.tileQueue;var r=d.minZoom,u,v,x,z,E,B;for(B=h;B>=r;--B)for(v=bg(d,g,B,v),x=d.$(B),z=v.b;z<=v.a;++z)for(E=v.g;E<=v.f;++E)h-B<=k?(u=c.Wb(B,z,E,e,f),0==u.V()&&(q[u.ja.toString()]=!0,u.gb()in a.g||a.f([u,p,fg(d,u.ja),x])),void 0!==m&&m.call(n,u)):c.Uf(B,z,E,f)};function ti(a){this.v=a.opacity;this.U=a.rotateWithView;this.j=a.rotation;this.i=a.scale;this.M=a.snapToPixel}l=ti.prototype;l.le=function(){return this.v};l.Rd=function(){return this.U};l.me=function(){return this.j};l.ne=function(){return this.i};l.Sd=function(){return this.M};l.oe=function(a){this.v=a};l.pe=function(a){this.j=a};l.qe=function(a){this.i=a};function ui(a){a=a||{};this.c=void 0!==a.anchor?a.anchor:[.5,.5];this.f=null;this.a=void 0!==a.anchorOrigin?a.anchorOrigin:"top-left";this.o=void 0!==a.anchorXUnits?a.anchorXUnits:"fraction";this.s=void 0!==a.anchorYUnits?a.anchorYUnits:"fraction";var c=void 0!==a.crossOrigin?a.crossOrigin:null,d=void 0!==a.img?a.img:null,e=void 0!==a.imgSize?a.imgSize:null,f=a.src;void 0!==f&&0!==f.length||!d||(f=d.src||w(d).toString());var g=void 0!==a.src?0:2,h=void 0!==a.color?Fe(a.color):null,k=vi.Ub(),m=k.get(f, +c,h);m||(m=new wi(d,f,e,c,g,h),k.set(f,c,h,m));this.b=m;this.N=void 0!==a.offset?a.offset:[0,0];this.g=void 0!==a.offsetOrigin?a.offsetOrigin:"top-left";this.l=null;this.B=void 0!==a.size?a.size:null;ti.call(this,{opacity:void 0!==a.opacity?a.opacity:1,rotation:void 0!==a.rotation?a.rotation:0,scale:void 0!==a.scale?a.scale:1,snapToPixel:void 0!==a.snapToPixel?a.snapToPixel:!0,rotateWithView:void 0!==a.rotateWithView?a.rotateWithView:!1})}y(ui,ti);l=ui.prototype; +l.Tb=function(){if(this.f)return this.f;var a=this.c,c=this.Bb();if("fraction"==this.o||"fraction"==this.s){if(!c)return null;a=this.c.slice();"fraction"==this.o&&(a[0]*=c[0]);"fraction"==this.s&&(a[1]*=c[1])}if("top-left"!=this.a){if(!c)return null;a===this.c&&(a=this.c.slice());if("top-right"==this.a||"bottom-right"==this.a)a[0]=-a[0]+c[0];if("bottom-left"==this.a||"bottom-right"==this.a)a[1]=-a[1]+c[1]}return this.f=a};l.ec=function(){var a=this.b;return a.c?a.c:a.a};l.fd=function(){return this.b.g}; +l.od=function(){return this.b.f};l.ke=function(){var a=this.b;if(!a.o)if(a.s){var c=a.g[0],d=a.g[1],e=Mg(c,d);e.fillRect(0,0,c,d);a.o=e.canvas}else a.o=a.a;return a.o};l.Fa=function(){if(this.l)return this.l;var a=this.N;if("top-left"!=this.g){var c=this.Bb(),d=this.b.g;if(!c||!d)return null;a=a.slice();if("top-right"==this.g||"bottom-right"==this.g)a[0]=d[0]-c[0]-a[0];if("bottom-left"==this.g||"bottom-right"==this.g)a[1]=d[1]-c[1]-a[1]}return this.l=a};l.yn=function(){return this.b.j}; +l.Bb=function(){return this.B?this.B:this.b.g};l.kf=function(a,c){return C(this.b,"change",a,c)};l.load=function(){this.b.load()};l.Tf=function(a,c){cb(this.b,"change",a,c)};function wi(a,c,d,e,f,g){jb.call(this);this.o=null;this.a=a?a:new Image;null!==e&&(this.a.crossOrigin=e);this.c=g?document.createElement("CANVAS"):null;this.l=g;this.i=null;this.f=f;this.g=d;this.j=c;this.s=!1;2==this.f&&xi(this)}y(wi,jb); +function xi(a){var c=Mg(1,1);try{c.drawImage(a.a,0,0),c.getImageData(0,0,1,1)}catch(d){a.s=!0}}wi.prototype.v=function(){this.f=3;this.i.forEach(Xa);this.i=null;this.b("change")}; +wi.prototype.U=function(){this.f=2;this.g&&(this.a.width=this.g[0],this.a.height=this.g[1]);this.g=[this.a.width,this.a.height];this.i.forEach(Xa);this.i=null;xi(this);if(!this.s&&null!==this.l){this.c.width=this.a.width;this.c.height=this.a.height;var a=this.c.getContext("2d");a.drawImage(this.a,0,0);for(var c=a.getImageData(0,0,this.a.width,this.a.height),d=c.data,e=this.l[0]/255,f=this.l[1]/255,g=this.l[2]/255,h=0,k=d.length;h<k;h+=4)d[h]*=e,d[h+1]*=f,d[h+2]*=g;a.putImageData(c,0,0)}this.b("change")}; +wi.prototype.load=function(){if(0==this.f){this.f=1;this.i=[bb(this.a,"error",this.v,this),bb(this.a,"load",this.U,this)];try{this.a.src=this.j}catch(a){this.v()}}};function vi(){this.b={};this.a=0}ba(vi);vi.prototype.clear=function(){this.b={};this.a=0};vi.prototype.get=function(a,c,d){a=c+":"+a+":"+(d?He(d):"null");return a in this.b?this.b[a]:null};vi.prototype.set=function(a,c,d,e){this.b[c+":"+a+":"+(d?He(d):"null")]=e;++this.a};function yi(a,c){this.i=c;this.g={};this.s={}}y(yi,eb);function zi(a){var c=a.viewState,d=a.coordinateToPixelMatrix;hi(d,a.size[0]/2,a.size[1]/2,1/c.resolution,-1/c.resolution,-c.rotation,-c.center[0],-c.center[1]);nd(d,a.pixelToCoordinateMatrix)}l=yi.prototype;l.fa=function(){for(var a in this.g)fb(this.g[a])};function Ai(){var a=vi.Ub();if(32<a.a){var c=0,d,e;for(d in a.b)e=a.b[d],0!==(c++&3)||lb(e)||(delete a.b[d],--a.a)}} +l.oa=function(a,c,d,e,f,g){function h(a,f){var g=w(a).toString(),h=c.layerStates[w(f)].Lc;if(!(g in c.skippedFeatureUids)||h)return d.call(e,a,h?f:null)}var k,m=c.viewState,n=m.resolution,p=m.projection,m=a;if(p.a){var p=p.O(),q=rc(p),r=a[0];if(r<p[0]||r>p[2])m=[r+q*Math.ceil((p[0]-r)/q),a[1]]}p=c.layerStatesArray;for(q=p.length-1;0<=q;--q){var u=p[q],r=u.layer;if(ei(u,n)&&f.call(g,r)&&(u=Bi(this,r),r.da()&&(k=u.oa(r.da().N?m:a,c,h,e)),k))return k}}; +l.mh=function(a,c,d,e,f,g){var h,k=c.viewState.resolution,m=c.layerStatesArray,n;for(n=m.length-1;0<=n;--n){h=m[n];var p=h.layer;if(ei(h,k)&&f.call(g,p)&&(h=Bi(this,p).xc(a,c,d,e)))return h}};l.nh=function(a,c,d,e){return void 0!==this.oa(a,c,Ac,this,d,e)};function Bi(a,c){var d=w(c).toString();if(d in a.g)return a.g[d];var e=a.Te(c);a.g[d]=e;a.s[d]=C(e,"change",a.Nk,a);return e}l.Nk=function(){this.i.render()};l.xe=pa; +l.No=function(a,c){for(var d in this.g)if(!(c&&d in c.layerStates)){var e=d,f=this.g[e];delete this.g[e];Xa(this.s[e]);delete this.s[e];fb(f)}};function Ci(a,c){for(var d in a.g)if(!(d in c.layerStates)){c.postRenderFunctions.push(a.No.bind(a));break}}function Cb(a,c){return a.zIndex-c.zIndex};function Di(a,c){this.j=a;this.l=c;this.b=[];this.a=[];this.g={}}Di.prototype.clear=function(){this.b.length=0;this.a.length=0;Qa(this.g)};function Ei(a){var c=a.b,d=a.a,e=c[0];1==c.length?(c.length=0,d.length=0):(c[0]=c.pop(),d[0]=d.pop(),Fi(a,0));c=a.l(e);delete a.g[c];return e}Di.prototype.f=function(a){var c=this.j(a);return Infinity!=c?(this.b.push(a),this.a.push(c),this.g[this.l(a)]=!0,Gi(this,0,this.b.length-1),!0):!1};Di.prototype.rc=function(){return this.b.length}; +Di.prototype.Sa=function(){return 0===this.b.length};function Fi(a,c){for(var d=a.b,e=a.a,f=d.length,g=d[c],h=e[c],k=c;c<f>>1;){var m=2*c+1,n=2*c+2,m=n<f&&e[n]<e[m]?n:m;d[c]=d[m];e[c]=e[m];c=m}d[c]=g;e[c]=h;Gi(a,k,c)}function Gi(a,c,d){var e=a.b;a=a.a;for(var f=e[d],g=a[d];d>c;){var h=d-1>>1;if(a[h]>g)e[d]=e[h],a[d]=a[h],d=h;else break}e[d]=f;a[d]=g} +function Hi(a){var c=a.j,d=a.b,e=a.a,f=0,g=d.length,h,k,m;for(k=0;k<g;++k)h=d[k],m=c(h),Infinity==m?delete a.g[a.l(h)]:(e[f]=m,d[f++]=h);d.length=f;e.length=f;for(c=(a.b.length>>1)-1;0<=c;c--)Fi(a,c)};function Ii(a,c){Di.call(this,function(c){return a.apply(null,c)},function(a){return a[0].gb()});this.s=c;this.i=0;this.c={}}y(Ii,Di);Ii.prototype.f=function(a){var c=Ii.ia.f.call(this,a);c&&C(a[0],"change",this.o,this);return c};Ii.prototype.o=function(a){a=a.target;var c=a.V();if(2===c||3===c||4===c||5===c)cb(a,"change",this.o,this),a=a.gb(),a in this.c&&(delete this.c[a],--this.i),this.s()}; +function Ji(a,c,d){for(var e=0,f,g;a.i<c&&e<d&&0<a.rc();)f=Ei(a)[0],g=f.gb(),0!==f.V()||g in a.c||(a.c[g]=!0,++a.i,++e,f.load())};function Ki(a,c,d){this.f=a;this.g=c;this.i=d;this.b=[];this.a=this.c=0}function Li(a,c){var d=a.f,e=a.a,f=a.g-e,g=Math.log(a.g/a.a)/a.f;return ne({source:c,duration:g,easing:function(a){return e*(Math.exp(d*a*g)-1)/f}})};function Mi(a){pb.call(this);this.v=null;this.i(!0);this.handleEvent=a.handleEvent}y(Mi,pb);Mi.prototype.f=function(){return this.get("active")};Mi.prototype.l=function(){return this.v};Mi.prototype.i=function(a){this.set("active",a)};Mi.prototype.setMap=function(a){this.v=a};function Ni(a,c,d,e,f){if(void 0!==d){var g=c.Ka(),h=c.bb();void 0!==g&&h&&f&&0<f&&(a.Va(oe({rotation:g,duration:f,easing:je})),e&&a.Va(ne({source:h,duration:f,easing:je})));c.rotate(d,e)}} +function Oi(a,c,d,e,f){var g=c.$();d=c.constrainResolution(g,d,0);Pi(a,c,d,e,f)}function Pi(a,c,d,e,f){if(d){var g=c.$(),h=c.bb();void 0!==g&&h&&d!==g&&f&&0<f&&(a.Va(pe({resolution:g,duration:f,easing:je})),e&&a.Va(ne({source:h,duration:f,easing:je})));if(e){var k;a=c.bb();f=c.$();void 0!==a&&void 0!==f&&(k=[e[0]-d*(e[0]-a[0])/f,e[1]-d*(e[1]-a[1])/f]);c.jb(k)}c.Qb(d)}};function Qi(a){a=a?a:{};this.a=a.delta?a.delta:1;Mi.call(this,{handleEvent:Ri});this.c=void 0!==a.duration?a.duration:250}y(Qi,Mi);function Ri(a){var c=!1,d=a.originalEvent;if(a.type==Rh){var c=a.map,e=a.coordinate,d=d.shiftKey?-this.a:this.a,f=c.aa();Oi(c,f,d,e,this.c);a.preventDefault();c=!0}return!c};function Si(a){a=a.originalEvent;return a.altKey&&!(a.metaKey||a.ctrlKey)&&a.shiftKey}function Ti(a){a=a.originalEvent;return 0==a.button&&!(Ve&&Xg&&a.ctrlKey)}function Ui(a){return"pointermove"==a.type}function Vi(a){return a.type==Sh}function Wi(a){a=a.originalEvent;return!a.altKey&&!(a.metaKey||a.ctrlKey)&&!a.shiftKey}function Xi(a){a=a.originalEvent;return!a.altKey&&!(a.metaKey||a.ctrlKey)&&a.shiftKey} +function Yi(a){a=a.originalEvent.target.tagName;return"INPUT"!==a&&"SELECT"!==a&&"TEXTAREA"!==a}function Zi(a){return"mouse"==a.b.pointerType}function $i(a){a=a.b;return a.isPrimary&&0===a.button};function aj(a){a=a?a:{};Mi.call(this,{handleEvent:a.handleEvent?a.handleEvent:bj});this.Ke=a.handleDownEvent?a.handleDownEvent:Bc;this.Le=a.handleDragEvent?a.handleDragEvent:pa;this.Hi=a.handleMoveEvent?a.handleMoveEvent:pa;this.oj=a.handleUpEvent?a.handleUpEvent:Bc;this.M=!1;this.ea={};this.o=[]}y(aj,Mi);function cj(a){for(var c=a.length,d=0,e=0,f=0;f<c;f++)d+=a[f].clientX,e+=a[f].clientY;return[d/c,e/c]} +function bj(a){if(!(a instanceof Nh))return!0;var c=!1,d=a.type;if(d===Wh||d===Yh||d===Uh)d=a.b,a.type==Uh?delete this.ea[d.pointerId]:a.type==Wh?this.ea[d.pointerId]=d:d.pointerId in this.ea&&(this.ea[d.pointerId]=d),this.o=Ra(this.ea);this.M&&(a.type==Yh?this.Le(a):a.type==Uh&&(this.M=this.oj(a)));a.type==Wh?(this.M=a=this.Ke(a),c=this.Bc(a)):a.type==Xh&&this.Hi(a);return!c}aj.prototype.Bc=function(a){return a};function dj(a){aj.call(this,{handleDownEvent:ej,handleDragEvent:fj,handleUpEvent:gj});a=a?a:{};this.a=a.kinetic;this.c=this.j=null;this.B=a.condition?a.condition:Wi;this.s=!1}y(dj,aj);function fj(a){var c=cj(this.o);this.a&&this.a.b.push(c[0],c[1],Date.now());if(this.c){var d=this.c[0]-c[0],e=c[1]-this.c[1];a=a.map;var f=a.aa(),g=f.V(),e=d=[d,e],h=g.resolution;e[0]*=h;e[1]*=h;Rb(d,g.rotation);Mb(d,g.center);d=f.Kd(d);a.render();f.jb(d)}this.c=c} +function gj(a){a=a.map;var c=a.aa();if(0===this.o.length){var d;if(d=!this.s&&this.a)if(d=this.a,6>d.b.length)d=!1;else{var e=Date.now()-d.i,f=d.b.length-3;if(d.b[f+2]<e)d=!1;else{for(var g=f-3;0<g&&d.b[g+2]>e;)g-=3;var e=d.b[f+2]-d.b[g+2],h=d.b[f]-d.b[g],f=d.b[f+1]-d.b[g+1];d.c=Math.atan2(f,h);d.a=Math.sqrt(h*h+f*f)/e;d=d.a>d.g}}d&&(d=this.a,d=(d.g-d.a)/d.f,f=this.a.c,g=c.bb(),this.j=Li(this.a,g),a.Va(this.j),g=a.Da(g),d=a.Ma([g[0]-d*Math.cos(f),g[1]-d*Math.sin(f)]),d=c.Kd(d),c.jb(d));he(c,-1);a.render(); +return!1}this.c=null;return!0}function ej(a){if(0<this.o.length&&this.B(a)){var c=a.map,d=c.aa();this.c=null;this.M||he(d,1);c.render();this.j&&yb(c.R,this.j)&&(d.jb(a.frameState.viewState.center),this.j=null);this.a&&(a=this.a,a.b.length=0,a.c=0,a.a=0);this.s=1<this.o.length;return!0}return!1}dj.prototype.Bc=Bc;function hj(a){a=a?a:{};aj.call(this,{handleDownEvent:ij,handleDragEvent:jj,handleUpEvent:kj});this.c=a.condition?a.condition:Si;this.a=void 0;this.j=void 0!==a.duration?a.duration:250}y(hj,aj);function jj(a){if(Zi(a)){var c=a.map,d=c.$a();a=a.pixel;d=Math.atan2(d[1]/2-a[1],a[0]-d[0]/2);if(void 0!==this.a){a=d-this.a;var e=c.aa(),f=e.Ka();c.render();Ni(c,e,f-a)}this.a=d}} +function kj(a){if(!Zi(a))return!0;a=a.map;var c=a.aa();he(c,-1);var d=c.Ka(),e=this.j,d=c.constrainRotation(d,0);Ni(a,c,d,void 0,e);return!1}function ij(a){return Zi(a)&&Ti(a)&&this.c(a)?(a=a.map,he(a.aa(),1),a.render(),this.a=void 0,!0):!1}hj.prototype.Bc=Bc;function lj(a){this.f=null;this.a=document.createElement("div");this.a.style.position="absolute";this.a.className="ol-box "+a;this.g=this.c=this.b=null}y(lj,eb);lj.prototype.fa=function(){this.setMap(null)};function mj(a){var c=a.c,d=a.g;a=a.a.style;a.left=Math.min(c[0],d[0])+"px";a.top=Math.min(c[1],d[1])+"px";a.width=Math.abs(d[0]-c[0])+"px";a.height=Math.abs(d[1]-c[1])+"px"} +lj.prototype.setMap=function(a){if(this.b){this.b.B.removeChild(this.a);var c=this.a.style;c.left=c.top=c.width=c.height="inherit"}(this.b=a)&&this.b.B.appendChild(this.a)};function nj(a){var c=a.c,d=a.g,c=[c,[c[0],d[1]],d,[d[0],c[1]]].map(a.b.Ma,a.b);c[4]=c[0].slice();a.f?a.f.ma([c]):a.f=new F([c])}lj.prototype.W=function(){return this.f};function oj(a,c,d){gb.call(this,a);this.coordinate=c;this.mapBrowserEvent=d}y(oj,gb);function pj(a){aj.call(this,{handleDownEvent:qj,handleDragEvent:rj,handleUpEvent:sj});a=a?a:{};this.a=new lj(a.className||"ol-dragbox");this.c=null;this.N=a.condition?a.condition:Ac;this.B=a.boxEndCondition?a.boxEndCondition:tj}y(pj,aj);function tj(a,c,d){a=d[0]-c[0];c=d[1]-c[1];return 64<=a*a+c*c} +function rj(a){if(Zi(a)){var c=this.a,d=a.pixel;c.c=this.c;c.g=d;nj(c);mj(c);this.b(new oj("boxdrag",a.coordinate,a))}}pj.prototype.W=function(){return this.a.W()};pj.prototype.s=pa;function sj(a){if(!Zi(a))return!0;this.a.setMap(null);this.B(a,this.c,a.pixel)&&(this.s(a),this.b(new oj("boxend",a.coordinate,a)));return!1} +function qj(a){if(Zi(a)&&Ti(a)&&this.N(a)){this.c=a.pixel;this.a.setMap(a.map);var c=this.a,d=this.c;c.c=this.c;c.g=d;nj(c);mj(c);this.b(new oj("boxstart",a.coordinate,a));return!0}return!1};function uj(a){a=a?a:{};var c=a.condition?a.condition:Xi;this.j=void 0!==a.duration?a.duration:200;this.R=void 0!==a.out?a.out:!1;pj.call(this,{condition:c,className:a.className||"ol-dragzoom"})}y(uj,pj); +uj.prototype.s=function(){var a=this.v,c=a.aa(),d=a.$a(),e=this.W().O();if(this.R){var f=c.Fc(d),e=[a.Da(lc(e)),a.Da(nc(e))],g=ec(Infinity,Infinity,-Infinity,-Infinity,void 0),h,k;h=0;for(k=e.length;h<k;++h)Xb(g,e[h]);yc(f,1/de(g,d));e=f}d=c.constrainResolution(de(e,d));f=c.$();g=c.bb();a.Va(pe({resolution:f,duration:this.j,easing:je}));a.Va(ne({source:g,duration:this.j,easing:je}));c.jb(tc(e));c.Qb(d)};function vj(a){Mi.call(this,{handleEvent:wj});a=a||{};this.a=function(a){return Wi(a)&&Yi(a)};this.c=void 0!==a.condition?a.condition:this.a;this.o=void 0!==a.duration?a.duration:100;this.j=void 0!==a.pixelDelta?a.pixelDelta:128}y(vj,Mi); +function wj(a){var c=!1;if("keydown"==a.type){var d=a.originalEvent.keyCode;if(this.c(a)&&(40==d||37==d||39==d||38==d)){var e=a.map,c=e.aa(),f=c.$()*this.j,g=0,h=0;40==d?h=-f:37==d?g=-f:39==d?g=f:h=f;d=[g,h];Rb(d,c.Ka());f=this.o;if(g=c.bb())f&&0<f&&e.Va(ne({source:g,duration:f,easing:le})),e=c.Kd([g[0]+d[0],g[1]+d[1]]),c.jb(e);a.preventDefault();c=!0}}return!c};function xj(a){Mi.call(this,{handleEvent:yj});a=a?a:{};this.c=a.condition?a.condition:Yi;this.a=a.delta?a.delta:1;this.o=void 0!==a.duration?a.duration:100}y(xj,Mi);function yj(a){var c=!1;if("keydown"==a.type||"keypress"==a.type){var d=a.originalEvent.charCode;if(this.c(a)&&(43==d||45==d)){c=a.map;d=43==d?this.a:-this.a;c.render();var e=c.aa();Oi(c,e,d,void 0,this.o);a.preventDefault();c=!0}}return!c};function zj(a){Mi.call(this,{handleEvent:Aj});a=a||{};this.c=0;this.M=void 0!==a.duration?a.duration:250;this.s=void 0!==a.useAnchor?a.useAnchor:!0;this.a=null;this.j=this.o=void 0}y(zj,Mi); +function Aj(a){var c=!1;if("wheel"==a.type||"mousewheel"==a.type){var c=a.map,d=a.originalEvent;this.s&&(this.a=a.coordinate);var e;"wheel"==a.type?(e=d.deltaY,Vg&&d.deltaMode===qa.WheelEvent.DOM_DELTA_PIXEL&&(e/=Yg),d.deltaMode===qa.WheelEvent.DOM_DELTA_LINE&&(e*=40)):"mousewheel"==a.type&&(e=-d.wheelDeltaY,Wg&&(e/=3));this.c+=e;void 0===this.o&&(this.o=Date.now());e=Math.max(80-(Date.now()-this.o),0);qa.clearTimeout(this.j);this.j=qa.setTimeout(this.B.bind(this,c),e);a.preventDefault();c=!0}return!c} +zj.prototype.B=function(a){var c=Da(this.c,-1,1),d=a.aa();a.render();Oi(a,d,-c,this.a,this.M);this.c=0;this.a=null;this.j=this.o=void 0};zj.prototype.N=function(a){this.s=a;a||(this.a=null)};function Bj(a){aj.call(this,{handleDownEvent:Cj,handleDragEvent:Dj,handleUpEvent:Ej});a=a||{};this.c=null;this.j=void 0;this.a=!1;this.s=0;this.N=void 0!==a.threshold?a.threshold:.3;this.B=void 0!==a.duration?a.duration:250}y(Bj,aj); +function Dj(a){var c=0,d=this.o[0],e=this.o[1],d=Math.atan2(e.clientY-d.clientY,e.clientX-d.clientX);void 0!==this.j&&(c=d-this.j,this.s+=c,!this.a&&Math.abs(this.s)>this.N&&(this.a=!0));this.j=d;a=a.map;d=a.a.getBoundingClientRect();e=cj(this.o);e[0]-=d.left;e[1]-=d.top;this.c=a.Ma(e);this.a&&(d=a.aa(),e=d.Ka(),a.render(),Ni(a,d,e+c,this.c))} +function Ej(a){if(2>this.o.length){a=a.map;var c=a.aa();he(c,-1);if(this.a){var d=c.Ka(),e=this.c,f=this.B,d=c.constrainRotation(d,0);Ni(a,c,d,e,f)}return!1}return!0}function Cj(a){return 2<=this.o.length?(a=a.map,this.c=null,this.j=void 0,this.a=!1,this.s=0,this.M||he(a.aa(),1),a.render(),!0):!1}Bj.prototype.Bc=Bc;function Fj(a){aj.call(this,{handleDownEvent:Gj,handleDragEvent:Hj,handleUpEvent:Ij});a=a?a:{};this.c=null;this.s=void 0!==a.duration?a.duration:400;this.a=void 0;this.j=1}y(Fj,aj);function Hj(a){var c=1,d=this.o[0],e=this.o[1],f=d.clientX-e.clientX,d=d.clientY-e.clientY,f=Math.sqrt(f*f+d*d);void 0!==this.a&&(c=this.a/f);this.a=f;1!=c&&(this.j=c);a=a.map;var f=a.aa(),d=f.$(),e=a.a.getBoundingClientRect(),g=cj(this.o);g[0]-=e.left;g[1]-=e.top;this.c=a.Ma(g);a.render();Pi(a,f,d*c,this.c)} +function Ij(a){if(2>this.o.length){a=a.map;var c=a.aa();he(c,-1);var d=c.$(),e=this.c,f=this.s,d=c.constrainResolution(d,0,this.j-1);Pi(a,c,d,e,f);return!1}return!0}function Gj(a){return 2<=this.o.length?(a=a.map,this.c=null,this.a=void 0,this.j=1,this.M||he(a.aa(),1),a.render(),!0):!1}Fj.prototype.Bc=Bc;function Jj(a){a=a?a:{};var c=new we,d=new Ki(-.005,.05,100);(void 0!==a.altShiftDragRotate?a.altShiftDragRotate:1)&&c.push(new hj);(void 0!==a.doubleClickZoom?a.doubleClickZoom:1)&&c.push(new Qi({delta:a.zoomDelta,duration:a.zoomDuration}));(void 0!==a.dragPan?a.dragPan:1)&&c.push(new dj({kinetic:d}));(void 0!==a.pinchRotate?a.pinchRotate:1)&&c.push(new Bj);(void 0!==a.pinchZoom?a.pinchZoom:1)&&c.push(new Fj({duration:a.zoomDuration}));if(void 0!==a.keyboard?a.keyboard:1)c.push(new vj),c.push(new xj({delta:a.zoomDelta, +duration:a.zoomDuration}));(void 0!==a.mouseWheelZoom?a.mouseWheelZoom:1)&&c.push(new zj({duration:a.zoomDuration}));(void 0!==a.shiftDragZoom?a.shiftDragZoom:1)&&c.push(new uj({duration:a.zoomDuration}));return c};function Kj(a){var c=a||{};a=Pa({},c);delete a.layers;c=c.layers;$h.call(this,a);this.f=[];this.a={};C(this,rb("layers"),this.Pk,this);c?Array.isArray(c)&&(c=new we(c.slice())):c=new we;this.jh(c)}y(Kj,$h);l=Kj.prototype;l.Xd=function(){this.wb()&&this.u()}; +l.Pk=function(){this.f.forEach(Xa);this.f.length=0;var a=this.Oc();this.f.push(C(a,"add",this.Ok,this),C(a,"remove",this.Qk,this));for(var c in this.a)this.a[c].forEach(Xa);Qa(this.a);var a=a.a,d,e;c=0;for(d=a.length;c<d;c++)e=a[c],this.a[w(e).toString()]=[C(e,"propertychange",this.Xd,this),C(e,"change",this.Xd,this)];this.u()};l.Ok=function(a){a=a.element;var c=w(a).toString();this.a[c]=[C(a,"propertychange",this.Xd,this),C(a,"change",this.Xd,this)];this.u()}; +l.Qk=function(a){a=w(a.element).toString();this.a[a].forEach(Xa);delete this.a[a];this.u()};l.Oc=function(){return this.get("layers")};l.jh=function(a){this.set("layers",a)}; +l.df=function(a){var c=void 0!==a?a:[],d=c.length;this.Oc().forEach(function(a){a.df(c)});a=ai(this);var e,f;for(e=c.length;d<e;d++)f=c[d],f.opacity*=a.opacity,f.visible=f.visible&&a.visible,f.maxResolution=Math.min(f.maxResolution,a.maxResolution),f.minResolution=Math.max(f.minResolution,a.minResolution),void 0!==a.extent&&(f.extent=void 0!==f.extent?vc(f.extent,a.extent):a.extent);return c};l.ff=function(){return"ready"};function Lj(a){Fc.call(this,{code:a,units:"m",extent:Mj,global:!0,worldExtent:Nj})}y(Lj,Fc);Lj.prototype.getPointResolution=function(a,c){return a/Ea(c[1]/6378137)};var Oj=6378137*Math.PI,Mj=[-Oj,-Oj,Oj,Oj],Nj=[-180,-85,180,85],Sc="EPSG:3857 EPSG:102100 EPSG:102113 EPSG:900913 urn:ogc:def:crs:EPSG:6.18:3:3857 urn:ogc:def:crs:EPSG::3857 http://www.opengis.net/gml/srs/epsg.xml#3857".split(" ").map(function(a){return new Lj(a)}); +function Tc(a,c,d){var e=a.length;d=1<d?d:2;void 0===c&&(2<d?c=a.slice():c=Array(e));for(var f=0;f<e;f+=d)c[f]=6378137*Math.PI*a[f]/180,c[f+1]=6378137*Math.log(Math.tan(Math.PI*(a[f+1]+90)/360));return c}function Uc(a,c,d){var e=a.length;d=1<d?d:2;void 0===c&&(2<d?c=a.slice():c=Array(e));for(var f=0;f<e;f+=d)c[f]=180*a[f]/(6378137*Math.PI),c[f+1]=360*Math.atan(Math.exp(a[f+1]/6378137))/Math.PI-90;return c};var Pj=new Cc(6378137);function Qj(a,c){Fc.call(this,{code:a,units:"degrees",extent:Rj,axisOrientation:c,global:!0,metersPerUnit:Sj,worldExtent:Rj})}y(Qj,Fc);Qj.prototype.getPointResolution=function(a){return a}; +var Rj=[-180,-90,180,90],Sj=Math.PI*Pj.radius/180,Vc=[new Qj("CRS:84"),new Qj("EPSG:4326","neu"),new Qj("urn:ogc:def:crs:EPSG::4326","neu"),new Qj("urn:ogc:def:crs:EPSG:6.6:4326","neu"),new Qj("urn:ogc:def:crs:OGC:1.3:CRS84"),new Qj("urn:ogc:def:crs:OGC:2:84"),new Qj("http://www.opengis.net/gml/srs/epsg.xml#4326","neu"),new Qj("urn:x-ogc:def:crs:EPSG:4326","neu")];function Tj(){Jc(Sc);Jc(Vc);Rc()};function Uj(a){di.call(this,a?a:{})}y(Uj,di);function Vj(a){a=a?a:{};var c=Pa({},a);delete c.preload;delete c.useInterimTilesOnError;di.call(this,c);this.l(void 0!==a.preload?a.preload:0);this.B(void 0!==a.useInterimTilesOnError?a.useInterimTilesOnError:!0)}y(Vj,di);Vj.prototype.f=function(){return this.get("preload")};Vj.prototype.l=function(a){this.set("preload",a)};Vj.prototype.c=function(){return this.get("useInterimTilesOnError")};Vj.prototype.B=function(a){this.set("useInterimTilesOnError",a)};var Wj=[0,0,0,1],Xj=[],Yj=[0,0,0,1];function Zj(a,c,d,e){0!==c&&(a.translate(d,e),a.rotate(c),a.translate(-d,-e))};function ak(a){a=a||{};this.b=void 0!==a.color?a.color:null;this.a=void 0}ak.prototype.g=function(){return this.b};ak.prototype.f=function(a){this.b=a;this.a=void 0};function bk(a){void 0===a.a&&(a.a=a.b instanceof CanvasPattern||a.b instanceof CanvasGradient?w(a.b).toString():"f"+(a.b?He(a.b):"-"));return a.a};function ck(){this.a=-1};function dk(){this.a=-1;this.a=64;this.b=Array(4);this.c=Array(this.a);this.f=this.g=0;this.b[0]=1732584193;this.b[1]=4023233417;this.b[2]=2562383102;this.b[3]=271733878;this.f=this.g=0}y(dk,ck); +function ek(a,c,d){d||(d=0);var e=Array(16);if(ea(c))for(var f=0;16>f;++f)e[f]=c.charCodeAt(d++)|c.charCodeAt(d++)<<8|c.charCodeAt(d++)<<16|c.charCodeAt(d++)<<24;else for(f=0;16>f;++f)e[f]=c[d++]|c[d++]<<8|c[d++]<<16|c[d++]<<24;c=a.b[0];d=a.b[1];var f=a.b[2],g=a.b[3],h=0,h=c+(g^d&(f^g))+e[0]+3614090360&4294967295;c=d+(h<<7&4294967295|h>>>25);h=g+(f^c&(d^f))+e[1]+3905402710&4294967295;g=c+(h<<12&4294967295|h>>>20);h=f+(d^g&(c^d))+e[2]+606105819&4294967295;f=g+(h<<17&4294967295|h>>>15);h=d+(c^f&(g^ c))+e[3]+3250441966&4294967295;d=f+(h<<22&4294967295|h>>>10);h=c+(g^d&(f^g))+e[4]+4118548399&4294967295;c=d+(h<<7&4294967295|h>>>25);h=g+(f^c&(d^f))+e[5]+1200080426&4294967295;g=c+(h<<12&4294967295|h>>>20);h=f+(d^g&(c^d))+e[6]+2821735955&4294967295;f=g+(h<<17&4294967295|h>>>15);h=d+(c^f&(g^c))+e[7]+4249261313&4294967295;d=f+(h<<22&4294967295|h>>>10);h=c+(g^d&(f^g))+e[8]+1770035416&4294967295;c=d+(h<<7&4294967295|h>>>25);h=g+(f^c&(d^f))+e[9]+2336552879&4294967295;g=c+(h<<12&4294967295|h>>>20);h=f+ (d^g&(c^d))+e[10]+4294925233&4294967295;f=g+(h<<17&4294967295|h>>>15);h=d+(c^f&(g^c))+e[11]+2304563134&4294967295;d=f+(h<<22&4294967295|h>>>10);h=c+(g^d&(f^g))+e[12]+1804603682&4294967295;c=d+(h<<7&4294967295|h>>>25);h=g+(f^c&(d^f))+e[13]+4254626195&4294967295;g=c+(h<<12&4294967295|h>>>20);h=f+(d^g&(c^d))+e[14]+2792965006&4294967295;f=g+(h<<17&4294967295|h>>>15);h=d+(c^f&(g^c))+e[15]+1236535329&4294967295;d=f+(h<<22&4294967295|h>>>10);h=c+(f^g&(d^f))+e[1]+4129170786&4294967295;c=d+(h<<5&4294967295| h>>>27);h=g+(d^f&(c^d))+e[6]+3225465664&4294967295;g=c+(h<<9&4294967295|h>>>23);h=f+(c^d&(g^c))+e[11]+643717713&4294967295;f=g+(h<<14&4294967295|h>>>18);h=d+(g^c&(f^g))+e[0]+3921069994&4294967295;d=f+(h<<20&4294967295|h>>>12);h=c+(f^g&(d^f))+e[5]+3593408605&4294967295;c=d+(h<<5&4294967295|h>>>27);h=g+(d^f&(c^d))+e[10]+38016083&4294967295;g=c+(h<<9&4294967295|h>>>23);h=f+(c^d&(g^c))+e[15]+3634488961&4294967295;f=g+(h<<14&4294967295|h>>>18);h=d+(g^c&(f^g))+e[4]+3889429448&4294967295;d=f+(h<<20&4294967295| @@ -217,808 +197,829 @@ h>>>18);h=d+(g^c&(f^g))+e[12]+2368359562&4294967295;d=f+(h<<20&4294967295|h>>>12 c^d)+e[7]+4139469664&4294967295;f=g+(h<<16&4294967295|h>>>16);h=d+(f^g^c)+e[10]+3200236656&4294967295;d=f+(h<<23&4294967295|h>>>9);h=c+(d^f^g)+e[13]+681279174&4294967295;c=d+(h<<4&4294967295|h>>>28);h=g+(c^d^f)+e[0]+3936430074&4294967295;g=c+(h<<11&4294967295|h>>>21);h=f+(g^c^d)+e[3]+3572445317&4294967295;f=g+(h<<16&4294967295|h>>>16);h=d+(f^g^c)+e[6]+76029189&4294967295;d=f+(h<<23&4294967295|h>>>9);h=c+(d^f^g)+e[9]+3654602809&4294967295;c=d+(h<<4&4294967295|h>>>28);h=g+(c^d^f)+e[12]+3873151461&4294967295; g=c+(h<<11&4294967295|h>>>21);h=f+(g^c^d)+e[15]+530742520&4294967295;f=g+(h<<16&4294967295|h>>>16);h=d+(f^g^c)+e[2]+3299628645&4294967295;d=f+(h<<23&4294967295|h>>>9);h=c+(f^(d|~g))+e[0]+4096336452&4294967295;c=d+(h<<6&4294967295|h>>>26);h=g+(d^(c|~f))+e[7]+1126891415&4294967295;g=c+(h<<10&4294967295|h>>>22);h=f+(c^(g|~d))+e[14]+2878612391&4294967295;f=g+(h<<15&4294967295|h>>>17);h=d+(g^(f|~c))+e[5]+4237533241&4294967295;d=f+(h<<21&4294967295|h>>>11);h=c+(f^(d|~g))+e[12]+1700485571&4294967295;c=d+ (h<<6&4294967295|h>>>26);h=g+(d^(c|~f))+e[3]+2399980690&4294967295;g=c+(h<<10&4294967295|h>>>22);h=f+(c^(g|~d))+e[10]+4293915773&4294967295;f=g+(h<<15&4294967295|h>>>17);h=d+(g^(f|~c))+e[1]+2240044497&4294967295;d=f+(h<<21&4294967295|h>>>11);h=c+(f^(d|~g))+e[8]+1873313359&4294967295;c=d+(h<<6&4294967295|h>>>26);h=g+(d^(c|~f))+e[15]+4264355552&4294967295;g=c+(h<<10&4294967295|h>>>22);h=f+(c^(g|~d))+e[6]+2734768916&4294967295;f=g+(h<<15&4294967295|h>>>17);h=d+(g^(f|~c))+e[13]+1309151649&4294967295; -d=f+(h<<21&4294967295|h>>>11);h=c+(f^(d|~g))+e[4]+4149444226&4294967295;c=d+(h<<6&4294967295|h>>>26);h=g+(d^(c|~f))+e[11]+3174756917&4294967295;g=c+(h<<10&4294967295|h>>>22);h=f+(c^(g|~d))+e[2]+718787259&4294967295;f=g+(h<<15&4294967295|h>>>17);h=d+(g^(f|~c))+e[9]+3951481745&4294967295;b.a[0]=b.a[0]+c&4294967295;b.a[1]=b.a[1]+(f+(h<<21&4294967295|h>>>11))&4294967295;b.a[2]=b.a[2]+f&4294967295;b.a[3]=b.a[3]+g&4294967295} -function Xl(b,c){var d;ca(d)||(d=c.length);for(var e=d-b.f,f=b.g,g=b.b,h=0;h<d;){if(0==g)for(;h<=e;)Wl(b,c,h),h+=b.f;if(ia(c))for(;h<d;){if(f[g++]=c.charCodeAt(h++),g==b.f){Wl(b,f);g=0;break}}else for(;h<d;)if(f[g++]=c[h++],g==b.f){Wl(b,f);g=0;break}}b.b=g;b.c+=d};function Yl(b){b=b||{};this.a=void 0!==b.color?b.color:null;this.c=b.lineCap;this.b=void 0!==b.lineDash?b.lineDash:null;this.g=b.lineJoin;this.i=b.miterLimit;this.f=b.width;this.j=void 0}l=Yl.prototype;l.pn=function(){return this.a};l.Uj=function(){return this.c};l.qn=function(){return this.b};l.Vj=function(){return this.g};l.$j=function(){return this.i};l.rn=function(){return this.f};l.sn=function(b){this.a=b;this.j=void 0};l.Oo=function(b){this.c=b;this.j=void 0}; -l.tn=function(b){this.b=b;this.j=void 0};l.Po=function(b){this.g=b;this.j=void 0};l.Qo=function(b){this.i=b;this.j=void 0};l.Uo=function(b){this.f=b;this.j=void 0}; -l.Jb=function(){if(void 0===this.j){var b="s"+(this.a?vg(this.a):"-")+","+(void 0!==this.c?this.c.toString():"-")+","+(this.b?this.b.toString():"-")+","+(void 0!==this.g?this.g:"-")+","+(void 0!==this.i?this.i.toString():"-")+","+(void 0!==this.f?this.f.toString():"-"),c=new Vl;Xl(c,b);b=Array((56>c.b?c.f:2*c.f)-c.b);b[0]=128;for(var d=1;d<b.length-8;++d)b[d]=0;for(var e=8*c.c,d=b.length-8;d<b.length;++d)b[d]=e&255,e/=256;Xl(c,b);b=Array(16);for(d=e=0;4>d;++d)for(var f=0;32>f;f+=8)b[e++]=c.a[d]>>> -f&255;if(8192>=b.length)c=String.fromCharCode.apply(null,b);else for(c="",d=0;d<b.length;d+=8192)e=mb(b,d,d+8192),c+=String.fromCharCode.apply(null,e);this.j=c}return this.j};function Zl(b){b=b||{};this.i=this.a=this.g=null;this.c=void 0!==b.fill?b.fill:null;this.f=void 0!==b.stroke?b.stroke:null;this.b=b.radius;this.v=[0,0];this.o=this.O=this.l=null;var c=b.atlasManager,d,e=null,f,g=0;this.f&&(f=vg(this.f.a),g=this.f.f,void 0===g&&(g=1),e=this.f.b,Wi||(e=null));var h=2*(this.b+g)+1;f={strokeStyle:f,Id:g,size:h,lineDash:e};void 0===c?(this.a=document.createElement("CANVAS"),this.a.height=h,this.a.width=h,d=h=this.a.width,c=this.a.getContext("2d"),this.vh(f,c,0,0),this.c? -this.i=this.a:(c=this.i=document.createElement("CANVAS"),c.height=f.size,c.width=f.size,c=c.getContext("2d"),this.uh(f,c,0,0))):(h=Math.round(h),(e=!this.c)&&(d=ua(this.uh,this,f)),g=this.Jb(),f=c.add(g,h,h,ua(this.vh,this,f),d),this.a=f.image,this.v=[f.offsetX,f.offsetY],d=f.image.width,this.i=e?f.Og:this.a);this.l=[h/2,h/2];this.O=[h,h];this.o=[d,d];sk.call(this,{opacity:1,rotateWithView:!1,rotation:0,scale:1,snapToPixel:void 0!==b.snapToPixel?b.snapToPixel:!0})}y(Zl,sk);l=Zl.prototype;l.Xb=function(){return this.l}; -l.en=function(){return this.c};l.Ae=function(){return this.i};l.gc=function(){return this.a};l.Cd=function(){return 2};l.rd=function(){return this.o};l.Da=function(){return this.v};l.fn=function(){return this.b};l.Cb=function(){return this.O};l.gn=function(){return this.f};l.tf=za;l.load=za;l.Xf=za; -l.vh=function(b,c,d,e){c.setTransform(1,0,0,1,0,0);c.translate(d,e);c.beginPath();c.arc(b.size/2,b.size/2,this.b,0,2*Math.PI,!0);this.c&&(c.fillStyle=vg(this.c.a),c.fill());this.f&&(c.strokeStyle=b.strokeStyle,c.lineWidth=b.Id,b.lineDash&&c.setLineDash(b.lineDash),c.stroke());c.closePath()}; -l.uh=function(b,c,d,e){c.setTransform(1,0,0,1,0,0);c.translate(d,e);c.beginPath();c.arc(b.size/2,b.size/2,this.b,0,2*Math.PI,!0);c.fillStyle=vg(Ql);c.fill();this.f&&(c.strokeStyle=b.strokeStyle,c.lineWidth=b.Id,b.lineDash&&c.setLineDash(b.lineDash),c.stroke());c.closePath()};l.Jb=function(){var b=this.f?this.f.Jb():"-",c=this.c?this.c.Jb():"-";this.g&&b==this.g[1]&&c==this.g[2]&&this.b==this.g[3]||(this.g=["c"+b+c+(void 0!==this.b?this.b.toString():"-"),b,c,this.b]);return this.g[0]};function $l(b){b=b||{};this.i=null;this.c=am;void 0!==b.geometry&&this.yh(b.geometry);this.g=void 0!==b.fill?b.fill:null;this.f=void 0!==b.image?b.image:null;this.b=void 0!==b.stroke?b.stroke:null;this.j=void 0!==b.text?b.text:null;this.a=b.zIndex}l=$l.prototype;l.X=function(){return this.i};l.Pj=function(){return this.c};l.vn=function(){return this.g};l.wn=function(){return this.f};l.xn=function(){return this.b};l.Ca=function(){return this.j};l.yn=function(){return this.a}; -l.yh=function(b){ka(b)?this.c=b:ia(b)?this.c=function(c){return c.get(b)}:b?void 0!==b&&(this.c=function(){return b}):this.c=am;this.i=b};l.zn=function(b){this.a=b};function bm(b){if(!ka(b)){var c;c=ga(b)?b:[b];b=function(){return c}}return b}var cm=null;function dm(){if(!cm){var b=new Tl({color:"rgba(255,255,255,0.4)"}),c=new Yl({color:"#3399CC",width:1.25});cm=[new $l({image:new Zl({fill:b,stroke:c,radius:5}),fill:b,stroke:c})]}return cm} -function em(){var b={},c=[255,255,255,1],d=[0,153,255,1];b.Polygon=[new $l({fill:new Tl({color:[255,255,255,.5]})})];b.MultiPolygon=b.Polygon;b.LineString=[new $l({stroke:new Yl({color:c,width:5})}),new $l({stroke:new Yl({color:d,width:3})})];b.MultiLineString=b.LineString;b.Circle=b.Polygon.concat(b.LineString);b.Point=[new $l({image:new Zl({radius:6,fill:new Tl({color:d}),stroke:new Yl({color:c,width:1.5})}),zIndex:Infinity})];b.MultiPoint=b.Point;b.GeometryCollection=b.Polygon.concat(b.LineString, -b.Point);return b}function am(b){return b.X()};function H(b){b=b?b:{};var c=Tb(b);delete c.style;delete c.renderBuffer;delete c.updateWhileAnimating;delete c.updateWhileInteracting;ck.call(this,c);this.a=void 0!==b.renderBuffer?b.renderBuffer:100;this.v=null;this.b=void 0;this.c(b.style);this.j=void 0!==b.updateWhileAnimating?b.updateWhileAnimating:!1;this.l=void 0!==b.updateWhileInteracting?b.updateWhileInteracting:!1}y(H,ck);function fm(b){return b.get("renderOrder")}H.prototype.C=function(){return this.v};H.prototype.D=function(){return this.b}; -H.prototype.c=function(b){this.v=void 0!==b?b:dm;this.b=null===b?void 0:bm(this.v);this.u()};function I(b){b=b?b:{};var c=Tb(b);delete c.preload;delete c.useInterimTilesOnError;H.call(this,c);this.T(b.preload?b.preload:0);this.V(b.useInterimTilesOnError?b.useInterimTilesOnError:!0)}y(I,H);I.prototype.g=function(){return this.get("preload")};I.prototype.U=function(){return this.get("useInterimTilesOnError")};I.prototype.T=function(b){this.set("preload",b)};I.prototype.V=function(b){this.set("useInterimTilesOnError",b)};function gm(b,c,d,e,f){this.v={};this.b=b;this.D=c;this.g=d;this.na=e;this.Yc=f;this.i=this.a=this.f=this.gb=this.oa=this.ga=null;this.wa=this.pa=this.B=this.T=this.U=this.va=0;this.hb=!1;this.j=this.Db=0;this.Eb=!1;this.V=0;this.c="";this.o=this.O=this.Od=this.nc=0;this.fa=this.G=this.l=null;this.C=[];this.Cc=Bd()} -function hm(b,c,d){if(b.i){c=af(c,0,d,2,b.na,b.C);d=b.b;var e=b.Cc,f=d.globalAlpha;1!=b.B&&(d.globalAlpha=f*b.B);var g=b.Db;b.hb&&(g+=b.Yc);var h,k;h=0;for(k=c.length;h<k;h+=2){var m=c[h]-b.va,n=c[h+1]-b.U;b.Eb&&(m=m+.5|0,n=n+.5|0);if(0!==g||1!=b.j){var p=m+b.va,q=n+b.U;gk(e,p,q,b.j,b.j,g,-p,-q);d.setTransform(e[0],e[1],e[4],e[5],e[12],e[13])}d.drawImage(b.i,b.pa,b.wa,b.V,b.T,m,n,b.V,b.T)}0===g&&1==b.j||d.setTransform(1,0,0,1,0,0);1!=b.B&&(d.globalAlpha=f)}} -function im(b,c,d,e){var f=0;if(b.fa&&""!==b.c){b.l&&jm(b,b.l);b.G&&km(b,b.G);var g=b.fa,h=b.b,k=b.gb;k?(k.font!=g.font&&(k.font=h.font=g.font),k.textAlign!=g.textAlign&&(k.textAlign=h.textAlign=g.textAlign),k.textBaseline!=g.textBaseline&&(k.textBaseline=h.textBaseline=g.textBaseline)):(h.font=g.font,h.textAlign=g.textAlign,h.textBaseline=g.textBaseline,b.gb={font:g.font,textAlign:g.textAlign,textBaseline:g.textBaseline});c=af(c,f,d,e,b.na,b.C);for(g=b.b;f<d;f+=e){h=c[f]+b.nc;k=c[f+1]+b.Od;if(0!== -b.O||1!=b.o){var m=gk(b.Cc,h,k,b.o,b.o,b.O,-h,-k);g.setTransform(m[0],m[1],m[4],m[5],m[12],m[13])}b.G&&g.strokeText(b.c,h,k);b.l&&g.fillText(b.c,h,k)}0===b.O&&1==b.o||g.setTransform(1,0,0,1,0,0)}}function lm(b,c,d,e,f,g){var h=b.b;b=af(c,d,e,f,b.na,b.C);h.moveTo(b[0],b[1]);for(c=2;c<b.length;c+=2)h.lineTo(b[c],b[c+1]);g&&h.lineTo(b[0],b[1]);return e}function mm(b,c,d,e,f){var g=b.b,h,k;h=0;for(k=e.length;h<k;++h)d=lm(b,c,d,e[h],f,!0),g.closePath();return d}l=gm.prototype; -l.md=function(b,c){var d=b.toString(),e=this.v[d];void 0!==e?e.push(c):this.v[d]=[c]};l.Gc=function(b){if(oe(this.g,b.J())){if(this.f||this.a){this.f&&jm(this,this.f);this.a&&km(this,this.a);var c;c=this.na;var d=this.C,e=b.ia();c=e?af(e,0,e.length,b.ra(),c,d):null;d=c[2]-c[0];e=c[3]-c[1];d=Math.sqrt(d*d+e*e);e=this.b;e.beginPath();e.arc(c[0],c[1],d,0,2*Math.PI);this.f&&e.fill();this.a&&e.stroke()}""!==this.c&&im(this,b.wd(),2,2)}}; -l.jf=function(b,c){var d=(0,c.c)(b);if(d&&oe(this.g,d.J())){var e=c.a;void 0===e&&(e=0);this.md(e,function(b){b.bb(c.g,c.b);b.ub(c.f);b.cb(c.Ca());nm[d.W()].call(b,d,null)})}};l.Yd=function(b,c){var d=b.c,e,f;e=0;for(f=d.length;e<f;++e){var g=d[e];nm[g.W()].call(this,g,c)}};l.Hb=function(b){var c=b.ia();b=b.ra();this.i&&hm(this,c,c.length);""!==this.c&&im(this,c,c.length,b)};l.Gb=function(b){var c=b.ia();b=b.ra();this.i&&hm(this,c,c.length);""!==this.c&&im(this,c,c.length,b)}; -l.Wb=function(b){if(oe(this.g,b.J())){if(this.a){km(this,this.a);var c=this.b,d=b.ia();c.beginPath();lm(this,d,0,d.length,b.ra(),!1);c.stroke()}""!==this.c&&(b=om(b),im(this,b,2,2))}};l.Hc=function(b){var c=b.J();if(oe(this.g,c)){if(this.a){km(this,this.a);var c=this.b,d=b.ia(),e=0,f=b.zb(),g=b.ra();c.beginPath();var h,k;h=0;for(k=f.length;h<k;++h)e=lm(this,d,e,f[h],g,!1);c.stroke()}""!==this.c&&(b=pm(b),im(this,b,b.length,2))}}; -l.Jc=function(b){if(oe(this.g,b.J())){if(this.a||this.f){this.f&&jm(this,this.f);this.a&&km(this,this.a);var c=this.b;c.beginPath();mm(this,b.bc(),0,b.zb(),b.ra());this.f&&c.fill();this.a&&c.stroke()}""!==this.c&&(b=If(b),im(this,b,2,2))}}; -l.Ic=function(b){if(oe(this.g,b.J())){if(this.a||this.f){this.f&&jm(this,this.f);this.a&&km(this,this.a);var c=this.b,d=rm(b),e=0,f=b.g,g=b.ra(),h,k;h=0;for(k=f.length;h<k;++h){var m=f[h];c.beginPath();e=mm(this,d,e,m,g);this.f&&c.fill();this.a&&c.stroke()}}""!==this.c&&(b=sm(b),im(this,b,b.length,2))}};function tm(b){var c=Object.keys(b.v).map(Number);c.sort(ub);var d,e,f,g,h;d=0;for(e=c.length;d<e;++d)for(f=b.v[c[d].toString()],g=0,h=f.length;g<h;++g)f[g](b)} -function jm(b,c){var d=b.b,e=b.ga;e?e.fillStyle!=c.fillStyle&&(e.fillStyle=d.fillStyle=c.fillStyle):(d.fillStyle=c.fillStyle,b.ga={fillStyle:c.fillStyle})} -function km(b,c){var d=b.b,e=b.oa;e?(e.lineCap!=c.lineCap&&(e.lineCap=d.lineCap=c.lineCap),Wi&&!rb(e.lineDash,c.lineDash)&&d.setLineDash(e.lineDash=c.lineDash),e.lineJoin!=c.lineJoin&&(e.lineJoin=d.lineJoin=c.lineJoin),e.lineWidth!=c.lineWidth&&(e.lineWidth=d.lineWidth=c.lineWidth),e.miterLimit!=c.miterLimit&&(e.miterLimit=d.miterLimit=c.miterLimit),e.strokeStyle!=c.strokeStyle&&(e.strokeStyle=d.strokeStyle=c.strokeStyle)):(d.lineCap=c.lineCap,Wi&&d.setLineDash(c.lineDash),d.lineJoin=c.lineJoin,d.lineWidth= -c.lineWidth,d.miterLimit=c.miterLimit,d.strokeStyle=c.strokeStyle,b.oa={lineCap:c.lineCap,lineDash:c.lineDash,lineJoin:c.lineJoin,lineWidth:c.lineWidth,miterLimit:c.miterLimit,strokeStyle:c.strokeStyle})} -l.bb=function(b,c){if(b){var d=b.a;this.f={fillStyle:vg(d?d:Ql)}}else this.f=null;if(c){var d=c.a,e=c.c,f=c.b,g=c.g,h=c.f,k=c.i;this.a={lineCap:void 0!==e?e:"round",lineDash:f?f:Rl,lineJoin:void 0!==g?g:"round",lineWidth:this.D*(void 0!==h?h:1),miterLimit:void 0!==k?k:10,strokeStyle:vg(d?d:Sl)}}else this.a=null}; -l.ub=function(b){if(b){var c=b.Xb(),d=b.gc(1),e=b.Da(),f=b.Cb();this.va=c[0];this.U=c[1];this.T=f[1];this.i=d;this.B=b.B;this.pa=e[0];this.wa=e[1];this.hb=b.C;this.Db=b.G;this.j=b.j;this.Eb=b.D;this.V=f[0]}else this.i=null}; -l.cb=function(b){if(b){var c=b.a;c?(c=c.a,this.l={fillStyle:vg(c?c:Ql)}):this.l=null;var d=b.j;if(d){var c=d.a,e=d.c,f=d.b,g=d.g,h=d.f,d=d.i;this.G={lineCap:void 0!==e?e:"round",lineDash:f?f:Rl,lineJoin:void 0!==g?g:"round",lineWidth:void 0!==h?h:1,miterLimit:void 0!==d?d:10,strokeStyle:vg(c?c:Sl)}}else this.G=null;var c=b.b,e=b.c,f=b.g,g=b.i,h=b.f,d=b.Ca(),k=b.l;b=b.o;this.fa={font:void 0!==c?c:"10px sans-serif",textAlign:void 0!==k?k:"center",textBaseline:void 0!==b?b:"middle"};this.c=void 0!== -d?d:"";this.nc=void 0!==e?this.D*e:0;this.Od=void 0!==f?this.D*f:0;this.O=void 0!==g?g:0;this.o=this.D*(void 0!==h?h:1)}else this.c=""};var nm={Point:gm.prototype.Hb,LineString:gm.prototype.Wb,Polygon:gm.prototype.Jc,MultiPoint:gm.prototype.Gb,MultiLineString:gm.prototype.Hc,MultiPolygon:gm.prototype.Ic,GeometryCollection:gm.prototype.Yd,Circle:gm.prototype.Gc};function um(b){jk.call(this,b);this.O=Bd()}y(um,jk); -um.prototype.G=function(b,c,d){vm(this,"precompose",d,b,void 0);var e=this.zd();if(e){var f=c.extent,g=void 0!==f;if(g){var h=b.pixelRatio,k=ge(f),m=fe(f),n=ee(f),f=de(f);ik(b.coordinateToPixelMatrix,k,k);ik(b.coordinateToPixelMatrix,m,m);ik(b.coordinateToPixelMatrix,n,n);ik(b.coordinateToPixelMatrix,f,f);d.save();d.beginPath();d.moveTo(k[0]*h,k[1]*h);d.lineTo(m[0]*h,m[1]*h);d.lineTo(n[0]*h,n[1]*h);d.lineTo(f[0]*h,f[1]*h);d.clip()}h=this.nf();k=d.globalAlpha;d.globalAlpha=c.opacity;0===b.viewState.rotation? -d.drawImage(e,0,0,+e.width,+e.height,Math.round(h[12]),Math.round(h[13]),Math.round(e.width*h[0]),Math.round(e.height*h[5])):(d.setTransform(h[0],h[1],h[4],h[5],h[12],h[13]),d.drawImage(e,0,0),d.setTransform(1,0,0,1,0,0));d.globalAlpha=k;g&&d.restore()}vm(this,"postcompose",d,b,void 0)};function vm(b,c,d,e,f){var g=b.a;cd(g,c)&&(b=void 0!==f?f:wm(b,e,0),b=new gm(d,e.pixelRatio,e.extent,b,e.viewState.rotation),g.s(new bk(c,g,b,e,d,null)),tm(b))} -function wm(b,c,d){var e=c.viewState,f=c.pixelRatio;return gk(b.O,f*c.size[0]/2,f*c.size[1]/2,f/e.resolution,-f/e.resolution,-e.rotation,-e.center[0]+d,-e.center[1])}function xm(b,c){var d=[0,0];ik(c,b,d);return d} -var ym=function(){var b=null,c=null;return function(d){if(!b){b=Ni(1,1);c=b.createImageData(1,1);var e=c.data;e[0]=42;e[1]=84;e[2]=126;e[3]=255}var e=b.canvas,f=d[0]<=e.width&&d[1]<=e.height;f||(e.width=d[0],e.height=d[1],e=d[0]-1,d=d[1]-1,b.putImageData(c,e,d),d=b.getImageData(e,d,1,1),f=rb(c.data,d.data));return f}}();var zm=["Polygon","LineString","Image","Text"];function Am(b,c,d){this.gb=b;this.V=c;this.c=null;this.g=0;this.resolution=d;this.U=this.va=null;this.f=[];this.coordinates=[];this.ga=Bd();this.a=[];this.fa=[];this.oa=Bd()}y(Am,ak); -function Bm(b,c,d,e,f,g){var h=b.coordinates.length,k=b.lf(),m=[c[d],c[d+1]],n=[NaN,NaN],p=!0,q,r,t;for(q=d+f;q<e;q+=f)n[0]=c[q],n[1]=c[q+1],t=Wd(k,n),t!==r?(p&&(b.coordinates[h++]=m[0],b.coordinates[h++]=m[1]),b.coordinates[h++]=n[0],b.coordinates[h++]=n[1],p=!1):1===t?(b.coordinates[h++]=n[0],b.coordinates[h++]=n[1],p=!1):p=!0,m[0]=n[0],m[1]=n[1],r=t;q===d+f&&(b.coordinates[h++]=m[0],b.coordinates[h++]=m[1]);g&&(b.coordinates[h++]=c[d],b.coordinates[h++]=c[d+1]);return h} -function Cm(b,c){b.va=[0,c,0];b.f.push(b.va);b.U=[0,c,0];b.a.push(b.U)} -function Dm(b,c,d,e,f,g,h,k,m){var n;hk(e,b.ga)?n=b.fa:(n=af(b.coordinates,0,b.coordinates.length,2,e,b.fa),Ed(b.ga,e));e=!Pb(g);var p=0,q=h.length,r=0,t;b=b.oa;for(var x,z,A,B;p<q;){var v=h[p],L,M,J,C;switch(v[0]){case 0:r=v[1];e&&g[w(r).toString()]||!r.X()?p=v[2]:void 0===m||oe(m,r.X().J())?++p:p=v[2];break;case 1:c.beginPath();++p;break;case 2:r=v[1];t=n[r];v=n[r+1];A=n[r+2]-t;r=n[r+3]-v;c.arc(t,v,Math.sqrt(A*A+r*r),0,2*Math.PI,!0);++p;break;case 3:c.closePath();++p;break;case 4:r=v[1];t=v[2]; -L=v[3];J=v[4]*d;var sa=v[5]*d,la=v[6];M=v[7];var K=v[8],ma=v[9];A=v[11];B=v[12];var Ua=v[13],Nb=v[14];for(v[10]&&(A+=f);r<t;r+=2){v=n[r]-J;C=n[r+1]-sa;Ua&&(v=v+.5|0,C=C+.5|0);if(1!=B||0!==A){var na=v+J,Fa=C+sa;gk(b,na,Fa,B,B,A,-na,-Fa);c.setTransform(b[0],b[1],b[4],b[5],b[12],b[13])}na=c.globalAlpha;1!=M&&(c.globalAlpha=na*M);c.drawImage(L,K,ma,Nb,la,v,C,Nb*d,la*d);1!=M&&(c.globalAlpha=na);1==B&&0===A||c.setTransform(1,0,0,1,0,0)}++p;break;case 5:r=v[1];t=v[2];J=v[3];sa=v[4]*d;la=v[5]*d;A=v[6];B= -v[7]*d;L=v[8];for(M=v[9];r<t;r+=2){v=n[r]+sa;C=n[r+1]+la;if(1!=B||0!==A)gk(b,v,C,B,B,A,-v,-C),c.setTransform(b[0],b[1],b[4],b[5],b[12],b[13]);K=J.split("\n");ma=K.length;1<ma?(Ua=Math.round(1.5*c.measureText("M").width),C-=(ma-1)/2*Ua):Ua=0;for(Nb=0;Nb<ma;Nb++)na=K[Nb],M&&c.strokeText(na,v,C),L&&c.fillText(na,v,C),C+=Ua;1==B&&0===A||c.setTransform(1,0,0,1,0,0)}++p;break;case 6:if(void 0!==k&&(r=v[1],r=k(r)))return r;++p;break;case 7:c.fill();++p;break;case 8:r=v[1];t=v[2];v=n[r];C=n[r+1];A=v+.5|0; -B=C+.5|0;if(A!==x||B!==z)c.moveTo(v,C),x=A,z=B;for(r+=2;r<t;r+=2)if(v=n[r],C=n[r+1],A=v+.5|0,B=C+.5|0,A!==x||B!==z)c.lineTo(v,C),x=A,z=B;++p;break;case 9:c.fillStyle=v[1];++p;break;case 10:x=void 0!==v[7]?v[7]:!0;z=v[2];c.strokeStyle=v[1];c.lineWidth=x?z*d:z;c.lineCap=v[3];c.lineJoin=v[4];c.miterLimit=v[5];Wi&&c.setLineDash(v[6]);z=x=NaN;++p;break;case 11:c.font=v[1];c.textAlign=v[2];c.textBaseline=v[3];++p;break;case 12:c.stroke();++p;break;default:++p}}} -function Em(b){var c=b.a;c.reverse();var d,e=c.length,f,g,h=-1;for(d=0;d<e;++d)if(f=c[d],g=f[0],6==g)h=d;else if(0==g){f[2]=d;f=b.a;for(g=d;h<g;){var k=f[h];f[h]=f[g];f[g]=k;++h;--g}h=-1}}function Fm(b,c){b.va[2]=b.f.length;b.va=null;b.U[2]=b.a.length;b.U=null;var d=[6,c];b.f.push(d);b.a.push(d)}Am.prototype.we=za;Am.prototype.lf=function(){return this.V}; -function Gm(b,c,d){Am.call(this,b,c,d);this.l=this.T=null;this.na=this.O=this.D=this.C=this.v=this.B=this.G=this.o=this.j=this.i=this.b=void 0}y(Gm,Am);Gm.prototype.Hb=function(b,c){if(this.l){Cm(this,c);var d=b.ia(),e=this.coordinates.length,d=Bm(this,d,0,d.length,b.ra(),!1);this.f.push([4,e,d,this.l,this.b,this.i,this.j,this.o,this.G,this.B,this.v,this.C,this.D,this.O,this.na]);this.a.push([4,e,d,this.T,this.b,this.i,this.j,this.o,this.G,this.B,this.v,this.C,this.D,this.O,this.na]);Fm(this,c)}}; -Gm.prototype.Gb=function(b,c){if(this.l){Cm(this,c);var d=b.ia(),e=this.coordinates.length,d=Bm(this,d,0,d.length,b.ra(),!1);this.f.push([4,e,d,this.l,this.b,this.i,this.j,this.o,this.G,this.B,this.v,this.C,this.D,this.O,this.na]);this.a.push([4,e,d,this.T,this.b,this.i,this.j,this.o,this.G,this.B,this.v,this.C,this.D,this.O,this.na]);Fm(this,c)}};Gm.prototype.we=function(){Em(this);this.i=this.b=void 0;this.l=this.T=null;this.na=this.O=this.C=this.v=this.B=this.G=this.o=this.D=this.j=void 0}; -Gm.prototype.ub=function(b){var c=b.Xb(),d=b.Cb(),e=b.Ae(1),f=b.gc(1),g=b.Da();this.b=c[0];this.i=c[1];this.T=e;this.l=f;this.j=d[1];this.o=b.B;this.G=g[0];this.B=g[1];this.v=b.C;this.C=b.G;this.D=b.j;this.O=b.D;this.na=d[0]};function Hm(b,c,d){Am.call(this,b,c,d);this.b={jd:void 0,dd:void 0,ed:null,fd:void 0,gd:void 0,hd:void 0,sf:0,strokeStyle:void 0,lineCap:void 0,lineDash:null,lineJoin:void 0,lineWidth:void 0,miterLimit:void 0}}y(Hm,Am); -function Im(b,c,d,e,f){var g=b.coordinates.length;c=Bm(b,c,d,e,f,!1);g=[8,g,c];b.f.push(g);b.a.push(g);return e}l=Hm.prototype;l.lf=function(){this.c||(this.c=Rd(this.V),0<this.g&&Qd(this.c,this.resolution*(this.g+1)/2,this.c));return this.c}; -function Jm(b){var c=b.b,d=c.strokeStyle,e=c.lineCap,f=c.lineDash,g=c.lineJoin,h=c.lineWidth,k=c.miterLimit;c.jd==d&&c.dd==e&&rb(c.ed,f)&&c.fd==g&&c.gd==h&&c.hd==k||(c.sf!=b.coordinates.length&&(b.f.push([12]),c.sf=b.coordinates.length),b.f.push([10,d,h,e,g,k,f],[1]),c.jd=d,c.dd=e,c.ed=f,c.fd=g,c.gd=h,c.hd=k)} -l.Wb=function(b,c){var d=this.b,e=d.lineWidth;void 0!==d.strokeStyle&&void 0!==e&&(Jm(this),Cm(this,c),this.a.push([10,d.strokeStyle,d.lineWidth,d.lineCap,d.lineJoin,d.miterLimit,d.lineDash],[1]),d=b.ia(),Im(this,d,0,d.length,b.ra()),this.a.push([12]),Fm(this,c))}; -l.Hc=function(b,c){var d=this.b,e=d.lineWidth;if(void 0!==d.strokeStyle&&void 0!==e){Jm(this);Cm(this,c);this.a.push([10,d.strokeStyle,d.lineWidth,d.lineCap,d.lineJoin,d.miterLimit,d.lineDash],[1]);var d=b.zb(),e=b.ia(),f=b.ra(),g=0,h,k;h=0;for(k=d.length;h<k;++h)g=Im(this,e,g,d[h],f);this.a.push([12]);Fm(this,c)}};l.we=function(){this.b.sf!=this.coordinates.length&&this.f.push([12]);Em(this);this.b=null}; -l.bb=function(b,c){var d=c.a;this.b.strokeStyle=vg(d?d:Sl);d=c.c;this.b.lineCap=void 0!==d?d:"round";d=c.b;this.b.lineDash=d?d:Rl;d=c.g;this.b.lineJoin=void 0!==d?d:"round";d=c.f;this.b.lineWidth=void 0!==d?d:1;d=c.i;this.b.miterLimit=void 0!==d?d:10;this.b.lineWidth>this.g&&(this.g=this.b.lineWidth,this.c=null)}; -function Km(b,c,d){Am.call(this,b,c,d);this.b={qg:void 0,jd:void 0,dd:void 0,ed:null,fd:void 0,gd:void 0,hd:void 0,fillStyle:void 0,strokeStyle:void 0,lineCap:void 0,lineDash:null,lineJoin:void 0,lineWidth:void 0,miterLimit:void 0}}y(Km,Am); -function Lm(b,c,d,e,f){var g=b.b,h=[1];b.f.push(h);b.a.push(h);var k,h=0;for(k=e.length;h<k;++h){var m=e[h],n=b.coordinates.length;d=Bm(b,c,d,m,f,!0);d=[8,n,d];n=[3];b.f.push(d,n);b.a.push(d,n);d=m}c=[7];b.a.push(c);void 0!==g.fillStyle&&b.f.push(c);void 0!==g.strokeStyle&&(g=[12],b.f.push(g),b.a.push(g));return d}l=Km.prototype; -l.Gc=function(b,c){var d=this.b,e=d.strokeStyle;if(void 0!==d.fillStyle||void 0!==e){Mm(this);Cm(this,c);this.a.push([9,vg(Ql)]);void 0!==d.strokeStyle&&this.a.push([10,d.strokeStyle,d.lineWidth,d.lineCap,d.lineJoin,d.miterLimit,d.lineDash]);var f=b.ia(),e=this.coordinates.length;Bm(this,f,0,f.length,b.ra(),!1);f=[1];e=[2,e];this.f.push(f,e);this.a.push(f,e);e=[7];this.a.push(e);void 0!==d.fillStyle&&this.f.push(e);void 0!==d.strokeStyle&&(d=[12],this.f.push(d),this.a.push(d));Fm(this,c)}}; -l.Jc=function(b,c){var d=this.b,e=d.strokeStyle;if(void 0!==d.fillStyle||void 0!==e)Mm(this),Cm(this,c),this.a.push([9,vg(Ql)]),void 0!==d.strokeStyle&&this.a.push([10,d.strokeStyle,d.lineWidth,d.lineCap,d.lineJoin,d.miterLimit,d.lineDash]),d=b.zb(),e=b.bc(),Lm(this,e,0,d,b.ra()),Fm(this,c)}; -l.Ic=function(b,c){var d=this.b,e=d.strokeStyle;if(void 0!==d.fillStyle||void 0!==e){Mm(this);Cm(this,c);this.a.push([9,vg(Ql)]);void 0!==d.strokeStyle&&this.a.push([10,d.strokeStyle,d.lineWidth,d.lineCap,d.lineJoin,d.miterLimit,d.lineDash]);var d=b.g,e=rm(b),f=b.ra(),g=0,h,k;h=0;for(k=d.length;h<k;++h)g=Lm(this,e,g,d[h],f);Fm(this,c)}};l.we=function(){Em(this);this.b=null;var b=this.gb;if(0!==b){var c=this.coordinates,d,e;d=0;for(e=c.length;d<e;++d)c[d]=b*Math.round(c[d]/b)}}; -l.lf=function(){this.c||(this.c=Rd(this.V),0<this.g&&Qd(this.c,this.resolution*(this.g+1)/2,this.c));return this.c}; -l.bb=function(b,c){var d=this.b;if(b){var e=b.a;d.fillStyle=vg(e?e:Ql)}else d.fillStyle=void 0;c?(e=c.a,d.strokeStyle=vg(e?e:Sl),e=c.c,d.lineCap=void 0!==e?e:"round",e=c.b,d.lineDash=e?e.slice():Rl,e=c.g,d.lineJoin=void 0!==e?e:"round",e=c.f,d.lineWidth=void 0!==e?e:1,e=c.i,d.miterLimit=void 0!==e?e:10,d.lineWidth>this.g&&(this.g=d.lineWidth,this.c=null)):(d.strokeStyle=void 0,d.lineCap=void 0,d.lineDash=null,d.lineJoin=void 0,d.lineWidth=void 0,d.miterLimit=void 0)}; -function Mm(b){var c=b.b,d=c.fillStyle,e=c.strokeStyle,f=c.lineCap,g=c.lineDash,h=c.lineJoin,k=c.lineWidth,m=c.miterLimit;void 0!==d&&c.qg!=d&&(b.f.push([9,d]),c.qg=c.fillStyle);void 0===e||c.jd==e&&c.dd==f&&c.ed==g&&c.fd==h&&c.gd==k&&c.hd==m||(b.f.push([10,e,k,f,h,m,g]),c.jd=e,c.dd=f,c.ed=g,c.fd=h,c.gd=k,c.hd=m)}function Nm(b,c,d){Am.call(this,b,c,d);this.O=this.D=this.C=null;this.l="";this.v=this.B=this.G=this.o=0;this.j=this.i=this.b=null}y(Nm,Am); -Nm.prototype.Ib=function(b,c,d,e,f,g){if(""!==this.l&&this.j&&(this.b||this.i)){if(this.b){f=this.b;var h=this.C;if(!h||h.fillStyle!=f.fillStyle){var k=[9,f.fillStyle];this.f.push(k);this.a.push(k);h?h.fillStyle=f.fillStyle:this.C={fillStyle:f.fillStyle}}}this.i&&(f=this.i,h=this.D,h&&h.lineCap==f.lineCap&&h.lineDash==f.lineDash&&h.lineJoin==f.lineJoin&&h.lineWidth==f.lineWidth&&h.miterLimit==f.miterLimit&&h.strokeStyle==f.strokeStyle||(k=[10,f.strokeStyle,f.lineWidth,f.lineCap,f.lineJoin,f.miterLimit, -f.lineDash,!1],this.f.push(k),this.a.push(k),h?(h.lineCap=f.lineCap,h.lineDash=f.lineDash,h.lineJoin=f.lineJoin,h.lineWidth=f.lineWidth,h.miterLimit=f.miterLimit,h.strokeStyle=f.strokeStyle):this.D={lineCap:f.lineCap,lineDash:f.lineDash,lineJoin:f.lineJoin,lineWidth:f.lineWidth,miterLimit:f.miterLimit,strokeStyle:f.strokeStyle}));f=this.j;h=this.O;h&&h.font==f.font&&h.textAlign==f.textAlign&&h.textBaseline==f.textBaseline||(k=[11,f.font,f.textAlign,f.textBaseline],this.f.push(k),this.a.push(k),h? -(h.font=f.font,h.textAlign=f.textAlign,h.textBaseline=f.textBaseline):this.O={font:f.font,textAlign:f.textAlign,textBaseline:f.textBaseline});Cm(this,g);f=this.coordinates.length;b=Bm(this,b,c,d,e,!1);b=[5,f,b,this.l,this.o,this.G,this.B,this.v,!!this.b,!!this.i];this.f.push(b);this.a.push(b);Fm(this,g)}}; -Nm.prototype.cb=function(b){if(b){var c=b.a;c?(c=c.a,c=vg(c?c:Ql),this.b?this.b.fillStyle=c:this.b={fillStyle:c}):this.b=null;var d=b.j;if(d){var c=d.a,e=d.c,f=d.b,g=d.g,h=d.f,d=d.i,e=void 0!==e?e:"round",f=f?f.slice():Rl,g=void 0!==g?g:"round",h=void 0!==h?h:1,d=void 0!==d?d:10,c=vg(c?c:Sl);if(this.i){var k=this.i;k.lineCap=e;k.lineDash=f;k.lineJoin=g;k.lineWidth=h;k.miterLimit=d;k.strokeStyle=c}else this.i={lineCap:e,lineDash:f,lineJoin:g,lineWidth:h,miterLimit:d,strokeStyle:c}}else this.i=null; -var m=b.b,c=b.c,e=b.g,f=b.i,h=b.f,d=b.Ca(),g=b.l,k=b.o;b=void 0!==m?m:"10px sans-serif";g=void 0!==g?g:"center";k=void 0!==k?k:"middle";this.j?(m=this.j,m.font=b,m.textAlign=g,m.textBaseline=k):this.j={font:b,textAlign:g,textBaseline:k};this.l=void 0!==d?d:"";this.o=void 0!==c?c:0;this.G=void 0!==e?e:0;this.B=void 0!==f?f:0;this.v=void 0!==h?h:1}else this.l=""};function Om(b,c,d,e){this.G=b;this.g=c;this.o=d;this.i=e;this.f={};this.j=Ni(1,1);this.l=Bd()} -function Pm(b){for(var c in b.f){var d=b.f[c],e;for(e in d)d[e].we()}}Om.prototype.c=function(b,c,d,e,f){var g=this.l;gk(g,.5,.5,1/c,-1/c,-d,-b[0],-b[1]);var h=this.j;h.clearRect(0,0,1,1);var k;void 0!==this.i&&(k=Md(),Nd(k,b),Qd(k,c*this.i,k));return Qm(this,h,g,d,e,function(b){if(0<h.getImageData(0,0,1,1).data[3]){if(b=f(b))return b;h.clearRect(0,0,1,1)}},k)}; -Om.prototype.a=function(b,c){var d=void 0!==b?b.toString():"0",e=this.f[d];void 0===e&&(e={},this.f[d]=e);d=e[c];void 0===d&&(d=new Rm[c](this.G,this.g,this.o),e[c]=d);return d};Om.prototype.La=function(){return Pb(this.f)}; -Om.prototype.b=function(b,c,d,e,f){var g=Object.keys(this.f).map(Number);g.sort(ub);var h=this.g,k=h[0],m=h[1],n=h[2],h=h[3],k=[k,m,k,h,n,h,n,m];af(k,0,8,2,d,k);b.save();b.beginPath();b.moveTo(k[0],k[1]);b.lineTo(k[2],k[3]);b.lineTo(k[4],k[5]);b.lineTo(k[6],k[7]);b.closePath();b.clip();for(var p,q,k=0,m=g.length;k<m;++k)for(p=this.f[g[k].toString()],n=0,h=zm.length;n<h;++n)q=p[zm[n]],void 0!==q&&Dm(q,b,c,d,e,f,q.f,void 0);b.restore()}; -function Qm(b,c,d,e,f,g,h){var k=Object.keys(b.f).map(Number);k.sort(function(b,c){return c-b});var m,n,p,q,r;m=0;for(n=k.length;m<n;++m)for(q=b.f[k[m].toString()],p=zm.length-1;0<=p;--p)if(r=q[zm[p]],void 0!==r&&(r=Dm(r,c,1,d,e,f,r.a,g,h)))return r}var Rm={Image:Gm,LineString:Hm,Polygon:Km,Text:Nm};function Sm(b,c,d,e){this.b=b;this.a=c;this.g=d;this.c=e}l=Sm.prototype;l.get=function(b){return this.c[b]};l.zb=function(){return this.g};l.J=function(){this.f||(this.f="Point"===this.b?Xd(this.a):Yd(this.a,0,this.a.length,2));return this.f};l.ia=Sm.prototype.bc=function(){return this.a};l.X=function(){return this};l.Cm=function(){return this.c};l.td=Sm.prototype.X;l.ra=function(){return 2};l.ac=za;l.W=function(){return this.b};function Tm(b,c){return w(b)-w(c)}function Um(b,c){var d=.5*b/c;return d*d}function Vm(b,c,d,e,f,g){var h=!1,k,m;if(k=d.f)m=k.Cd(),2==m||3==m?k.Xf(f,g):(0==m&&k.load(),k.tf(f,g),h=!0);if(f=(0,d.c)(c))e=f.td(e),(0,Wm[e.W()])(b,e,d,c);return h} -var Wm={Point:function(b,c,d,e){var f=d.f;if(f){if(2!=f.Cd())return;var g=b.a(d.a,"Image");g.ub(f);g.Hb(c,e)}if(f=d.Ca())b=b.a(d.a,"Text"),b.cb(f),b.Ib(c.ia(),0,2,2,c,e)},LineString:function(b,c,d,e){var f=d.b;if(f){var g=b.a(d.a,"LineString");g.bb(null,f);g.Wb(c,e)}if(f=d.Ca())b=b.a(d.a,"Text"),b.cb(f),b.Ib(om(c),0,2,2,c,e)},Polygon:function(b,c,d,e){var f=d.g,g=d.b;if(f||g){var h=b.a(d.a,"Polygon");h.bb(f,g);h.Jc(c,e)}if(f=d.Ca())b=b.a(d.a,"Text"),b.cb(f),b.Ib(If(c),0,2,2,c,e)},MultiPoint:function(b, -c,d,e){var f=d.f;if(f){if(2!=f.Cd())return;var g=b.a(d.a,"Image");g.ub(f);g.Gb(c,e)}if(f=d.Ca())b=b.a(d.a,"Text"),b.cb(f),d=c.ia(),b.Ib(d,0,d.length,c.ra(),c,e)},MultiLineString:function(b,c,d,e){var f=d.b;if(f){var g=b.a(d.a,"LineString");g.bb(null,f);g.Hc(c,e)}if(f=d.Ca())b=b.a(d.a,"Text"),b.cb(f),d=pm(c),b.Ib(d,0,d.length,2,c,e)},MultiPolygon:function(b,c,d,e){var f=d.g,g=d.b;if(g||f){var h=b.a(d.a,"Polygon");h.bb(f,g);h.Ic(c,e)}if(f=d.Ca())b=b.a(d.a,"Text"),b.cb(f),d=sm(c),b.Ib(d,0,d.length,2, -c,e)},GeometryCollection:function(b,c,d,e){c=c.c;var f,g;f=0;for(g=c.length;f<g;++f)(0,Wm[c[f].W()])(b,c[f],d,e)},Circle:function(b,c,d,e){var f=d.g,g=d.b;if(f||g){var h=b.a(d.a,"Polygon");h.bb(f,g);h.Gc(c,e)}if(f=d.Ca())b=b.a(d.a,"Text"),b.cb(f),b.Ib(c.wd(),0,2,2,c,e)}};function Xm(b,c,d,e,f,g){this.g=void 0!==g?g:null;ek.call(this,b,c,d,void 0!==g?0:2,e);this.c=f;this.f=null}y(Xm,ek);Xm.prototype.getError=function(){return this.f};Xm.prototype.j=function(b){b?(this.f=b,this.state=3):this.state=2;fk(this)};Xm.prototype.load=function(){0==this.state&&(this.state=1,fk(this),this.g(ua(this.j,this)))};Xm.prototype.a=function(){return this.c};var Ym=!((Hb("Chrome")||Hb("CriOS"))&&!Hb("Opera")&&!Hb("OPR")&&!Hb("Edge"))||Hb("iPhone")&&!Hb("iPod")&&!Hb("iPad")||Hb("iPad")||Hb("iPod");function Zm(b,c,d,e){var f=Ye(d,c,b);d=c.getPointResolution(e,d);c=c.Kc();void 0!==c&&(d*=c);c=b.Kc();void 0!==c&&(d/=c);b=b.getPointResolution(d,f)/d;isFinite(b)&&!isNaN(b)&&0<b&&(d/=b);return d}function $m(b,c,d,e){b=d-b;c=e-c;var f=Math.sqrt(b*b+c*c);return[Math.round(d+b/f),Math.round(e+c/f)]} -function an(b,c,d,e,f,g,h,k,m,n){var p=Ni(Math.round(d*b),Math.round(d*c));if(0===m.length)return p.canvas;p.scale(d,d);var q=Md();m.forEach(function(b){be(q,b.extent)});var r=Ni(Math.round(d*je(q)/e),Math.round(d*ke(q)/e));r.scale(d/e,d/e);r.translate(-q[0],q[3]);m.forEach(function(b){r.drawImage(b.image,b.extent[0],-b.extent[3],je(b.extent),ke(b.extent))});var t=ge(h);k.c.forEach(function(b){var c=b.source,f=b.target,h=c[1][0],k=c[1][1],m=c[2][0],n=c[2][1];b=(f[0][0]-t[0])/g;var J=-(f[0][1]-t[1])/ -g,C=(f[1][0]-t[0])/g,sa=-(f[1][1]-t[1])/g,la=(f[2][0]-t[0])/g,K=-(f[2][1]-t[1])/g,f=c[0][0],c=c[0][1],h=h-f,k=k-c,m=m-f,n=n-c;a:{h=[[h,k,0,0,C-b],[m,n,0,0,la-b],[0,0,h,k,sa-J],[0,0,m,n,K-J]];k=h.length;for(m=0;m<k;m++){for(var n=m,ma=Math.abs(h[m][m]),Ua=m+1;Ua<k;Ua++){var Nb=Math.abs(h[Ua][m]);Nb>ma&&(ma=Nb,n=Ua)}if(0===ma){h=null;break a}ma=h[n];h[n]=h[m];h[m]=ma;for(n=m+1;n<k;n++)for(ma=-h[n][m]/h[m][m],Ua=m;Ua<k+1;Ua++)h[n][Ua]=m==Ua?0:h[n][Ua]+ma*h[m][Ua]}m=Array(k);for(n=k-1;0<=n;n--)for(m[n]= -h[n][k]/h[n][n],ma=n-1;0<=ma;ma--)h[ma][k]-=h[ma][n]*m[n];h=m}h&&(p.save(),p.beginPath(),Ym?(m=(b+C+la)/3,n=(J+sa+K)/3,k=$m(m,n,b,J),C=$m(m,n,C,sa),la=$m(m,n,la,K),p.moveTo(k[0],k[1]),p.lineTo(C[0],C[1]),p.lineTo(la[0],la[1])):(p.moveTo(b,J),p.lineTo(C,sa),p.lineTo(la,K)),p.closePath(),p.clip(),p.transform(h[0],h[2],h[1],h[3],b,J),p.translate(q[0]-f,q[3]-c),p.scale(e/d,-e/d),p.drawImage(r.canvas,0,0),p.restore())});n&&(p.save(),p.strokeStyle="black",p.lineWidth=1,k.c.forEach(function(b){var c=b.target; -b=(c[0][0]-t[0])/g;var d=-(c[0][1]-t[1])/g,e=(c[1][0]-t[0])/g,f=-(c[1][1]-t[1])/g,h=(c[2][0]-t[0])/g,c=-(c[2][1]-t[1])/g;p.beginPath();p.moveTo(b,d);p.lineTo(e,f);p.lineTo(h,c);p.closePath();p.stroke()}),p.restore());return p.canvas};function bn(b,c,d,e,f){this.b=b;this.g=c;var g={},h=We(this.g,this.b);this.f=function(b){var c=b[0]+"/"+b[1];g[c]||(g[c]=h(b));return g[c]};this.i=e;this.G=f*f;this.c=[];this.l=!1;this.o=this.b.b&&!!e&&!!this.b.J()&&je(e)==je(this.b.J());this.a=this.b.J()?je(this.b.J()):null;this.j=this.g.J()?je(this.g.J()):null;b=ge(d);c=fe(d);e=ee(d);d=de(d);f=this.f(b);var k=this.f(c),m=this.f(e),n=this.f(d);cn(this,b,c,e,d,f,k,m,n,10);if(this.l){var p=Infinity;this.c.forEach(function(b){p=Math.min(p,b.source[0][0], -b.source[1][0],b.source[2][0])});this.c.forEach(function(b){if(Math.max(b.source[0][0],b.source[1][0],b.source[2][0])-p>this.a/2){var c=[[b.source[0][0],b.source[0][1]],[b.source[1][0],b.source[1][1]],[b.source[2][0],b.source[2][1]]];c[0][0]-p>this.a/2&&(c[0][0]-=this.a);c[1][0]-p>this.a/2&&(c[1][0]-=this.a);c[2][0]-p>this.a/2&&(c[2][0]-=this.a);Math.max(c[0][0],c[1][0],c[2][0])-Math.min(c[0][0],c[1][0],c[2][0])<this.a/2&&(b.source=c)}},this)}g={}} -function cn(b,c,d,e,f,g,h,k,m,n){var p=Ld([g,h,k,m]),q=b.a?je(p)/b.a:null,r=b.b.b&&.5<q&&1>q,t=!1;if(0<n){if(b.g.c&&b.j)var x=Ld([c,d,e,f]),t=t|.25<je(x)/b.j;!r&&b.b.c&&q&&(t|=.25<q)}if(t||!b.i||oe(p,b.i)){if(!(t||isFinite(g[0])&&isFinite(g[1])&&isFinite(h[0])&&isFinite(h[1])&&isFinite(k[0])&&isFinite(k[1])&&isFinite(m[0])&&isFinite(m[1])))if(0<n)t=!0;else return;if(0<n&&(t||(q=b.f([(c[0]+e[0])/2,(c[1]+e[1])/2]),p=r?(nd(g[0],b.a)+nd(k[0],b.a))/2-nd(q[0],b.a):(g[0]+k[0])/2-q[0],q=(g[1]+k[1])/2-q[1], -t=p*p+q*q>b.G),t)){Math.abs(c[0]-e[0])<=Math.abs(c[1]-e[1])?(r=[(d[0]+e[0])/2,(d[1]+e[1])/2],p=b.f(r),q=[(f[0]+c[0])/2,(f[1]+c[1])/2],t=b.f(q),cn(b,c,d,r,q,g,h,p,t,n-1),cn(b,q,r,e,f,t,p,k,m,n-1)):(r=[(c[0]+d[0])/2,(c[1]+d[1])/2],p=b.f(r),q=[(e[0]+f[0])/2,(e[1]+f[1])/2],t=b.f(q),cn(b,c,r,q,f,g,p,t,m,n-1),cn(b,r,d,e,q,p,h,k,t,n-1));return}if(r){if(!b.o)return;b.l=!0}b.c.push({source:[g,k,m],target:[c,e,f]});b.c.push({source:[g,h,k],target:[c,d,e]})}} -function dn(b){var c=Md();b.c.forEach(function(b){b=b.source;Nd(c,b[0]);Nd(c,b[1]);Nd(c,b[2])});return c};function en(b,c,d,e,f,g){this.v=c;this.B=b.J();var h=c.J(),k=h?ne(d,h):d,h=Zm(b,c,le(k),e);this.o=new bn(b,c,k,this.B,.5*h);this.j=e;this.g=d;b=dn(this.o);this.G=(this.f=g(b,h,f))?this.f.b:1;this.c=this.l=null;f=2;g=[];this.f&&(f=0,g=this.f.i);ek.call(this,d,e,this.G,f,g)}y(en,ek);en.prototype.Y=function(){1==this.state&&(Wc(this.c),this.c=null);en.ca.Y.call(this)};en.prototype.a=function(){return this.l}; -function fn(b){var c=b.f.state;2==c&&(b.l=an(je(b.g)/b.j,ke(b.g)/b.j,b.G,b.f.$(),0,b.j,b.g,b.o,[{extent:b.f.J(),image:b.f.a()}]));b.state=c;fk(b)}en.prototype.load=function(){if(0==this.state){this.state=1;fk(this);var b=this.f.state;2==b||3==b?fn(this):(this.c=this.f.Ra("change",function(){var b=this.f.state;if(2==b||3==b)Wc(this.c),this.c=null,fn(this)},!1,this),this.f.load())}};function gn(b){wh.call(this,{attributions:b.attributions,extent:b.extent,logo:b.logo,projection:b.projection,state:b.state});this.D=void 0!==b.resolutions?b.resolutions:null;this.a=null;this.oa=0}y(gn,wh);function hn(b,c){if(b.D){var d=wb(b.D,c,0);c=b.D[d]}return c} -gn.prototype.C=function(b,c,d,e){var f=this.b;if(f&&e&&!Ve(f,e)){if(this.a){if(this.oa==this.f&&Ve(this.a.v,e)&&this.a.$()==c&&this.a.b==d&&ae(this.a.J(),b))return this.a;this.a.Fc();this.a=null}this.a=new en(f,e,b,c,d,ua(function(b,c,d){return this.qd(b,c,d,f)},this));this.oa=this.f;return this.a}f&&(e=f);return this.qd(b,c,d,e)};gn.prototype.l=function(b){b=b.target;switch(b.state){case 1:this.s(new jn(kn,b));break;case 2:this.s(new jn(ln,b));break;case 3:this.s(new jn(mn,b))}}; -function nn(b,c){b.a().src=c}function jn(b,c){tc.call(this,b);this.image=c}y(jn,tc);var kn="imageloadstart",ln="imageloadend",mn="imageloaderror";function on(b){gn.call(this,{attributions:b.attributions,logo:b.logo,projection:b.projection,resolutions:b.resolutions,state:void 0!==b.state?b.state:void 0});this.ga=b.canvasFunction;this.V=null;this.fa=0;this.pa=void 0!==b.ratio?b.ratio:1.5}y(on,gn);on.prototype.qd=function(b,c,d,e){c=hn(this,c);var f=this.V;if(f&&this.fa==this.f&&f.$()==c&&f.b==d&&Vd(f.J(),b))return f;b=b.slice();pe(b,this.pa);(e=this.ga(b,c,d,[je(b)/c*d,ke(b)/c*d],e))&&(f=new Xm(b,c,d,this.i,e));this.V=f;this.fa=this.f;return f};function pn(b){gd.call(this);this.xa=void 0;this.a="geometry";this.c=null;this.g=void 0;this.b=null;D(this,id(this.a),this.he,!1,this);void 0!==b&&(b instanceof $e||!b?this.Ma(b):this.I(b))}y(pn,gd);l=pn.prototype;l.clone=function(){var b=new pn(this.R());b.yc(this.a);var c=this.X();c&&b.Ma(c.clone());(c=this.c)&&b.wf(c);return b};l.X=function(){return this.get(this.a)};l.Oa=function(){return this.xa};l.Qj=function(){return this.a};l.zl=function(){return this.c};l.ac=function(){return this.g}; -l.Al=function(){this.u()};l.he=function(){this.b&&(Wc(this.b),this.b=null);var b=this.X();b&&(this.b=D(b,"change",this.Al,!1,this));this.u()};l.Ma=function(b){this.set(this.a,b)};l.wf=function(b){this.g=(this.c=b)?qn(b):void 0;this.u()};l.jc=function(b){this.xa=b;this.u()};l.yc=function(b){Vc(this,id(this.a),this.he,!1,this);this.a=b;D(this,id(this.a),this.he,!1,this);this.he()};function qn(b){if(!ka(b)){var c;c=ga(b)?b:[b];b=function(){return c}}return b};function rn(b){b.prototype.then=b.prototype.then;b.prototype.$goog_Thenable=!0}function sn(b){if(!b)return!1;try{return!!b.$goog_Thenable}catch(c){return!1}};function tn(b,c,d){this.c=d;this.b=b;this.g=c;this.f=0;this.a=null}tn.prototype.get=function(){var b;0<this.f?(this.f--,b=this.a,this.a=b.next,b.next=null):b=this.b();return b};function un(b,c){b.g(c);b.f<b.c&&(b.f++,c.next=b.a,b.a=c)};function vn(){this.f=this.a=null}var xn=new tn(function(){return new wn},function(b){b.reset()},100);vn.prototype.add=function(b,c){var d=xn.get();d.set(b,c);this.f?this.f.next=d:this.a=d;this.f=d};vn.prototype.remove=function(){var b=null;this.a&&(b=this.a,this.a=this.a.next,this.a||(this.f=null),b.next=null);return b};function wn(){this.next=this.f=this.a=null}wn.prototype.set=function(b,c){this.a=b;this.f=c;this.next=null};wn.prototype.reset=function(){this.next=this.f=this.a=null};function yn(b,c){zn||An();Bn||(zn(),Bn=!0);Cn.add(b,c)}var zn;function An(){if(ba.Promise&&ba.Promise.resolve){var b=ba.Promise.resolve(void 0);zn=function(){b.then(Dn)}}else zn=function(){li(Dn)}}var Bn=!1,Cn=new vn;function Dn(){for(var b=null;b=Cn.remove();){try{b.a.call(b.f)}catch(c){ki(c)}un(xn,b)}Bn=!1};function En(b,c){this.a=Fn;this.j=void 0;this.c=this.f=this.b=null;this.g=this.i=!1;if(b!=da)try{var d=this;b.call(c,function(b){Gn(d,Hn,b)},function(b){Gn(d,In,b)})}catch(e){Gn(this,In,e)}}var Fn=0,Hn=2,In=3;function Jn(){this.next=this.b=this.f=this.c=this.a=null;this.g=!1}Jn.prototype.reset=function(){this.b=this.f=this.c=this.a=null;this.g=!1};var Kn=new tn(function(){return new Jn},function(b){b.reset()},100);function Ln(b,c,d){var e=Kn.get();e.c=b;e.f=c;e.b=d;return e} -En.prototype.then=function(b,c,d){return Mn(this,ka(b)?b:null,ka(c)?c:null,d)};rn(En);En.prototype.cancel=function(b){this.a==Fn&&yn(function(){var c=new Nn(b);On(this,c)},this)};function On(b,c){if(b.a==Fn)if(b.b){var d=b.b;if(d.f){for(var e=0,f=null,g=null,h=d.f;h&&(h.g||(e++,h.a==b&&(f=h),!(f&&1<e)));h=h.next)f||(g=h);f&&(d.a==Fn&&1==e?On(d,c):(g?(e=g,e.next==d.c&&(d.c=e),e.next=e.next.next):Pn(d),Qn(d,f,In,c)))}b.b=null}else Gn(b,In,c)} -function Rn(b,c){b.f||b.a!=Hn&&b.a!=In||Sn(b);b.c?b.c.next=c:b.f=c;b.c=c}function Mn(b,c,d,e){var f=Ln(null,null,null);f.a=new En(function(b,h){f.c=c?function(d){try{var f=c.call(e,d);b(f)}catch(n){h(n)}}:b;f.f=d?function(c){try{var f=d.call(e,c);!ca(f)&&c instanceof Nn?h(c):b(f)}catch(n){h(n)}}:h});f.a.b=b;Rn(b,f);return f.a}En.prototype.o=function(b){this.a=Fn;Gn(this,Hn,b)};En.prototype.G=function(b){this.a=Fn;Gn(this,In,b)}; -function Gn(b,c,d){if(b.a==Fn){b==d&&(c=In,d=new TypeError("Promise cannot resolve to itself"));b.a=1;var e;a:{var f=d,g=b.o,h=b.G;if(f instanceof En)Rn(f,Ln(g||da,h||null,b)),e=!0;else if(sn(f))f.then(g,h,b),e=!0;else{if(oa(f))try{var k=f.then;if(ka(k)){Tn(f,k,g,h,b);e=!0;break a}}catch(m){h.call(b,m);e=!0;break a}e=!1}}e||(b.j=d,b.a=c,b.b=null,Sn(b),c!=In||d instanceof Nn||Un(b,d))}} -function Tn(b,c,d,e,f){function g(b){k||(k=!0,e.call(f,b))}function h(b){k||(k=!0,d.call(f,b))}var k=!1;try{c.call(b,h,g)}catch(m){g(m)}}function Sn(b){b.i||(b.i=!0,yn(b.l,b))}function Pn(b){var c=null;b.f&&(c=b.f,b.f=c.next,c.next=null);b.f||(b.c=null);return c}En.prototype.l=function(){for(var b=null;b=Pn(this);)Qn(this,b,this.a,this.j);this.i=!1}; -function Qn(b,c,d,e){if(d==In&&c.f&&!c.g)for(;b&&b.g;b=b.b)b.g=!1;if(c.a)c.a.b=null,Vn(c,d,e);else try{c.g?c.c.call(c.b):Vn(c,d,e)}catch(f){Wn.call(null,f)}un(Kn,c)}function Vn(b,c,d){c==Hn?b.c.call(b.b,d):b.f&&b.f.call(b.b,d)}function Un(b,c){b.g=!0;yn(function(){b.g&&Wn.call(null,c)})}var Wn=ki;function Nn(b){Aa.call(this,b)}y(Nn,Aa);Nn.prototype.name="cancel";function Xn(b,c,d){if(ka(b))d&&(b=ua(b,d));else if(b&&"function"==typeof b.handleEvent)b=ua(b.handleEvent,b);else throw Error("Invalid listener argument");return 2147483647<c?-1:ba.setTimeout(b,c||0)};var Yn=ba.JSON.parse,Zn=ba.JSON.stringify;function $n(){}$n.prototype.a=null;function ao(b){var c;(c=b.a)||(c={},bo(b)&&(c[0]=!0,c[1]=!0),c=b.a=c);return c};var co;function eo(){}y(eo,$n);function fo(b){return(b=bo(b))?new ActiveXObject(b):new XMLHttpRequest}function bo(b){if(!b.f&&"undefined"==typeof XMLHttpRequest&&"undefined"!=typeof ActiveXObject){for(var c=["MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"],d=0;d<c.length;d++){var e=c[d];try{return new ActiveXObject(e),b.f=e}catch(f){}}throw Error("Could not create ActiveXObject. ActiveX might be disabled, or MSXML might not be installed");}return b.f}co=new eo;var go=/^(?:([^:/?#.]+):)?(?:\/\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\?([^#]*))?(?:#(.*))?$/;function ho(b,c){if(b)for(var d=b.split("&"),e=0;e<d.length;e++){var f=d[e].indexOf("="),g=null,h=null;0<=f?(g=d[e].substring(0,f),h=d[e].substring(f+1)):g=d[e];c(g,h?decodeURIComponent(h.replace(/\+/g," ")):"")}} -function io(b){if(b[1]){var c=b[0],d=c.indexOf("#");0<=d&&(b.push(c.substr(d)),b[0]=c=c.substr(0,d));d=c.indexOf("?");0>d?b[1]="?":d==c.length-1&&(b[1]=void 0)}return b.join("")}function jo(b,c,d){if(ga(c))for(var e=0;e<c.length;e++)jo(b,String(c[e]),d);else null!=c&&d.push("&",b,""===c?"":"=",encodeURIComponent(String(c)))}function ko(b,c){for(var d in c)jo(d,c[d],b);return b};function lo(b){$c.call(this);this.O=new pi;this.o=b||null;this.a=!1;this.l=this.ha=null;this.g=this.U=this.v="";this.f=this.B=this.c=this.G=!1;this.j=0;this.b=null;this.i=mo;this.C=this.V=!1}y(lo,$c);var mo="",no=/^https?$/i,oo=["POST","PUT"]; -function po(b,c){if(b.ha)throw Error("[goog.net.XhrIo] Object is active with another request="+b.v+"; newUri="+c);b.v=c;b.g="";b.U="GET";b.G=!1;b.a=!0;b.ha=b.o?fo(b.o):fo(co);b.l=b.o?ao(b.o):ao(co);b.ha.onreadystatechange=ua(b.D,b);try{b.B=!0,b.ha.open("GET",String(c),!0),b.B=!1}catch(g){qo(b,g);return}var d=b.O.clone(),e=fb(d.P(),ro),f=ba.FormData&&!1;!(0<=ab(oo,"GET"))||e||f||d.set("Content-Type","application/x-www-form-urlencoded;charset=utf-8");d.forEach(function(b,c){this.ha.setRequestHeader(c, -b)},b);b.i&&(b.ha.responseType=b.i);"withCredentials"in b.ha&&(b.ha.withCredentials=b.V);try{so(b),0<b.j&&(b.C=to(b.ha),b.C?(b.ha.timeout=b.j,b.ha.ontimeout=ua(b.Bc,b)):b.b=Xn(b.Bc,b.j,b)),b.c=!0,b.ha.send(""),b.c=!1}catch(g){qo(b,g)}}function to(b){return Yb&&ic(9)&&ja(b.timeout)&&ca(b.ontimeout)}function ro(b){return"content-type"==b.toLowerCase()} -lo.prototype.Bc=function(){"undefined"!=typeof aa&&this.ha&&(this.g="Timed out after "+this.j+"ms, aborting",this.s("timeout"),this.ha&&this.a&&(this.a=!1,this.f=!0,this.ha.abort(),this.f=!1,this.s("complete"),this.s("abort"),uo(this)))};function qo(b,c){b.a=!1;b.ha&&(b.f=!0,b.ha.abort(),b.f=!1);b.g=c;vo(b);uo(b)}function vo(b){b.G||(b.G=!0,b.s("complete"),b.s("error"))}lo.prototype.Y=function(){this.ha&&(this.a&&(this.a=!1,this.f=!0,this.ha.abort(),this.f=!1),uo(this,!0));lo.ca.Y.call(this)}; -lo.prototype.D=function(){this.na||(this.B||this.c||this.f?wo(this):this.T())};lo.prototype.T=function(){wo(this)};function wo(b){if(b.a&&"undefined"!=typeof aa&&(!b.l[1]||4!=xo(b)||2!=yo(b)))if(b.c&&4==xo(b))Xn(b.D,0,b);else if(b.s("readystatechange"),4==xo(b)){b.a=!1;try{if(zo(b))b.s("complete"),b.s("success");else{var c;try{c=2<xo(b)?b.ha.statusText:""}catch(d){c=""}b.g=c+" ["+yo(b)+"]";vo(b)}}finally{uo(b)}}} -function uo(b,c){if(b.ha){so(b);var d=b.ha,e=b.l[0]?da:null;b.ha=null;b.l=null;c||b.s("ready");try{d.onreadystatechange=e}catch(f){}}}function so(b){b.ha&&b.C&&(b.ha.ontimeout=null);ja(b.b)&&(ba.clearTimeout(b.b),b.b=null)} -function zo(b){var c=yo(b),d;a:switch(c){case 200:case 201:case 202:case 204:case 206:case 304:case 1223:d=!0;break a;default:d=!1}if(!d){if(c=0===c)b=String(b.v).match(go)[1]||null,!b&&ba.self&&ba.self.location&&(b=ba.self.location.protocol,b=b.substr(0,b.length-1)),c=!no.test(b?b.toLowerCase():"");d=c}return d}function xo(b){return b.ha?b.ha.readyState:0}function yo(b){try{return 2<xo(b)?b.ha.status:-1}catch(c){return-1}}function Ao(b){try{return b.ha?b.ha.responseText:""}catch(c){return""}} -function Bo(b){try{if(!b.ha)return null;if("response"in b.ha)return b.ha.response;switch(b.i){case mo:case "text":return b.ha.responseText;case "arraybuffer":if("mozResponseArrayBuffer"in b.ha)return b.ha.mozResponseArrayBuffer}return null}catch(c){return null}};function Co(b,c,d,e,f,g){uh.call(this,b,c);this.j=e;this.i=null;this.b=g;this.c={kd:!1,Tf:null,Rh:-1,Hd:null};this.G=f;this.l=d}y(Co,uh);l=Co.prototype;l.Y=function(){Co.ca.Y.call(this)};l.Ll=function(){return this.j};l.$a=function(){return this.l};l.load=function(){0==this.state&&(this.state=1,vh(this),this.G(this,this.l),this.o(null,NaN,this.b))};l.ai=function(b){this.o=b};function Do(){if(!Yb)return!1;try{return new ActiveXObject("MSXML2.DOMDocument"),!0}catch(b){return!1}}var Eo=Yb&&Do();function Fo(b){var c=b.xml;if(c)return c;if("undefined"!=typeof XMLSerializer)return(new XMLSerializer).serializeToString(b);throw Error("Your browser does not support serializing XML documents");};var Go;a:if(document.implementation&&document.implementation.createDocument)Go=document.implementation.createDocument("","",null);else{if(Eo){var Ho=new ActiveXObject("MSXML2.DOMDocument");if(Ho){Ho.resolveExternals=!1;Ho.validateOnParse=!1;try{Ho.setProperty("ProhibitDTD",!0),Ho.setProperty("MaxXMLSize",2048),Ho.setProperty("MaxElementDepth",256)}catch(b){}}if(Ho){Go=Ho;break a}}throw Error("Your browser does not support creating new documents");}var Io=Go; -function Jo(b,c){return Io.createElementNS(b,c)}function Ko(b,c){b||(b="");return Io.createNode(1,c,b)}var Lo=document.implementation&&document.implementation.createDocument?Jo:Ko;function Mo(b,c){return No(b,c,[]).join("")}function No(b,c,d){if(4==b.nodeType||3==b.nodeType)c?d.push(String(b.nodeValue).replace(/(\r\n|\r|\n)/g,"")):d.push(b.nodeValue);else for(b=b.firstChild;b;b=b.nextSibling)No(b,c,d);return d}function Oo(b){return b.localName} -function Po(b){var c=b.localName;return void 0!==c?c:b.baseName}var Qo=Yb?Po:Oo;function Ro(b){return b instanceof Document}function So(b){return oa(b)&&9==b.nodeType}var To=Yb?So:Ro;function Uo(b){return b instanceof Node}function Vo(b){return oa(b)&&void 0!==b.nodeType}var Wo=Yb?Vo:Uo;function Xo(b,c,d){return b.getAttributeNS(c,d)||""}function Yo(b,c,d){var e="";b=Zo(b,c,d);void 0!==b&&(e=b.nodeValue);return e}var $o=document.implementation&&document.implementation.createDocument?Xo:Yo; -function ap(b,c,d){return b.getAttributeNodeNS(c,d)}function bp(b,c,d){var e=null;b=b.attributes;for(var f,g,h=0,k=b.length;h<k;++h)if(f=b[h],f.namespaceURI==c&&(g=f.prefix?f.prefix+":"+d:d,g==f.nodeName)){e=f;break}return e}var Zo=document.implementation&&document.implementation.createDocument?ap:bp;function cp(b,c,d,e){b.setAttributeNS(c,d,e)}function dp(b,c,d,e){c?(c=b.ownerDocument.createNode(2,d,c),c.nodeValue=e,b.setAttributeNode(c)):b.setAttribute(d,e)} -var ep=document.implementation&&document.implementation.createDocument?cp:dp;function fp(b){return(new DOMParser).parseFromString(b,"application/xml")}function gp(b,c){return function(d,e){var f=b.call(c,d,e);void 0!==f&&kb(e[e.length-1],f)}}function hp(b,c){return function(d,e){var f=b.call(void 0!==c?c:this,d,e);void 0!==f&&e[e.length-1].push(f)}}function ip(b,c){return function(d,e){var f=b.call(void 0!==c?c:this,d,e);void 0!==f&&(e[e.length-1]=f)}} -function jp(b){return function(c,d){var e=b.call(this,c,d);void 0!==e&&Sb(d[d.length-1],c.localName).push(e)}}function N(b,c){return function(d,e){var f=b.call(this,d,e);void 0!==f&&(e[e.length-1][void 0!==c?c:d.localName]=f)}}function O(b,c){return function(d,e,f){b.call(void 0!==c?c:this,d,e,f);f[f.length-1].node.appendChild(d)}}function kp(b){var c,d;return function(e,f,g){if(void 0===c){c={};var h={};h[e.localName]=b;c[e.namespaceURI]=h;d=lp(e.localName)}mp(c,d,f,g)}} -function lp(b,c){return function(d,e,f){d=e[e.length-1].node;e=b;void 0===e&&(e=f);f=c;void 0===c&&(f=d.namespaceURI);return Lo(f,e)}}var np=lp();function op(b,c){for(var d=c.length,e=Array(d),f=0;f<d;++f)e[f]=b[c[f]];return e}function P(b,c,d){d=void 0!==d?d:{};var e,f;e=0;for(f=b.length;e<f;++e)d[b[e]]=c;return d}function pp(b,c,d,e){for(c=c.firstElementChild;c;c=c.nextElementSibling){var f=b[c.namespaceURI];void 0!==f&&(f=f[c.localName],void 0!==f&&f.call(e,c,d))}} -function Q(b,c,d,e,f){e.push(b);pp(c,d,e,f);return e.pop()}function mp(b,c,d,e,f,g){for(var h=(void 0!==f?f:d).length,k,m,n=0;n<h;++n)k=d[n],void 0!==k&&(m=c.call(g,k,e,void 0!==f?f[n]:void 0),void 0!==m&&b[m.namespaceURI][m.localName].call(g,m,k,e))}function qp(b,c,d,e,f,g,h){f.push(b);mp(c,d,e,f,g,h);f.pop()};function rp(b,c,d,e){return function(f,g,h){var k=new lo;k.i="arraybuffer"==c.W()?"arraybuffer":"text";D(k,"complete",function(b){b=b.target;if(zo(b)){var f=c.W(),g;if("json"==f)g=Ao(b);else if("text"==f)g=Ao(b);else if("xml"==f){if(!Yb)try{g=b.ha?b.ha.responseXML:null}catch(k){g=null}g||(g=fp(Ao(b)))}else"arraybuffer"==f&&(g=Bo(b));g&&(this instanceof Co&&(f=c.Ia(g).f,"tile-pixels"===f&&(this.b=h=new Ce({code:this.b.a,units:f}))),d.call(this,c.Ba(g,{featureProjection:h})))}else e.call(this);sc(b)}, -!1,this);ka(b)?po(k,b(f,g,h)):po(k,b)}}function sp(b,c){return rp(b,c,function(b){this.i=b;this.state=2;vh(this)},function(){this.state=3;vh(this)})}function tp(b,c){return rp(b,c,function(b){this.Ec(b)},za)};function up(){return[[-Infinity,-Infinity,Infinity,Infinity]]};var vp,wp,xp,yp; -(function(){var b={ja:{}};(function(){function c(b,d){if(!(this instanceof c))return new c(b,d);this.bf=Math.max(4,b||9);this.hg=Math.max(2,Math.ceil(.4*this.bf));d&&this.cj(d);this.clear()}function d(b,c){b.bbox=e(b,0,b.children.length,c)}function e(b,c,d,e){for(var g=[Infinity,Infinity,-Infinity,-Infinity],h;c<d;c++)h=b.children[c],f(g,b.Qa?e(h):h.bbox);return g}function f(b,c){b[0]=Math.min(b[0],c[0]);b[1]=Math.min(b[1],c[1]);b[2]=Math.max(b[2],c[2]);b[3]=Math.max(b[3],c[3])}function g(b,c){return b.bbox[0]- -c.bbox[0]}function h(b,c){return b.bbox[1]-c.bbox[1]}function k(b){return(b[2]-b[0])*(b[3]-b[1])}function m(b){return b[2]-b[0]+(b[3]-b[1])}function n(b,c){return b[0]<=c[0]&&b[1]<=c[1]&&c[2]<=b[2]&&c[3]<=b[3]}function p(b,c){return c[0]<=b[2]&&c[1]<=b[3]&&c[2]>=b[0]&&c[3]>=b[1]}function q(b,c,d,e,f){for(var g=[c,d],h;g.length;)d=g.pop(),c=g.pop(),d-c<=e||(h=c+Math.ceil((d-c)/e/2)*e,r(b,c,d,h,f),g.push(c,h,h,d))}function r(b,c,d,e,f){for(var g,h,k,m,n;d>c;){600<d-c&&(g=d-c+1,h=e-c+1,k=Math.log(g), -m=.5*Math.exp(2*k/3),n=.5*Math.sqrt(k*m*(g-m)/g)*(0>h-g/2?-1:1),k=Math.max(c,Math.floor(e-h*m/g+n)),h=Math.min(d,Math.floor(e+(g-h)*m/g+n)),r(b,k,h,e,f));g=b[e];h=c;m=d;t(b,c,e);for(0<f(b[d],g)&&t(b,c,d);h<m;){t(b,h,m);h++;for(m--;0>f(b[h],g);)h++;for(;0<f(b[m],g);)m--}0===f(b[c],g)?t(b,c,m):(m++,t(b,m,d));m<=e&&(c=m+1);e<=m&&(d=m-1)}}function t(b,c,d){var e=b[c];b[c]=b[d];b[d]=e}c.prototype={all:function(){return this.cg(this.data,[])},search:function(b){var c=this.data,d=[],e=this.fb;if(!p(b,c.bbox))return d; -for(var f=[],g,h,k,m;c;){g=0;for(h=c.children.length;g<h;g++)k=c.children[g],m=c.Qa?e(k):k.bbox,p(b,m)&&(c.Qa?d.push(k):n(b,m)?this.cg(k,d):f.push(k));c=f.pop()}return d},load:function(b){if(!b||!b.length)return this;if(b.length<this.hg){for(var c=0,d=b.length;c<d;c++)this.ya(b[c]);return this}b=this.eg(b.slice(),0,b.length-1,0);this.data.children.length?this.data.height===b.height?this.jg(this.data,b):(this.data.height<b.height&&(c=this.data,this.data=b,b=c),this.gg(b,this.data.height-b.height-1, -!0)):this.data=b;return this},ya:function(b){b&&this.gg(b,this.data.height-1);return this},clear:function(){this.data={children:[],height:1,bbox:[Infinity,Infinity,-Infinity,-Infinity],Qa:!0};return this},remove:function(b){if(!b)return this;for(var c=this.data,d=this.fb(b),e=[],f=[],g,h,k,m;c||e.length;){c||(c=e.pop(),h=e[e.length-1],g=f.pop(),m=!0);if(c.Qa&&(k=c.children.indexOf(b),-1!==k)){c.children.splice(k,1);e.push(c);this.aj(e);break}m||c.Qa||!n(c.bbox,d)?h?(g++,c=h.children[g],m=!1):c=null: -(e.push(c),f.push(g),g=0,h=c,c=c.children[0])}return this},fb:function(b){return b},ff:function(b,c){return b[0]-c[0]},gf:function(b,c){return b[1]-c[1]},toJSON:function(){return this.data},cg:function(b,c){for(var d=[];b;)b.Qa?c.push.apply(c,b.children):d.push.apply(d,b.children),b=d.pop();return c},eg:function(b,c,e,f){var g=e-c+1,h=this.bf,k;if(g<=h)return k={children:b.slice(c,e+1),height:1,bbox:null,Qa:!0},d(k,this.fb),k;f||(f=Math.ceil(Math.log(g)/Math.log(h)),h=Math.ceil(g/Math.pow(h,f-1))); -k={children:[],height:f,bbox:null};var g=Math.ceil(g/h),h=g*Math.ceil(Math.sqrt(h)),m,n,p;for(q(b,c,e,h,this.ff);c<=e;c+=h)for(n=Math.min(c+h-1,e),q(b,c,n,g,this.gf),m=c;m<=n;m+=g)p=Math.min(m+g-1,n),k.children.push(this.eg(b,m,p,f-1));d(k,this.fb);return k},$i:function(b,c,d,e){for(var f,g,h,m,n,p,q,r;;){e.push(c);if(c.Qa||e.length-1===d)break;q=r=Infinity;f=0;for(g=c.children.length;f<g;f++)h=c.children[f],n=k(h.bbox),p=h.bbox,p=(Math.max(p[2],b[2])-Math.min(p[0],b[0]))*(Math.max(p[3],b[3])-Math.min(p[1], -b[1]))-n,p<r?(r=p,q=n<q?n:q,m=h):p===r&&n<q&&(q=n,m=h);c=m}return c},gg:function(b,c,d){var e=this.fb;d=d?b.bbox:e(b);var e=[],g=this.$i(d,this.data,c,e);g.children.push(b);for(f(g.bbox,d);0<=c;)if(e[c].children.length>this.bf)this.ij(e,c),c--;else break;this.Xi(d,e,c)},ij:function(b,c){var e=b[c],f=e.children.length,g=this.hg;this.Yi(e,g,f);f=this.Zi(e,g,f);f={children:e.children.splice(f,e.children.length-f),height:e.height};e.Qa&&(f.Qa=!0);d(e,this.fb);d(f,this.fb);c?b[c-1].children.push(f):this.jg(e, -f)},jg:function(b,c){this.data={children:[b,c],height:b.height+1};d(this.data,this.fb)},Zi:function(b,c,d){var f,g,h,m,n,p,q;n=p=Infinity;for(f=c;f<=d-c;f++)g=e(b,0,f,this.fb),h=e(b,f,d,this.fb),m=Math.max(0,Math.min(g[2],h[2])-Math.max(g[0],h[0]))*Math.max(0,Math.min(g[3],h[3])-Math.max(g[1],h[1])),g=k(g)+k(h),m<n?(n=m,q=f,p=g<p?g:p):m===n&&g<p&&(p=g,q=f);return q},Yi:function(b,c,d){var e=b.Qa?this.ff:g,f=b.Qa?this.gf:h,k=this.dg(b,c,d,e);c=this.dg(b,c,d,f);k<c&&b.children.sort(e)},dg:function(b, -c,d,g){b.children.sort(g);g=this.fb;var h=e(b,0,c,g),k=e(b,d-c,d,g),n=m(h)+m(k),p,q;for(p=c;p<d-c;p++)q=b.children[p],f(h,b.Qa?g(q):q.bbox),n+=m(h);for(p=d-c-1;p>=c;p--)q=b.children[p],f(k,b.Qa?g(q):q.bbox),n+=m(k);return n},Xi:function(b,c,d){for(;0<=d;d--)f(c[d].bbox,b)},aj:function(b){for(var c=b.length-1,e;0<=c;c--)0===b[c].children.length?0<c?(e=b[c-1].children,e.splice(e.indexOf(b[c]),1)):this.clear():d(b[c],this.fb)},cj:function(b){var c=["return a"," - b",";"];this.ff=new Function("a","b", -c.join(b[0]));this.gf=new Function("a","b",c.join(b[1]));this.fb=new Function("a","return [a"+b.join(", a")+"];")}};"undefined"!==typeof b?b.ja=c:"undefined"!==typeof self?self.a=c:window.a=c})();vp=b.ja})();function zp(b){this.f=vp(b);this.a={}}l=zp.prototype;l.ya=function(b,c){var d=[b[0],b[1],b[2],b[3],c];this.f.ya(d);this.a[w(c)]=d};l.load=function(b,c){for(var d=Array(c.length),e=0,f=c.length;e<f;e++){var g=b[e],h=c[e],g=[g[0],g[1],g[2],g[3],h];d[e]=g;this.a[w(h)]=g}this.f.load(d)};l.remove=function(b){b=w(b);var c=this.a[b];delete this.a[b];return null!==this.f.remove(c)};function Ap(b,c,d){var e=w(d);ae(b.a[e].slice(0,4),c)||(b.remove(d),b.ya(c,d))} -function Bp(b){return b.f.all().map(function(b){return b[4]})}function Cp(b,c){return b.f.search(c).map(function(b){return b[4]})}l.forEach=function(b,c){return Dp(Bp(this),b,c)};function Ep(b,c,d,e){return Dp(Cp(b,c),d,e)}function Dp(b,c,d){for(var e,f=0,g=b.length;f<g&&!(e=c.call(d,b[f]));f++);return e}l.La=function(){return Pb(this.a)};l.clear=function(){this.f.clear();this.a={}};l.J=function(){return this.f.data.bbox};function R(b){b=b||{};wh.call(this,{attributions:b.attributions,logo:b.logo,projection:void 0,state:"ready",wrapX:void 0!==b.wrapX?b.wrapX:!0});this.T=za;void 0!==b.loader?this.T=b.loader:void 0!==b.url&&(this.T=tp(b.url,b.format));this.pa=void 0!==b.strategy?b.strategy:up;var c=void 0!==b.useSpatialIndex?b.useSpatialIndex:!0;this.a=c?new zp:null;this.V=new zp;this.g={};this.j={};this.l={};this.o={};this.c=null;var d,e;b.features instanceof og?(d=b.features,e=d.a):ga(b.features)&&(e=b.features);c|| -void 0!==d||(d=new og(e));void 0!==e&&Fp(this,e);void 0!==d&&Gp(this,d)}y(R,wh);l=R.prototype;l.Bd=function(b){var c=w(b).toString();if(Hp(this,c,b)){Ip(this,c,b);var d=b.X();d?(c=d.J(),this.a&&this.a.ya(c,b)):this.g[c]=b;this.s(new Jp("addfeature",b))}this.u()};function Ip(b,c,d){b.o[c]=[D(d,"change",b.th,!1,b),D(d,"propertychange",b.th,!1,b)]}function Hp(b,c,d){var e=!0,f=d.Oa();void 0!==f?f.toString()in b.j?e=!1:b.j[f.toString()]=d:b.l[c]=d;return e}l.Ec=function(b){Fp(this,b);this.u()}; -function Fp(b,c){var d,e,f,g,h=[],k=[],m=[];e=0;for(f=c.length;e<f;e++)g=c[e],d=w(g).toString(),Hp(b,d,g)&&k.push(g);e=0;for(f=k.length;e<f;e++){g=k[e];d=w(g).toString();Ip(b,d,g);var n=g.X();n?(d=n.J(),h.push(d),m.push(g)):b.g[d]=g}b.a&&b.a.load(h,m);e=0;for(f=k.length;e<f;e++)b.s(new Jp("addfeature",k[e]))} -function Gp(b,c){var d=!1;D(b,"addfeature",function(b){d||(d=!0,c.push(b.feature),d=!1)});D(b,"removefeature",function(b){d||(d=!0,c.remove(b.feature),d=!1)});D(c,"add",function(b){d||(b=b.element,d=!0,this.Bd(b),d=!1)},!1,b);D(c,"remove",function(b){d||(b=b.element,d=!0,this.Rc(b),d=!1)},!1,b);b.c=c} -l.clear=function(b){if(b){for(var c in this.o)this.o[c].forEach(Wc);this.c||(this.o={},this.j={},this.l={})}else b=this.Qh,this.a&&(this.a.forEach(b,this),Ib(this.g,b,this));this.c&&this.c.clear();this.a&&this.a.clear();this.V.clear();this.g={};this.s(new Jp("clear"));this.u()};l.sg=function(b,c){if(this.a)return this.a.forEach(b,c);if(this.c)return this.c.forEach(b,c)};function Kp(b,c,d){b.pb([c[0],c[1],c[0],c[1]],function(b){if(b.X().og(c))return d.call(void 0,b)})} -l.pb=function(b,c,d){if(this.a)return Ep(this.a,b,c,d);if(this.c)return this.c.forEach(c,d)};l.tg=function(b,c,d){return this.pb(b,function(e){if(e.X().Ea(b)&&(e=c.call(d,e)))return e})};l.zg=function(){return this.c};l.ze=function(){var b;this.c?b=this.c.a:this.a&&(b=Bp(this.a),Pb(this.g)||kb(b,Lb(this.g)));return b};l.yg=function(b){var c=[];Kp(this,b,function(b){c.push(b)});return c};l.mf=function(b){return Cp(this.a,b)}; -l.vg=function(b){var c=b[0],d=b[1],e=null,f=[NaN,NaN],g=Infinity,h=[-Infinity,-Infinity,Infinity,Infinity];Ep(this.a,h,function(b){var m=b.X(),n=g;g=m.nb(c,d,f,g);g<n&&(e=b,b=Math.sqrt(g),h[0]=c-b,h[1]=d-b,h[2]=c+b,h[3]=d+b)});return e};l.J=function(){return this.a.J()};l.xg=function(b){b=this.j[b.toString()];return void 0!==b?b:null}; -l.th=function(b){b=b.target;var c=w(b).toString(),d=b.X();d?(d=d.J(),c in this.g?(delete this.g[c],this.a&&this.a.ya(d,b)):this.a&&Ap(this.a,d,b)):c in this.g||(this.a&&this.a.remove(b),this.g[c]=b);d=b.Oa();void 0!==d?(d=d.toString(),c in this.l?(delete this.l[c],this.j[d]=b):this.j[d]!==b&&(Lp(this,b),this.j[d]=b)):c in this.l||(Lp(this,b),this.l[c]=b);this.u();this.s(new Jp("changefeature",b))};l.La=function(){return this.a.La()&&Pb(this.g)}; -l.Nc=function(b,c,d){var e=this.V;b=this.pa(b,c);var f,g;f=0;for(g=b.length;f<g;++f){var h=b[f];Ep(e,h,function(b){return Vd(b.extent,h)})||(this.T.call(this,h,c,d),e.ya(h,{extent:h.slice()}))}};l.Rc=function(b){var c=w(b).toString();c in this.g?delete this.g[c]:this.a&&this.a.remove(b);this.Qh(b);this.u()};l.Qh=function(b){var c=w(b).toString();this.o[c].forEach(Wc);delete this.o[c];var d=b.Oa();void 0!==d?delete this.j[d.toString()]:delete this.l[c];this.s(new Jp("removefeature",b))}; -function Lp(b,c){for(var d in b.j)if(b.j[d]===c){delete b.j[d];break}}function Jp(b,c){tc.call(this,b);this.feature=c}y(Jp,tc);function Mp(b){this.c=b.source;this.wa=Bd();this.g=Ni();this.j=[0,0];this.v=null;on.call(this,{attributions:b.attributions,canvasFunction:ua(this.tj,this),logo:b.logo,projection:b.projection,ratio:b.ratio,resolutions:b.resolutions,state:this.c.B});this.T=null;this.o=void 0;this.ph(b.style);D(this.c,"change",this.Om,void 0,this)}y(Mp,on);l=Mp.prototype; -l.tj=function(b,c,d,e,f){var g=new Om(.5*c/d,b,c);this.c.Nc(b,c,f);var h=!1;this.c.pb(b,function(b){var e;if(!(e=h)){var f;(e=b.ac())?f=e.call(b,c):this.o&&(f=this.o(b,c));if(f){var p,q=!1;e=0;for(p=f.length;e<p;++e)q=Vm(g,b,f[e],Um(c,d),this.Nm,this)||q;e=q}else e=!1}h=e},this);Pm(g);if(h)return null;this.j[0]!=e[0]||this.j[1]!=e[1]?(this.g.canvas.width=e[0],this.g.canvas.height=e[1],this.j[0]=e[0],this.j[1]=e[1]):this.g.clearRect(0,0,e[0],e[1]);b=Np(this,le(b),c,d,e);g.b(this.g,d,b,0,{});this.v= -g;return this.g.canvas};l.ye=function(b,c,d,e,f){if(this.v){var g={};return this.v.c(b,c,0,e,function(b){var c=w(b).toString();if(!(c in g))return g[c]=!0,f(b)})}};l.Km=function(){return this.c};l.Lm=function(){return this.T};l.Mm=function(){return this.o};function Np(b,c,d,e,f){return gk(b.wa,f[0]/2,f[1]/2,e/d,-e/d,0,-c[0],-c[1])}l.Nm=function(){this.u()};l.Om=function(){yh(this,this.c.B)};l.ph=function(b){this.T=void 0!==b?b:dm;this.o=b?bm(this.T):void 0;this.u()};function Op(b){um.call(this,b);this.g=null;this.i=Bd();this.b=this.c=null}y(Op,um);l=Op.prototype;l.ab=function(b,c,d,e){var f=this.a;return f.ea().ye(b,c.viewState.resolution,c.viewState.rotation,c.skippedFeatureUids,function(b){return d.call(e,b,f)})}; -l.vc=function(b,c,d,e){if(this.zd())if(this.a.ea()instanceof Mp){if(b=b.slice(),ik(c.pixelToCoordinateMatrix,b,b),this.ab(b,c,te,this))return d.call(e,this.a)}else if(this.c||(this.c=Bd(),Hd(this.i,this.c)),c=xm(b,this.c),this.b||(this.b=Ni(1,1)),this.b.clearRect(0,0,1,1),this.b.drawImage(this.zd(),c[0],c[1],1,1,0,0,1,1),0<this.b.getImageData(0,0,1,1).data[3])return d.call(e,this.a)};l.zd=function(){return this.g?this.g.a():null};l.nf=function(){return this.i}; -l.Ad=function(b,c){var d=b.pixelRatio,e=b.viewState,f=e.center,g=e.resolution,h=e.rotation,k=this.a.ea(),m=b.viewHints,n=b.extent;void 0!==c.extent&&(n=ne(n,c.extent));m[0]||m[1]||ie(n)||(e=k.C(n,g,d,e.projection))&&lk(this,e)&&(this.g=e);if(this.g){var e=this.g,m=e.J(),n=e.$(),p=e.b,g=d*n/(g*p);gk(this.i,d*b.size[0]/2,d*b.size[1]/2,g,g,h,p*(m[0]-f[0])/n,p*(f[1]-m[3])/n);this.c=null;nk(b.attributions,e.i);ok(b,k)}return!0};function Pp(b){um.call(this,b);this.b=this.i=null;this.o=!1;this.j=null;this.B=Bd();this.g=null;this.C=this.D=this.v=NaN;this.l=this.c=null;this.U=[0,0]}y(Pp,um);Pp.prototype.zd=function(){return this.i};Pp.prototype.nf=function(){return this.B}; -Pp.prototype.Ad=function(b,c){function d(b){b=b.state;return 2==b||4==b||3==b&&!K}var e=b.pixelRatio,f=b.viewState,g=f.projection,h=this.a,k=h.ea(),m=k.ib(g),n=k.ae(),p=Ih(m,f.resolution),q=k.Qb(p,b.pixelRatio,g),r=q[0]/md(m.Ka(p),this.U)[0],t=m.$(p),r=t/r,x=f.center,z;t==f.resolution?(x=qk(x,t,b.size),z=me(x,t,f.rotation,b.size)):z=b.extent;void 0!==c.extent&&(z=ne(z,c.extent));if(ie(z))return!1;var A=Fh(m,z,t),B=q[0]*kg(A),v=q[1]*jg(A),L,M;this.i?(L=this.i,M=this.j,this.b[0]<B||this.b[1]<v||this.D!== -q[0]||this.C!==q[1]||this.o&&(this.b[0]>B||this.b[1]>v)?(L.width=B,L.height=v,this.b=[B,v],this.o=!ym(this.b),this.c=null):(B=this.b[0],v=this.b[1],p==this.v&&hg(this.c,A)||(this.c=null))):(M=Ni(B,v),this.i=M.canvas,this.b=[B,v],this.j=M,this.o=!ym(this.b));var J,C;this.c?(v=this.c,B=kg(v)):(B/=q[0],v/=q[1],J=A.a-Math.floor((B-kg(A))/2),C=A.f-Math.floor((v-jg(A))/2),this.v=p,this.D=q[0],this.C=q[1],this.c=new fg(J,J+B-1,C,C+v-1),this.l=Array(B*v),v=this.c);L={};L[p]={};var sa=[],la=this.cd(k,g,L), -K=h.b(),ma=Md(),Ua=new fg(0,0,0,0),Nb,na,Fa;for(C=A.a;C<=A.c;++C)for(Fa=A.f;Fa<=A.b;++Fa)na=k.Pb(p,C,Fa,e,g),!d(na)&&na.f&&(na=na.f),d(na)?L[p][eg(na.a)]=na:(Nb=Ch(m,na.a,la,Ua,ma),Nb||(sa.push(na),(Nb=Eh(m,na.a,Ua,ma))&&la(p+1,Nb)));la=0;for(Nb=sa.length;la<Nb;++la)na=sa[la],C=q[0]*(na.a[1]-v.a),Fa=q[1]*(v.b-na.a[2]),M.clearRect(C,Fa,q[0],q[1]);sa=Object.keys(L).map(Number);sa.sort(ub);var ad=k.pa,Qc=ge(m.Aa([p,v.a,v.b],ma)),sf,zj,$d,ci,cg,qm,la=0;for(Nb=sa.length;la<Nb;++la)if(sf=sa[la],q=k.Qb(sf, -e,g),ci=L[sf],sf==p)for(zj in ci)na=ci[zj],J=(na.a[2]-v.f)*B+(na.a[1]-v.a),this.l[J]!=na&&(C=q[0]*(na.a[1]-v.a),Fa=q[1]*(v.b-na.a[2]),$d=na.state,4!=$d&&(3!=$d||K)&&ad||M.clearRect(C,Fa,q[0],q[1]),2==$d&&M.drawImage(na.Ta(),n,n,q[0],q[1],C,Fa,q[0],q[1]),this.l[J]=na);else for(zj in sf=m.$(sf)/t,ci)for(na=ci[zj],J=m.Aa(na.a,ma),C=(J[0]-Qc[0])/r,Fa=(Qc[1]-J[3])/r,qm=sf*q[0],cg=sf*q[1],$d=na.state,4!=$d&&ad||M.clearRect(C,Fa,qm,cg),2==$d&&M.drawImage(na.Ta(),n,n,q[0],q[1],C,Fa,qm,cg),na=Dh(m,J,p,Ua), -J=Math.max(na.a,v.a),Fa=Math.min(na.c,v.c),C=Math.max(na.f,v.f),na=Math.min(na.b,v.b),$d=J;$d<=Fa;++$d)for(cg=C;cg<=na;++cg)J=(cg-v.f)*B+($d-v.a),this.l[J]=void 0;pk(b.usedTiles,k,p,A);rk(b,k,m,e,g,z,p,h.a());mk(b,k);ok(b,k);gk(this.B,e*b.size[0]/2,e*b.size[1]/2,e*r/f.resolution,e*r/f.resolution,f.rotation,(Qc[0]-x[0])/r,(x[1]-Qc[1])/r);this.g=null;return!0}; -Pp.prototype.vc=function(b,c,d,e){if(this.j&&(this.g||(this.g=Bd(),Hd(this.B,this.g)),b=xm(b,this.g),0<this.j.getImageData(b[0],b[1],1,1).data[3]))return d.call(e,this.a)};function Qp(b){um.call(this,b);this.c=!1;this.o=-1;this.l=NaN;this.i=Md();this.b=this.j=null;this.g=Ni()}y(Qp,um); -Qp.prototype.G=function(b,c,d){var e=b.extent,f=b.pixelRatio,g=c.Bb?b.skippedFeatureUids:{},h=b.viewState,k=h.projection,h=h.rotation,m=k.J(),n=this.a.ea(),p=wm(this,b,0);vm(this,"precompose",d,b,p);var q=this.b;if(q&&!q.La()){var r;cd(this.a,"render")?(this.g.canvas.width=d.canvas.width,this.g.canvas.height=d.canvas.height,r=this.g):r=d;var t=r.globalAlpha;r.globalAlpha=c.opacity;q.b(r,f,p,h,g);if(n.O&&k.b&&!Vd(m,e)){c=e[0];k=je(m);for(n=0;c<m[0];)--n,p=k*n,p=wm(this,b,p),q.b(r,f,p,h,g),c+=k;n=0; -for(c=e[2];c>m[2];)++n,p=k*n,p=wm(this,b,p),q.b(r,f,p,h,g),c-=k;p=wm(this,b,0)}r!=d&&(vm(this,"render",r,b,p),d.drawImage(r.canvas,0,0));r.globalAlpha=t}vm(this,"postcompose",d,b,p)};Qp.prototype.ab=function(b,c,d,e){if(this.b){var f=c.viewState.resolution,g=c.viewState.rotation,h=this.a,k=c.layerStates[w(h)],m={};return this.b.c(b,f,g,k.Bb?c.skippedFeatureUids:{},function(b){var c=w(b).toString();if(!(c in m))return m[c]=!0,d.call(e,b,h)})}};Qp.prototype.B=function(){kk(this)}; -Qp.prototype.Ad=function(b){function c(b){var c,e=b.ac();e?c=e.call(b,n):(e=d.b)&&(c=e(b,n));if(c){if(c){e=!1;if(ga(c))for(var f=0,g=c.length;f<g;++f)e=Vm(r,b,c[f],Um(n,p),this.B,this)||e;else e=Vm(r,b,c,Um(n,p),this.B,this)||e;b=e}else b=!1;this.c=this.c||b}}var d=this.a,e=d.ea();nk(b.attributions,e.i);ok(b,e);var f=b.viewHints[0],g=b.viewHints[1],h=d.j,k=d.l;if(!this.c&&!h&&f||!k&&g)return!0;var m=b.extent,k=b.viewState,f=k.projection,n=k.resolution,p=b.pixelRatio,g=d.f,q=d.a,h=fm(d);void 0===h&& -(h=Tm);m=Qd(m,q*n);q=k.projection.J();e.O&&k.projection.b&&!Vd(q,b.extent)&&(b=Math.max(je(m)/2,je(q)),m[0]=q[0]-b,m[2]=q[2]+b);if(!this.c&&this.l==n&&this.o==g&&this.j==h&&Vd(this.i,m))return!0;sc(this.b);this.b=null;this.c=!1;var r=new Om(.5*n/p,m,n,d.a);e.Nc(m,n,f);if(h){var t=[];e.pb(m,function(b){t.push(b)},this);t.sort(h);t.forEach(c,this)}else e.pb(m,c,this);Pm(r);this.l=n;this.o=g;this.j=h;this.i=m;this.b=r;return!0};function Rp(b,c){var d=/\{z\}/g,e=/\{x\}/g,f=/\{y\}/g,g=/\{-y\}/g;return function(h){if(h)return b.replace(d,h[0].toString()).replace(e,h[1].toString()).replace(f,function(){return(-h[2]-1).toString()}).replace(g,function(){return(jg(c.f?c.f[h[0]]:null)+h[2]).toString()})}}function Sp(b,c){for(var d=b.length,e=Array(d),f=0;f<d;++f)e[f]=Rp(b[f],c);return Tp(e)}function Tp(b){return 1===b.length?b[0]:function(c,d,e){if(c)return b[nd((c[1]<<c[0])+c[2],b.length)](c,d,e)}}function Up(){} -function Vp(b){var c=[],d=/\{(\d)-(\d)\}/.exec(b)||/\{([a-z])-([a-z])\}/.exec(b);if(d){var e=d[2].charCodeAt(0),f;for(f=d[1].charCodeAt(0);f<=e;++f)c.push(b.replace(d[0],String.fromCharCode(f)))}else c.push(b);return c};function Wp(b){Nh.call(this,{attributions:b.attributions,df:b.df,extent:b.extent,logo:b.logo,opaque:b.opaque,projection:b.projection,state:b.state?b.state:void 0,tileGrid:b.tileGrid,tilePixelRatio:b.tilePixelRatio,wrapX:b.wrapX});this.tileLoadFunction=b.tileLoadFunction;this.tileUrlFunction=b.tileUrlFunction?b.tileUrlFunction:Up;this.urls=null;b.urls?b.tileUrlFunction?this.urls=b.urls:this.Wa(b.urls):b.url&&this.Va(b.url);b.tileUrlFunction&&this.Ja(b.tileUrlFunction)}y(Wp,Nh);l=Wp.prototype; -l.Xa=function(){return this.tileLoadFunction};l.Ya=function(){return this.tileUrlFunction};l.Za=function(){return this.urls};l.sh=function(b){b=b.target;switch(b.state){case 1:this.s(new Qh("tileloadstart",b));break;case 2:this.s(new Qh("tileloadend",b));break;case 3:this.s(new Qh("tileloaderror",b))}};l.eb=function(b){this.a.clear();this.tileLoadFunction=b;this.u()};l.Ja=function(b){this.a.clear();this.tileUrlFunction=b;this.u()};l.Va=function(b){this.Ja(Sp(Vp(b),this.tileGrid));this.urls=[b]}; -l.Wa=function(b){this.Ja(Sp(b,this.tileGrid));this.urls=b};l.Yf=function(b,c,d){b=this.Ab(b,c,d);qh(this.a,b)&&this.a.get(b)};function Xp(b){Wp.call(this,{attributions:b.attributions,df:128,extent:b.extent,logo:b.logo,opaque:b.opaque,projection:b.projection,state:b.state?b.state:void 0,tileGrid:b.tileGrid,tileLoadFunction:b.tileLoadFunction?b.tileLoadFunction:Yp,tileUrlFunction:b.tileUrlFunction,tilePixelRatio:b.tilePixelRatio,url:b.url,urls:b.urls,wrapX:void 0===b.wrapX?!0:b.wrapX});this.g=b.format?b.format:null;this.tileClass=b.tileClass?b.tileClass:Co}y(Xp,Wp); -Xp.prototype.Pb=function(b,c,d,e,f){var g=this.Ab(b,c,d);if(qh(this.a,g))return this.a.get(g);b=[b,c,d];e=(c=Ph(this,b,f))?this.tileUrlFunction(c,e,f):void 0;f=new this.tileClass(b,void 0!==e?0:4,void 0!==e?e:"",this.g,this.tileLoadFunction,f);D(f,"change",this.sh,!1,this);this.a.set(g,f);return f};function Yp(b,c){b.ai(sp(c,b.j))};function Zp(b){um.call(this,b);this.c=Ni();this.b=!1;this.g=[];this.i=Md();this.l=[NaN,NaN];this.o=Bd()}y(Zp,um); -Zp.prototype.G=function(b,c,d){var e=b.pixelRatio,f=c.Bb?b.skippedFeatureUids:{},g=b.viewState,h=g.center,k=g.projection,m=g.resolution,n=g.rotation,p=this.a,q=p.ea(),r=wm(this,b,0);vm(this,"precompose",d,b,r);cd(p,"render")?(this.c.canvas.width=d.canvas.width,this.c.canvas.height=d.canvas.height,p=this.c):p=d;var t=p.globalAlpha;p.globalAlpha=c.opacity;c=this.g;var x=q.tileGrid,z,A,B,v,L,M;A=0;for(B=c.length;A<B;++A)v=c[A],z=v.a[0],L=x.Ka(z),M=q.Qb(z,e,k),L=M[0]/md(L,this.l)[0],z=x.$(z),z/=L,"tile-pixels"== -v.b.f&&(r=ge(x.Aa(v.a,this.i)),r=gk(this.o,e*b.size[0]/2,e*b.size[1]/2,e*z/m,e*z/m,g.rotation,(r[0]-h[0])/z,(h[1]-r[1])/z)),v.c.Hd.b(p,e,r,n,f);r=wm(this,b,0);p!=d&&(vm(this,"render",p,b,r),d.drawImage(p.canvas,0,0));p.globalAlpha=t;vm(this,"postcompose",d,b,r)}; -function $p(b,c,d,e){function f(b){var c,e=b.ac();e?c=e.call(b,t):(e=d.b)&&(c=e(b,t));if(c){ga(c)||(c=[c]);var e=z,f=x;if(c){var g=!1;if(ga(c))for(var h=0,m=c.length;h<m;++h)g=Vm(f,b,c[h],e,this.j,this)||g;else g=Vm(f,b,c,e,this.j,this)||g;b=g}else b=!1;this.b=this.b||b;k.kd=k.kd||b}}var g=d.f,h=fm(d)||null,k=c.c;if(k.kd||k.Rh!=g||k.Tf!=h){sc(k.Hd);k.Hd=null;k.kd=!1;var m=d.ea(),n=m.tileGrid,p=c.a,q="tile-pixels"==c.b.f,r;q?(r=m.Qb(p[0],e,c.b),r=[0,0,r[0],r[1]]):r=n.Aa(p);var t=n.$(p[0]),m=q?m.v: -t;k.kd=!1;var x=new Om(0,r,m,d.a),z=Um(m,e);c=c.i;h&&h!==k.Tf&&c.sort(h);c.forEach(f,b);Pm(x);k.Rh=g;k.Tf=h;k.Hd=x}} -Zp.prototype.ab=function(b,c,d,e){var f=c.viewState.resolution,g=c.viewState.rotation,h=this.a,k=c.layerStates[w(h)],m={},n=this.g,p=h.ea(),q=p.tileGrid,r,t,x,z,A,B;x=0;for(z=n.length;x<z;++x)B=n[x],t=B.a,A=p.tileGrid.Aa(t,this.i),Td(A,b)&&("tile-pixels"===B.b.f?(A=ge(A),f=p.v,t=q.$(t[0])/f,t=[(b[0]-A[0])/t,(A[1]-b[1])/t]):t=b,B=B.c.Hd,r=r||B.c(t,f,g,k.Bb?c.skippedFeatureUids:{},function(b){var c=w(b).toString();if(!(c in m))return m[c]=!0,d.call(e,b,h)}));return r};Zp.prototype.j=function(){kk(this)}; -Zp.prototype.Ad=function(b,c){var d=this.a,e=d.ea();nk(b.attributions,e.i);ok(b,e);var f=b.viewHints[0],g=b.viewHints[1],h=d.j,k=d.l;if(!this.b&&!h&&f||!k&&g)return!0;g=b.extent;c.extent&&(g=ne(g,c.extent));if(ie(g))return!1;for(var f=b.viewState,h=f.projection,k=f.resolution,f=b.pixelRatio,m=e.tileGrid,n=m.a,p=n.length-1;0<p&&n[p]<k;)--p;n=Dh(m,g,p);pk(b.usedTiles,e,p,n);rk(b,e,m,f,h,g,p,d.g());mk(b,e);g={};g[p]={};var q=this.cd(e,h,g),r=d.U(),t=this.i,x=new fg(0,0,0,0),z,A,B;for(A=n.a;A<=n.c;++A)for(B= -n.f;B<=n.b;++B)k=e.Pb(p,A,B,f,h),z=k.state,2==z||4==z||3==z&&!r?g[p][eg(k.a)]=k:(z=Ch(m,k.a,q,x,t),z||(k=Eh(m,k.a,x,t))&&q(p+1,k));this.b=!1;e=Object.keys(g).map(Number);e.sort(ub);for(var h=[],v,m=0,p=e.length;m<p;++m)for(v in k=e[m],n=g[k],n)k=n[v],2==k.state&&(h.push(k),$p(this,k,d,f));this.g=h;return!0};function aq(b,c){xk.call(this,0,c);this.b=Ni();this.a=this.b.canvas;this.a.style.width="100%";this.a.style.height="100%";this.a.className="ol-unselectable";Lg(b,this.a,0);this.f=!0;this.g=Bd()}y(aq,xk);aq.prototype.hf=function(b){return b instanceof Pl?new Op(b):b instanceof G?new Pp(b):b instanceof I?new Zp(b):b instanceof H?new Qp(b):null}; -function bq(b,c,d){var e=b.i,f=b.b;if(cd(e,c)){var g=d.extent,h=d.pixelRatio,k=d.viewState.rotation,m=d.pixelRatio,n=d.viewState,p=n.resolution;b=gk(b.g,b.a.width/2,b.a.height/2,m/p,-m/p,-n.rotation,-n.center[0],-n.center[1]);g=new gm(f,h,g,b,k);e.s(new bk(c,e,g,d,f,null));tm(g)}}aq.prototype.W=function(){return"canvas"}; -aq.prototype.Ne=function(b){if(b){var c=this.b,d=b.size[0]*b.pixelRatio,e=b.size[1]*b.pixelRatio;this.a.width!=d||this.a.height!=e?(this.a.width=d,this.a.height=e):c.clearRect(0,0,this.a.width,this.a.height);yk(b);bq(this,"precompose",b);d=b.layerStatesArray;pb(d);var e=b.viewState.resolution,f,g,h,k;f=0;for(g=d.length;f<g;++f)k=d[f],h=k.layer,h=Ak(this,h),dk(k,e)&&"ready"==k.O&&h.Ad(b,k)&&h.G(b,k,c);bq(this,"postcompose",b);this.f||(gh(this.a,!0),this.f=!0);Bk(this,b);b.postRenderFunctions.push(zk)}else this.f&& -(gh(this.a,!1),this.f=!1)};function cq(b,c){jk.call(this,b);this.target=c}y(cq,jk);cq.prototype.g=za;cq.prototype.l=za;function dq(b){var c=document.createElement("DIV");c.style.position="absolute";cq.call(this,b,c);this.b=null;this.c=Dd()}y(dq,cq);dq.prototype.ab=function(b,c,d,e){var f=this.a;return f.ea().ye(b,c.viewState.resolution,c.viewState.rotation,c.skippedFeatureUids,function(b){return d.call(e,b,f)})};dq.prototype.g=function(){Kg(this.target);this.b=null}; -dq.prototype.i=function(b,c){var d=b.viewState,e=d.center,f=d.resolution,g=d.rotation,h=this.b,k=this.a.ea(),m=b.viewHints,n=b.extent;void 0!==c.extent&&(n=ne(n,c.extent));m[0]||m[1]||ie(n)||(d=k.C(n,f,b.pixelRatio,d.projection))&&lk(this,d)&&(h=d);h&&(m=h.J(),n=h.$(),d=Bd(),gk(d,b.size[0]/2,b.size[1]/2,n/f,n/f,g,(m[0]-e[0])/n,(e[1]-m[3])/n),h!=this.b&&(e=h.a(this),e.style.maxWidth="none",e.style.position="absolute",Kg(this.target),this.target.appendChild(e),this.b=h),hk(d,this.c)||(Ri(this.target, -d),Ed(this.c,d)),nk(b.attributions,h.i),ok(b,k));return!0};function eq(b){var c=document.createElement("DIV");c.style.position="absolute";cq.call(this,b,c);this.c=!0;this.o=1;this.j=0;this.b={}}y(eq,cq);eq.prototype.g=function(){Kg(this.target);this.j=0}; -eq.prototype.i=function(b,c){if(!c.visible)return this.c&&(gh(this.target,!1),this.c=!1),!0;var d=b.pixelRatio,e=b.viewState,f=e.projection,g=this.a,h=g.ea(),k=h.ib(f),m=h.ae(),n=Ih(k,e.resolution),p=k.$(n),q=e.center,r;p==e.resolution?(q=qk(q,p,b.size),r=me(q,p,e.rotation,b.size)):r=b.extent;void 0!==c.extent&&(r=ne(r,c.extent));var p=Fh(k,r,p),t={};t[n]={};var x=this.cd(h,f,t),z=g.b(),A=Md(),B=new fg(0,0,0,0),v,L,M,J;for(M=p.a;M<=p.c;++M)for(J=p.f;J<=p.b;++J)v=h.Pb(n,M,J,d,f),L=v.state,L=2==L|| -4==L||3==L&&!z,!L&&v.f&&(v=v.f),L=v.state,2==L?t[n][eg(v.a)]=v:4==L||3==L&&!z||(L=Ch(k,v.a,x,B,A),L||(v=Eh(k,v.a,B,A))&&x(n+1,v));var C;if(this.j!=h.f){for(C in this.b)z=this.b[+C],Mg(z.target);this.b={};this.j=h.f}A=Object.keys(t).map(Number);A.sort(ub);var x={},sa;M=0;for(J=A.length;M<J;++M){C=A[M];C in this.b?z=this.b[C]:(z=k.ge(q,C),z=new fq(k,z),x[C]=!0,this.b[C]=z);C=t[C];for(sa in C){v=z;L=C[sa];var la=m,K=L.a,ma=K[0],Ua=K[1],Nb=K[2],K=eg(K);if(!(K in v.f)){var ma=md(v.g.Ka(ma),v.l),na=L.Ta(v), -Fa=na.style;Fa.maxWidth="none";var ad=void 0,Qc=void 0;0<la?(ad=document.createElement("DIV"),Qc=ad.style,Qc.overflow="hidden",Qc.width=ma[0]+"px",Qc.height=ma[1]+"px",Fa.position="absolute",Fa.left=-la+"px",Fa.top=-la+"px",Fa.width=ma[0]+2*la+"px",Fa.height=ma[1]+2*la+"px",ad.appendChild(na)):(Fa.width=ma[0]+"px",Fa.height=ma[1]+"px",ad=na,Qc=Fa);Qc.position="absolute";Qc.left=(Ua-v.b[1])*ma[0]+"px";Qc.top=(v.b[2]-Nb)*ma[1]+"px";v.a||(v.a=document.createDocumentFragment());v.a.appendChild(ad);v.f[K]= -L}}z.a&&(z.target.appendChild(z.a),z.a=null)}m=Object.keys(this.b).map(Number);m.sort(ub);M=Bd();sa=0;for(A=m.length;sa<A;++sa)if(C=m[sa],z=this.b[C],C in t)if(v=z.$(),J=z.Da(),gk(M,b.size[0]/2,b.size[1]/2,v/e.resolution,v/e.resolution,e.rotation,(J[0]-q[0])/v,(q[1]-J[1])/v),z.setTransform(M),C in x){for(--C;0<=C;--C)if(C in this.b){J=this.b[C].target;J.parentNode&&J.parentNode.insertBefore(z.target,J.nextSibling);break}0>C&&Lg(this.target,z.target,0)}else{if(!b.viewHints[0]&&!b.viewHints[1]){L=Dh(z.g, -r,z.b[0],B);C=[];v=J=void 0;for(v in z.f)J=z.f[v],L.contains(J.a)||C.push(J);la=L=void 0;L=0;for(la=C.length;L<la;++L)J=C[L],v=eg(J.a),Mg(J.Ta(z)),delete z.f[v]}}else Mg(z.target),delete this.b[C];c.opacity!=this.o&&(this.o=this.target.style.opacity=c.opacity);c.visible&&!this.c&&(gh(this.target,!0),this.c=!0);pk(b.usedTiles,h,n,p);rk(b,h,k,d,f,r,n,g.a());mk(b,h);ok(b,h);return!0}; -function fq(b,c){this.target=document.createElement("DIV");this.target.style.position="absolute";this.target.style.width="100%";this.target.style.height="100%";this.g=b;this.b=c;this.i=ge(b.Aa(c));this.j=b.$(c[0]);this.f={};this.a=null;this.c=Dd();this.l=[0,0]}fq.prototype.Da=function(){return this.i};fq.prototype.$=function(){return this.j};fq.prototype.setTransform=function(b){hk(b,this.c)||(Ri(this.target,b),Ed(this.c,b))};function gq(b){this.j=Ni();var c=this.j.canvas;c.style.maxWidth="none";c.style.position="absolute";cq.call(this,b,c);this.c=!1;this.v=-1;this.B=NaN;this.o=Md();this.b=this.G=null;this.O=Bd();this.D=Bd()}y(gq,cq); -gq.prototype.l=function(b,c){var d=b.viewState,e=d.center,f=d.rotation,g=d.resolution,d=b.pixelRatio,h=b.size[0],k=b.size[1],m=h*d,n=k*d,e=gk(this.O,d*h/2,d*k/2,d/g,-d/g,-f,-e[0],-e[1]),g=this.j;g.canvas.width=m;g.canvas.height=n;h=gk(this.D,0,0,1/d,1/d,0,-(m-h)/2*d,-(n-k)/2*d);Ri(g.canvas,h);hq(this,"precompose",b,e);(h=this.b)&&!h.La()&&(g.globalAlpha=c.opacity,h.b(g,d,e,f,c.Bb?b.skippedFeatureUids:{}),hq(this,"render",b,e));hq(this,"postcompose",b,e)}; -function hq(b,c,d,e){var f=b.j;b=b.a;cd(b,c)&&(e=new gm(f,d.pixelRatio,d.extent,e,d.viewState.rotation),b.s(new bk(c,b,e,d,f,null)),tm(e))}gq.prototype.ab=function(b,c,d,e){if(this.b){var f=c.viewState.resolution,g=c.viewState.rotation,h=this.a,k=c.layerStates[w(h)],m={};return this.b.c(b,f,g,k.Bb?c.skippedFeatureUids:{},function(b){var c=w(b).toString();if(!(c in m))return m[c]=!0,d.call(e,b,h)})}};gq.prototype.C=function(){kk(this)}; -gq.prototype.i=function(b){function c(b){var c,e=b.ac();e?c=e.call(b,m):(e=d.b)&&(c=e(b,m));if(c){if(c){e=!1;if(ga(c))for(var f=0,g=c.length;f<g;++f)e=Vm(p,b,c[f],Um(m,n),this.C,this)||e;else e=Vm(p,b,c,Um(m,n),this.C,this)||e;b=e}else b=!1;this.c=this.c||b}}var d=this.a,e=d.ea();nk(b.attributions,e.i);ok(b,e);var f=b.viewHints[0],g=b.viewHints[1],h=d.j,k=d.l;if(!this.c&&!h&&f||!k&&g)return!0;var g=b.extent,h=b.viewState,f=h.projection,m=h.resolution,n=b.pixelRatio;b=d.f;k=d.a;h=fm(d);void 0===h&& -(h=Tm);g=Qd(g,k*m);if(!this.c&&this.B==m&&this.v==b&&this.G==h&&Vd(this.o,g))return!0;sc(this.b);this.b=null;this.c=!1;var p=new Om(.5*m/n,g,m,d.a);e.Nc(g,m,f);if(h){var q=[];e.pb(g,function(b){q.push(b)},this);q.sort(h);q.forEach(c,this)}else e.pb(g,c,this);Pm(p);this.B=m;this.v=b;this.G=h;this.o=g;this.b=p;return!0};function iq(b,c){xk.call(this,0,c);this.b=Ni();var d=this.b.canvas;d.style.position="absolute";d.style.width="100%";d.style.height="100%";d.className="ol-unselectable";Lg(b,d,0);this.g=Bd();this.a=document.createElement("DIV");this.a.className="ol-unselectable";d=this.a.style;d.position="absolute";d.width="100%";d.height="100%";D(this.a,"touchstart",vc);Lg(b,this.a,0);this.f=!0}y(iq,xk);iq.prototype.Y=function(){Mg(this.a);iq.ca.Y.call(this)}; -iq.prototype.hf=function(b){if(b instanceof Pl)b=new dq(b);else if(b instanceof G)b=new eq(b);else if(b instanceof H)b=new gq(b);else return null;return b};function jq(b,c,d){var e=b.i;if(cd(e,c)){var f=d.extent,g=d.pixelRatio,h=d.viewState,k=h.rotation,m=b.b,n=m.canvas;gk(b.g,n.width/2,n.height/2,g/h.resolution,-g/h.resolution,-h.rotation,-h.center[0],-h.center[1]);b=new gm(m,g,f,b.g,k);e.s(new bk(c,e,b,d,m,null));tm(b)}}iq.prototype.W=function(){return"dom"}; -iq.prototype.Ne=function(b){if(b){var c=this.i;if(cd(c,"precompose")||cd(c,"postcompose")){var c=this.b.canvas,d=b.pixelRatio;c.width=b.size[0]*d;c.height=b.size[1]*d}jq(this,"precompose",b);c=b.layerStatesArray;pb(c);var d=b.viewState.resolution,e,f,g,h;e=0;for(f=c.length;e<f;++e)h=c[e],g=h.layer,g=Ak(this,g),Lg(this.a,g.target,e),dk(h,d)&&"ready"==h.O?g.i(b,h)&&g.l(b,h):g.g();var c=b.layerStates,k;for(k in this.c)k in c||(g=this.c[k],Mg(g.target));this.f||(gh(this.a,!0),this.f=!0);yk(b);Bk(this, -b);b.postRenderFunctions.push(zk);jq(this,"postcompose",b)}else this.f&&(gh(this.a,!1),this.f=!1)};function kq(b){this.a=b}function lq(b){this.a=b}y(lq,kq);lq.prototype.W=function(){return 35632};function mq(b){this.a=b}y(mq,kq);mq.prototype.W=function(){return 35633};function nq(){this.a="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;}"}y(nq,lq);ea(nq); -function oq(){this.a="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.);gl_Position=h*vec4(c,0.,1.)+offsets;a=d;b=f;}"}y(oq,mq);ea(oq); -function pq(b,c){this.l=b.getUniformLocation(c,"j");this.o=b.getUniformLocation(c,"i");this.i=b.getUniformLocation(c,"k");this.j=b.getUniformLocation(c,"h");this.a=b.getAttribLocation(c,"e");this.f=b.getAttribLocation(c,"f");this.c=b.getAttribLocation(c,"c");this.b=b.getAttribLocation(c,"g");this.g=b.getAttribLocation(c,"d")};function qq(b){this.a=void 0!==b?b:[]};function rq(b,c){this.G=b;this.a=c;this.f={};this.i={};this.g={};this.l=this.o=this.c=this.j=null;(this.b=vb(ya,"OES_element_index_uint"))&&c.getExtension("OES_element_index_uint");D(this.G,"webglcontextlost",this.Hn,!1,this);D(this.G,"webglcontextrestored",this.In,!1,this)} -function sq(b,c,d){var e=b.a,f=d.a,g=w(d);if(g in b.f)e.bindBuffer(c,b.f[g].buffer);else{var h=e.createBuffer();e.bindBuffer(c,h);var k;34962==c?k=new Float32Array(f):34963==c&&(k=b.b?new Uint32Array(f):new Uint16Array(f));e.bufferData(c,k,35044);b.f[g]={Fb:d,buffer:h}}}function tq(b,c){var d=b.a,e=w(c),f=b.f[e];d.isContextLost()||d.deleteBuffer(f.buffer);delete b.f[e]}l=rq.prototype; -l.Y=function(){var b=this.a;b.isContextLost()||(Ib(this.f,function(c){b.deleteBuffer(c.buffer)}),Ib(this.g,function(c){b.deleteProgram(c)}),Ib(this.i,function(c){b.deleteShader(c)}),b.deleteFramebuffer(this.c),b.deleteRenderbuffer(this.l),b.deleteTexture(this.o))};l.Gn=function(){return this.a}; -function uq(b){if(!b.c){var c=b.a,d=c.createFramebuffer();c.bindFramebuffer(c.FRAMEBUFFER,d);var e=vq(c,1,1),f=c.createRenderbuffer();c.bindRenderbuffer(c.RENDERBUFFER,f);c.renderbufferStorage(c.RENDERBUFFER,c.DEPTH_COMPONENT16,1,1);c.framebufferTexture2D(c.FRAMEBUFFER,c.COLOR_ATTACHMENT0,c.TEXTURE_2D,e,0);c.framebufferRenderbuffer(c.FRAMEBUFFER,c.DEPTH_ATTACHMENT,c.RENDERBUFFER,f);c.bindTexture(c.TEXTURE_2D,null);c.bindRenderbuffer(c.RENDERBUFFER,null);c.bindFramebuffer(c.FRAMEBUFFER,null);b.c=d; -b.o=e;b.l=f}return b.c}function wq(b,c){var d=w(c);if(d in b.i)return b.i[d];var e=b.a,f=e.createShader(c.W());e.shaderSource(f,c.a);e.compileShader(f);return b.i[d]=f}function xq(b,c,d){var e=w(c)+"/"+w(d);if(e in b.g)return b.g[e];var f=b.a,g=f.createProgram();f.attachShader(g,wq(b,c));f.attachShader(g,wq(b,d));f.linkProgram(g);return b.g[e]=g}l.Hn=function(){Qb(this.f);Qb(this.i);Qb(this.g);this.l=this.o=this.c=this.j=null};l.In=function(){}; -l.He=function(b){if(b==this.j)return!1;this.a.useProgram(b);this.j=b;return!0};function yq(b,c,d){var e=b.createTexture();b.bindTexture(b.TEXTURE_2D,e);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MAG_FILTER,b.LINEAR);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MIN_FILTER,b.LINEAR);void 0!==c&&b.texParameteri(3553,10242,c);void 0!==d&&b.texParameteri(3553,10243,d);return e}function vq(b,c,d){var e=yq(b,void 0,void 0);b.texImage2D(b.TEXTURE_2D,0,b.RGBA,c,d,0,b.RGBA,b.UNSIGNED_BYTE,null);return e} -function zq(b,c){var d=yq(b,33071,33071);b.texImage2D(b.TEXTURE_2D,0,b.RGBA,b.RGBA,b.UNSIGNED_BYTE,c);return d};function Aq(b,c){this.D=this.C=void 0;this.o=le(c);this.v=[];this.i=[];this.na=void 0;this.g=[];this.c=[];this.U=this.va=void 0;this.f=[];this.O=this.l=null;this.T=void 0;this.hb=Dd();this.Db=Dd();this.fa=this.V=void 0;this.Eb=Dd();this.gb=this.oa=this.ga=void 0;this.wa=[];this.j=[];this.a=[];this.B=null;this.b=[];this.G=[];this.pa=void 0}y(Aq,ak); -function Bq(b,c){var d=b.B,e=b.l,f=b.wa,g=b.j,h=c.a;return function(){if(!h.isContextLost()){var b,m;b=0;for(m=f.length;b<m;++b)h.deleteTexture(f[b]);b=0;for(m=g.length;b<m;++b)h.deleteTexture(g[b])}tq(c,d);tq(c,e)}} -function Cq(b,c,d,e){var f=b.C,g=b.D,h=b.na,k=b.va,m=b.U,n=b.T,p=b.V,q=b.fa,r=b.ga?1:0,t=b.oa,x=b.gb,z=b.pa,A=Math.cos(t),t=Math.sin(t),B=b.f.length,v=b.a.length,L,M,J,C,sa,la;for(L=0;L<d;L+=e)sa=c[L]-b.o[0],la=c[L+1]-b.o[1],M=v/8,J=-x*f,C=-x*(h-g),b.a[v++]=sa,b.a[v++]=la,b.a[v++]=J*A-C*t,b.a[v++]=J*t+C*A,b.a[v++]=p/m,b.a[v++]=(q+h)/k,b.a[v++]=n,b.a[v++]=r,J=x*(z-f),C=-x*(h-g),b.a[v++]=sa,b.a[v++]=la,b.a[v++]=J*A-C*t,b.a[v++]=J*t+C*A,b.a[v++]=(p+z)/m,b.a[v++]=(q+h)/k,b.a[v++]=n,b.a[v++]=r,J=x*(z- -f),C=x*g,b.a[v++]=sa,b.a[v++]=la,b.a[v++]=J*A-C*t,b.a[v++]=J*t+C*A,b.a[v++]=(p+z)/m,b.a[v++]=q/k,b.a[v++]=n,b.a[v++]=r,J=-x*f,C=x*g,b.a[v++]=sa,b.a[v++]=la,b.a[v++]=J*A-C*t,b.a[v++]=J*t+C*A,b.a[v++]=p/m,b.a[v++]=q/k,b.a[v++]=n,b.a[v++]=r,b.f[B++]=M,b.f[B++]=M+1,b.f[B++]=M+2,b.f[B++]=M,b.f[B++]=M+2,b.f[B++]=M+3}Aq.prototype.Gb=function(b,c){this.b.push(this.f.length);this.G.push(c);var d=b.ia();Cq(this,d,d.length,b.ra())}; -Aq.prototype.Hb=function(b,c){this.b.push(this.f.length);this.G.push(c);var d=b.ia();Cq(this,d,d.length,b.ra())};function Dq(b,c){var d=c.a;b.v.push(b.f.length);b.i.push(b.f.length);b.B=new qq(b.a);sq(c,34962,b.B);b.l=new qq(b.f);sq(c,34963,b.l);var e={};Eq(b.wa,b.g,e,d);Eq(b.j,b.c,e,d);b.C=void 0;b.D=void 0;b.na=void 0;b.g=null;b.c=null;b.va=void 0;b.U=void 0;b.f=null;b.T=void 0;b.V=void 0;b.fa=void 0;b.ga=void 0;b.oa=void 0;b.gb=void 0;b.a=null;b.pa=void 0} -function Eq(b,c,d,e){var f,g,h,k=c.length;for(h=0;h<k;++h)f=c[h],g=w(f).toString(),g in d?f=d[g]:(f=zq(e,f),d[g]=f),b[h]=f} -function Fq(b,c,d,e,f,g,h,k,m,n,p){var q=c.a;sq(c,34962,b.B);sq(c,34963,b.l);var r=nq.Yb(),t=oq.Yb(),t=xq(c,r,t);b.O?r=b.O:(r=new pq(q,t),b.O=r);c.He(t);q.enableVertexAttribArray(r.c);q.vertexAttribPointer(r.c,2,5126,!1,32,0);q.enableVertexAttribArray(r.a);q.vertexAttribPointer(r.a,2,5126,!1,32,8);q.enableVertexAttribArray(r.g);q.vertexAttribPointer(r.g,2,5126,!1,32,16);q.enableVertexAttribArray(r.f);q.vertexAttribPointer(r.f,1,5126,!1,32,24);q.enableVertexAttribArray(r.b);q.vertexAttribPointer(r.b, -1,5126,!1,32,28);t=b.Eb;gk(t,0,0,2/(e*g[0]),2/(e*g[1]),-f,-(d[0]-b.o[0]),-(d[1]-b.o[1]));d=b.Db;e=2/g[0];g=2/g[1];Fd(d);d[0]=e;d[5]=g;d[10]=1;d[15]=1;g=b.hb;Fd(g);0!==f&&Kd(g,-f);q.uniformMatrix4fv(r.j,!1,t);q.uniformMatrix4fv(r.o,!1,d);q.uniformMatrix4fv(r.l,!1,g);q.uniform1f(r.i,h);var x;if(void 0===m)Gq(b,q,c,k,b.wa,b.v);else{if(n)a:{f=c.b?5125:5123;c=c.b?4:2;g=b.b.length-1;for(h=b.j.length-1;0<=h;--h)for(q.bindTexture(3553,b.j[h]),n=0<h?b.i[h-1]:0,t=b.i[h];0<=g&&b.b[g]>=n;){x=b.b[g];d=b.G[g]; -e=w(d).toString();if(void 0===k[e]&&d.X()&&(void 0===p||oe(p,d.X().J()))&&(q.clear(q.COLOR_BUFFER_BIT|q.DEPTH_BUFFER_BIT),q.drawElements(4,t-x,f,x*c),t=m(d))){b=t;break a}t=x;g--}b=void 0}else q.clear(q.COLOR_BUFFER_BIT|q.DEPTH_BUFFER_BIT),Gq(b,q,c,k,b.j,b.i),b=(b=m(null))?b:void 0;x=b}q.disableVertexAttribArray(r.c);q.disableVertexAttribArray(r.a);q.disableVertexAttribArray(r.g);q.disableVertexAttribArray(r.f);q.disableVertexAttribArray(r.b);return x} -function Gq(b,c,d,e,f,g){var h=d.b?5125:5123;d=d.b?4:2;if(Pb(e)){var k;b=0;e=f.length;for(k=0;b<e;++b){c.bindTexture(3553,f[b]);var m=g[b];c.drawElements(4,m-k,h,k*d);k=m}}else{k=0;var n,m=0;for(n=f.length;m<n;++m){c.bindTexture(3553,f[m]);for(var p=0<m?g[m-1]:0,q=g[m],r=p;k<b.b.length&&b.b[k]<=q;){var t=w(b.G[k]).toString();void 0!==e[t]?(r!==p&&c.drawElements(4,p-r,h,r*d),p=r=k===b.b.length-1?q:b.b[k+1]):p=k===b.b.length-1?q:b.b[k+1];k++}r!==p&&c.drawElements(4,p-r,h,r*d)}}} -Aq.prototype.ub=function(b){var c=b.Xb(),d=b.gc(1),e=b.rd(),f=b.Ae(1),g=b.B,h=b.Da(),k=b.C,m=b.G,n=b.Cb();b=b.j;var p;0===this.g.length?this.g.push(d):(p=this.g[this.g.length-1],w(p)!=w(d)&&(this.v.push(this.f.length),this.g.push(d)));0===this.c.length?this.c.push(f):(p=this.c[this.c.length-1],w(p)!=w(f)&&(this.i.push(this.f.length),this.c.push(f)));this.C=c[0];this.D=c[1];this.na=n[1];this.va=e[1];this.U=e[0];this.T=g;this.V=h[0];this.fa=h[1];this.oa=m;this.ga=k;this.gb=b;this.pa=n[0]}; -function Hq(b,c,d){this.i=c;this.j=b;this.g=d;this.f={}}function Iq(b,c){var d=[],e;for(e in b.f)d.push(Bq(b.f[e],c));return xe.apply(null,d)}function Jq(b,c){for(var d in b.f)Dq(b.f[d],c)}Hq.prototype.a=function(b,c){var d=this.f[c];void 0===d&&(d=new Kq[c](this.j,this.i),this.f[c]=d);return d};Hq.prototype.La=function(){return Pb(this.f)};Hq.prototype.b=function(b,c,d,e,f,g,h,k){var m,n;g=0;for(m=zm.length;g<m;++g)n=this.f[zm[g]],void 0!==n&&Fq(n,b,c,d,e,f,h,k,void 0,!1)}; -function Lq(b,c,d,e,f,g,h,k,m,n){var p=Mq,q,r;for(q=zm.length-1;0<=q;--q)if(r=b.f[zm[q]],void 0!==r&&(r=Fq(r,c,d,e,f,p,g,h,k,m,n)))return r}Hq.prototype.c=function(b,c,d,e,f,g,h,k,m,n){var p=c.a;p.bindFramebuffer(p.FRAMEBUFFER,uq(c));var q;void 0!==this.g&&(q=Qd(Xd(b),e*this.g));return Lq(this,c,b,e,f,k,m,function(b){var c=new Uint8Array(4);p.readPixels(0,0,1,1,p.RGBA,p.UNSIGNED_BYTE,c);if(0<c[3]&&(b=n(b)))return b},!0,q)}; -function Nq(b,c,d,e,f,g,h){var k=d.a;k.bindFramebuffer(k.FRAMEBUFFER,uq(d));return void 0!==Lq(b,d,c,e,f,g,h,function(){var b=new Uint8Array(4);k.readPixels(0,0,1,1,k.RGBA,k.UNSIGNED_BYTE,b);return 0<b[3]},!1)}var Kq={Image:Aq},Mq=[1,1];function Oq(b,c,d,e,f,g){this.f=b;this.g=c;this.c=g;this.l=f;this.j=e;this.i=d;this.b=null;this.a={}}y(Oq,ak);l=Oq.prototype;l.md=function(b,c){var d=b.toString(),e=this.a[d];void 0!==e?e.push(c):this.a[d]=[c]};l.Gc=function(){};l.jf=function(b,c){var d=(0,c.c)(b);if(d&&oe(this.c,d.J())){var e=c.a;void 0===e&&(e=0);this.md(e,function(b){b.bb(c.g,c.b);b.ub(c.f);b.cb(c.Ca());var e=Pq[d.W()];e&&e.call(b,d,null)})}}; -l.Yd=function(b,c){var d=b.c,e,f;e=0;for(f=d.length;e<f;++e){var g=d[e],h=Pq[g.W()];h&&h.call(this,g,c)}};l.Hb=function(b,c){var d=this.f,e=(new Hq(1,this.c)).a(0,"Image");e.ub(this.b);e.Hb(b,c);Dq(e,d);Fq(e,this.f,this.g,this.i,this.j,this.l,1,{},void 0,!1);Bq(e,d)()};l.Wb=function(){};l.Hc=function(){};l.Gb=function(b,c){var d=this.f,e=(new Hq(1,this.c)).a(0,"Image");e.ub(this.b);e.Gb(b,c);Dq(e,d);Fq(e,this.f,this.g,this.i,this.j,this.l,1,{},void 0,!1);Bq(e,d)()};l.Ic=function(){};l.Jc=function(){}; -l.Ib=function(){};l.bb=function(){};l.ub=function(b){this.b=b};l.cb=function(){};var Pq={Point:Oq.prototype.Hb,MultiPoint:Oq.prototype.Gb,GeometryCollection:Oq.prototype.Yd};function Qq(){this.a="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;}"}y(Qq,lq);ea(Qq);function Rq(){this.a="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;}"}y(Rq,mq);ea(Rq); -function Sq(b,c){this.b=b.getUniformLocation(c,"f");this.c=b.getUniformLocation(c,"e");this.i=b.getUniformLocation(c,"d");this.g=b.getUniformLocation(c,"g");this.a=b.getAttribLocation(c,"b");this.f=b.getAttribLocation(c,"c")};function Tq(b,c){jk.call(this,c);this.b=b;this.U=new qq([-1,-1,0,0,1,-1,1,0,-1,1,0,1,1,1,1,1]);this.g=this.mb=null;this.i=void 0;this.o=Bd();this.B=Dd();this.G=null}y(Tq,jk); -function Uq(b,c,d){var e=b.b.b;if(void 0===b.i||b.i!=d){c.postRenderFunctions.push(va(function(b,c,d){b.isContextLost()||(b.deleteFramebuffer(c),b.deleteTexture(d))},e,b.g,b.mb));c=vq(e,d,d);var f=e.createFramebuffer();e.bindFramebuffer(36160,f);e.framebufferTexture2D(36160,36064,3553,c,0);b.mb=c;b.g=f;b.i=d}else e.bindFramebuffer(36160,b.g)} -Tq.prototype.nh=function(b,c,d){Vq(this,"precompose",d,b);sq(d,34962,this.U);var e=d.a,f=Qq.Yb(),g=Rq.Yb(),f=xq(d,f,g);this.G?g=this.G:this.G=g=new Sq(e,f);d.He(f)&&(e.enableVertexAttribArray(g.a),e.vertexAttribPointer(g.a,2,5126,!1,16,0),e.enableVertexAttribArray(g.f),e.vertexAttribPointer(g.f,2,5126,!1,16,8),e.uniform1i(g.g,0));e.uniformMatrix4fv(g.i,!1,this.o);e.uniformMatrix4fv(g.c,!1,this.B);e.uniform1f(g.b,c.opacity);e.bindTexture(3553,this.mb);e.drawArrays(5,0,4);Vq(this,"postcompose",d,b)}; -function Vq(b,c,d,e){b=b.a;if(cd(b,c)){var f=e.viewState;b.s(new bk(c,b,new Oq(d,f.center,f.resolution,f.rotation,e.size,e.extent),e,null,d))}}Tq.prototype.Cf=function(){this.g=this.mb=null;this.i=void 0};function Wq(b,c){Tq.call(this,b,c);this.l=this.j=this.c=null}y(Wq,Tq);function Xq(b,c){var d=c.a();return zq(b.b.b,d)}Wq.prototype.ab=function(b,c,d,e){var f=this.a;return f.ea().ye(b,c.viewState.resolution,c.viewState.rotation,c.skippedFeatureUids,function(b){return d.call(e,b,f)})}; -Wq.prototype.Df=function(b,c){var d=this.b.b,e=b.pixelRatio,f=b.viewState,g=f.center,h=f.resolution,k=f.rotation,m=this.c,n=this.mb,p=this.a.ea(),q=b.viewHints,r=b.extent;void 0!==c.extent&&(r=ne(r,c.extent));q[0]||q[1]||ie(r)||(f=p.C(r,h,e,f.projection))&&lk(this,f)&&(m=f,n=Xq(this,f),this.mb&&b.postRenderFunctions.push(va(function(b,c){b.isContextLost()||b.deleteTexture(c)},d,this.mb)));m&&(d=this.b.g.G,Yq(this,d.width,d.height,e,g,h,k,m.J()),this.l=null,e=this.o,Fd(e),Jd(e,1,-1),Id(e,0,-1),this.c= -m,this.mb=n,nk(b.attributions,m.i),ok(b,p));return!0};function Yq(b,c,d,e,f,g,h,k){c*=g;d*=g;b=b.B;Fd(b);Jd(b,2*e/c,2*e/d);Kd(b,-h);Id(b,k[0]-f[0],k[1]-f[1]);Jd(b,(k[2]-k[0])/2,(k[3]-k[1])/2);Id(b,1,1)}Wq.prototype.xe=function(b,c){return void 0!==this.ab(b,c,te,this)}; -Wq.prototype.vc=function(b,c,d,e){if(this.c&&this.c.a())if(this.a.ea()instanceof Mp){if(b=b.slice(),ik(c.pixelToCoordinateMatrix,b,b),this.ab(b,c,te,this))return d.call(e,this.a)}else{var f=[this.c.a().width,this.c.a().height];if(!this.l){var g=c.size;c=Bd();Fd(c);Id(c,-1,-1);Jd(c,2/g[0],2/g[1]);Id(c,0,g[1]);Jd(c,1,-1);g=Bd();Hd(this.B,g);var h=Bd();Fd(h);Id(h,0,f[1]);Jd(h,1,-1);Jd(h,f[0]/2,f[1]/2);Id(h,1,1);var k=Bd();Gd(h,g,k);Gd(k,c,k);this.l=k}c=[0,0];ik(this.l,b,c);if(!(0>c[0]||c[0]>f[0]||0> -c[1]||c[1]>f[1])&&(this.j||(this.j=Ni(1,1)),this.j.clearRect(0,0,1,1),this.j.drawImage(this.c.a(),c[0],c[1],1,1,0,0,1,1),0<this.j.getImageData(0,0,1,1).data[3]))return d.call(e,this.a)}};function Zq(){this.a="precision mediump float;varying vec2 a;uniform sampler2D e;void main(void){gl_FragColor=texture2D(e,a);}"}y(Zq,lq);ea(Zq);function $q(){this.a="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;}"}y($q,mq);ea($q);function ar(b,c){this.b=b.getUniformLocation(c,"e");this.c=b.getUniformLocation(c,"d");this.a=b.getAttribLocation(c,"b");this.f=b.getAttribLocation(c,"c")};function br(b,c){Tq.call(this,b,c);this.D=Zq.Yb();this.T=$q.Yb();this.c=null;this.C=new qq([0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0]);this.v=this.j=null;this.l=-1;this.O=[0,0]}y(br,Tq);l=br.prototype;l.Y=function(){tq(this.b.g,this.C);br.ca.Y.call(this)};l.cd=function(b,c,d){var e=this.b;return function(f,g){return Oh(b,c,f,g,function(b){var c=qh(e.f,b.$a());c&&(d[f]||(d[f]={}),d[f][b.a.toString()]=b);return c})}};l.Cf=function(){br.ca.Cf.call(this);this.c=null}; -l.Df=function(b,c,d){var e=this.b,f=d.a,g=b.viewState,h=g.projection,k=this.a,m=k.ea(),n=m.ib(h),p=Ih(n,g.resolution),q=n.$(p),r=m.Qb(p,b.pixelRatio,h),t=r[0]/md(n.Ka(p),this.O)[0],x=q/t,z=m.ae(),A=g.center,B;q==g.resolution?(A=qk(A,q,b.size),B=me(A,q,g.rotation,b.size)):B=b.extent;q=Fh(n,B,q);if(this.j&&ig(this.j,q)&&this.l==m.f)x=this.v;else{var v=[kg(q),jg(q)],L=Math.pow(2,Math.ceil(Math.log(Math.max(v[0]*r[0],v[1]*r[1]))/Math.LN2)),v=x*L,M=n.Da(p),J=M[0]+q.a*r[0]*x,x=M[1]+q.f*r[1]*x,x=[J,x,J+ -v,x+v];Uq(this,b,L);f.viewport(0,0,L,L);f.clearColor(0,0,0,0);f.clear(16384);f.disable(3042);L=xq(d,this.D,this.T);d.He(L);this.c||(this.c=new ar(f,L));sq(d,34962,this.C);f.enableVertexAttribArray(this.c.a);f.vertexAttribPointer(this.c.a,2,5126,!1,16,0);f.enableVertexAttribArray(this.c.f);f.vertexAttribPointer(this.c.f,2,5126,!1,16,8);f.uniform1i(this.c.b,0);d={};d[p]={};var C=this.cd(m,h,d),sa=k.b(),L=!0,J=Md(),la=new fg(0,0,0,0),K,ma,Ua;for(ma=q.a;ma<=q.c;++ma)for(Ua=q.f;Ua<=q.b;++Ua){M=m.Pb(p, -ma,Ua,t,h);if(void 0!==c.extent&&(K=n.Aa(M.a,J),!oe(K,c.extent)))continue;K=M.state;K=2==K||4==K||3==K&&!sa;!K&&M.f&&(M=M.f);K=M.state;if(2==K){if(qh(e.f,M.$a())){d[p][eg(M.a)]=M;continue}}else if(4==K||3==K&&!sa)continue;L=!1;K=Ch(n,M.a,C,la,J);K||(M=Eh(n,M.a,la,J))&&C(p+1,M)}c=Object.keys(d).map(Number);c.sort(ub);for(var C=new Float32Array(4),Nb,na,Fa,sa=0,la=c.length;sa<la;++sa)for(Nb in na=d[c[sa]],na)M=na[Nb],K=n.Aa(M.a,J),ma=2*(K[2]-K[0])/v,Ua=2*(K[3]-K[1])/v,Fa=2*(K[0]-x[0])/v-1,K=2*(K[1]- -x[1])/v-1,Ad(C,ma,Ua,Fa,K),f.uniform4fv(this.c.c,C),cr(e,M,r,z*t),f.drawArrays(5,0,4);L?(this.j=q,this.v=x,this.l=m.f):(this.v=this.j=null,this.l=-1,b.animate=!0)}pk(b.usedTiles,m,p,q);var ad=e.l;rk(b,m,n,t,h,B,p,k.a(),function(b){var c;(c=2!=b.state||qh(e.f,b.$a()))||(c=b.$a()in ad.b);c||ad.c([b,Hh(n,b.a),n.$(b.a[0]),r,z*t])},this);mk(b,m);ok(b,m);f=this.o;Fd(f);Id(f,(A[0]-x[0])/(x[2]-x[0]),(A[1]-x[1])/(x[3]-x[1]));0!==g.rotation&&Kd(f,g.rotation);Jd(f,b.size[0]*g.resolution/(x[2]-x[0]),b.size[1]* -g.resolution/(x[3]-x[1]));Id(f,-.5,-.5);return!0};l.vc=function(b,c,d,e){if(this.g){var f=[0,0];ik(this.o,[b[0]/c.size[0],(c.size[1]-b[1])/c.size[1]],f);b=[f[0]*this.i,f[1]*this.i];c=this.b.g.a;c.bindFramebuffer(c.FRAMEBUFFER,this.g);f=new Uint8Array(4);c.readPixels(b[0],b[1],1,1,c.RGBA,c.UNSIGNED_BYTE,f);if(0<f[3])return d.call(e,this.a)}};function dr(b,c){Tq.call(this,b,c);this.l=!1;this.O=-1;this.D=NaN;this.v=Md();this.j=this.c=this.C=null}y(dr,Tq);l=dr.prototype;l.nh=function(b,c,d){this.j=c;var e=b.viewState,f=this.c;f&&!f.La()&&f.b(d,e.center,e.resolution,e.rotation,b.size,b.pixelRatio,c.opacity,c.Bb?b.skippedFeatureUids:{})};l.Y=function(){var b=this.c;b&&(Iq(b,this.b.g)(),this.c=null);dr.ca.Y.call(this)}; -l.ab=function(b,c,d,e){if(this.c&&this.j){var f=c.viewState,g=this.a,h=this.j,k={};return this.c.c(b,this.b.g,f.center,f.resolution,f.rotation,c.size,c.pixelRatio,h.opacity,h.Bb?c.skippedFeatureUids:{},function(b){var c=w(b).toString();if(!(c in k))return k[c]=!0,d.call(e,b,g)})}};l.xe=function(b,c){if(this.c&&this.j){var d=c.viewState;return Nq(this.c,b,this.b.g,d.resolution,d.rotation,this.j.opacity,c.skippedFeatureUids)}return!1}; -l.vc=function(b,c,d,e){b=b.slice();ik(c.pixelToCoordinateMatrix,b,b);if(this.xe(b,c))return d.call(e,this.a)};l.oh=function(){kk(this)}; -l.Df=function(b,c,d){function e(b){var c,d=b.ac();d?c=d.call(b,n):(d=f.b)&&(c=d(b,n));if(c){if(c){d=!1;if(ga(c))for(var e=0,g=c.length;e<g;++e)d=Vm(r,b,c[e],Um(n,p),this.oh,this)||d;else d=Vm(r,b,c,Um(n,p),this.oh,this)||d;b=d}else b=!1;this.l=this.l||b}}var f=this.a;c=f.ea();nk(b.attributions,c.i);ok(b,c);var g=b.viewHints[0],h=b.viewHints[1],k=f.j,m=f.l;if(!this.l&&!k&&g||!m&&h)return!0;var h=b.extent,k=b.viewState,g=k.projection,n=k.resolution,p=b.pixelRatio,k=f.f,q=f.a,m=fm(f);void 0===m&&(m= -Tm);h=Qd(h,q*n);if(!this.l&&this.D==n&&this.O==k&&this.C==m&&Vd(this.v,h))return!0;this.c&&b.postRenderFunctions.push(Iq(this.c,d));this.l=!1;var r=new Hq(.5*n/p,h,f.a);c.Nc(h,n,g);if(m){var t=[];c.pb(h,function(b){t.push(b)},this);t.sort(m);t.forEach(e,this)}else c.pb(h,e,this);Jq(r,d);this.D=n;this.O=k;this.C=m;this.v=h;this.c=r;return!0};function er(b,c){xk.call(this,0,c);this.a=document.createElement("CANVAS");this.a.style.width="100%";this.a.style.height="100%";this.a.className="ol-unselectable";Lg(b,this.a,0);this.v=this.C=0;this.D=Ni();this.o=!0;this.b=Ti(this.a,{antialias:!0,depth:!1,failIfMajorPerformanceCaveat:!0,preserveDrawingBuffer:!1,stencil:!0});this.g=new rq(this.a,this.b);D(this.a,"webglcontextlost",this.Em,!1,this);D(this.a,"webglcontextrestored",this.Fm,!1,this);this.f=new ph;this.B=null;this.l=new Ck(ua(function(b){var c= -b[1];b=b[2];var f=c[0]-this.B[0],c=c[1]-this.B[1];return 65536*Math.log(b)+Math.sqrt(f*f+c*c)/b},this),function(b){return b[0].$a()});this.O=ua(function(){if(!this.l.La()){Gk(this.l);var b=Dk(this.l);cr(this,b[0],b[3],b[4])}},this);this.j=0;fr(this)}y(er,xk); -function cr(b,c,d,e){var f=b.b,g=c.$a();if(qh(b.f,g))b=b.f.get(g),f.bindTexture(3553,b.mb),9729!=b.Sg&&(f.texParameteri(3553,10240,9729),b.Sg=9729),9729!=b.Tg&&(f.texParameteri(3553,10240,9729),b.Tg=9729);else{var h=f.createTexture();f.bindTexture(3553,h);if(0<e){var k=b.D.canvas,m=b.D;b.C!==d[0]||b.v!==d[1]?(k.width=d[0],k.height=d[1],b.C=d[0],b.v=d[1]):m.clearRect(0,0,d[0],d[1]);m.drawImage(c.Ta(),e,e,d[0],d[1],0,0,d[0],d[1]);f.texImage2D(3553,0,6408,6408,5121,k)}else f.texImage2D(3553,0,6408,6408, -5121,c.Ta());f.texParameteri(3553,10240,9729);f.texParameteri(3553,10241,9729);f.texParameteri(3553,10242,33071);f.texParameteri(3553,10243,33071);b.f.set(g,{mb:h,Sg:9729,Tg:9729})}}l=er.prototype;l.hf=function(b){return b instanceof Pl?new Wq(this,b):b instanceof G?new br(this,b):b instanceof H?new dr(this,b):null}; -function gr(b,c,d){var e=b.i;if(cd(e,c)){var f=b.g;b=d.viewState;b=new Oq(f,b.center,b.resolution,b.rotation,d.size,d.extent);e.s(new bk(c,e,b,d,null,f));c=Object.keys(b.a).map(Number);c.sort(ub);var g,h;d=0;for(e=c.length;d<e;++d)for(f=b.a[c[d].toString()],g=0,h=f.length;g<h;++g)f[g](b)}}l.Y=function(){var b=this.b;b.isContextLost()||this.f.forEach(function(c){c&&b.deleteTexture(c.mb)});sc(this.g);er.ca.Y.call(this)}; -l.xj=function(b,c){for(var d=this.b,e;1024<this.f.qc()-this.j;){if(e=this.f.a.mc)d.deleteTexture(e.mb);else if(+this.f.a.oe==c.index)break;else--this.j;this.f.pop()}};l.W=function(){return"webgl"};l.Em=function(b){b.preventDefault();this.f.clear();this.j=0;Ib(this.c,function(b){b.Cf()})};l.Fm=function(){fr(this);this.i.render()};function fr(b){b=b.b;b.activeTexture(33984);b.blendFuncSeparate(770,771,1,771);b.disable(2884);b.disable(2929);b.disable(3089);b.disable(2960)} -l.Ne=function(b){var c=this.g,d=this.b;if(d.isContextLost())return!1;if(!b)return this.o&&(gh(this.a,!1),this.o=!1),!1;this.B=b.focus;this.f.set((-b.index).toString(),null);++this.j;gr(this,"precompose",b);var e=[],f=b.layerStatesArray;pb(f);var g=b.viewState.resolution,h,k,m,n;h=0;for(k=f.length;h<k;++h)n=f[h],dk(n,g)&&"ready"==n.O&&(m=Ak(this,n.layer),m.Df(b,n,c)&&e.push(n));f=b.size[0]*b.pixelRatio;g=b.size[1]*b.pixelRatio;if(this.a.width!=f||this.a.height!=g)this.a.width=f,this.a.height=g;d.bindFramebuffer(36160, -null);d.clearColor(0,0,0,0);d.clear(16384);d.enable(3042);d.viewport(0,0,this.a.width,this.a.height);h=0;for(k=e.length;h<k;++h)n=e[h],m=Ak(this,n.layer),m.nh(b,n,c);this.o||(gh(this.a,!0),this.o=!0);yk(b);1024<this.f.qc()-this.j&&b.postRenderFunctions.push(ua(this.xj,this));this.l.La()||(b.postRenderFunctions.push(this.O),b.animate=!0);gr(this,"postcompose",b);Bk(this,b);b.postRenderFunctions.push(zk)}; -l.Bf=function(b,c,d,e,f,g){var h;if(this.b.isContextLost())return!1;var k=c.viewState,m=c.layerStatesArray,n;for(n=m.length-1;0<=n;--n){h=m[n];var p=h.layer;if(dk(h,k.resolution)&&f.call(g,p)&&(h=Ak(this,p).ab(b,c,d,e)))return h}};l.mh=function(b,c,d,e){var f=!1;if(this.b.isContextLost())return!1;var g=c.viewState,h=c.layerStatesArray,k;for(k=h.length-1;0<=k;--k){var m=h[k],n=m.layer;if(dk(m,g.resolution)&&d.call(e,n)&&(f=Ak(this,n).xe(b,c)))return!0}return f}; -l.lh=function(b,c,d,e,f){if(this.b.isContextLost())return!1;var g=c.viewState,h,k=c.layerStatesArray,m;for(m=k.length-1;0<=m;--m){h=k[m];var n=h.layer;if(dk(h,g.resolution)&&f.call(e,n)&&(h=Ak(this,n).vc(b,c,d,e)))return h}};var hr=["canvas","webgl","dom"]; -function S(b){gd.call(this);var c=ir(b);this.nc=void 0!==b.loadTilesWhileAnimating?b.loadTilesWhileAnimating:!1;this.Cc=void 0!==b.loadTilesWhileInteracting?b.loadTilesWhileInteracting:!1;this.Xe=void 0!==b.pixelRatio?b.pixelRatio:Vi;this.Yc=c.logos;this.v=new gi(this.Eo,void 0,this);rc(this,this.v);this.Db=Bd();this.Ye=Bd();this.Eb=0;this.b=null;this.wa=Md();this.D=this.U=null;this.a=document.createElement("DIV");this.a.className="ol-viewport";this.a.style.position="relative";this.a.style.overflow= -"hidden";this.a.style.width="100%";this.a.style.height="100%";this.a.style.msTouchAction="none";this.a.style.touchAction="none";$i&&Ug(this.a,"ol-touch");this.l=document.createElement("DIV");this.l.className="ol-overlaycontainer";this.a.appendChild(this.l);this.j=document.createElement("DIV");this.j.className="ol-overlaycontainer-stopevent";D(this.j,["click","dblclick","mousedown","touchstart","MSPointerDown",Uj,$b?"DOMMouseScroll":"mousewheel"],uc);this.a.appendChild(this.j);b=new Mj(this);D(b,Lb(Xj), -this.Kg,!1,this);rc(this,b);this.ga=c.keyboardEventTarget;this.C=new yi;D(this.C,"key",this.Jg,!1,this);rc(this,this.C);b=new Gi(this.a);D(b,"mousewheel",this.Jg,!1,this);rc(this,b);this.g=c.controls;this.c=c.interactions;this.i=c.overlays;this.V={};this.o=new c.Go(this.a,this);rc(this,this.o);this.hb=new ti;rc(this,this.hb);this.T=this.B=null;this.O=[];this.pa=[];this.oa=new Hk(ua(this.qk,this),ua(this.Zk,this));this.fa={};D(this,id("layergroup"),this.Ek,!1,this);D(this,id("view"),this.$k,!1,this); -D(this,id("size"),this.Wk,!1,this);D(this,id("target"),this.Yk,!1,this);this.I(c.values);this.g.forEach(function(b){b.setMap(this)},this);D(this.g,"add",function(b){b.element.setMap(this)},!1,this);D(this.g,"remove",function(b){b.element.setMap(null)},!1,this);this.c.forEach(function(b){b.setMap(this)},this);D(this.c,"add",function(b){b.element.setMap(this)},!1,this);D(this.c,"remove",function(b){b.element.setMap(null)},!1,this);this.i.forEach(this.mg,this);D(this.i,"add",function(b){this.mg(b.element)}, -!1,this);D(this.i,"remove",function(b){var c=b.element.Oa();void 0!==c&&delete this.V[c.toString()];b.element.setMap(null)},!1,this)}y(S,gd);l=S.prototype;l.kj=function(b){this.g.push(b)};l.lj=function(b){this.c.push(b)};l.kg=function(b){this.rc().Qc().push(b)};l.lg=function(b){this.i.push(b)};l.mg=function(b){var c=b.Oa();void 0!==c&&(this.V[c.toString()]=b);b.setMap(this)};l.Na=function(b){this.render();Array.prototype.push.apply(this.O,arguments)};l.Y=function(){Mg(this.a);S.ca.Y.call(this)}; -l.pd=function(b,c,d,e,f){if(this.b)return b=this.Ga(b),this.o.Bf(b,this.b,c,void 0!==d?d:null,void 0!==e?e:te,void 0!==f?f:null)};l.Jl=function(b,c,d,e,f){if(this.b)return this.o.lh(b,this.b,c,void 0!==d?d:null,void 0!==e?e:te,void 0!==f?f:null)};l.bl=function(b,c,d){if(!this.b)return!1;b=this.Ga(b);return this.o.mh(b,this.b,void 0!==c?c:te,void 0!==d?d:null)};l.Mj=function(b){return this.Ga(this.$d(b))};l.$d=function(b){var c;c=this.a;b=dh(b);c=dh(c);c=new yg(b.x-c.x,b.y-c.y);return[c.x,c.y]}; -l.xf=function(){return this.get("target")};l.Mc=function(){var b=this.xf();return void 0!==b?Dg(b):null};l.Ga=function(b){var c=this.b;return c?(b=b.slice(),ik(c.pixelToCoordinateMatrix,b,b)):null};l.Kj=function(){return this.g};l.dk=function(){return this.i};l.ck=function(b){b=this.V[b.toString()];return void 0!==b?b:null};l.Rj=function(){return this.c};l.rc=function(){return this.get("layergroup")};l.Zg=function(){return this.rc().Qc()}; -l.Pa=function(b){var c=this.b;return c?(b=b.slice(0,2),ik(c.coordinateToPixelMatrix,b,b)):null};l.Sa=function(){return this.get("size")};l.aa=function(){return this.get("view")};l.sk=function(){return this.a};l.qk=function(b,c,d,e){var f=this.b;if(!(f&&c in f.wantedTiles&&f.wantedTiles[c][eg(b.a)]))return Infinity;b=d[0]-f.focus[0];d=d[1]-f.focus[1];return 65536*Math.log(e)+Math.sqrt(b*b+d*d)/e};l.Jg=function(b,c){var d=new Kj(c||b.type,this,b);this.Kg(d)}; -l.Kg=function(b){if(this.b){this.T=b.coordinate;b.frameState=this.b;var c=this.c.a,d;if(!1!==this.s(b))for(d=c.length-1;0<=d;d--){var e=c[d];if(e.b()&&!e.handleEvent(b))break}}};l.Uk=function(){var b=this.b,c=this.oa;if(!c.La()){var d=16,e=d,f=0;b&&(f=b.viewHints,f[0]&&(d=this.nc?8:0,e=2),f[1]&&(d=this.Cc?8:0,e=2),f=Kb(b.wantedTiles));d*=f;e*=f;c.g<d&&(Gk(c),Ik(c,d,e))}c=this.pa;d=0;for(e=c.length;d<e;++d)c[d](this,b);c.length=0};l.Wk=function(){this.render()}; -l.Yk=function(){var b=this.Mc();Fi(this.C);b?(b.appendChild(this.a),zi(this.C,this.ga?this.ga:b),this.B||(this.B=D(this.hb,"resize",this.Vc,!1,this))):(Mg(this.a),this.B&&(Wc(this.B),this.B=null));this.Vc()};l.Zk=function(){this.render()};l.al=function(){this.render()};l.$k=function(){this.U&&(Wc(this.U),this.U=null);var b=this.aa();b&&(this.U=D(b,"propertychange",this.al,!1,this));this.render()};l.Fk=function(){this.render()};l.Gk=function(){this.render()}; -l.Ek=function(){this.D&&(this.D.forEach(Wc),this.D=null);var b=this.rc();b&&(this.D=[D(b,"propertychange",this.Gk,!1,this),D(b,"change",this.Fk,!1,this)]);this.render()};l.Fo=function(){var b=this.v;hi(b);b.c()};l.render=function(){null!=this.v.xa||this.v.start()};l.yo=function(b){return this.g.remove(b)};l.zo=function(b){return this.c.remove(b)};l.Bo=function(b){return this.rc().Qc().remove(b)};l.Co=function(b){return this.i.remove(b)}; -l.Eo=function(b){var c,d,e,f=this.Sa(),g=this.aa(),h=null;if(void 0!==f&&0<f[0]&&0<f[1]&&g&&Rf(g)){var h=g.b.slice(),k=this.rc().of(),m={};c=0;for(d=k.length;c<d;++c)m[w(k[c].layer)]=k[c];e=Qf(g);h={animate:!1,attributions:{},coordinateToPixelMatrix:this.Db,extent:null,focus:this.T?this.T:e.center,index:this.Eb++,layerStates:m,layerStatesArray:k,logos:Tb(this.Yc),pixelRatio:this.Xe,pixelToCoordinateMatrix:this.Ye,postRenderFunctions:[],size:f,skippedFeatureUids:this.fa,tileQueue:this.oa,time:b,usedTiles:{}, -viewState:e,viewHints:h,wantedTiles:{}}}if(h){b=this.O;c=f=0;for(d=b.length;c<d;++c)g=b[c],g(this,h)&&(b[f++]=g);b.length=f;h.extent=me(e.center,e.resolution,e.rotation,h.size)}this.b=h;this.o.Ne(h);h&&(h.animate&&this.render(),Array.prototype.push.apply(this.pa,h.postRenderFunctions),0!==this.O.length||h.viewHints[0]||h.viewHints[1]||ae(h.extent,this.wa)||(this.s(new nh("moveend",this,h)),Rd(h.extent,this.wa)));this.s(new nh("postrender",this,h));li(this.Uk,this)}; -l.$h=function(b){this.set("layergroup",b)};l.Vf=function(b){this.set("size",b)};l.Kl=function(b){this.set("target",b)};l.To=function(b){this.set("view",b)};l.ii=function(b){b=w(b).toString();this.fa[b]=!0;this.render()}; -l.Vc=function(){var b=this.Mc();if(b){var c=Cg(b),d=Yb&&b.currentStyle;d&&Qg(Ag(c))&&"auto"!=d.width&&"auto"!=d.height&&!d.boxSizing?(c=hh(b,d.width,"width","pixelWidth"),b=hh(b,d.height,"height","pixelHeight"),b=new zg(c,b)):(d=new zg(b.offsetWidth,b.offsetHeight),c=jh(b,"padding"),b=mh(b),b=new zg(d.width-b.left-c.left-c.right-b.right,d.height-b.top-c.top-c.bottom-b.bottom));this.Vf([b.width,b.height])}else this.Vf(void 0)};l.li=function(b){b=w(b).toString();delete this.fa[b];this.render()}; -function ir(b){var c=null;void 0!==b.keyboardEventTarget&&(c=ia(b.keyboardEventTarget)?document.getElementById(b.keyboardEventTarget):b.keyboardEventTarget);var d={},e={};if(void 0===b.logo||"boolean"==typeof b.logo&&b.logo)e["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAHGAAABxgEXwfpGAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAhNQTFRF////AP//AICAgP//AFVVQECA////K1VVSbbbYL/fJ05idsTYJFtbbcjbJllmZszWWMTOIFhoHlNiZszTa9DdUcHNHlNlV8XRIVdiasrUHlZjIVZjaMnVH1RlIFRkH1RkH1ZlasvYasvXVsPQH1VkacnVa8vWIVZjIFRjVMPQa8rXIVVkXsXRsNveIFVkIFZlIVVj3eDeh6GmbMvXH1ZkIFRka8rWbMvXIFVkIFVjIFVkbMvWH1VjbMvWIFVlbcvWIFVla8vVIFVkbMvWbMvVH1VkbMvWIFVlbcvWIFVkbcvVbMvWjNPbIFVkU8LPwMzNIFVkbczWIFVkbsvWbMvXIFVkRnB8bcvW2+TkW8XRIFVkIlZlJVloJlpoKlxrLl9tMmJwOWd0Omh1RXF8TneCT3iDUHiDU8LPVMLPVcLPVcPQVsPPVsPQV8PQWMTQWsTQW8TQXMXSXsXRX4SNX8bSYMfTYcfTYsfTY8jUZcfSZsnUaIqTacrVasrVa8jTa8rWbI2VbMvWbcvWdJObdcvUdszUd8vVeJaee87Yfc3WgJyjhqGnitDYjaarldPZnrK2oNbborW5o9bbo9fbpLa6q9ndrL3ArtndscDDutzfu8fJwN7gwt7gxc/QyuHhy+HizeHi0NfX0+Pj19zb1+Tj2uXk29/e3uLg3+Lh3+bl4uXj4ufl4+fl5Ofl5ufl5ujm5+jmySDnBAAAAFp0Uk5TAAECAgMEBAYHCA0NDg4UGRogIiMmKSssLzU7PkJJT1JTVFliY2hrdHZ3foSFhYeJjY2QkpugqbG1tre5w8zQ09XY3uXn6+zx8vT09vf4+Pj5+fr6/P39/f3+gz7SsAAAAVVJREFUOMtjYKA7EBDnwCPLrObS1BRiLoJLnte6CQy8FLHLCzs2QUG4FjZ5GbcmBDDjxJBXDWxCBrb8aM4zbkIDzpLYnAcE9VXlJSWlZRU13koIeW57mGx5XjoMZEUqwxWYQaQbSzLSkYGfKFSe0QMsX5WbjgY0YS4MBplemI4BdGBW+DQ11eZiymfqQuXZIjqwyadPNoSZ4L+0FVM6e+oGI6g8a9iKNT3o8kVzNkzRg5lgl7p4wyRUL9Yt2jAxVh6mQCogae6GmflI8p0r13VFWTHBQ0rWPW7ahgWVcPm+9cuLoyy4kCJDzCm6d8PSFoh0zvQNC5OjDJhQopPPJqph1doJBUD5tnkbZiUEqaCnB3bTqLTFG1bPn71kw4b+GFdpLElKIzRxxgYgWNYc5SCENVHKeUaltHdXx0dZ8uBI1hJ2UUDgq82CM2MwKeibqAvSO7MCABq0wXEPiqWEAAAAAElFTkSuQmCC"]= -"http://openlayers.org/";else{var f=b.logo;ia(f)?e[f]="":oa(f)&&(e[f.src]=f.href)}f=b.layers instanceof Hl?b.layers:new Hl({layers:b.layers});d.layergroup=f;d.target=b.target;d.view=void 0!==b.view?b.view:new Nf;var f=xk,g;void 0!==b.renderer?ga(b.renderer)?g=b.renderer:ia(b.renderer)&&(g=[b.renderer]):g=hr;var h,k;h=0;for(k=g.length;h<k;++h){var m=g[h];if("canvas"==m){if(Xi){f=aq;break}}else if("dom"==m){f=iq;break}else if("webgl"==m&&Ui){f=er;break}}var n;void 0!==b.controls?n=ga(b.controls)?new og(b.controls.slice()): -b.controls:n=Xh();var p;void 0!==b.interactions?p=ga(b.interactions)?new og(b.interactions.slice()):b.interactions:p=Gl();b=void 0!==b.overlays?ga(b.overlays)?new og(b.overlays.slice()):b.overlays:new og;return{controls:n,interactions:p,keyboardEventTarget:c,logos:e,overlays:b,Go:f,values:d}}Ol();function jr(b){gd.call(this);this.xa=b.id;this.j=void 0!==b.insertFirst?b.insertFirst:!0;this.l=void 0!==b.stopEvent?b.stopEvent:!0;this.b=document.createElement("DIV");this.b.className="ol-overlay-container";this.b.style.position="absolute";this.autoPan=void 0!==b.autoPan?b.autoPan:!1;this.g=void 0!==b.autoPanAnimation?b.autoPanAnimation:{};this.i=void 0!==b.autoPanMargin?b.autoPanMargin:20;this.a={Ud:"",pe:"",Oe:"",Pe:"",visible:!0};this.c=null;D(this,id("element"),this.Ak,!1,this);D(this,id("map"), -this.Lk,!1,this);D(this,id("offset"),this.Qk,!1,this);D(this,id("position"),this.Sk,!1,this);D(this,id("positioning"),this.Tk,!1,this);void 0!==b.element&&this.Xh(b.element);this.bi(void 0!==b.offset?b.offset:[0,0]);this.ei(void 0!==b.positioning?b.positioning:"top-left");void 0!==b.position&&this.yf(b.position)}y(jr,gd);l=jr.prototype;l.se=function(){return this.get("element")};l.Oa=function(){return this.xa};l.te=function(){return this.get("map")};l.Gg=function(){return this.get("offset")}; -l.$g=function(){return this.get("position")};l.Hg=function(){return this.get("positioning")};l.Ak=function(){Kg(this.b);var b=this.se();b&&this.b.appendChild(b)};l.Lk=function(){this.c&&(Mg(this.b),Wc(this.c),this.c=null);var b=this.te();b&&(this.c=D(b,"postrender",this.render,!1,this),kr(this),b=this.l?b.j:b.l,this.j?Lg(b,this.b,0):b.appendChild(this.b))};l.render=function(){kr(this)};l.Qk=function(){kr(this)}; -l.Sk=function(){kr(this);if(void 0!==this.get("position")&&this.autoPan){var b=this.te();if(void 0!==b&&b.Mc()){var c=lr(b.Mc(),b.Sa()),d=this.se(),e=d.offsetWidth,f=d.currentStyle||window.getComputedStyle(d),e=e+(parseInt(f.marginLeft,10)+parseInt(f.marginRight,10)),f=d.offsetHeight,g=d.currentStyle||window.getComputedStyle(d),f=f+(parseInt(g.marginTop,10)+parseInt(g.marginBottom,10)),h=lr(d,[e,f]),d=this.i;Vd(c,h)||(e=h[0]-c[0],f=c[2]-h[2],g=h[1]-c[1],h=c[3]-h[3],c=[0,0],0>e?c[0]=e-d:0>f&&(c[0]= -Math.abs(f)+d),0>g?c[1]=g-d:0>h&&(c[1]=Math.abs(h)+d),0===c[0]&&0===c[1])||(d=b.aa().Ua(),e=b.Pa(d),c=[e[0]+c[0],e[1]+c[1]],this.g&&(this.g.source=d,b.Na(Yf(this.g))),b.aa().kb(b.Ga(c)))}}};l.Tk=function(){kr(this)};l.Xh=function(b){this.set("element",b)};l.setMap=function(b){this.set("map",b)};l.bi=function(b){this.set("offset",b)};l.yf=function(b){this.set("position",b)}; -function lr(b,c){var d=Cg(b),e=new yg(0,0),f;f=d?Cg(d):document;f=!Yb||9<=kc||Qg(Ag(f))?f.documentElement:f.body;b!=f&&(f=ch(b),d=Rg(Ag(d)),e.x=f.left+d.x,e.y=f.top+d.y);return[e.x,e.y,e.x+c[0],e.y+c[1]]}l.ei=function(b){this.set("positioning",b)};function mr(b,c){b.a.visible!==c&&(gh(b.b,c),b.a.visible=c)} -function kr(b){var c=b.te(),d=b.$g();if(void 0!==c&&c.b&&void 0!==d){var d=c.Pa(d),e=c.Sa(),c=b.b.style,f=b.Gg(),g=b.Hg(),h=f[0],f=f[1];if("bottom-right"==g||"center-right"==g||"top-right"==g)""!==b.a.pe&&(b.a.pe=c.left=""),h=Math.round(e[0]-d[0]-h)+"px",b.a.Oe!=h&&(b.a.Oe=c.right=h);else{""!==b.a.Oe&&(b.a.Oe=c.right="");if("bottom-center"==g||"center-center"==g||"top-center"==g)h-=eh(b.b).width/2;h=Math.round(d[0]+h)+"px";b.a.pe!=h&&(b.a.pe=c.left=h)}if("bottom-left"==g||"bottom-center"==g||"bottom-right"== -g)""!==b.a.Pe&&(b.a.Pe=c.top=""),d=Math.round(e[1]-d[1]-f)+"px",b.a.Ud!=d&&(b.a.Ud=c.bottom=d);else{""!==b.a.Ud&&(b.a.Ud=c.bottom="");if("center-left"==g||"center-center"==g||"center-right"==g)f-=eh(b.b).height/2;d=Math.round(d[1]+f)+"px";b.a.Pe!=d&&(b.a.Pe=c.top=d)}mr(b,!0)}else mr(b,!1)};function nr(b){b=b?b:{};this.i=void 0!==b.collapsed?b.collapsed:!0;this.j=void 0!==b.collapsible?b.collapsible:!0;this.j||(this.i=!1);var c=b.className?b.className:"ol-overviewmap",d=b.tipLabel?b.tipLabel:"Overview map",e=b.collapseLabel?b.collapseLabel:"\u00ab";this.B=ia(e)?Hg("SPAN",{},e):e;e=b.label?b.label:"\u00bb";this.v=ia(e)?Hg("SPAN",{},e):e;d=Hg("BUTTON",{type:"button",title:d},this.j&&!this.i?this.B:this.v);D(d,"click",this.Vl,!1,this);var e=Hg("DIV","ol-overviewmap-map"),f=this.b=new S({controls:new og, -interactions:new og,target:e,view:b.view});b.layers&&b.layers.forEach(function(b){f.kg(b)},this);var g=Hg("DIV","ol-overviewmap-box");this.l=new jr({position:[0,0],positioning:"bottom-left",element:g});this.b.lg(this.l);c=Hg("DIV",c+" ol-unselectable ol-control"+(this.i&&this.j?" ol-collapsed":"")+(this.j?"":" ol-uncollapsible"),e,d);oh.call(this,{element:c,render:b.render?b.render:or,target:b.target})}y(nr,oh);l=nr.prototype; -l.setMap=function(b){var c=this.a;b!==c&&(c&&(c=c.aa())&&Vc(c,id("rotation"),this.je,!1,this),nr.ca.setMap.call(this,b),b&&(this.o.push(D(b,"propertychange",this.Mk,!1,this)),0===this.b.Zg().$b()&&this.b.$h(b.rc()),b=b.aa()))&&(D(b,id("rotation"),this.je,!1,this),Rf(b)&&(this.b.Vc(),pr(this)))};l.Mk=function(b){"view"===b.key&&((b=b.oldValue)&&Vc(b,id("rotation"),this.je,!1,this),b=this.a.aa(),D(b,id("rotation"),this.je,!1,this))};l.je=function(){this.b.aa().ue(this.a.aa().Fa())}; -function or(){var b=this.a,c=this.b;if(b.b&&c.b){var d=b.Sa(),b=b.aa().$c(d),e=c.Sa(),d=c.aa().$c(e),f=c.Pa(ge(b)),c=c.Pa(ee(b)),c=new zg(Math.abs(f[0]-c[0]),Math.abs(f[1]-c[1])),f=e[0],e=e[1];c.width<.1*f||c.height<.1*e||c.width>.75*f||c.height>.75*e?pr(this):Vd(d,b)||(b=this.b,d=this.a.aa(),b.aa().kb(d.Ua()))}qr(this)}function pr(b){var c=b.a;b=b.b;var d=c.Sa(),c=c.aa().$c(d),d=b.Sa();b=b.aa();pe(c,1/(.1*Math.pow(2,Math.log(7.5)/Math.LN2/2)));b.kf(c,d)} -function qr(b){var c=b.a,d=b.b;if(c.b&&d.b){var e=c.Sa(),f=c.aa(),g=d.aa();d.Sa();var c=f.Fa(),h=b.l,d=b.l.se(),f=f.$c(e),e=g.$(),g=de(f),f=fe(f),k;if(b=b.a.aa().Ua())k=[g[0]-b[0],g[1]-b[1]],ud(k,c),pd(k,b);h.yf(k);d&&(k=new zg(Math.abs((g[0]-f[0])/e),Math.abs((f[1]-g[1])/e)),c=Qg(Ag(Cg(d))),!Yb||ic("10")||c&&ic("8")?(d=d.style,$b?d.MozBoxSizing="border-box":ac?d.WebkitBoxSizing="border-box":d.boxSizing="border-box",d.width=Math.max(k.width,0)+"px",d.height=Math.max(k.height,0)+"px"):(b=d.style,c? -(c=jh(d,"padding"),d=mh(d),b.pixelWidth=k.width-d.left-c.left-c.right-d.right,b.pixelHeight=k.height-d.top-c.top-c.bottom-d.bottom):(b.pixelWidth=k.width,b.pixelHeight=k.height)))}}l.Vl=function(b){b.preventDefault();rr(this)};function rr(b){Wg(b.element,"ol-collapsed");b.i?Ng(b.B,b.v):Ng(b.v,b.B);b.i=!b.i;var c=b.b;b.i||c.b||(c.Vc(),pr(b),Uc(c,"postrender",function(){qr(this)},!1,b))}l.Ul=function(){return this.j}; -l.Xl=function(b){this.j!==b&&(this.j=b,Wg(this.element,"ol-uncollapsible"),!b&&this.i&&rr(this))};l.Wl=function(b){this.j&&this.i!==b&&rr(this)};l.Tl=function(){return this.i};l.ek=function(){return this.b};function sr(b){b=b?b:{};var c=b.className?b.className:"ol-scale-line";this.l=Hg("DIV",c+"-inner");this.j=Hg("DIV",c+" ol-unselectable",this.l);this.v=null;this.B=void 0!==b.minWidth?b.minWidth:64;this.b=!1;this.O=void 0;this.C="";this.i=null;oh.call(this,{element:this.j,render:b.render?b.render:tr,target:b.target});D(this,id("units"),this.V,!1,this);this.T(b.units||"metric")}y(sr,oh);var ur=[1,2,5];sr.prototype.D=function(){return this.get("units")}; -function tr(b){(b=b.frameState)?this.v=b.viewState:this.v=null;vr(this)}sr.prototype.V=function(){vr(this)};sr.prototype.T=function(b){this.set("units",b)}; -function vr(b){var c=b.v;if(c){var d=c.center,e=c.projection,c=e.getPointResolution(c.resolution,d),f=e.f,g=b.D();"degrees"!=f||"metric"!=g&&"imperial"!=g&&"us"!=g&&"nautical"!=g?"degrees"!=f&&"degrees"==g?(b.i||(b.i=Ie(e,Ee("EPSG:4326"))),d=Math.cos(Xa(b.i(d)[1])),e=Ae.radius,e/=Be[f],c*=180/(Math.PI*d*e)):b.i=null:(b.i=null,d=Math.cos(Xa(d[1])),c*=Math.PI*d*Ae.radius/180);d=b.B*c;f="";"degrees"==g?d<1/60?(f="\u2033",c*=3600):1>d?(f="\u2032",c*=60):f="\u00b0":"imperial"==g?.9144>d?(f="in",c/=.0254): -1609.344>d?(f="ft",c/=.3048):(f="mi",c/=1609.344):"nautical"==g?(c/=1852,f="nm"):"metric"==g?1>d?(f="mm",c*=1E3):1E3>d?f="m":(f="km",c/=1E3):"us"==g&&(.9144>d?(f="in",c*=39.37):1609.344>d?(f="ft",c/=.30480061):(f="mi",c/=1609.3472));for(d=3*Math.floor(Math.log(b.B*c)/Math.log(10));;){e=ur[d%3]*Math.pow(10,Math.floor(d/3));g=Math.round(e/c);if(isNaN(g)){gh(b.j,!1);b.b=!1;return}if(g>=b.B)break;++d}c=e+" "+f;b.C!=c&&(b.l.innerHTML=c,b.C=c);b.O!=g&&(b.l.style.width=g+"px",b.O=g);b.b||(gh(b.j,!0),b.b= -!0)}else b.b&&(gh(b.j,!1),b.b=!1)};function wr(b){oc.call(this);this.f=b;this.a={}}y(wr,oc);var xr=[];wr.prototype.Ra=function(b,c,d,e){ga(c)||(c&&(xr[0]=c.toString()),c=xr);for(var f=0;f<c.length;f++){var g=D(b,c[f],d||this.handleEvent,e||!1,this.f||this);if(!g)break;this.a[g.key]=g}return this}; -wr.prototype.Wf=function(b,c,d,e,f){if(ga(c))for(var g=0;g<c.length;g++)this.Wf(b,c[g],d,e,f);else d=d||this.handleEvent,f=f||this.f||this,d=Nc(d),e=!!e,c=Bc(b)?Ic(b.yb,String(c),d,e,f):b?(b=Pc(b))?Ic(b,c,d,e,f):null:null,c&&(Wc(c),delete this.a[c.key]);return this};function yr(b){Ib(b.a,function(b,d){this.a.hasOwnProperty(d)&&Wc(b)},b);b.a={}}wr.prototype.Y=function(){wr.ca.Y.call(this);yr(this)};wr.prototype.handleEvent=function(){throw Error("EventHandler.handleEvent not implemented");};function zr(b,c,d){$c.call(this);this.target=b;this.handle=c||b;this.a=d||new Yg(NaN,NaN,NaN,NaN);this.i=Cg(b);this.f=new wr(this);rc(this,this.f);this.g=this.c=this.o=this.l=this.screenY=this.screenX=this.clientY=this.clientX=0;this.b=!1;D(this.handle,["touchstart","mousedown"],this.ji,!1,this)}y(zr,$c);var Ar=Yb||$b&&ic("1.9.3");l=zr.prototype; -l.Y=function(){zr.ca.Y.call(this);Vc(this.handle,["touchstart","mousedown"],this.ji,!1,this);yr(this.f);Ar&&this.i.releaseCapture();this.handle=this.target=null}; -l.ji=function(b){var c="mousedown"==b.type;if(this.b||c&&!zc(b))this.s("earlycancel");else if(this.s(new Br("start",this,b.clientX,b.clientY))){this.b=!0;b.preventDefault();var c=this.i,d=c.documentElement,e=!Ar;this.f.Ra(c,["touchmove","mousemove"],this.Pk,e);this.f.Ra(c,["touchend","mouseup"],this.Zd,e);Ar?(d.setCapture(!1),this.f.Ra(d,"losecapture",this.Zd)):this.f.Ra(c?c.parentWindow||c.defaultView:window,"blur",this.Zd);this.G&&this.f.Ra(this.G,"scroll",this.Nn,e);this.clientX=this.l=b.clientX; -this.clientY=this.o=b.clientY;this.screenX=b.screenX;this.screenY=b.screenY;this.c=this.target.offsetLeft;this.g=this.target.offsetTop;this.j=Rg(Ag(this.i))}};l.Zd=function(b){yr(this.f);Ar&&this.i.releaseCapture();this.b?(this.b=!1,this.s(new Br("end",this,b.clientX,b.clientY,0,Cr(this,this.c),Dr(this,this.g)))):this.s("earlycancel")}; -l.Pk=function(b){var c=1*(b.clientX-this.clientX),d=b.clientY-this.clientY;this.clientX=b.clientX;this.clientY=b.clientY;this.screenX=b.screenX;this.screenY=b.screenY;if(!this.b){var e=this.l-this.clientX,f=this.o-this.clientY;if(0<e*e+f*f)if(this.s(new Br("start",this,b.clientX,b.clientY)))this.b=!0;else{this.na||this.Zd(b);return}}d=Er(this,c,d);c=d.x;d=d.y;this.b&&this.s(new Br("beforedrag",this,b.clientX,b.clientY,0,c,d))&&(Fr(this,b,c,d),b.preventDefault())}; -function Er(b,c,d){var e=Rg(Ag(b.i));c+=e.x-b.j.x;d+=e.y-b.j.y;b.j=e;b.c+=c;b.g+=d;return new yg(Cr(b,b.c),Dr(b,b.g))}l.Nn=function(b){var c=Er(this,0,0);b.clientX=this.clientX;b.clientY=this.clientY;Fr(this,b,c.x,c.y)};function Fr(b,c,d,e){b.target.style.left=d+"px";b.target.style.top=e+"px";b.s(new Br("drag",b,c.clientX,c.clientY,0,d,e))}function Cr(b,c){var d=b.a,e=isNaN(d.left)?null:d.left,d=isNaN(d.width)?0:d.width;return Math.min(null!=e?e+d:Infinity,Math.max(null!=e?e:-Infinity,c))} -function Dr(b,c){var d=b.a,e=isNaN(d.top)?null:d.top,d=isNaN(d.height)?0:d.height;return Math.min(null!=e?e+d:Infinity,Math.max(null!=e?e:-Infinity,c))}function Br(b,c,d,e,f,g,h){tc.call(this,b);this.clientX=d;this.clientY=e;this.left=ca(g)?g:c.c;this.top=ca(h)?h:c.g}y(Br,tc);function Gr(b){b=b?b:{};this.i=void 0;this.j=Hr;this.l=null;this.v=!1;this.B=void 0!==b.duration?b.duration:200;var c=b.className?b.className:"ol-zoomslider",d=Hg("BUTTON",{type:"button","class":c+"-thumb ol-unselectable"}),c=Hg("DIV",[c,"ol-unselectable","ol-control"],d);this.b=new zr(d);rc(this,this.b);D(this.b,"start",this.zk,!1,this);D(this.b,"drag",this.xk,!1,this);D(this.b,"end",this.yk,!1,this);D(c,"click",this.wk,!1,this);D(d,"click",uc);oh.call(this,{element:c,render:b.render?b.render:Ir})} -y(Gr,oh);var Hr=0;l=Gr.prototype;l.setMap=function(b){Gr.ca.setMap.call(this,b);b&&b.render()}; -function Ir(b){if(b.frameState){if(!this.v){var c=this.element,d=eh(c),e=Og(c),c=jh(e,"margin"),f=new zg(e.offsetWidth,e.offsetHeight),e=f.width+c.right+c.left,c=f.height+c.top+c.bottom;this.l=[e,c];e=d.width-e;c=d.height-c;d.width>d.height?(this.j=1,d=new Yg(0,0,e,0)):(this.j=Hr,d=new Yg(0,0,0,c));this.b.a=d||new Yg(NaN,NaN,NaN,NaN);this.v=!0}b=b.frameState.viewState.resolution;b!==this.i&&(this.i=b,b=1-Pf(this.a.aa())(b),d=this.b,c=Og(this.element),1==this.j?ah(c,d.a.left+d.a.width*b):ah(c,d.a.left, -d.a.top+d.a.height*b))}}l.wk=function(b){var c=this.a,d=c.aa(),e=d.$();c.Na($f({resolution:e,duration:this.B,easing:Uf}));b=Jr(this,Kr(this,b.offsetX-this.l[0]/2,b.offsetY-this.l[1]/2));d.Ub(d.constrainResolution(b))};l.zk=function(){Sf(this.a.aa(),1)};l.xk=function(b){this.i=Jr(this,Kr(this,b.left,b.top));this.a.aa().Ub(this.i)};l.yk=function(){var b=this.a,c=b.aa();Sf(c,-1);b.Na($f({resolution:this.i,duration:this.B,easing:Uf}));b=c.constrainResolution(this.i);c.Ub(b)}; -function Kr(b,c,d){var e=b.b.a;return Sa(1===b.j?(c-e.left)/e.width:(d-e.top)/e.height,0,1)}function Jr(b,c){return Of(b.a.aa())(1-c)};function Lr(b){b=b?b:{};this.b=b.extent?b.extent:null;var c=b.className?b.className:"ol-zoom-extent",d=Hg("BUTTON",{type:"button",title:b.tipLabel?b.tipLabel:"Fit to extent"},b.label?b.label:"E");D(d,"click",this.i,!1,this);c=Hg("DIV",c+" ol-unselectable ol-control",d);oh.call(this,{element:c,target:b.target})}y(Lr,oh);Lr.prototype.i=function(b){b.preventDefault();var c=this.a;b=c.aa();var d=this.b?this.b:b.g.J(),c=c.Sa();b.kf(d,c)};function Mr(b){gd.call(this);b=b?b:{};this.a=null;D(this,id("tracking"),this.yl,!1,this);this.vf(void 0!==b.tracking?b.tracking:!1)}y(Mr,gd);l=Mr.prototype;l.Y=function(){this.vf(!1);Mr.ca.Y.call(this)}; -l.On=function(b){b=b.a;if(null!==b.alpha){var c=Xa(b.alpha);this.set("alpha",c);"boolean"==typeof b.absolute&&b.absolute?this.set("heading",c):ja(b.webkitCompassHeading)&&-1!=b.webkitCompassAccuracy&&this.set("heading",Xa(b.webkitCompassHeading))}null!==b.beta&&this.set("beta",Xa(b.beta));null!==b.gamma&&this.set("gamma",Xa(b.gamma));this.u()};l.Fj=function(){return this.get("alpha")};l.Ij=function(){return this.get("beta")};l.Oj=function(){return this.get("gamma")};l.xl=function(){return this.get("heading")}; -l.Vg=function(){return this.get("tracking")};l.yl=function(){if(Yi){var b=this.Vg();b&&!this.a?this.a=D(ba,"deviceorientation",this.On,!1,this):!b&&this.a&&(Wc(this.a),this.a=null)}};l.vf=function(b){this.set("tracking",b)};function Nr(){this.defaultDataProjection=null}function Or(b,c,d){var e;d&&(e={dataProjection:d.dataProjection?d.dataProjection:b.Ia(c),featureProjection:d.featureProjection});return Pr(b,e)}function Pr(b,c){var d;c&&(d={featureProjection:c.featureProjection,dataProjection:c.dataProjection?c.dataProjection:b.defaultDataProjection,rightHanded:c.rightHanded});return d} -function Qr(b,c,d){var e=d?Ee(d.featureProjection):null;d=d?Ee(d.dataProjection):null;return e&&d&&!Ve(e,d)?b instanceof $e?(c?b.clone():b).lb(c?e:d,c?d:e):Ze(c?b.slice():b,c?e:d,c?d:e):b};function Rr(){this.defaultDataProjection=null}y(Rr,Nr);function Sr(b){return oa(b)?b:ia(b)?(b=Yn(b))?b:null:null}l=Rr.prototype;l.W=function(){return"json"};l.Tb=function(b,c){return this.Sc(Sr(b),Or(this,b,c))};l.Ba=function(b,c){return this.Kf(Sr(b),Or(this,b,c))};l.Tc=function(b,c){return this.Gh(Sr(b),Or(this,b,c))};l.Ia=function(b){return this.Nh(Sr(b))};l.Kd=function(b,c){return Zn(this.Wc(b,c))};l.Vb=function(b,c){return Zn(this.Se(b,c))};l.Xc=function(b,c){return Zn(this.Ue(b,c))};function Tr(b,c,d,e,f){var g=NaN,h=NaN,k=(d-c)/e;if(0!==k)if(1==k)g=b[c],h=b[c+1];else if(2==k)g=.5*b[c]+.5*b[c+e],h=.5*b[c+1]+.5*b[c+e+1];else{var h=b[c],k=b[c+1],m=0,g=[0],n;for(n=c+e;n<d;n+=e){var p=b[n],q=b[n+1],m=m+Math.sqrt((p-h)*(p-h)+(q-k)*(q-k));g.push(m);h=p;k=q}d=.5*m;for(var r,h=ob,k=0,m=g.length;k<m;)n=k+m>>1,p=h(d,g[n]),0<p?k=n+1:(m=n,r=!p);r=r?k:~k;0>r?(d=(d-g[-r-2])/(g[-r-1]-g[-r-2]),c+=(-r-2)*e,g=od(b[c],b[c+e],d),h=od(b[c+1],b[c+e+1],d)):(g=b[c+r*e],h=b[c+r*e+1])}return f?(f[0]= -g,f[1]=h,f):[g,h]}function Ur(b,c,d,e,f,g){if(d==c)return null;if(f<b[c+e-1])return g?(d=b.slice(c,c+e),d[e-1]=f,d):null;if(b[d-1]<f)return g?(d=b.slice(d-e,d),d[e-1]=f,d):null;if(f==b[c+e-1])return b.slice(c,c+e);c/=e;for(d/=e;c<d;)g=c+d>>1,f<b[(g+1)*e-1]?d=g:c=g+1;d=b[c*e-1];if(f==d)return b.slice((c-1)*e,(c-1)*e+e);g=(f-d)/(b[(c+1)*e-1]-d);d=[];var h;for(h=0;h<e-1;++h)d.push(od(b[(c-1)*e+h],b[c*e+h],g));d.push(f);return d} -function Vr(b,c,d,e,f,g){var h=0;if(g)return Ur(b,h,c[c.length-1],d,e,f);if(e<b[d-1])return f?(b=b.slice(0,d),b[d-1]=e,b):null;if(b[b.length-1]<e)return f?(b=b.slice(b.length-d),b[d-1]=e,b):null;f=0;for(g=c.length;f<g;++f){var k=c[f];if(h!=k){if(e<b[h+d-1])break;if(e<=b[k-1])return Ur(b,h,k,d,e,!1);h=k}}return null};function T(b,c){bf.call(this);this.g=null;this.C=this.D=this.l=-1;this.la(b,c)}y(T,bf);l=T.prototype;l.mj=function(b){this.A?kb(this.A,b):this.A=b.slice();this.u()};l.clone=function(){var b=new T(null);b.ba(this.b,this.A.slice());return b};l.nb=function(b,c,d,e){if(e<Sd(this.J(),b,c))return e;this.C!=this.f&&(this.D=Math.sqrt(jf(this.A,0,this.A.length,this.a,0)),this.C=this.f);return lf(this.A,0,this.A.length,this.a,this.D,!1,b,c,d,e)}; -l.Cj=function(b,c){return Bf(this.A,0,this.A.length,this.a,b,c)};l.$l=function(b,c){return"XYM"!=this.b&&"XYZM"!=this.b?null:Ur(this.A,0,this.A.length,this.a,b,void 0!==c?c:!1)};l.Z=function(){return qf(this.A,0,this.A.length,this.a)};l.am=function(){var b=this.A,c=this.a,d=b[0],e=b[1],f=0,g;for(g=0+c;g<this.A.length;g+=c)var h=b[g],k=b[g+1],f=f+Math.sqrt((h-d)*(h-d)+(k-e)*(k-e)),d=h,e=k;return f};function om(b){b.l!=b.f&&(b.g=Tr(b.A,0,b.A.length,b.a,b.g),b.l=b.f);return b.g} -l.Lc=function(b){var c=[];c.length=tf(this.A,0,this.A.length,this.a,b,c,0);b=new T(null);b.ba("XY",c);return b};l.W=function(){return"LineString"};l.Ea=function(b){return Cf(this.A,0,this.A.length,this.a,b)};l.la=function(b,c){b?(ef(this,c,b,1),this.A||(this.A=[]),this.A.length=of(this.A,0,b,this.a),this.u()):this.ba("XY",null)};l.ba=function(b,c){df(this,b,c);this.u()};function U(b,c){bf.call(this);this.g=[];this.l=this.C=-1;this.la(b,c)}y(U,bf);l=U.prototype;l.nj=function(b){this.A?kb(this.A,b.ia().slice()):this.A=b.ia().slice();this.g.push(this.A.length);this.u()};l.clone=function(){var b=new U(null);b.ba(this.b,this.A.slice(),this.g.slice());return b};l.nb=function(b,c,d,e){if(e<Sd(this.J(),b,c))return e;this.l!=this.f&&(this.C=Math.sqrt(kf(this.A,0,this.g,this.a,0)),this.l=this.f);return mf(this.A,0,this.g,this.a,this.C,!1,b,c,d,e)}; -l.cm=function(b,c,d){return"XYM"!=this.b&&"XYZM"!=this.b||0===this.A.length?null:Vr(this.A,this.g,this.a,b,void 0!==c?c:!1,void 0!==d?d:!1)};l.Z=function(){return rf(this.A,0,this.g,this.a)};l.zb=function(){return this.g};l.Wj=function(b){if(0>b||this.g.length<=b)return null;var c=new T(null);c.ba(this.b,this.A.slice(0===b?0:this.g[b-1],this.g[b]));return c}; -l.sd=function(){var b=this.A,c=this.g,d=this.b,e=[],f=0,g,h;g=0;for(h=c.length;g<h;++g){var k=c[g],m=new T(null);m.ba(d,b.slice(f,k));e.push(m);f=k}return e};function pm(b){var c=[],d=b.A,e=0,f=b.g;b=b.a;var g,h;g=0;for(h=f.length;g<h;++g){var k=f[g],e=Tr(d,e,k,b);kb(c,e);e=k}return c}l.Lc=function(b){var c=[],d=[],e=this.A,f=this.g,g=this.a,h=0,k=0,m,n;m=0;for(n=f.length;m<n;++m){var p=f[m],k=tf(e,h,p,g,b,c,k);d.push(k);h=p}c.length=k;b=new U(null);b.ba("XY",c,d);return b};l.W=function(){return"MultiLineString"}; -l.Ea=function(b){a:{var c=this.A,d=this.g,e=this.a,f=0,g,h;g=0;for(h=d.length;g<h;++g){if(Cf(c,f,d[g],e,b)){b=!0;break a}f=d[g]}b=!1}return b};l.la=function(b,c){if(b){ef(this,c,b,2);this.A||(this.A=[]);var d=pf(this.A,0,b,this.a,this.g);this.A.length=0===d.length?0:d[d.length-1];this.u()}else this.ba("XY",null,this.g)};l.ba=function(b,c,d){df(this,b,c);this.g=d;this.u()}; -function Wr(b,c){var d=b.b,e=[],f=[],g,h;g=0;for(h=c.length;g<h;++g){var k=c[g];0===g&&(d=k.b);kb(e,k.ia());f.push(e.length)}b.ba(d,e,f)};function Xr(b,c){bf.call(this);this.la(b,c)}y(Xr,bf);l=Xr.prototype;l.pj=function(b){this.A?kb(this.A,b.ia()):this.A=b.ia().slice();this.u()};l.clone=function(){var b=new Xr(null);b.ba(this.b,this.A.slice());return b};l.nb=function(b,c,d,e){if(e<Sd(this.J(),b,c))return e;var f=this.A,g=this.a,h,k,m;h=0;for(k=f.length;h<k;h+=g)if(m=Wa(b,c,f[h],f[h+1]),m<e){e=m;for(m=0;m<g;++m)d[m]=f[h+m];d.length=g}return e};l.Z=function(){return qf(this.A,0,this.A.length,this.a)}; -l.gk=function(b){var c=this.A?this.A.length/this.a:0;if(0>b||c<=b)return null;c=new E(null);c.ba(this.b,this.A.slice(b*this.a,(b+1)*this.a));return c};l.ve=function(){var b=this.A,c=this.b,d=this.a,e=[],f,g;f=0;for(g=b.length;f<g;f+=d){var h=new E(null);h.ba(c,b.slice(f,f+d));e.push(h)}return e};l.W=function(){return"MultiPoint"};l.Ea=function(b){var c=this.A,d=this.a,e,f,g,h;e=0;for(f=c.length;e<f;e+=d)if(g=c[e],h=c[e+1],Ud(b,g,h))return!0;return!1}; -l.la=function(b,c){b?(ef(this,c,b,1),this.A||(this.A=[]),this.A.length=of(this.A,0,b,this.a),this.u()):this.ba("XY",null)};l.ba=function(b,c){df(this,b,c);this.u()};function V(b,c){bf.call(this);this.g=[];this.C=-1;this.D=null;this.T=this.O=this.U=-1;this.l=null;this.la(b,c)}y(V,bf);l=V.prototype;l.qj=function(b){if(this.A){var c=this.A.length;kb(this.A,b.ia());b=b.zb().slice();var d,e;d=0;for(e=b.length;d<e;++d)b[d]+=c}else this.A=b.ia().slice(),b=b.zb().slice(),this.g.push();this.g.push(b);this.u()};l.clone=function(){var b=new V(null),c=Ub(this.g);Yr(b,this.b,this.A.slice(),c);return b}; -l.nb=function(b,c,d,e){if(e<Sd(this.J(),b,c))return e;if(this.O!=this.f){var f=this.g,g=0,h=0,k,m;k=0;for(m=f.length;k<m;++k)var n=f[k],h=kf(this.A,g,n,this.a,h),g=n[n.length-1];this.U=Math.sqrt(h);this.O=this.f}f=rm(this);g=this.g;h=this.a;k=this.U;m=0;var n=[NaN,NaN],p,q;p=0;for(q=g.length;p<q;++p){var r=g[p];e=mf(f,m,r,h,k,!0,b,c,d,e,n);m=r[r.length-1]}return e}; -l.uc=function(b,c){var d;a:{d=rm(this);var e=this.g,f=0;if(0!==e.length){var g,h;g=0;for(h=e.length;g<h;++g){var k=e[g];if(zf(d,f,k,this.a,b,c)){d=!0;break a}f=k[k.length-1]}}d=!1}return d};l.dm=function(){var b=rm(this),c=this.g,d=0,e=0,f,g;f=0;for(g=c.length;f<g;++f)var h=c[f],e=e+gf(b,d,h,this.a),d=h[h.length-1];return e}; -l.Z=function(b){var c;void 0!==b?(c=rm(this).slice(),Hf(c,this.g,this.a,b)):c=this.A;b=c;c=this.g;var d=this.a,e=0,f=[],g=0,h,k;h=0;for(k=c.length;h<k;++h){var m=c[h];f[g++]=rf(b,e,m,d,f[g]);e=m[m.length-1]}f.length=g;return f}; -function sm(b){if(b.C!=b.f){var c=b.A,d=b.g,e=b.a,f=0,g=[],h,k,m=Md();h=0;for(k=d.length;h<k;++h){var n=d[h],m=Yd(c,f,n[0],e);g.push((m[0]+m[2])/2,(m[1]+m[3])/2);f=n[n.length-1]}c=rm(b);d=b.g;e=b.a;f=0;h=[];k=0;for(m=d.length;k<m;++k)n=d[k],h=Af(c,f,n,e,g,2*k,h),f=n[n.length-1];b.D=h;b.C=b.f}return b.D}l.Tj=function(){var b=new Xr(null);b.ba("XY",sm(this).slice());return b}; -function rm(b){if(b.T!=b.f){var c=b.A,d;a:{d=b.g;var e,f;e=0;for(f=d.length;e<f;++e)if(!Ff(c,d[e],b.a,void 0)){d=!1;break a}d=!0}d?b.l=c:(b.l=c.slice(),b.l.length=Hf(b.l,b.g,b.a));b.T=b.f}return b.l}l.Lc=function(b){var c=[],d=[],e=this.A,f=this.g,g=this.a;b=Math.sqrt(b);var h=0,k=0,m,n;m=0;for(n=f.length;m<n;++m){var p=f[m],q=[],k=uf(e,h,p,g,b,c,k,q);d.push(q);h=p[p.length-1]}c.length=k;e=new V(null);Yr(e,"XY",c,d);return e}; -l.ik=function(b){if(0>b||this.g.length<=b)return null;var c;0===b?c=0:(c=this.g[b-1],c=c[c.length-1]);b=this.g[b].slice();var d=b[b.length-1];if(0!==c){var e,f;e=0;for(f=b.length;e<f;++e)b[e]-=c}e=new F(null);e.ba(this.b,this.A.slice(c,d),b);return e};l.ce=function(){var b=this.b,c=this.A,d=this.g,e=[],f=0,g,h,k,m;g=0;for(h=d.length;g<h;++g){var n=d[g].slice(),p=n[n.length-1];if(0!==f)for(k=0,m=n.length;k<m;++k)n[k]-=f;k=new F(null);k.ba(b,c.slice(f,p),n);e.push(k);f=p}return e};l.W=function(){return"MultiPolygon"}; -l.Ea=function(b){a:{var c=rm(this),d=this.g,e=this.a,f=0,g,h;g=0;for(h=d.length;g<h;++g){var k=d[g];if(Df(c,f,k,e,b)){b=!0;break a}f=k[k.length-1]}b=!1}return b};l.la=function(b,c){if(b){ef(this,c,b,3);this.A||(this.A=[]);var d=this.A,e=this.a,f=this.g,g=0,f=f?f:[],h=0,k,m;k=0;for(m=b.length;k<m;++k)g=pf(d,g,b[k],e,f[h]),f[h++]=g,g=g[g.length-1];f.length=h;0===f.length?this.A.length=0:(d=f[f.length-1],this.A.length=0===d.length?0:d[d.length-1]);this.u()}else Yr(this,"XY",null,this.g)}; -function Yr(b,c,d,e){df(b,c,d);b.g=e;b.u()}function Zr(b,c){var d=b.b,e=[],f=[],g,h,k;g=0;for(h=c.length;g<h;++g){var m=c[g];0===g&&(d=m.b);var n=e.length;k=m.zb();var p,q;p=0;for(q=k.length;p<q;++p)k[p]+=n;kb(e,m.ia());f.push(k)}Yr(b,d,e,f)};function $r(b){b=b?b:{};this.defaultDataProjection=null;this.a=b.geometryName}y($r,Rr); -function as(b,c){if(!b)return null;var d;if(ja(b.x)&&ja(b.y))d="Point";else if(b.points)d="MultiPoint";else if(b.paths)d=1===b.paths.length?"LineString":"MultiLineString";else if(b.rings){var e=b.rings,f=bs(b),g=[];d=[];var h,k;h=0;for(k=e.length;h<k;++h){var m=tb(e[h]);Ef(m,0,m.length,f.length)?g.push([e[h]]):d.push(e[h])}for(;d.length;){e=d.shift();f=!1;for(h=g.length-1;0<=h;h--)if(Vd((new vf(g[h][0])).J(),(new vf(e)).J())){g[h].push(e);f=!0;break}f||g.push([e.reverse()])}b=Tb(b);1===g.length?(d= -"Polygon",b.rings=g[0]):(d="MultiPolygon",b.rings=g)}return Qr((0,cs[d])(b),!1,c)}function bs(b){var c="XY";!0===b.hasZ&&!0===b.hasM?c="XYZM":!0===b.hasZ?c="XYZ":!0===b.hasM&&(c="XYM");return c}function ds(b){b=b.b;return{hasZ:"XYZ"===b||"XYZM"===b,hasM:"XYM"===b||"XYZM"===b}} -var cs={Point:function(b){return void 0!==b.m&&void 0!==b.z?new E([b.x,b.y,b.z,b.m],"XYZM"):void 0!==b.z?new E([b.x,b.y,b.z],"XYZ"):void 0!==b.m?new E([b.x,b.y,b.m],"XYM"):new E([b.x,b.y])},LineString:function(b){return new T(b.paths[0],bs(b))},Polygon:function(b){return new F(b.rings,bs(b))},MultiPoint:function(b){return new Xr(b.points,bs(b))},MultiLineString:function(b){return new U(b.paths,bs(b))},MultiPolygon:function(b){return new V(b.rings,bs(b))}},es={Point:function(b){var c=b.Z();b=b.b;if("XYZ"=== -b)return{x:c[0],y:c[1],z:c[2]};if("XYM"===b)return{x:c[0],y:c[1],m:c[2]};if("XYZM"===b)return{x:c[0],y:c[1],z:c[2],m:c[3]};if("XY"===b)return{x:c[0],y:c[1]}},LineString:function(b){var c=ds(b);return{hasZ:c.hasZ,hasM:c.hasM,paths:[b.Z()]}},Polygon:function(b){var c=ds(b);return{hasZ:c.hasZ,hasM:c.hasM,rings:b.Z(!1)}},MultiPoint:function(b){var c=ds(b);return{hasZ:c.hasZ,hasM:c.hasM,points:b.Z()}},MultiLineString:function(b){var c=ds(b);return{hasZ:c.hasZ,hasM:c.hasM,paths:b.Z()}},MultiPolygon:function(b){var c= -ds(b);b=b.Z(!1);for(var d=[],e=0;e<b.length;e++)for(var f=b[e].length-1;0<=f;f--)d.push(b[e][f]);return{hasZ:c.hasZ,hasM:c.hasM,rings:d}}};l=$r.prototype;l.Sc=function(b,c){var d=as(b.geometry,c),e=new pn;this.a&&e.yc(this.a);e.Ma(d);c&&c.qf&&b.attributes[c.qf]&&e.jc(b.attributes[c.qf]);b.attributes&&e.I(b.attributes);return e}; -l.Kf=function(b,c){var d=c?c:{};if(b.features){var e=[],f=b.features,g,h;d.qf=b.objectIdFieldName;g=0;for(h=f.length;g<h;++g)e.push(this.Sc(f[g],d));return e}return[this.Sc(b,d)]};l.Gh=function(b,c){return as(b,c)};l.Nh=function(b){return b.spatialReference&&b.spatialReference.wkid?Ee("EPSG:"+b.spatialReference.wkid):null};function fs(b,c){return(0,es[b.W()])(Qr(b,!0,c),c)}l.Ue=function(b,c){return fs(b,Pr(this,c))}; -l.Wc=function(b,c){c=Pr(this,c);var d={},e=b.X();e&&(d.geometry=fs(e,c));e=b.R();delete e[b.a];d.attributes=Pb(e)?{}:e;c&&c.featureProjection&&(d.spatialReference={wkid:Ee(c.featureProjection).a.split(":").pop()});return d};l.Se=function(b,c){c=Pr(this,c);var d=[],e,f;e=0;for(f=b.length;e<f;++e)d.push(this.Wc(b[e],c));return{features:d}};function gs(b){$e.call(this);this.c=b?b:null;hs(this)}y(gs,$e);function is(b){var c=[],d,e;d=0;for(e=b.length;d<e;++d)c.push(b[d].clone());return c}function js(b){var c,d;if(b.c)for(c=0,d=b.c.length;c<d;++c)Vc(b.c[c],"change",b.u,!1,b)}function hs(b){var c,d;if(b.c)for(c=0,d=b.c.length;c<d;++c)D(b.c[c],"change",b.u,!1,b)}l=gs.prototype;l.clone=function(){var b=new gs(null);b.Yh(this.c);return b}; -l.nb=function(b,c,d,e){if(e<Sd(this.J(),b,c))return e;var f=this.c,g,h;g=0;for(h=f.length;g<h;++g)e=f[g].nb(b,c,d,e);return e};l.uc=function(b,c){var d=this.c,e,f;e=0;for(f=d.length;e<f;++e)if(d[e].uc(b,c))return!0;return!1};l.Wd=function(b){Pd(Infinity,Infinity,-Infinity,-Infinity,b);for(var c=this.c,d=0,e=c.length;d<e;++d)be(b,c[d].J());return b};l.Ag=function(){return is(this.c)}; -l.td=function(b){this.o!=this.f&&(Qb(this.i),this.j=0,this.o=this.f);if(0>b||0!==this.j&&b<this.j)return this;var c=b.toString();if(this.i.hasOwnProperty(c))return this.i[c];var d=[],e=this.c,f=!1,g,h;g=0;for(h=e.length;g<h;++g){var k=e[g],m=k.td(b);d.push(m);m!==k&&(f=!0)}if(f)return b=new gs(null),js(b),b.c=d,hs(b),b.u(),this.i[c]=b;this.j=b;return this};l.W=function(){return"GeometryCollection"};l.Ea=function(b){var c=this.c,d,e;d=0;for(e=c.length;d<e;++d)if(c[d].Ea(b))return!0;return!1}; -l.La=function(){return 0===this.c.length};l.Yh=function(b){b=is(b);js(this);this.c=b;hs(this);this.u()};l.pc=function(b){var c=this.c,d,e;d=0;for(e=c.length;d<e;++d)c[d].pc(b);this.u()};l.Pc=function(b,c){var d=this.c,e,f;e=0;for(f=d.length;e<f;++e)d[e].Pc(b,c);this.u()};l.Y=function(){js(this);gs.ca.Y.call(this)};function ks(b){b=b?b:{};this.defaultDataProjection=null;this.defaultDataProjection=Ee(b.defaultDataProjection?b.defaultDataProjection:"EPSG:4326");this.a=b.geometryName}y(ks,Rr);function ls(b,c){return b?Qr((0,ms[b.type])(b),!1,c):null}function ns(b,c){return(0,os[b.W()])(Qr(b,!0,c),c)} -var ms={Point:function(b){return new E(b.coordinates)},LineString:function(b){return new T(b.coordinates)},Polygon:function(b){return new F(b.coordinates)},MultiPoint:function(b){return new Xr(b.coordinates)},MultiLineString:function(b){return new U(b.coordinates)},MultiPolygon:function(b){return new V(b.coordinates)},GeometryCollection:function(b,c){var d=b.geometries.map(function(b){return ls(b,c)});return new gs(d)}},os={Point:function(b){return{type:"Point",coordinates:b.Z()}},LineString:function(b){return{type:"LineString", -coordinates:b.Z()}},Polygon:function(b,c){var d;c&&(d=c.rightHanded);return{type:"Polygon",coordinates:b.Z(d)}},MultiPoint:function(b){return{type:"MultiPoint",coordinates:b.Z()}},MultiLineString:function(b){return{type:"MultiLineString",coordinates:b.Z()}},MultiPolygon:function(b,c){var d;c&&(d=c.rightHanded);return{type:"MultiPolygon",coordinates:b.Z(d)}},GeometryCollection:function(b,c){return{type:"GeometryCollection",geometries:b.c.map(function(b){return ns(b,c)})}},Circle:function(){return{type:"GeometryCollection", -geometries:[]}}};l=ks.prototype;l.Sc=function(b,c){var d=ls(b.geometry,c),e=new pn;this.a&&e.yc(this.a);e.Ma(d);void 0!==b.id&&e.jc(b.id);b.properties&&e.I(b.properties);return e};l.Kf=function(b,c){if("Feature"==b.type)return[this.Sc(b,c)];if("FeatureCollection"==b.type){var d=[],e=b.features,f,g;f=0;for(g=e.length;f<g;++f)d.push(this.Sc(e[f],c));return d}return[]};l.Gh=function(b,c){return ls(b,c)}; -l.Nh=function(b){return(b=b.crs)?"name"==b.type?Ee(b.properties.name):"EPSG"==b.type?Ee("EPSG:"+b.properties.code):null:this.defaultDataProjection};l.Wc=function(b,c){c=Pr(this,c);var d={type:"Feature"},e=b.Oa();void 0!==e&&(d.id=e);e=b.X();d.geometry=e?ns(e,c):null;e=b.R();delete e[b.a];d.properties=Pb(e)?null:e;return d};l.Se=function(b,c){c=Pr(this,c);var d=[],e,f;e=0;for(f=b.length;e<f;++e)d.push(this.Wc(b[e],c));return{type:"FeatureCollection",features:d}}; -l.Ue=function(b,c){return ns(b,Pr(this,c))};function ps(){this.defaultDataProjection=null}y(ps,Nr);l=ps.prototype;l.W=function(){return"xml"};l.Tb=function(b,c){if(To(b))return qs(this,b,c);if(Wo(b))return this.Eh(b,c);if(ia(b)){var d=fp(b);return qs(this,d,c)}return null};function qs(b,c,d){b=rs(b,c,d);return 0<b.length?b[0]:null}l.Ba=function(b,c){if(To(b))return rs(this,b,c);if(Wo(b))return this.ic(b,c);if(ia(b)){var d=fp(b);return rs(this,d,c)}return[]}; -function rs(b,c,d){var e=[];for(c=c.firstChild;c;c=c.nextSibling)1==c.nodeType&&kb(e,b.ic(c,d));return e}l.Tc=function(b,c){if(To(b))return this.G(b,c);if(Wo(b)){var d=this.Je(b,[Or(this,b,c?c:{})]);return d?d:null}return ia(b)?(d=fp(b),this.G(d,c)):null};l.Ia=function(b){return To(b)?this.Qf(b):Wo(b)?this.Me(b):ia(b)?(b=fp(b),this.Qf(b)):null};l.Qf=function(){return this.defaultDataProjection};l.Me=function(){return this.defaultDataProjection};l.Kd=function(b,c){var d=this.v(b,c);return Fo(d)}; -l.Vb=function(b,c){var d=this.f(b,c);return Fo(d)};l.Xc=function(b,c){var d=this.o(b,c);return Fo(d)};function ss(b){b=b?b:{};this.featureType=b.featureType;this.featureNS=b.featureNS;this.srsName=b.srsName;this.schemaLocation="";this.a={};this.a["http://www.opengis.net/gml"]={featureMember:ip(ss.prototype.Ed),featureMembers:ip(ss.prototype.Ed)};this.defaultDataProjection=null}y(ss,ps);l=ss.prototype; -l.Ed=function(b,c){var d=Qo(b),e;if("FeatureCollection"==d)"http://www.opengis.net/wfs"===b.namespaceURI?e=Q([],this.a,b,c,this):e=Q(null,this.a,b,c,this);else if("featureMembers"==d||"featureMember"==d){var f=c[0],g=f.featureType;e=f.featureNS;var h,k;if(!g&&b.childNodes){g=[];e={};h=0;for(k=b.childNodes.length;h<k;++h){var m=b.childNodes[h];if(1===m.nodeType){var n=m.nodeName.split(":").pop();if(-1===g.indexOf(n)){var p;Mb(e,m.namespaceURI)?p=Ob(e,function(b){return b===m.namespaceURI}):(p="p"+ -Kb(e),e[p]=m.namespaceURI);g.push(p+":"+n)}}}f.featureType=g;f.featureNS=e}ia(e)&&(h=e,e={},e.p0=h);var f={},g=ga(g)?g:[g],q;for(q in e){n={};h=0;for(k=g.length;h<k;++h)(-1===g[h].indexOf(":")?"p0":g[h].split(":")[0])===q&&(n[g[h].split(":").pop()]="featureMembers"==d?hp(this.Jf,this):ip(this.Jf,this));f[e[q]]=n}e=Q([],f,b,c)}e||(e=[]);return e};l.Je=function(b,c){var d=c[0];d.srsName=b.firstElementChild.getAttribute("srsName");var e=Q(null,this.bg,b,c,this);if(e)return Qr(e,!1,d)}; -l.Jf=function(b,c){var d,e=b.getAttribute("fid")||$o(b,"http://www.opengis.net/gml","id"),f={},g;for(d=b.firstElementChild;d;d=d.nextElementSibling){var h=Qo(d);if(0===d.childNodes.length||1===d.childNodes.length&&(3===d.firstChild.nodeType||4===d.firstChild.nodeType)){var k=Mo(d,!1);/^[\s\xa0]*$/.test(k)&&(k=void 0);f[h]=k}else"boundedBy"!==h&&(g=h),f[h]=this.Je(d,c)}d=new pn(f);g&&d.yc(g);e&&d.jc(e);return d};l.Mh=function(b,c){var d=this.Ie(b,c);if(d){var e=new E(null);e.ba("XYZ",d);return e}}; -l.Kh=function(b,c){var d=Q([],this.Ki,b,c,this);if(d)return new Xr(d)};l.Jh=function(b,c){var d=Q([],this.Ji,b,c,this);if(d){var e=new U(null);Wr(e,d);return e}};l.Lh=function(b,c){var d=Q([],this.Li,b,c,this);if(d){var e=new V(null);Zr(e,d);return e}};l.Bh=function(b,c){pp(this.Oi,b,c,this)};l.Qg=function(b,c){pp(this.Hi,b,c,this)};l.Ch=function(b,c){pp(this.Pi,b,c,this)};l.Ke=function(b,c){var d=this.Ie(b,c);if(d){var e=new T(null);e.ba("XYZ",d);return e}}; -l.jo=function(b,c){var d=Q(null,this.Md,b,c,this);if(d)return d};l.Ih=function(b,c){var d=this.Ie(b,c);if(d){var e=new vf(null);wf(e,"XYZ",d);return e}};l.Le=function(b,c){var d=Q([null],this.We,b,c,this);if(d&&d[0]){var e=new F(null),f=d[0],g=[f.length],h,k;h=1;for(k=d.length;h<k;++h)kb(f,d[h]),g.push(f.length);e.ba("XYZ",f,g);return e}};l.Ie=function(b,c){return Q(null,this.Md,b,c,this)};l.Ki=Object({"http://www.opengis.net/gml":{pointMember:hp(ss.prototype.Bh),pointMembers:hp(ss.prototype.Bh)}}); -l.Ji=Object({"http://www.opengis.net/gml":{lineStringMember:hp(ss.prototype.Qg),lineStringMembers:hp(ss.prototype.Qg)}});l.Li=Object({"http://www.opengis.net/gml":{polygonMember:hp(ss.prototype.Ch),polygonMembers:hp(ss.prototype.Ch)}});l.Oi=Object({"http://www.opengis.net/gml":{Point:hp(ss.prototype.Ie)}});l.Hi=Object({"http://www.opengis.net/gml":{LineString:hp(ss.prototype.Ke)}});l.Pi=Object({"http://www.opengis.net/gml":{Polygon:hp(ss.prototype.Le)}});l.Nd=Object({"http://www.opengis.net/gml":{LinearRing:ip(ss.prototype.jo)}}); -l.ic=function(b,c){var d={featureType:this.featureType,featureNS:this.featureNS};c&&Wb(d,Or(this,b,c));return this.Ed(b,[d])};l.Me=function(b){return Ee(this.B?this.B:b.firstElementChild.getAttribute("srsName"))};function ts(b){b=Mo(b,!1);return us(b)}function us(b){if(b=/^\s*(true|1)|(false|0)\s*$/.exec(b))return void 0!==b[1]||!1} -function vs(b){b=Mo(b,!1);if(b=/^\s*(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(Z|(?:([+\-])(\d{2})(?::(\d{2}))?))\s*$/.exec(b)){var c=Date.UTC(parseInt(b[1],10),parseInt(b[2],10)-1,parseInt(b[3],10),parseInt(b[4],10),parseInt(b[5],10),parseInt(b[6],10))/1E3;if("Z"!=b[7]){var d="-"==b[8]?-1:1,c=c+60*d*parseInt(b[9],10);void 0!==b[10]&&(c+=3600*d*parseInt(b[10],10))}return c}}function ws(b){b=Mo(b,!1);return xs(b)} -function xs(b){if(b=/^\s*([+\-]?\d*\.?\d+(?:e[+\-]?\d+)?)\s*$/i.exec(b))return parseFloat(b[1])}function ys(b){b=Mo(b,!1);return zs(b)}function zs(b){if(b=/^\s*(\d+)\s*$/.exec(b))return parseInt(b[1],10)}function W(b){return Mo(b,!1).trim()}function As(b,c){Bs(b,c?"1":"0")}function Cs(b,c){b.appendChild(Io.createTextNode(c.toPrecision()))}function Ds(b,c){b.appendChild(Io.createTextNode(c.toString()))}function Bs(b,c){b.appendChild(Io.createTextNode(c))};function Es(b){b=b?b:{};ss.call(this,b);this.a["http://www.opengis.net/gml"].featureMember=hp(ss.prototype.Ed);this.schemaLocation=b.schemaLocation?b.schemaLocation:"http://www.opengis.net/gml http://schemas.opengis.net/gml/2.1.2/feature.xsd"}y(Es,ss);l=Es.prototype; -l.Fh=function(b,c){var d=Mo(b,!1).replace(/^\s*|\s*$/g,""),e=c[0].srsName,f=b.parentNode.getAttribute("srsDimension"),g="enu";e&&(e=Ee(e))&&(g=e.g);d=d.split(/[\s,]+/);e=2;b.getAttribute("srsDimension")?e=zs(b.getAttribute("srsDimension")):b.getAttribute("dimension")?e=zs(b.getAttribute("dimension")):f&&(e=zs(f));for(var h,k,m=[],n=0,p=d.length;n<p;n+=e)f=parseFloat(d[n]),h=parseFloat(d[n+1]),k=3===e?parseFloat(d[n+2]):0,"en"===g.substr(0,2)?m.push(f,h,k):m.push(h,f,k);return m}; -l.fo=function(b,c){var d=Q([null],this.Di,b,c,this);return Pd(d[1][0],d[1][1],d[1][3],d[1][4])};l.dl=function(b,c){var d=Q(void 0,this.Nd,b,c,this);d&&c[c.length-1].push(d)};l.Pn=function(b,c){var d=Q(void 0,this.Nd,b,c,this);d&&(c[c.length-1][0]=d)};l.Md=Object({"http://www.opengis.net/gml":{coordinates:ip(Es.prototype.Fh)}});l.We=Object({"http://www.opengis.net/gml":{innerBoundaryIs:Es.prototype.dl,outerBoundaryIs:Es.prototype.Pn}});l.Di=Object({"http://www.opengis.net/gml":{coordinates:hp(Es.prototype.Fh)}}); -l.bg=Object({"http://www.opengis.net/gml":{Point:ip(ss.prototype.Mh),MultiPoint:ip(ss.prototype.Kh),LineString:ip(ss.prototype.Ke),MultiLineString:ip(ss.prototype.Jh),LinearRing:ip(ss.prototype.Ih),Polygon:ip(ss.prototype.Le),MultiPolygon:ip(ss.prototype.Lh),Box:ip(Es.prototype.fo)}});function Fs(b){b=b?b:{};ss.call(this,b);this.l=void 0!==b.surface?b.surface:!1;this.g=void 0!==b.curve?b.curve:!1;this.i=void 0!==b.multiCurve?b.multiCurve:!0;this.j=void 0!==b.multiSurface?b.multiSurface:!0;this.schemaLocation=b.schemaLocation?b.schemaLocation:"http://www.opengis.net/gml http://schemas.opengis.net/gml/3.1.1/profiles/gmlsfProfile/1.0.0/gmlsf.xsd"}y(Fs,ss);l=Fs.prototype;l.no=function(b,c){var d=Q([],this.Ii,b,c,this);if(d){var e=new U(null);Wr(e,d);return e}}; -l.oo=function(b,c){var d=Q([],this.Mi,b,c,this);if(d){var e=new V(null);Zr(e,d);return e}};l.rg=function(b,c){pp(this.Ei,b,c,this)};l.ki=function(b,c){pp(this.Ti,b,c,this)};l.ro=function(b,c){return Q([null],this.Ni,b,c,this)};l.to=function(b,c){return Q([null],this.Si,b,c,this)};l.so=function(b,c){return Q([null],this.We,b,c,this)};l.mo=function(b,c){return Q([null],this.Md,b,c,this)};l.fl=function(b,c){var d=Q(void 0,this.Nd,b,c,this);d&&c[c.length-1].push(d)}; -l.yj=function(b,c){var d=Q(void 0,this.Nd,b,c,this);d&&(c[c.length-1][0]=d)};l.Oh=function(b,c){var d=Q([null],this.Ui,b,c,this);if(d&&d[0]){var e=new F(null),f=d[0],g=[f.length],h,k;h=1;for(k=d.length;h<k;++h)kb(f,d[h]),g.push(f.length);e.ba("XYZ",f,g);return e}};l.Dh=function(b,c){var d=Q([null],this.Fi,b,c,this);if(d){var e=new T(null);e.ba("XYZ",d);return e}};l.io=function(b,c){var d=Q([null],this.Gi,b,c,this);return Pd(d[1][0],d[1][1],d[2][0],d[2][1])}; -l.ko=function(b,c){for(var d=Mo(b,!1),e=/^\s*([+\-]?\d*\.?\d+(?:[eE][+\-]?\d+)?)\s*/,f=[],g;g=e.exec(d);)f.push(parseFloat(g[1])),d=d.substr(g[0].length);if(""===d){d=c[0].srsName;e="enu";d&&(e=He(Ee(d)));if("neu"===e)for(d=0,e=f.length;d<e;d+=3)g=f[d],f[d]=f[d+1],f[d+1]=g;d=f.length;2==d&&f.push(0);return 0===d?void 0:f}}; -l.Nf=function(b,c){var d=Mo(b,!1).replace(/^\s*|\s*$/g,""),e=c[0].srsName,f=b.parentNode.getAttribute("srsDimension"),g="enu";e&&(g=He(Ee(e)));d=d.split(/\s+/);e=2;b.getAttribute("srsDimension")?e=zs(b.getAttribute("srsDimension")):b.getAttribute("dimension")?e=zs(b.getAttribute("dimension")):f&&(e=zs(f));for(var h,k,m=[],n=0,p=d.length;n<p;n+=e)f=parseFloat(d[n]),h=parseFloat(d[n+1]),k=3===e?parseFloat(d[n+2]):0,"en"===g.substr(0,2)?m.push(f,h,k):m.push(h,f,k);return m}; -l.Md=Object({"http://www.opengis.net/gml":{pos:ip(Fs.prototype.ko),posList:ip(Fs.prototype.Nf)}});l.We=Object({"http://www.opengis.net/gml":{interior:Fs.prototype.fl,exterior:Fs.prototype.yj}}); -l.bg=Object({"http://www.opengis.net/gml":{Point:ip(ss.prototype.Mh),MultiPoint:ip(ss.prototype.Kh),LineString:ip(ss.prototype.Ke),MultiLineString:ip(ss.prototype.Jh),LinearRing:ip(ss.prototype.Ih),Polygon:ip(ss.prototype.Le),MultiPolygon:ip(ss.prototype.Lh),Surface:ip(Fs.prototype.Oh),MultiSurface:ip(Fs.prototype.oo),Curve:ip(Fs.prototype.Dh),MultiCurve:ip(Fs.prototype.no),Envelope:ip(Fs.prototype.io)}});l.Ii=Object({"http://www.opengis.net/gml":{curveMember:hp(Fs.prototype.rg),curveMembers:hp(Fs.prototype.rg)}}); -l.Mi=Object({"http://www.opengis.net/gml":{surfaceMember:hp(Fs.prototype.ki),surfaceMembers:hp(Fs.prototype.ki)}});l.Ei=Object({"http://www.opengis.net/gml":{LineString:hp(ss.prototype.Ke),Curve:hp(Fs.prototype.Dh)}});l.Ti=Object({"http://www.opengis.net/gml":{Polygon:hp(ss.prototype.Le),Surface:hp(Fs.prototype.Oh)}});l.Ui=Object({"http://www.opengis.net/gml":{patches:ip(Fs.prototype.ro)}});l.Fi=Object({"http://www.opengis.net/gml":{segments:ip(Fs.prototype.to)}}); -l.Gi=Object({"http://www.opengis.net/gml":{lowerCorner:hp(Fs.prototype.Nf),upperCorner:hp(Fs.prototype.Nf)}});l.Ni=Object({"http://www.opengis.net/gml":{PolygonPatch:ip(Fs.prototype.so)}});l.Si=Object({"http://www.opengis.net/gml":{LineStringSegment:ip(Fs.prototype.mo)}});function Gs(b,c,d){d=d[d.length-1].srsName;c=c.Z();for(var e=c.length,f=Array(e),g,h=0;h<e;++h){g=c[h];var k=h,m="enu";d&&(m=He(Ee(d)));f[k]="en"===m.substr(0,2)?g[0]+" "+g[1]:g[1]+" "+g[0]}Bs(b,f.join(" "))} -l.zi=function(b,c,d){var e=d[d.length-1].srsName;e&&b.setAttribute("srsName",e);e=Lo(b.namespaceURI,"pos");b.appendChild(e);d=d[d.length-1].srsName;b="enu";d&&(b=He(Ee(d)));c=c.Z();Bs(e,"en"===b.substr(0,2)?c[0]+" "+c[1]:c[1]+" "+c[0])};var Hs={"http://www.opengis.net/gml":{lowerCorner:O(Bs),upperCorner:O(Bs)}};l=Fs.prototype;l.fp=function(b,c,d){var e=d[d.length-1].srsName;e&&b.setAttribute("srsName",e);qp({node:b},Hs,np,[c[0]+" "+c[1],c[2]+" "+c[3]],d,["lowerCorner","upperCorner"],this)}; -l.wi=function(b,c,d){var e=d[d.length-1].srsName;e&&b.setAttribute("srsName",e);e=Lo(b.namespaceURI,"posList");b.appendChild(e);Gs(e,c,d)};l.Ri=function(b,c){var d=c[c.length-1],e=d.node,f=d.exteriorWritten;void 0===f&&(d.exteriorWritten=!0);return Lo(e.namespaceURI,void 0!==f?"interior":"exterior")}; -l.Ve=function(b,c,d){var e=d[d.length-1].srsName;"PolygonPatch"!==b.nodeName&&e&&b.setAttribute("srsName",e);"Polygon"===b.nodeName||"PolygonPatch"===b.nodeName?(c=c.be(),qp({node:b,srsName:e},Is,this.Ri,c,d,void 0,this)):"Surface"===b.nodeName&&(e=Lo(b.namespaceURI,"patches"),b.appendChild(e),b=Lo(e.namespaceURI,"PolygonPatch"),e.appendChild(b),this.Ve(b,c,d))}; -l.Qe=function(b,c,d){var e=d[d.length-1].srsName;"LineStringSegment"!==b.nodeName&&e&&b.setAttribute("srsName",e);"LineString"===b.nodeName||"LineStringSegment"===b.nodeName?(e=Lo(b.namespaceURI,"posList"),b.appendChild(e),Gs(e,c,d)):"Curve"===b.nodeName&&(e=Lo(b.namespaceURI,"segments"),b.appendChild(e),b=Lo(e.namespaceURI,"LineStringSegment"),e.appendChild(b),this.Qe(b,c,d))}; -l.yi=function(b,c,d){var e=d[d.length-1],f=e.srsName,e=e.surface;f&&b.setAttribute("srsName",f);c=c.ce();qp({node:b,srsName:f,surface:e},Js,this.c,c,d,void 0,this)};l.gp=function(b,c,d){var e=d[d.length-1].srsName;e&&b.setAttribute("srsName",e);c=c.ve();qp({node:b,srsName:e},Ks,lp("pointMember"),c,d,void 0,this)};l.xi=function(b,c,d){var e=d[d.length-1],f=e.srsName,e=e.curve;f&&b.setAttribute("srsName",f);c=c.sd();qp({node:b,srsName:f,curve:e},Ls,this.c,c,d,void 0,this)}; -l.Ai=function(b,c,d){var e=Lo(b.namespaceURI,"LinearRing");b.appendChild(e);this.wi(e,c,d)};l.Bi=function(b,c,d){var e=this.b(c,d);e&&(b.appendChild(e),this.Ve(e,c,d))};l.hp=function(b,c,d){var e=Lo(b.namespaceURI,"Point");b.appendChild(e);this.zi(e,c,d)};l.vi=function(b,c,d){var e=this.b(c,d);e&&(b.appendChild(e),this.Qe(e,c,d))}; -l.Te=function(b,c,d){var e=d[d.length-1],f=Tb(e);f.node=b;var g;ga(c)?e.dataProjection?g=Ze(c,e.featureProjection,e.dataProjection):g=c:g=Qr(c,!0,e);qp(f,Ms,this.b,[g],d,void 0,this)}; -l.ri=function(b,c,d){var e=c.Oa();e&&b.setAttribute("fid",e);var e=d[d.length-1],f=e.featureNS,g=c.a;e.xc||(e.xc={},e.xc[f]={});var h=c.R();c=[];var k=[],m;for(m in h){var n=h[m];null!==n&&(c.push(m),k.push(n),m==g||n instanceof $e?m in e.xc[f]||(e.xc[f][m]=O(this.Te,this)):m in e.xc[f]||(e.xc[f][m]=O(Bs)))}m=Tb(e);m.node=b;qp(m,e.xc,lp(void 0,f),k,d,c)}; -var Js={"http://www.opengis.net/gml":{surfaceMember:O(Fs.prototype.Bi),polygonMember:O(Fs.prototype.Bi)}},Ks={"http://www.opengis.net/gml":{pointMember:O(Fs.prototype.hp)}},Ls={"http://www.opengis.net/gml":{lineStringMember:O(Fs.prototype.vi),curveMember:O(Fs.prototype.vi)}},Is={"http://www.opengis.net/gml":{exterior:O(Fs.prototype.Ai),interior:O(Fs.prototype.Ai)}},Ms={"http://www.opengis.net/gml":{Curve:O(Fs.prototype.Qe),MultiCurve:O(Fs.prototype.xi),Point:O(Fs.prototype.zi),MultiPoint:O(Fs.prototype.gp), -LineString:O(Fs.prototype.Qe),MultiLineString:O(Fs.prototype.xi),LinearRing:O(Fs.prototype.wi),Polygon:O(Fs.prototype.Ve),MultiPolygon:O(Fs.prototype.yi),Surface:O(Fs.prototype.Ve),MultiSurface:O(Fs.prototype.yi),Envelope:O(Fs.prototype.fp)}},Ns={MultiLineString:"lineStringMember",MultiCurve:"curveMember",MultiPolygon:"polygonMember",MultiSurface:"surfaceMember"};Fs.prototype.c=function(b,c){return Lo("http://www.opengis.net/gml",Ns[c[c.length-1].node.nodeName])}; -Fs.prototype.b=function(b,c){var d=c[c.length-1],e=d.multiSurface,f=d.surface,g=d.curve,d=d.multiCurve,h;ga(b)?h="Envelope":(h=b.W(),"MultiPolygon"===h&&!0===e?h="MultiSurface":"Polygon"===h&&!0===f?h="Surface":"LineString"===h&&!0===g?h="Curve":"MultiLineString"===h&&!0===d&&(h="MultiCurve"));return Lo("http://www.opengis.net/gml",h)}; -Fs.prototype.o=function(b,c){c=Pr(this,c);var d=Lo("http://www.opengis.net/gml","geom"),e={node:d,srsName:this.srsName,curve:this.g,surface:this.l,multiSurface:this.j,multiCurve:this.i};c&&Wb(e,c);this.Te(d,b,[e]);return d}; -Fs.prototype.f=function(b,c){c=Pr(this,c);var d=Lo("http://www.opengis.net/gml","featureMembers");ep(d,"http://www.w3.org/2001/XMLSchema-instance","xsi:schemaLocation",this.schemaLocation);var e={srsName:this.srsName,curve:this.g,surface:this.l,multiSurface:this.j,multiCurve:this.i,featureNS:this.featureNS,featureType:this.featureType};c&&Wb(e,c);var e=[e],f=e[e.length-1],g=f.featureType,h=f.featureNS,k={};k[h]={};k[h][g]=O(this.ri,this);f=Tb(f);f.node=d;qp(f,k,lp(g,h),b,e);return d};function Os(b){b=b?b:{};this.defaultDataProjection=null;this.defaultDataProjection=Ee("EPSG:4326");this.a=b.readExtensions}y(Os,ps);var Ps=[null,"http://www.topografix.com/GPX/1/0","http://www.topografix.com/GPX/1/1"];function Qs(b,c,d){b.push(parseFloat(c.getAttribute("lon")),parseFloat(c.getAttribute("lat")));"ele"in d?(b.push(d.ele),delete d.ele):b.push(0);"time"in d?(b.push(d.time),delete d.time):b.push(0);return b} -function Rs(b,c){var d=c[c.length-1],e=b.getAttribute("href");null!==e&&(d.link=e);pp(Ss,b,c)}function Ts(b,c){c[c.length-1].extensionsNode_=b}function Us(b,c){var d=c[0],e=Q({flatCoordinates:[]},Vs,b,c);if(e){var f=e.flatCoordinates;delete e.flatCoordinates;var g=new T(null);g.ba("XYZM",f);Qr(g,!1,d);d=new pn(g);d.I(e);return d}} -function Ws(b,c){var d=c[0],e=Q({flatCoordinates:[],ends:[]},Xs,b,c);if(e){var f=e.flatCoordinates;delete e.flatCoordinates;var g=e.ends;delete e.ends;var h=new U(null);h.ba("XYZM",f,g);Qr(h,!1,d);d=new pn(h);d.I(e);return d}}function Ys(b,c){var d=c[0],e=Q({},Zs,b,c);if(e){var f=Qs([],b,e),f=new E(f,"XYZM");Qr(f,!1,d);d=new pn(f);d.I(e);return d}} -var $s={rte:Us,trk:Ws,wpt:Ys},at=P(Ps,{rte:hp(Us),trk:hp(Ws),wpt:hp(Ys)}),Ss=P(Ps,{text:N(W,"linkText"),type:N(W,"linkType")}),Vs=P(Ps,{name:N(W),cmt:N(W),desc:N(W),src:N(W),link:Rs,number:N(ys),extensions:Ts,type:N(W),rtept:function(b,c){var d=Q({},bt,b,c);d&&Qs(c[c.length-1].flatCoordinates,b,d)}}),bt=P(Ps,{ele:N(ws),time:N(vs)}),Xs=P(Ps,{name:N(W),cmt:N(W),desc:N(W),src:N(W),link:Rs,number:N(ys),type:N(W),extensions:Ts,trkseg:function(b,c){var d=c[c.length-1];pp(ct,b,c);d.ends.push(d.flatCoordinates.length)}}), -ct=P(Ps,{trkpt:function(b,c){var d=Q({},dt,b,c);d&&Qs(c[c.length-1].flatCoordinates,b,d)}}),dt=P(Ps,{ele:N(ws),time:N(vs)}),Zs=P(Ps,{ele:N(ws),time:N(vs),magvar:N(ws),geoidheight:N(ws),name:N(W),cmt:N(W),desc:N(W),src:N(W),link:Rs,sym:N(W),type:N(W),fix:N(W),sat:N(ys),hdop:N(ws),vdop:N(ws),pdop:N(ws),ageofdgpsdata:N(ws),dgpsid:N(ys),extensions:Ts}); -function et(b,c){c||(c=[]);for(var d=0,e=c.length;d<e;++d){var f=c[d];if(b.a){var g=f.get("extensionsNode_")||null;b.a(f,g)}f.set("extensionsNode_",void 0)}}Os.prototype.Eh=function(b,c){if(!vb(Ps,b.namespaceURI))return null;var d=$s[b.localName];if(!d)return null;d=d(b,[Or(this,b,c)]);if(!d)return null;et(this,[d]);return d};Os.prototype.ic=function(b,c){if(!vb(Ps,b.namespaceURI))return[];if("gpx"==b.localName){var d=Q([],at,b,[Or(this,b,c)]);if(d)return et(this,d),d}return[]}; -function ft(b,c,d){b.setAttribute("href",c);c=d[d.length-1].properties;qp({node:b},gt,np,[c.linkText,c.linkType],d,ht)}function it(b,c,d){var e=d[d.length-1],f=e.node.namespaceURI,g=e.properties;ep(b,null,"lat",c[1]);ep(b,null,"lon",c[0]);switch(e.geometryLayout){case "XYZM":0!==c[3]&&(g.time=c[3]);case "XYZ":0!==c[2]&&(g.ele=c[2]);break;case "XYM":0!==c[2]&&(g.time=c[2])}c=jt[f];e=op(g,c);qp({node:b,properties:g},kt,np,e,d,c)} -var ht=["text","type"],gt=P(Ps,{text:O(Bs),type:O(Bs)}),lt=P(Ps,"name cmt desc src link number type rtept".split(" ")),mt=P(Ps,{name:O(Bs),cmt:O(Bs),desc:O(Bs),src:O(Bs),link:O(ft),number:O(Ds),type:O(Bs),rtept:kp(O(it))}),nt=P(Ps,"name cmt desc src link number type trkseg".split(" ")),qt=P(Ps,{name:O(Bs),cmt:O(Bs),desc:O(Bs),src:O(Bs),link:O(ft),number:O(Ds),type:O(Bs),trkseg:kp(O(function(b,c,d){qp({node:b,geometryLayout:c.b,properties:{}},ot,pt,c.Z(),d)}))}),pt=lp("trkpt"),ot=P(Ps,{trkpt:O(it)}), -jt=P(Ps,"ele time magvar geoidheight name cmt desc src link sym type fix sat hdop vdop pdop ageofdgpsdata dgpsid".split(" ")),kt=P(Ps,{ele:O(Cs),time:O(function(b,c){var d=new Date(1E3*c),d=d.getUTCFullYear()+"-"+Pa(d.getUTCMonth()+1)+"-"+Pa(d.getUTCDate())+"T"+Pa(d.getUTCHours())+":"+Pa(d.getUTCMinutes())+":"+Pa(d.getUTCSeconds())+"Z";b.appendChild(Io.createTextNode(d))}),magvar:O(Cs),geoidheight:O(Cs),name:O(Bs),cmt:O(Bs),desc:O(Bs),src:O(Bs),link:O(ft),sym:O(Bs),type:O(Bs),fix:O(Bs),sat:O(Ds), -hdop:O(Cs),vdop:O(Cs),pdop:O(Cs),ageofdgpsdata:O(Cs),dgpsid:O(Ds)}),rt={Point:"wpt",LineString:"rte",MultiLineString:"trk"};function st(b,c){var d=b.X();if(d&&(d=rt[d.W()]))return Lo(c[c.length-1].node.namespaceURI,d)} -var tt=P(Ps,{rte:O(function(b,c,d){var e=d[0],f=c.R();b={node:b,properties:f};if(c=c.X())c=Qr(c,!0,e),b.geometryLayout=c.b,f.rtept=c.Z();e=lt[d[d.length-1].node.namespaceURI];f=op(f,e);qp(b,mt,np,f,d,e)}),trk:O(function(b,c,d){var e=d[0],f=c.R();b={node:b,properties:f};if(c=c.X())c=Qr(c,!0,e),f.trkseg=c.sd();e=nt[d[d.length-1].node.namespaceURI];f=op(f,e);qp(b,qt,np,f,d,e)}),wpt:O(function(b,c,d){var e=d[0],f=d[d.length-1];f.properties=c.R();if(c=c.X())c=Qr(c,!0,e),f.geometryLayout=c.b,it(b,c.Z(), -d)})});Os.prototype.f=function(b,c){c=Pr(this,c);var d=Lo("http://www.topografix.com/GPX/1/1","gpx");qp({node:d},tt,st,b,[c]);return d};function ut(b){b=vt(b);return db(b,function(b){return b.b.substring(b.f,b.a)})}function wt(b,c,d){this.b=b;this.f=c;this.a=d}function vt(b){for(var c=RegExp("\r\n|\r|\n","g"),d=0,e,f=[];e=c.exec(b);)d=new wt(b,d,e.index),f.push(d),d=c.lastIndex;d<b.length&&(d=new wt(b,d,b.length),f.push(d));return f};function xt(){this.defaultDataProjection=null}y(xt,Nr);l=xt.prototype;l.W=function(){return"text"};l.Tb=function(b,c){return this.Dd(ia(b)?b:"",Pr(this,c))};l.Ba=function(b,c){return this.Lf(ia(b)?b:"",Pr(this,c))};l.Tc=function(b,c){return this.Fd(ia(b)?b:"",Pr(this,c))};l.Ia=function(){return this.defaultDataProjection};l.Kd=function(b,c){return this.Re(b,Pr(this,c))};l.Vb=function(b,c){return this.si(b,Pr(this,c))};l.Xc=function(b,c){return this.Ld(b,Pr(this,c))};function yt(b){b=b?b:{};this.defaultDataProjection=null;this.defaultDataProjection=Ee("EPSG:4326");this.a=b.altitudeMode?b.altitudeMode:"none"}y(yt,xt);var zt=/^B(\d{2})(\d{2})(\d{2})(\d{2})(\d{5})([NS])(\d{3})(\d{5})([EW])([AV])(\d{5})(\d{5})/,At=/^H.([A-Z]{3}).*?:(.*)/,Bt=/^HFDTE(\d{2})(\d{2})(\d{2})/; -yt.prototype.Dd=function(b,c){var d=this.a,e=ut(b),f={},g=[],h=2E3,k=0,m=1,n,p;n=0;for(p=e.length;n<p;++n){var q=e[n],r;if("B"==q.charAt(0)){if(r=zt.exec(q)){var q=parseInt(r[1],10),t=parseInt(r[2],10),x=parseInt(r[3],10),z=parseInt(r[4],10)+parseInt(r[5],10)/6E4;"S"==r[6]&&(z=-z);var A=parseInt(r[7],10)+parseInt(r[8],10)/6E4;"W"==r[9]&&(A=-A);g.push(A,z);"none"!=d&&g.push("gps"==d?parseInt(r[11],10):"barometric"==d?parseInt(r[12],10):0);g.push(Date.UTC(h,k,m,q,t,x)/1E3)}}else if("H"==q.charAt(0))if(r= -Bt.exec(q))m=parseInt(r[1],10),k=parseInt(r[2],10)-1,h=2E3+parseInt(r[3],10);else if(r=At.exec(q))f[r[1]]=r[2].trim(),Bt.exec(q)}if(0===g.length)return null;e=new T(null);e.ba("none"==d?"XYM":"XYZM",g);d=new pn(Qr(e,!1,c));d.I(f);return d};yt.prototype.Lf=function(b,c){var d=this.Dd(b,c);return d?[d]:[]};function Ct(b,c){this.f=this.j=this.c="";this.l=null;this.g=this.a="";this.i=!1;var d;b instanceof Ct?(this.i=ca(c)?c:b.i,Dt(this,b.c),this.j=b.j,this.f=b.f,Et(this,b.l),this.a=b.a,Ft(this,b.b.clone()),this.g=b.g):b&&(d=String(b).match(go))?(this.i=!!c,Dt(this,d[1]||"",!0),this.j=Gt(d[2]||""),this.f=Gt(d[3]||"",!0),Et(this,d[4]),this.a=Gt(d[5]||"",!0),Ft(this,d[6]||"",!0),this.g=Gt(d[7]||"")):(this.i=!!c,this.b=new Ht(null,0,this.i))} -Ct.prototype.toString=function(){var b=[],c=this.c;c&&b.push(It(c,Jt,!0),":");var d=this.f;if(d||"file"==c)b.push("//"),(c=this.j)&&b.push(It(c,Jt,!0),"@"),b.push(encodeURIComponent(String(d)).replace(/%25([0-9a-fA-F]{2})/g,"%$1")),d=this.l,null!=d&&b.push(":",String(d));if(d=this.a)this.f&&"/"!=d.charAt(0)&&b.push("/"),b.push(It(d,"/"==d.charAt(0)?Kt:Lt,!0));(d=this.b.toString())&&b.push("?",d);(d=this.g)&&b.push("#",It(d,Mt));return b.join("")};Ct.prototype.clone=function(){return new Ct(this)}; -function Dt(b,c,d){b.c=d?Gt(c,!0):c;b.c&&(b.c=b.c.replace(/:$/,""))}function Et(b,c){if(c){c=Number(c);if(isNaN(c)||0>c)throw Error("Bad port number "+c);b.l=c}else b.l=null}function Ft(b,c,d){c instanceof Ht?(b.b=c,Nt(b.b,b.i)):(d||(c=It(c,Ot)),b.b=new Ht(c,0,b.i))}function Pt(b){return b instanceof Ct?b.clone():new Ct(b,void 0)} -function Qt(b,c){b instanceof Ct||(b=Pt(b));c instanceof Ct||(c=Pt(c));var d=b,e=c,f=d.clone(),g=!!e.c;g?Dt(f,e.c):g=!!e.j;g?f.j=e.j:g=!!e.f;g?f.f=e.f:g=null!=e.l;var h=e.a;if(g)Et(f,e.l);else if(g=!!e.a)if("/"!=h.charAt(0)&&(d.f&&!d.a?h="/"+h:(d=f.a.lastIndexOf("/"),-1!=d&&(h=f.a.substr(0,d+1)+h))),d=h,".."==d||"."==d)h="";else if(-1!=d.indexOf("./")||-1!=d.indexOf("/.")){for(var h=0==d.lastIndexOf("/",0),d=d.split("/"),k=[],m=0;m<d.length;){var n=d[m++];"."==n?h&&m==d.length&&k.push(""):".."==n? -((1<k.length||1==k.length&&""!=k[0])&&k.pop(),h&&m==d.length&&k.push("")):(k.push(n),h=!0)}h=k.join("/")}else h=d;g?f.a=h:g=""!==e.b.toString();g?Ft(f,Gt(e.b.toString())):g=!!e.g;g&&(f.g=e.g);return f}function Gt(b,c){return b?c?decodeURI(b.replace(/%25/g,"%2525")):decodeURIComponent(b):""}function It(b,c,d){return ia(b)?(b=encodeURI(b).replace(c,Rt),d&&(b=b.replace(/%25([0-9a-fA-F]{2})/g,"%$1")),b):null}function Rt(b){b=b.charCodeAt(0);return"%"+(b>>4&15).toString(16)+(b&15).toString(16)} -var Jt=/[#\/\?@]/g,Lt=/[\#\?:]/g,Kt=/[\#\?]/g,Ot=/[\#\?@]/g,Mt=/#/g;function Ht(b,c,d){this.f=this.a=null;this.b=b||null;this.c=!!d}function St(b){b.a||(b.a=new pi,b.f=0,b.b&&ho(b.b,function(c,d){b.add(decodeURIComponent(c.replace(/\+/g," ")),d)}))}l=Ht.prototype;l.qc=function(){St(this);return this.f};l.add=function(b,c){St(this);this.b=null;b=Tt(this,b);var d=this.a.get(b);d||this.a.set(b,d=[]);d.push(c);this.f++;return this}; -l.remove=function(b){St(this);b=Tt(this,b);return ri(this.a.f,b)?(this.b=null,this.f-=this.a.get(b).length,this.a.remove(b)):!1};l.clear=function(){this.a=this.b=null;this.f=0};l.La=function(){St(this);return 0==this.f};function Ut(b,c){St(b);c=Tt(b,c);return ri(b.a.f,c)}l.P=function(){St(this);for(var b=this.a.sc(),c=this.a.P(),d=[],e=0;e<c.length;e++)for(var f=b[e],g=0;g<f.length;g++)d.push(c[e]);return d}; -l.sc=function(b){St(this);var c=[];if(ia(b))Ut(this,b)&&(c=ib(c,this.a.get(Tt(this,b))));else{b=this.a.sc();for(var d=0;d<b.length;d++)c=ib(c,b[d])}return c};l.set=function(b,c){St(this);this.b=null;b=Tt(this,b);Ut(this,b)&&(this.f-=this.a.get(b).length);this.a.set(b,[c]);this.f++;return this};l.get=function(b,c){var d=b?this.sc(b):[];return 0<d.length?String(d[0]):c};function Vt(b,c,d){b.remove(c);0<d.length&&(b.b=null,b.a.set(Tt(b,c),jb(d)),b.f+=d.length)} -l.toString=function(){if(this.b)return this.b;if(!this.a)return"";for(var b=[],c=this.a.P(),d=0;d<c.length;d++)for(var e=c[d],f=encodeURIComponent(String(e)),e=this.sc(e),g=0;g<e.length;g++){var h=f;""!==e[g]&&(h+="="+encodeURIComponent(String(e[g])));b.push(h)}return this.b=b.join("&")};l.clone=function(){var b=new Ht;b.b=this.b;this.a&&(b.a=this.a.clone(),b.f=this.f);return b};function Tt(b,c){var d=String(c);b.c&&(d=d.toLowerCase());return d} -function Nt(b,c){c&&!b.c&&(St(b),b.b=null,b.a.forEach(function(b,c){var f=c.toLowerCase();c!=f&&(this.remove(c),Vt(this,f,b))},b));b.c=c};function Wt(b){b=b||{};this.b=b.font;this.i=b.rotation;this.f=b.scale;this.G=b.text;this.l=b.textAlign;this.o=b.textBaseline;this.a=void 0!==b.fill?b.fill:new Tl({color:"#333"});this.j=void 0!==b.stroke?b.stroke:null;this.c=void 0!==b.offsetX?b.offsetX:0;this.g=void 0!==b.offsetY?b.offsetY:0}l=Wt.prototype;l.Nj=function(){return this.b};l.ak=function(){return this.c};l.bk=function(){return this.g};l.An=function(){return this.a};l.Bn=function(){return this.i};l.Cn=function(){return this.f};l.Dn=function(){return this.j}; -l.Ca=function(){return this.G};l.nk=function(){return this.l};l.pk=function(){return this.o};l.Lo=function(b){this.b=b};l.ci=function(b){this.c=b};l.di=function(b){this.g=b};l.Ko=function(b){this.a=b};l.En=function(b){this.i=b};l.Fn=function(b){this.f=b};l.Ro=function(b){this.j=b};l.fi=function(b){this.G=b};l.gi=function(b){this.l=b};l.So=function(b){this.o=b};function Xt(b){b=b?b:{};this.defaultDataProjection=null;this.defaultDataProjection=Ee("EPSG:4326");this.b=b.defaultStyle?b.defaultStyle:Yt;this.c=void 0!==b.extractStyles?b.extractStyles:!0;this.i=void 0!==b.writeStyles?b.writeStyles:!0;this.a={};this.g=void 0!==b.showPointNames?b.showPointNames:!0}y(Xt,ps); -var Zt=["http://www.google.com/kml/ext/2.2"],$t=[null,"http://earth.google.com/kml/2.0","http://earth.google.com/kml/2.1","http://earth.google.com/kml/2.2","http://www.opengis.net/kml/2.2"],au=[255,255,255,1],bu=new Tl({color:au}),cu=[20,2],du=[64,64],eu=new tk({anchor:cu,anchorOrigin:"bottom-left",anchorXUnits:"pixels",anchorYUnits:"pixels",crossOrigin:"anonymous",rotation:0,scale:.5,size:du,src:"https://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png"}),fu=new Yl({color:au,width:1}),gu=new Wt({font:"bold 16px Helvetica", -fill:bu,stroke:new Yl({color:[51,51,51,1],width:2}),scale:.8}),Yt=[new $l({fill:bu,image:eu,text:gu,stroke:fu,zIndex:0})],hu={fraction:"fraction",pixels:"pixels"};function iu(b,c){var d=null,e=[0,0],f="start";b.f&&(d=b.f.rd())&&2==d.length&&(e[0]=b.f.j*d[0]/2,e[1]=-b.f.j*d[1]/2,f="left");Pb(b.Ca())?d=new Wt({text:c,offsetX:e[0],offsetY:e[1],textAlign:f}):(d=Tb(b.Ca()),d.fi(c),d.gi(f),d.ci(e[0]),d.di(e[1]));return new $l({text:d})} -function ju(b,c,d,e,f){return function(){var g=f,h="";g&&this.X()&&(g="Point"===this.X().W());g&&(h=this.R().name,g=g&&h);if(b)return g?(g=iu(b[0],h),b.concat(g)):b;if(c){var k=ku(c,d,e);return g?(g=iu(k[0],h),k.concat(g)):k}return g?(g=iu(d[0],h),d.concat(g)):d}}function ku(b,c,d){return ga(b)?b:ia(b)?(!(b in d)&&"#"+b in d&&(b="#"+b),ku(d[b],c,d)):c} -function lu(b){b=Mo(b,!1);if(b=/^\s*#?\s*([0-9A-Fa-f]{8})\s*$/.exec(b))return b=b[1],[parseInt(b.substr(6,2),16),parseInt(b.substr(4,2),16),parseInt(b.substr(2,2),16),parseInt(b.substr(0,2),16)/255]}function mu(b){b=Mo(b,!1);for(var c=[],d=/^\s*([+\-]?\d*\.?\d+(?:e[+\-]?\d+)?)\s*,\s*([+\-]?\d*\.?\d+(?:e[+\-]?\d+)?)(?:\s*,\s*([+\-]?\d*\.?\d+(?:e[+\-]?\d+)?))?\s*/i,e;e=d.exec(b);)c.push(parseFloat(e[1]),parseFloat(e[2]),e[3]?parseFloat(e[3]):0),b=b.substr(e[0].length);return""!==b?void 0:c} -function nu(b){var c=Mo(b,!1);return b.baseURI?Qt(b.baseURI,c.trim()).toString():c.trim()}function ou(b){b=ws(b);if(void 0!==b)return Math.sqrt(b)}function pu(b,c){return Q(null,qu,b,c)}function ru(b,c){var d=Q({A:[],oi:[]},su,b,c);if(d){var e=d.A,d=d.oi,f,g;f=0;for(g=Math.min(e.length,d.length);f<g;++f)e[4*f+3]=d[f];d=new T(null);d.ba("XYZM",e);return d}}function tu(b,c){var d=Q({},uu,b,c),e=Q(null,vu,b,c);if(e){var f=new T(null);f.ba("XYZ",e);f.I(d);return f}} -function wu(b,c){var d=Q({},uu,b,c),e=Q(null,vu,b,c);if(e){var f=new F(null);f.ba("XYZ",e,[e.length]);f.I(d);return f}} -function xu(b,c){var d=Q([],yu,b,c);if(!d)return null;if(0===d.length)return new gs(d);var e=!0,f=d[0].W(),g,h,k;h=1;for(k=d.length;h<k;++h)if(g=d[h],g.W()!=f){e=!1;break}if(e){if("Point"==f){g=d[0];e=g.b;f=g.ia();h=1;for(k=d.length;h<k;++h)g=d[h],kb(f,g.ia());g=new Xr(null);g.ba(e,f);zu(g,d);return g}return"LineString"==f?(g=new U(null),Wr(g,d),zu(g,d),g):"Polygon"==f?(g=new V(null),Zr(g,d),zu(g,d),g):"GeometryCollection"==f?new gs(d):null}return new gs(d)} -function Au(b,c){var d=Q({},uu,b,c),e=Q(null,vu,b,c);if(e){var f=new E(null);f.ba("XYZ",e);f.I(d);return f}}function Bu(b,c){var d=Q({},uu,b,c),e=Q([null],Cu,b,c);if(e&&e[0]){var f=new F(null),g=e[0],h=[g.length],k,m;k=1;for(m=e.length;k<m;++k)kb(g,e[k]),h.push(g.length);f.ba("XYZ",g,h);f.I(d);return f}} -function Du(b,c){var d=Q({},Eu,b,c);if(!d)return null;var e="fillStyle"in d?d.fillStyle:bu,f=d.fill;void 0===f||f||(e=null);var f="imageStyle"in d?d.imageStyle:eu,g="textStyle"in d?d.textStyle:gu,h="strokeStyle"in d?d.strokeStyle:fu,d=d.outline;void 0===d||d||(h=null);return[new $l({fill:e,image:f,stroke:h,text:g,zIndex:void 0})]} -function zu(b,c){var d=c.length,e=Array(c.length),f=Array(c.length),g,h,k,m;k=m=!1;for(h=0;h<d;++h)g=c[h],e[h]=g.get("extrude"),f[h]=g.get("altitudeMode"),k=k||void 0!==e[h],m=m||f[h];k&&b.set("extrude",e);m&&b.set("altitudeMode",f)}function Fu(b,c){pp(Gu,b,c)} -var Hu=P($t,{value:ip(W)}),Gu=P($t,{Data:function(b,c){var d=b.getAttribute("name");if(null!==d){var e=Q(void 0,Hu,b,c);e&&(c[c.length-1][d]=e)}},SchemaData:function(b,c){pp(Iu,b,c)}}),uu=P($t,{extrude:N(ts),altitudeMode:N(W)}),qu=P($t,{coordinates:ip(mu)}),Cu=P($t,{innerBoundaryIs:function(b,c){var d=Q(void 0,Ju,b,c);d&&c[c.length-1].push(d)},outerBoundaryIs:function(b,c){var d=Q(void 0,Ku,b,c);d&&(c[c.length-1][0]=d)}}),su=P($t,{when:function(b,c){var d=c[c.length-1].oi,e=Mo(b,!1);if(e=/^\s*(\d{4})($|-(\d{2})($|-(\d{2})($|T(\d{2}):(\d{2}):(\d{2})(Z|(?:([+\-])(\d{2})(?::(\d{2}))?)))))\s*$/.exec(e)){var f= -Date.UTC(parseInt(e[1],10),e[3]?parseInt(e[3],10)-1:0,e[5]?parseInt(e[5],10):1,e[7]?parseInt(e[7],10):0,e[8]?parseInt(e[8],10):0,e[9]?parseInt(e[9],10):0);if(e[10]&&"Z"!=e[10]){var g="-"==e[11]?-1:1,f=f+60*g*parseInt(e[12],10);e[13]&&(f+=3600*g*parseInt(e[13],10))}d.push(f)}else d.push(0)}},P(Zt,{coord:function(b,c){var d=c[c.length-1].A,e=Mo(b,!1);(e=/^\s*([+\-]?\d+(?:\.\d*)?(?:e[+\-]?\d*)?)\s+([+\-]?\d+(?:\.\d*)?(?:e[+\-]?\d*)?)\s+([+\-]?\d+(?:\.\d*)?(?:e[+\-]?\d*)?)\s*$/i.exec(e))?d.push(parseFloat(e[1]), -parseFloat(e[2]),parseFloat(e[3]),0):d.push(0,0,0,0)}})),vu=P($t,{coordinates:ip(mu)}),Lu=P($t,{href:N(nu)},P(Zt,{x:N(ws),y:N(ws),w:N(ws),h:N(ws)})),Mu=P($t,{Icon:N(function(b,c){var d=Q({},Lu,b,c);return d?d:null}),heading:N(ws),hotSpot:N(function(b){var c=b.getAttribute("xunits"),d=b.getAttribute("yunits");return{x:parseFloat(b.getAttribute("x")),$f:hu[c],y:parseFloat(b.getAttribute("y")),ag:hu[d]}}),scale:N(ou)}),Ju=P($t,{LinearRing:ip(pu)}),Nu=P($t,{color:N(lu),scale:N(ou)}),Ou=P($t,{color:N(lu), -width:N(ws)}),yu=P($t,{LineString:hp(tu),LinearRing:hp(wu),MultiGeometry:hp(xu),Point:hp(Au),Polygon:hp(Bu)}),Pu=P(Zt,{Track:hp(ru)}),Ru=P($t,{ExtendedData:Fu,Link:function(b,c){pp(Qu,b,c)},address:N(W),description:N(W),name:N(W),open:N(ts),phoneNumber:N(W),visibility:N(ts)}),Qu=P($t,{href:N(nu)}),Ku=P($t,{LinearRing:ip(pu)}),Su=P($t,{Style:N(Du),key:N(W),styleUrl:N(function(b){var c=Mo(b,!1).trim();return b.baseURI?Qt(b.baseURI,c).toString():c})}),Uu=P($t,{ExtendedData:Fu,MultiGeometry:N(xu,"geometry"), -LineString:N(tu,"geometry"),LinearRing:N(wu,"geometry"),Point:N(Au,"geometry"),Polygon:N(Bu,"geometry"),Style:N(Du),StyleMap:function(b,c){var d=Q(void 0,Tu,b,c);if(d){var e=c[c.length-1];ga(d)?e.Style=d:ia(d)&&(e.styleUrl=d)}},address:N(W),description:N(W),name:N(W),open:N(ts),phoneNumber:N(W),styleUrl:N(nu),visibility:N(ts)},P(Zt,{MultiTrack:N(function(b,c){var d=Q([],Pu,b,c);if(d){var e=new U(null);Wr(e,d);return e}},"geometry"),Track:N(ru,"geometry")})),Vu=P($t,{color:N(lu),fill:N(ts),outline:N(ts)}), -Iu=P($t,{SimpleData:function(b,c){var d=b.getAttribute("name");if(null!==d){var e=W(b);c[c.length-1][d]=e}}}),Eu=P($t,{IconStyle:function(b,c){var d=Q({},Mu,b,c);if(d){var e=c[c.length-1],f="Icon"in d?d.Icon:{},g;g=(g=f.href)?g:"https://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png";var h,k,m,n=d.hotSpot;n?(h=[n.x,n.y],k=n.$f,m=n.ag):"https://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png"===g?(h=cu,m=k="pixels"):/^http:\/\/maps\.(?:google|gstatic)\.com\//.test(g)&&(h=[.5,0],m=k="fraction"); -var p,n=f.x,q=f.y;void 0!==n&&void 0!==q&&(p=[n,q]);var r,n=f.w,f=f.h;void 0!==n&&void 0!==f&&(r=[n,f]);var t,f=d.heading;void 0!==f&&(t=Xa(f));d=d.scale;"https://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png"==g&&(r=du,void 0===d&&(d=.5));h=new tk({anchor:h,anchorOrigin:"bottom-left",anchorXUnits:k,anchorYUnits:m,crossOrigin:"anonymous",offset:p,offsetOrigin:"bottom-left",rotation:t,scale:d,size:r,src:g});e.imageStyle=h}},LabelStyle:function(b,c){var d=Q({},Nu,b,c);d&&(c[c.length-1].textStyle= -new Wt({fill:new Tl({color:"color"in d?d.color:au}),scale:d.scale}))},LineStyle:function(b,c){var d=Q({},Ou,b,c);d&&(c[c.length-1].strokeStyle=new Yl({color:"color"in d?d.color:au,width:"width"in d?d.width:1}))},PolyStyle:function(b,c){var d=Q({},Vu,b,c);if(d){var e=c[c.length-1];e.fillStyle=new Tl({color:"color"in d?d.color:au});var f=d.fill;void 0!==f&&(e.fill=f);d=d.outline;void 0!==d&&(e.outline=d)}}}),Tu=P($t,{Pair:function(b,c){var d=Q({},Su,b,c);if(d){var e=d.key;e&&"normal"==e&&((e=d.styleUrl)&& -(c[c.length-1]=e),(d=d.Style)&&(c[c.length-1]=d))}}});l=Xt.prototype;l.Hf=function(b,c){Qo(b);var d=P($t,{Document:gp(this.Hf,this),Folder:gp(this.Hf,this),Placemark:hp(this.Pf,this),Style:ua(this.vo,this),StyleMap:ua(this.uo,this)});if(d=Q([],d,b,c,this))return d}; -l.Pf=function(b,c){var d=Q({geometry:null},Uu,b,c);if(d){var e=new pn,f=b.getAttribute("id");null!==f&&e.jc(f);var f=c[0],g=d.geometry;g&&Qr(g,!1,f);e.Ma(g);delete d.geometry;this.c&&e.wf(ju(d.Style,d.styleUrl,this.b,this.a,this.g));delete d.Style;e.I(d);return e}};l.vo=function(b,c){var d=b.getAttribute("id");if(null!==d){var e=Du(b,c);e&&(d=b.baseURI?Qt(b.baseURI,"#"+d).toString():"#"+d,this.a[d]=e)}}; -l.uo=function(b,c){var d=b.getAttribute("id");if(null!==d){var e=Q(void 0,Tu,b,c);e&&(d=b.baseURI?Qt(b.baseURI,"#"+d).toString():"#"+d,this.a[d]=e)}};l.Eh=function(b,c){if(!vb($t,b.namespaceURI))return null;var d=this.Pf(b,[Or(this,b,c)]);return d?d:null}; -l.ic=function(b,c){if(!vb($t,b.namespaceURI))return[];var d;d=Qo(b);if("Document"==d||"Folder"==d)return(d=this.Hf(b,[Or(this,b,c)]))?d:[];if("Placemark"==d)return(d=this.Pf(b,[Or(this,b,c)]))?[d]:[];if("kml"==d){d=[];var e;for(e=b.firstElementChild;e;e=e.nextElementSibling){var f=this.ic(e,c);f&&kb(d,f)}return d}return[]};l.po=function(b){if(To(b))return Wu(this,b);if(Wo(b))return Xu(this,b);if(ia(b))return b=fp(b),Wu(this,b)}; -function Wu(b,c){var d;for(d=c.firstChild;d;d=d.nextSibling)if(1==d.nodeType){var e=Xu(b,d);if(e)return e}}function Xu(b,c){var d;for(d=c.firstElementChild;d;d=d.nextElementSibling)if(vb($t,d.namespaceURI)&&"name"==d.localName)return W(d);for(d=c.firstElementChild;d;d=d.nextElementSibling){var e=Qo(d);if(vb($t,d.namespaceURI)&&("Document"==e||"Folder"==e||"Placemark"==e||"kml"==e)&&(e=Xu(b,d)))return e}} -l.qo=function(b){var c=[];To(b)?kb(c,Yu(this,b)):Wo(b)?kb(c,Zu(this,b)):ia(b)&&(b=fp(b),kb(c,Yu(this,b)));return c};function Yu(b,c){var d,e=[];for(d=c.firstChild;d;d=d.nextSibling)1==d.nodeType&&kb(e,Zu(b,d));return e} -function Zu(b,c){var d,e=[];for(d=c.firstElementChild;d;d=d.nextElementSibling)if(vb($t,d.namespaceURI)&&"NetworkLink"==d.localName){var f=Q({},Ru,d,[]);e.push(f)}for(d=c.firstElementChild;d;d=d.nextElementSibling)f=Qo(d),!vb($t,d.namespaceURI)||"Document"!=f&&"Folder"!=f&&"kml"!=f||kb(e,Zu(b,d));return e}function $u(b,c){var d=tg(c),d=[255*(4==d.length?d[3]:1),d[2],d[1],d[0]],e;for(e=0;4>e;++e){var f=parseInt(d[e],10).toString(16);d[e]=1==f.length?"0"+f:f}Bs(b,d.join(""))} -function av(b,c,d){qp({node:b},bv,cv,[c],d)}function dv(b,c,d){var e={node:b};c.Oa()&&b.setAttribute("id",c.Oa());b=c.R();var f=c.ac();if(f&&(f=f.call(c,0))&&0<f.length){var g=f[0];this.i&&(b.Style=f[0]);(f=g.Ca())&&(b.name=f.Ca())}f=ev[d[d.length-1].node.namespaceURI];b=op(b,f);qp(e,fv,np,b,d,f);b=d[0];(c=c.X())&&(c=Qr(c,!0,b));qp(e,fv,gv,[c],d)}function hv(b,c,d){var e=c.ia();b={node:b};b.layout=c.b;b.stride=c.ra();qp(b,iv,jv,[e],d)} -function kv(b,c,d){c=c.be();var e=c.shift();b={node:b};qp(b,lv,mv,c,d);qp(b,lv,nv,[e],d)}function ov(b,c){Cs(b,c*c)} -var pv=P($t,["Document","Placemark"]),sv=P($t,{Document:O(function(b,c,d){qp({node:b},qv,rv,c,d,void 0,this)}),Placemark:O(dv)}),qv=P($t,{Placemark:O(dv)}),tv={Point:"Point",LineString:"LineString",LinearRing:"LinearRing",Polygon:"Polygon",MultiPoint:"MultiGeometry",MultiLineString:"MultiGeometry",MultiPolygon:"MultiGeometry"},uv=P($t,["href"],P(Zt,["x","y","w","h"])),vv=P($t,{href:O(Bs)},P(Zt,{x:O(Cs),y:O(Cs),w:O(Cs),h:O(Cs)})),wv=P($t,["scale","heading","Icon","hotSpot"]),yv=P($t,{Icon:O(function(b, -c,d){b={node:b};var e=uv[d[d.length-1].node.namespaceURI],f=op(c,e);qp(b,vv,np,f,d,e);e=uv[Zt[0]];f=op(c,e);qp(b,vv,xv,f,d,e)}),heading:O(Cs),hotSpot:O(function(b,c){b.setAttribute("x",c.x);b.setAttribute("y",c.y);b.setAttribute("xunits",c.$f);b.setAttribute("yunits",c.ag)}),scale:O(ov)}),zv=P($t,["color","scale"]),Av=P($t,{color:O($u),scale:O(ov)}),Bv=P($t,["color","width"]),Cv=P($t,{color:O($u),width:O(Cs)}),bv=P($t,{LinearRing:O(hv)}),Dv=P($t,{LineString:O(hv),Point:O(hv),Polygon:O(kv)}),ev=P($t, -"name open visibility address phoneNumber description styleUrl Style".split(" ")),fv=P($t,{MultiGeometry:O(function(b,c,d){b={node:b};var e=c.W(),f,g;"MultiPoint"==e?(f=c.ve(),g=Ev):"MultiLineString"==e?(f=c.sd(),g=Fv):"MultiPolygon"==e&&(f=c.ce(),g=Gv);qp(b,Dv,g,f,d)}),LineString:O(hv),LinearRing:O(hv),Point:O(hv),Polygon:O(kv),Style:O(function(b,c,d){b={node:b};var e={},f=c.g,g=c.b,h=c.f;c=c.Ca();h instanceof tk&&(e.IconStyle=h);c&&(e.LabelStyle=c);g&&(e.LineStyle=g);f&&(e.PolyStyle=f);c=Hv[d[d.length- -1].node.namespaceURI];e=op(e,c);qp(b,Iv,np,e,d,c)}),address:O(Bs),description:O(Bs),name:O(Bs),open:O(As),phoneNumber:O(Bs),styleUrl:O(Bs),visibility:O(As)}),iv=P($t,{coordinates:O(function(b,c,d){d=d[d.length-1];var e=d.layout;d=d.stride;var f;"XY"==e||"XYM"==e?f=2:("XYZ"==e||"XYZM"==e)&&(f=3);var g,h=c.length,k="";if(0<h){k+=c[0];for(e=1;e<f;++e)k+=","+c[e];for(g=d;g<h;g+=d)for(k+=" "+c[g],e=1;e<f;++e)k+=","+c[g+e]}Bs(b,k)})}),lv=P($t,{outerBoundaryIs:O(av),innerBoundaryIs:O(av)}),Jv=P($t,{color:O($u)}), -Hv=P($t,["IconStyle","LabelStyle","LineStyle","PolyStyle"]),Iv=P($t,{IconStyle:O(function(b,c,d){b={node:b};var e={},f=c.Cb(),g=c.rd(),h={href:c.a.i};if(f){h.w=f[0];h.h=f[1];var k=c.Xb(),m=c.Da();m&&g&&0!==m[0]&&m[1]!==f[1]&&(h.x=m[0],h.y=g[1]-(m[1]+f[1]));k&&0!==k[0]&&k[1]!==f[1]&&(e.hotSpot={x:k[0],$f:"pixels",y:f[1]-k[1],ag:"pixels"})}e.Icon=h;f=c.j;1!==f&&(e.scale=f);c=c.G;0!==c&&(e.heading=c);c=wv[d[d.length-1].node.namespaceURI];e=op(e,c);qp(b,yv,np,e,d,c)}),LabelStyle:O(function(b,c,d){b={node:b}; -var e={},f=c.a;f&&(e.color=f.a);(c=c.f)&&1!==c&&(e.scale=c);c=zv[d[d.length-1].node.namespaceURI];e=op(e,c);qp(b,Av,np,e,d,c)}),LineStyle:O(function(b,c,d){b={node:b};var e=Bv[d[d.length-1].node.namespaceURI];c=op({color:c.a,width:c.f},e);qp(b,Cv,np,c,d,e)}),PolyStyle:O(function(b,c,d){qp({node:b},Jv,Kv,[c.a],d)})});function xv(b,c,d){return Lo(Zt[0],"gx:"+d)}function rv(b,c){return Lo(c[c.length-1].node.namespaceURI,"Placemark")} -function gv(b,c){if(b)return Lo(c[c.length-1].node.namespaceURI,tv[b.W()])}var Kv=lp("color"),jv=lp("coordinates"),mv=lp("innerBoundaryIs"),Ev=lp("Point"),Fv=lp("LineString"),cv=lp("LinearRing"),Gv=lp("Polygon"),nv=lp("outerBoundaryIs"); -Xt.prototype.f=function(b,c){c=Pr(this,c);var d=Lo($t[4],"kml");ep(d,"http://www.w3.org/2000/xmlns/","xmlns:gx",Zt[0]);ep(d,"http://www.w3.org/2000/xmlns/","xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance");ep(d,"http://www.w3.org/2001/XMLSchema-instance","xsi:schemaLocation","http://www.opengis.net/kml/2.2 https://developers.google.com/kml/schema/kml22gx.xsd");var e={node:d},f={};1<b.length?f.Document=b:1==b.length&&(f.Placemark=b[0]);var g=pv[d.namespaceURI],f=op(f,g);qp(e,sv,np,f,[c],g,this); -return d};(function(){var b={},c={ja:b};(function(d){if("object"===typeof b&&"undefined"!==typeof c)c.ja=d();else{var e;"undefined"!==typeof window?e=window:"undefined"!==typeof global?e=global:"undefined"!==typeof self?e=self:e=this;e.Ap=d()}})(function(){return function e(b,c,h){function k(n,q){if(!c[n]){if(!b[n]){var r="function"==typeof require&&require;if(!q&&r)return r(n,!0);if(m)return m(n,!0);r=Error("Cannot find module '"+n+"'");throw r.code="MODULE_NOT_FOUND",r;}r=c[n]={ja:{}};b[n][0].call(r.ja,function(c){var e= -b[n][1][c];return k(e?e:c)},r,r.ja,e,b,c,h)}return c[n].ja}for(var m="function"==typeof require&&require,n=0;n<h.length;n++)k(h[n]);return k}({1:[function(b,c){function g(b){var c;b&&b.length&&(c=b,b=c.length);b=new Uint8Array(b||0);c&&b.set(c);b.Ph=m.Ph;b.Zf=m.Zf;b.Hh=m.Hh;b.ui=m.ui;b.Of=m.Of;b.ti=m.ti;b.If=m.If;b.pi=m.pi;b.toString=m.toString;b.write=m.write;b.slice=m.slice;b.pg=m.pg;b.dj=!0;return b}function h(b){for(var c=b.length,e=[],f=0,g,h;f<c;f++){g=b.charCodeAt(f);if(55295<g&&57344>g)if(h)if(56320> -g){e.push(239,191,189);h=g;continue}else g=h-55296<<10|g-56320|65536,h=null;else{56319<g||f+1===c?e.push(239,191,189):h=g;continue}else h&&(e.push(239,191,189),h=null);128>g?e.push(g):2048>g?e.push(g>>6|192,g&63|128):65536>g?e.push(g>>12|224,g>>6&63|128,g&63|128):e.push(g>>18|240,g>>12&63|128,g>>6&63|128,g&63|128)}return e}c.ja=g;var k=b("ieee754"),m,n,p;m={Ph:function(b){return(this[b]|this[b+1]<<8|this[b+2]<<16)+16777216*this[b+3]},Zf:function(b,c){this[c]=b;this[c+1]=b>>>8;this[c+2]=b>>>16;this[c+ -3]=b>>>24},Hh:function(b){return(this[b]|this[b+1]<<8|this[b+2]<<16)+(this[b+3]<<24)},Of:function(b){return k.read(this,b,!0,23,4)},If:function(b){return k.read(this,b,!0,52,8)},ti:function(b,c){return k.write(this,b,c,!0,23,4)},pi:function(b,c){return k.write(this,b,c,!0,52,8)},toString:function(b,c,e){var f=b="";e=Math.min(this.length,e||this.length);for(c=c||0;c<e;c++){var g=this[c];127>=g?(b+=decodeURIComponent(f)+String.fromCharCode(g),f=""):f+="%"+g.toString(16)}return b+=decodeURIComponent(f)}, -write:function(b,c){for(var e=b===n?p:h(b),f=0;f<e.length;f++)this[c+f]=e[f]},slice:function(b,c){return this.subarray(b,c)},pg:function(b,c){c=c||0;for(var e=0;e<this.length;e++)b[c+e]=this[e]}};m.ui=m.Zf;g.byteLength=function(b){n=b;p=h(b);return p.length};g.isBuffer=function(b){return!(!b||!b.dj)}},{ieee754:3}],2:[function(b,c){(function(g){function h(b){this.Fb=k.isBuffer(b)?b:new k(b||0);this.da=0;this.length=this.Fb.length}c.ja=h;var k=g.ip||b("./buffer");h.c=0;h.b=1;h.a=2;h.f=5;var m=Math.pow(2, -63);h.prototype={Mf:function(b,c,e){for(e=e||this.length;this.da<e;){var f=this.za(),g=this.da;b(f>>3,c,this);this.da===g&&this.Xo(f)}return c},lo:function(){var b=this.Fb.Of(this.da);this.da+=4;return b},ho:function(){var b=this.Fb.If(this.da);this.da+=8;return b},za:function(){var b=this.Fb,c,e,f,g,h;c=b[this.da++];if(128>c)return c;c=c&127;f=b[this.da++];if(128>f)return c|f<<7;f=(f&127)<<7;g=b[this.da++];if(128>g)return c|f|g<<14;g=(g&127)<<14;h=b[this.da++];if(128>h)return c|f|g|h<<21;e=b[this.da++]; -c=(c|f|g|(h&127)<<21)+268435456*(e&127);if(128>e)return c;e=b[this.da++];c+=34359738368*(e&127);if(128>e)return c;e=b[this.da++];c+=4398046511104*(e&127);if(128>e)return c;e=b[this.da++];c+=562949953421312*(e&127);if(128>e)return c;e=b[this.da++];c+=72057594037927936*(e&127);if(128>e)return c;e=b[this.da++];c+=0x7fffffffffffffff*(e&127);if(128>e)return c;throw Error("Expected varint not more than 10 bytes");},wo:function(){var b=this.da,c=this.za();if(c<m)return c;for(var e=this.da-2;255===this.Fb[e];)e--; -e<b&&(e=b);for(var f=c=0;f<e-b+1;f++)var g=~this.Fb[b+f]&127,c=c+(4>f?g<<7*f:g*Math.pow(2,7*f));return-c-1},Gd:function(){var b=this.za();return 1===b%2?(b+1)/-2:b/2},eo:function(){return Boolean(this.za())},Rf:function(){var b=this.za()+this.da,c=this.Fb.toString("utf8",this.da,b);this.da=b;return c},Xo:function(b){b=b&7;if(b===h.c)for(;127<this.Fb[this.da++];);else if(b===h.a)this.da=this.za()+this.da;else if(b===h.f)this.da+=4;else if(b===h.b)this.da+=8;else throw Error("Unimplemented type: "+ -b);}}}).call(this,"undefined"!==typeof global?global:"undefined"!==typeof self?self:"undefined"!==typeof window?window:{})},{"./buffer":1}],3:[function(b,c,g){g.read=function(b,c,e,f,g){var q;q=8*g-f-1;var r=(1<<q)-1,t=r>>1,x=-7;g=e?g-1:0;var z=e?-1:1,A=b[c+g];g+=z;e=A&(1<<-x)-1;A>>=-x;for(x+=q;0<x;e=256*e+b[c+g],g+=z,x-=8);q=e&(1<<-x)-1;e>>=-x;for(x+=f;0<x;q=256*q+b[c+g],g+=z,x-=8);if(0===e)e=1-t;else{if(e===r)return q?NaN:Infinity*(A?-1:1);q+=Math.pow(2,f);e=e-t}return(A?-1:1)*q*Math.pow(2,e-f)}; -g.write=function(b,c,e,f,g,q){var r,t=8*q-g-1,x=(1<<t)-1,z=x>>1,A=23===g?Math.pow(2,-24)-Math.pow(2,-77):0;q=f?0:q-1;var B=f?1:-1,v=0>c||0===c&&0>1/c?1:0;c=Math.abs(c);isNaN(c)||Infinity===c?(c=isNaN(c)?1:0,f=x):(f=Math.floor(Math.log(c)/Math.LN2),1>c*(r=Math.pow(2,-f))&&(f--,r*=2),c=1<=f+z?c+A/r:c+A*Math.pow(2,1-z),2<=c*r&&(f++,r/=2),f+z>=x?(c=0,f=x):1<=f+z?(c=(c*r-1)*Math.pow(2,g),f+=z):(c=c*Math.pow(2,z-1)*Math.pow(2,g),f=0));for(;8<=g;b[e+q]=c&255,q+=B,c/=256,g-=8);f=f<<g|c;for(t+=g;0<t;b[e+q]= -f&255,q+=B,f/=256,t-=8);b[e+q-B]|=128*v}},{}]},{},[2])(2)});wp=c.ja})();(function(){var b={},c={ja:b};(function(d){if("object"===typeof b&&"undefined"!==typeof c)c.ja=d();else{var e;"undefined"!==typeof window?e=window:"undefined"!==typeof global?e=global:"undefined"!==typeof self?e=self:e=this;e.Cp=d()}})(function(){return function e(b,c,h){function k(n,q){if(!c[n]){if(!b[n]){var r="function"==typeof require&&require;if(!q&&r)return r(n,!0);if(m)return m(n,!0);r=Error("Cannot find module '"+n+"'");throw r.code="MODULE_NOT_FOUND",r;}r=c[n]={ja:{}};b[n][0].call(r.ja,function(c){var e= -b[n][1][c];return k(e?e:c)},r,r.ja,e,b,c,h)}return c[n].ja}for(var m="function"==typeof require&&require,n=0;n<h.length;n++)k(h[n]);return k}({1:[function(b,c){c.ja.Vi=b("./lib/vectortile.js");c.ja.vp=b("./lib/vectortilefeature.js");c.ja.wp=b("./lib/vectortilelayer.js")},{"./lib/vectortile.js":2,"./lib/vectortilefeature.js":3,"./lib/vectortilelayer.js":4}],2:[function(b,c){function g(b,c,e){3===b&&(b=new h(e,e.za()+e.da),b.length&&(c[b.name]=b))}var h=b("./vectortilelayer");c.ja=function(b,c){this.layers= -b.Mf(g,{},c)}},{"./vectortilelayer":4}],3:[function(b,c){function g(b,c,e,f,g){this.properties={};this.extent=e;this.type=0;this.oc=b;this.Ze=-1;this.Qd=f;this.Sd=g;b.Mf(h,this,c)}function h(b,c,e){if(1==b)c.yp=e.za();else if(2==b)for(b=e.za()+e.da;e.da<b;){var f=c.Qd[e.za()],g=c.Sd[e.za()];c.properties[f]=g}else 3==b?c.type=e.za():4==b&&(c.Ze=e.da)}var k=b("point-geometry");c.ja=g;g.types=["Unknown","Point","LineString","Polygon"];g.prototype.Rg=function(){var b=this.oc;b.da=this.Ze;for(var c=b.za()+ -b.da,e=1,f=0,g=0,h=0,x=[],z;b.da<c;)if(f||(f=b.za(),e=f&7,f=f>>3),f--,1===e||2===e)g+=b.Gd(),h+=b.Gd(),1===e&&(z&&x.push(z),z=[]),z.push(new k(g,h));else if(7===e)z&&z.push(z[0].clone());else throw Error("unknown command "+e);z&&x.push(z);return x};g.prototype.bbox=function(){var b=this.oc;b.da=this.Ze;for(var c=b.za()+b.da,e=1,f=0,g=0,h=0,k=Infinity,z=-Infinity,A=Infinity,B=-Infinity;b.da<c;)if(f||(f=b.za(),e=f&7,f=f>>3),f--,1===e||2===e)g+=b.Gd(),h+=b.Gd(),g<k&&(k=g),g>z&&(z=g),h<A&&(A=h),h>B&& -(B=h);else if(7!==e)throw Error("unknown command "+e);return[k,A,z,B]}},{"point-geometry":5}],4:[function(b,c){function g(b,c){this.version=1;this.name=null;this.extent=4096;this.length=0;this.oc=b;this.Qd=[];this.Sd=[];this.Pd=[];b.Mf(h,this,c);this.length=this.Pd.length}function h(b,c,e){15===b?c.version=e.za():1===b?c.name=e.Rf():5===b?c.extent=e.za():2===b?c.Pd.push(e.da):3===b?c.Qd.push(e.Rf()):4===b&&c.Sd.push(k(e))}function k(b){for(var c=null,e=b.za()+b.da;b.da<e;)c=b.za()>>3,c=1===c?b.Rf(): -2===c?b.lo():3===c?b.ho():4===c?b.wo():5===c?b.za():6===c?b.Gd():7===c?b.eo():null;return c}var m=b("./vectortilefeature.js");c.ja=g;g.prototype.feature=function(b){if(0>b||b>=this.Pd.length)throw Error("feature index out of bounds");this.oc.da=this.Pd[b];b=this.oc.za()+this.oc.da;return new m(this.oc,b,this.extent,this.Qd,this.Sd)}},{"./vectortilefeature.js":3}],5:[function(b,c){function g(b,c){this.x=b;this.y=c}c.ja=g;g.prototype={clone:function(){return new g(this.x,this.y)},add:function(b){return this.clone().Wi(b)}, -rotate:function(b){return this.clone().gj(b)},round:function(){return this.clone().hj()},angle:function(){return Math.atan2(this.y,this.x)},Wi:function(b){this.x+=b.x;this.y+=b.y;return this},gj:function(b){var c=Math.cos(b);b=Math.sin(b);var e=b*this.x+c*this.y;this.x=c*this.x-b*this.y;this.y=e;return this},hj:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this}};g.a=function(b){return b instanceof g?b:Array.isArray(b)?new g(b[0],b[1]):b}},{}]},{},[1])(1)});xp=c.ja})();function Lv(b){this.defaultDataProjection=null;b=b?b:{};this.defaultDataProjection=new Ce({code:"EPSG:3857",units:"tile-pixels"});this.a=b.featureClass?b.featureClass:Sm;this.c=b.geometryName?b.geometryName:"geometry";this.f=b.layerName?b.layerName:"layer";this.b=b.layers?b.layers:null}y(Lv,Nr);Lv.prototype.W=function(){return"arraybuffer"}; -Lv.prototype.Ba=function(b,c){var d=this.b,e=new wp(b),e=new xp.Vi(e),f=[],g=this.a,h,k,m;for(m in e.layers)if(!d||-1!=d.indexOf(m)){h=e.layers[m];for(var n=0,p=h.length;n<p;++n){if(g===Sm){var q=h.feature(n);k=m;var r=q.Rg(),t=[],x=[];Mv(r,x,t);var z=q.type,A=void 0;1===z?A=1===r.length?"Point":"MultiPoint":2===z?A=1===r.length?"LineString":"MultiLineString":3===z&&(A="Polygon");q=q.properties;q[this.f]=k;k=new this.a(A,x,t,q)}else{q=h.feature(n);A=m;x=c;k=new this.a;t=q.properties;t[this.f]=A;A= -q.type;if(0===A)A=null;else{q=q.Rg();r=[];z=[];Mv(q,z,r);var B=void 0;1===A?B=1===q.length?new E(null):new Xr(null):2===A?1===q.length?B=new T(null):B=new U(null):3===A&&(B=new F(null));B.ba("XY",z,r);A=B}(x=Qr(A,!1,Pr(this,x)))&&(t[this.c]=x);k.I(t);k.yc(this.c)}f.push(k)}}return f};Lv.prototype.Ia=function(){return this.defaultDataProjection};Lv.prototype.g=function(b){this.b=b}; -function Mv(b,c,d){for(var e=0,f,g,h=0,k=b.length;h<k;++h){f=b[h];for(var m=0,n=f.length;m<n;++m)g=f[m],c.push(g.x,g.y);e+=2*m;d.push(e)}};function Nv(){this.defaultDataProjection=null;this.defaultDataProjection=Ee("EPSG:4326")}y(Nv,ps);function Ov(b,c){c[c.length-1].Jd[b.getAttribute("k")]=b.getAttribute("v")} -var Pv=[null],Qv=P(Pv,{nd:function(b,c){c[c.length-1].Oc.push(b.getAttribute("ref"))},tag:Ov}),Sv=P(Pv,{node:function(b,c){var d=c[0],e=c[c.length-1],f=b.getAttribute("id"),g=[parseFloat(b.getAttribute("lon")),parseFloat(b.getAttribute("lat"))];e.Ug[f]=g;var h=Q({Jd:{}},Rv,b,c);Pb(h.Jd)||(g=new E(g),Qr(g,!1,d),d=new pn(g),d.jc(f),d.I(h.Jd),e.features.push(d))},way:function(b,c){for(var d=c[0],e=b.getAttribute("id"),f=Q({Oc:[],Jd:{}},Qv,b,c),g=c[c.length-1],h=[],k=0,m=f.Oc.length;k<m;k++)kb(h,g.Ug[f.Oc[k]]); -f.Oc[0]==f.Oc[f.Oc.length-1]?(k=new F(null),k.ba("XY",h,[h.length])):(k=new T(null),k.ba("XY",h));Qr(k,!1,d);d=new pn(k);d.jc(e);d.I(f.Jd);g.features.push(d)}}),Rv=P(Pv,{tag:Ov});Nv.prototype.ic=function(b,c){var d=Or(this,b,c);return"osm"==b.localName&&(d=Q({Ug:{},features:[]},Sv,b,[d]),d.features)?d.features:[]};function Tv(b){return b.getAttributeNS("http://www.w3.org/1999/xlink","href")};function Uv(){}Uv.prototype.read=function(b){return To(b)?this.f(b):Wo(b)?this.a(b):ia(b)?(b=fp(b),this.f(b)):null};function Vv(){}y(Vv,Uv);Vv.prototype.f=function(b){for(b=b.firstChild;b;b=b.nextSibling)if(1==b.nodeType)return this.a(b);return null};Vv.prototype.a=function(b){return(b=Q({},Wv,b,[]))?b:null}; -var Xv=[null,"http://www.opengis.net/ows/1.1"],Wv=P(Xv,{ServiceIdentification:N(function(b,c){return Q({},Yv,b,c)}),ServiceProvider:N(function(b,c){return Q({},Zv,b,c)}),OperationsMetadata:N(function(b,c){return Q({},$v,b,c)})}),aw=P(Xv,{DeliveryPoint:N(W),City:N(W),AdministrativeArea:N(W),PostalCode:N(W),Country:N(W),ElectronicMailAddress:N(W)}),bw=P(Xv,{Value:jp(function(b){return W(b)})}),cw=P(Xv,{AllowedValues:N(function(b,c){return Q({},bw,b,c)})}),ew=P(Xv,{Phone:N(function(b,c){return Q({}, -dw,b,c)}),Address:N(function(b,c){return Q({},aw,b,c)})}),gw=P(Xv,{HTTP:N(function(b,c){return Q({},fw,b,c)})}),fw=P(Xv,{Get:jp(function(b,c){var d=Tv(b);return d?Q({href:d},hw,b,c):void 0}),Post:void 0}),iw=P(Xv,{DCP:N(function(b,c){return Q({},gw,b,c)})}),$v=P(Xv,{Operation:function(b,c){var d=b.getAttribute("name"),e=Q({},iw,b,c);e&&(c[c.length-1][d]=e)}}),dw=P(Xv,{Voice:N(W),Facsimile:N(W)}),hw=P(Xv,{Constraint:jp(function(b,c){var d=b.getAttribute("name");return d?Q({name:d},cw,b,c):void 0})}), -jw=P(Xv,{IndividualName:N(W),PositionName:N(W),ContactInfo:N(function(b,c){return Q({},ew,b,c)})}),Yv=P(Xv,{Title:N(W),ServiceTypeVersion:N(W),ServiceType:N(W)}),Zv=P(Xv,{ProviderName:N(W),ProviderSite:N(Tv),ServiceContact:N(function(b,c){return Q({},jw,b,c)})});function kw(b,c,d,e){var f;void 0!==e?f=e:f=[];e=0;var g,h;for(g=0;g<c;)for(h=b[g++],f[e++]=b[g++],f[e++]=h,h=2;h<d;++h)f[e++]=b[g++];f.length=e};function lw(b){b=b?b:{};this.defaultDataProjection=null;this.defaultDataProjection=Ee("EPSG:4326");this.a=b.factor?b.factor:1E5;this.f=b.geometryLayout?b.geometryLayout:"XY"}y(lw,xt);function mw(b,c,d){var e,f=Array(c);for(e=0;e<c;++e)f[e]=0;var g,h;g=0;for(h=b.length;g<h;)for(e=0;e<c;++e,++g){var k=b[g],m=k-f[e];f[e]=k;b[g]=m}return nw(b,d?d:1E5)} -function ow(b,c,d){var e,f=Array(c);for(e=0;e<c;++e)f[e]=0;b=pw(b,d?d:1E5);var g;d=0;for(g=b.length;d<g;)for(e=0;e<c;++e,++d)f[e]+=b[d],b[d]=f[e];return b}function nw(b,c){var d=c?c:1E5,e,f;e=0;for(f=b.length;e<f;++e)b[e]=Math.round(b[e]*d);d=0;for(e=b.length;d<e;++d)f=b[d],b[d]=0>f?~(f<<1):f<<1;d="";e=0;for(f=b.length;e<f;++e){for(var g=b[e],h=void 0,k="";32<=g;)h=(32|g&31)+63,k+=String.fromCharCode(h),g>>=5;h=g+63;k+=String.fromCharCode(h);d+=k}return d} -function pw(b,c){var d=c?c:1E5,e=[],f=0,g=0,h,k;h=0;for(k=b.length;h<k;++h){var m=b.charCodeAt(h)-63,f=f|(m&31)<<g;32>m?(e.push(f),g=f=0):g+=5}f=0;for(g=e.length;f<g;++f)h=e[f],e[f]=h&1?~(h>>1):h>>1;f=0;for(g=e.length;f<g;++f)e[f]/=d;return e}l=lw.prototype;l.Dd=function(b,c){var d=this.Fd(b,c);return new pn(d)};l.Lf=function(b,c){return[this.Dd(b,c)]};l.Fd=function(b,c){var d=cf(this.f),e=ow(b,d,this.a);kw(e,e.length,d,e);d=qf(e,0,e.length,d);return Qr(new T(d,this.f),!1,Pr(this,c))}; -l.Re=function(b,c){var d=b.X();return d?this.Ld(d,c):""};l.si=function(b,c){return this.Re(b[0],c)};l.Ld=function(b,c){b=Qr(b,!0,Pr(this,c));var d=b.ia(),e=b.ra();kw(d,d.length,e,d);return mw(d,e,this.a)};function qw(b){b=b?b:{};this.defaultDataProjection=null;this.defaultDataProjection=Ee(b.defaultDataProjection?b.defaultDataProjection:"EPSG:4326")}y(qw,Rr);function rw(b,c){var d=[],e,f,g,h;g=0;for(h=b.length;g<h;++g)e=b[g],0<g&&d.pop(),0<=e?f=c[e]:f=c[~e].slice().reverse(),d.push.apply(d,f);e=0;for(f=d.length;e<f;++e)d[e]=d[e].slice();return d}function sw(b,c,d,e,f){b=b.geometries;var g=[],h,k;h=0;for(k=b.length;h<k;++h)g[h]=tw(b[h],c,d,e,f);return g} -function tw(b,c,d,e,f){var g=b.type,h=uw[g];c="Point"===g||"MultiPoint"===g?h(b,d,e):h(b,c);d=new pn;d.Ma(Qr(c,!1,f));void 0!==b.id&&d.jc(b.id);b.properties&&d.I(b.properties);return d} -qw.prototype.Kf=function(b,c){if("Topology"==b.type){var d,e=null,f=null;b.transform&&(d=b.transform,e=d.scale,f=d.translate);var g=b.arcs;if(d){d=e;var h=f,k,m;k=0;for(m=g.length;k<m;++k)for(var n=g[k],p=d,q=h,r=0,t=0,x=void 0,z=void 0,A=void 0,z=0,A=n.length;z<A;++z)x=n[z],r+=x[0],t+=x[1],x[0]=r,x[1]=t,vw(x,p,q)}d=[];h=Lb(b.objects);k=0;for(m=h.length;k<m;++k)"GeometryCollection"===h[k].type?(n=h[k],d.push.apply(d,sw(n,g,e,f,c))):(n=h[k],d.push(tw(n,g,e,f,c)));return d}return[]}; -function vw(b,c,d){b[0]=b[0]*c[0]+d[0];b[1]=b[1]*c[1]+d[1]}qw.prototype.Ia=function(){return this.defaultDataProjection}; -var uw={Point:function(b,c,d){b=b.coordinates;c&&d&&vw(b,c,d);return new E(b)},LineString:function(b,c){var d=rw(b.arcs,c);return new T(d)},Polygon:function(b,c){var d=[],e,f;e=0;for(f=b.arcs.length;e<f;++e)d[e]=rw(b.arcs[e],c);return new F(d)},MultiPoint:function(b,c,d){b=b.coordinates;var e,f;if(c&&d)for(e=0,f=b.length;e<f;++e)vw(b[e],c,d);return new Xr(b)},MultiLineString:function(b,c){var d=[],e,f;e=0;for(f=b.arcs.length;e<f;++e)d[e]=rw(b.arcs[e],c);return new U(d)},MultiPolygon:function(b,c){var d= -[],e,f,g,h,k,m;k=0;for(m=b.arcs.length;k<m;++k){e=b.arcs[k];f=[];g=0;for(h=e.length;g<h;++g)f[g]=rw(e[g],c);d[k]=f}return new V(d)}};function ww(b){b=b?b:{};this.g=b.featureType;this.b=b.featureNS;this.a=b.gmlFormat?b.gmlFormat:new Fs;this.c=b.schemaLocation?b.schemaLocation:"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd";this.defaultDataProjection=null}y(ww,ps);ww.prototype.ic=function(b,c){var d={featureType:this.g,featureNS:this.b};Wb(d,Or(this,b,c?c:{}));d=[d];this.a.a["http://www.opengis.net/gml"].featureMember=hp(ss.prototype.Ed);(d=Q([],this.a.a,b,d,this.a))||(d=[]);return d}; -ww.prototype.j=function(b){if(To(b))return xw(b);if(Wo(b))return Q({},yw,b,[]);if(ia(b))return b=fp(b),xw(b)};ww.prototype.i=function(b){if(To(b))return zw(this,b);if(Wo(b))return Aw(this,b);if(ia(b))return b=fp(b),zw(this,b)};function zw(b,c){for(var d=c.firstChild;d;d=d.nextSibling)if(1==d.nodeType)return Aw(b,d)}var Bw={"http://www.opengis.net/gml":{boundedBy:N(ss.prototype.Je,"bounds")}}; -function Aw(b,c){var d={},e=zs(c.getAttribute("numberOfFeatures"));d.numberOfFeatures=e;return Q(d,Bw,c,[],b.a)} -var Cw={"http://www.opengis.net/wfs":{totalInserted:N(ys),totalUpdated:N(ys),totalDeleted:N(ys)}},Dw={"http://www.opengis.net/ogc":{FeatureId:hp(function(b){return b.getAttribute("fid")})}},Ew={"http://www.opengis.net/wfs":{Feature:function(b,c){pp(Dw,b,c)}}},yw={"http://www.opengis.net/wfs":{TransactionSummary:N(function(b,c){return Q({},Cw,b,c)},"transactionSummary"),InsertResults:N(function(b,c){return Q([],Ew,b,c)},"insertIds")}}; -function xw(b){for(b=b.firstChild;b;b=b.nextSibling)if(1==b.nodeType)return Q({},yw,b,[])}var Fw={"http://www.opengis.net/wfs":{PropertyName:O(Bs)}};function Gw(b,c){var d=Lo("http://www.opengis.net/ogc","Filter"),e=Lo("http://www.opengis.net/ogc","FeatureId");d.appendChild(e);e.setAttribute("fid",c);b.appendChild(d)} -var Hw={"http://www.opengis.net/wfs":{Insert:O(function(b,c,d){var e=d[d.length-1],e=Lo(e.featureNS,e.featureType);b.appendChild(e);Fs.prototype.ri(e,c,d)}),Update:O(function(b,c,d){var e=d[d.length-1],f=e.featureType,g=e.featurePrefix,g=g?g:"feature",h=e.featureNS;b.setAttribute("typeName",g+":"+f);ep(b,"http://www.w3.org/2000/xmlns/","xmlns:"+g,h);if(f=c.Oa()){for(var g=c.P(),h=[],k=0,m=g.length;k<m;k++){var n=c.get(g[k]);void 0!==n&&h.push({name:g[k],value:n})}qp({node:b,srsName:e.srsName},Hw, -lp("Property"),h,d);Gw(b,f)}}),Delete:O(function(b,c,d){var e=d[d.length-1];d=e.featureType;var f=e.featurePrefix,f=f?f:"feature",e=e.featureNS;b.setAttribute("typeName",f+":"+d);ep(b,"http://www.w3.org/2000/xmlns/","xmlns:"+f,e);(c=c.Oa())&&Gw(b,c)}),Property:O(function(b,c,d){var e=Lo("http://www.opengis.net/wfs","Name");b.appendChild(e);Bs(e,c.name);void 0!==c.value&&null!==c.value&&(e=Lo("http://www.opengis.net/wfs","Value"),b.appendChild(e),c.value instanceof $e?Fs.prototype.Te(e,c.value,d): -Bs(e,c.value))}),Native:O(function(b,c){c.ep&&b.setAttribute("vendorId",c.ep);void 0!==c.Io&&b.setAttribute("safeToIgnore",c.Io);void 0!==c.value&&Bs(b,c.value)})}},Iw={"http://www.opengis.net/wfs":{Query:O(function(b,c,d){var e=d[d.length-1],f=e.featurePrefix,g=e.featureNS,h=e.propertyNames,k=e.srsName;b.setAttribute("typeName",(f?f+":":"")+c);k&&b.setAttribute("srsName",k);g&&ep(b,"http://www.w3.org/2000/xmlns/","xmlns:"+f,g);c=Tb(e);c.node=b;qp(c,Fw,lp("PropertyName"),h,d);if(e=e.bbox)h=Lo("http://www.opengis.net/ogc", -"Filter"),c=d[d.length-1].geometryName,f=Lo("http://www.opengis.net/ogc","BBOX"),h.appendChild(f),g=Lo("http://www.opengis.net/ogc","PropertyName"),Bs(g,c),f.appendChild(g),Fs.prototype.Te(f,e,d),b.appendChild(h)})}}; -ww.prototype.l=function(b){var c=Lo("http://www.opengis.net/wfs","GetFeature");c.setAttribute("service","WFS");c.setAttribute("version","1.1.0");b&&(b.handle&&c.setAttribute("handle",b.handle),b.outputFormat&&c.setAttribute("outputFormat",b.outputFormat),void 0!==b.maxFeatures&&c.setAttribute("maxFeatures",b.maxFeatures),b.resultType&&c.setAttribute("resultType",b.resultType),void 0!==b.startIndex&&c.setAttribute("startIndex",b.startIndex),void 0!==b.count&&c.setAttribute("count",b.count));ep(c,"http://www.w3.org/2001/XMLSchema-instance", -"xsi:schemaLocation",this.c);var d=b.featureTypes;b=[{node:c,srsName:b.srsName,featureNS:b.featureNS?b.featureNS:this.b,featurePrefix:b.featurePrefix,geometryName:b.geometryName,bbox:b.bbox,propertyNames:b.propertyNames?b.propertyNames:[]}];var e=Tb(b[b.length-1]);e.node=c;qp(e,Iw,lp("Query"),d,b);return c}; -ww.prototype.B=function(b,c,d,e){var f=[],g=Lo("http://www.opengis.net/wfs","Transaction");g.setAttribute("service","WFS");g.setAttribute("version","1.1.0");var h,k;e&&(h=e.gmlOptions?e.gmlOptions:{},e.handle&&g.setAttribute("handle",e.handle));ep(g,"http://www.w3.org/2001/XMLSchema-instance","xsi:schemaLocation",this.c);b&&(k={node:g,featureNS:e.featureNS,featureType:e.featureType,featurePrefix:e.featurePrefix},Wb(k,h),qp(k,Hw,lp("Insert"),b,f));c&&(k={node:g,featureNS:e.featureNS,featureType:e.featureType, -featurePrefix:e.featurePrefix},Wb(k,h),qp(k,Hw,lp("Update"),c,f));d&&qp({node:g,featureNS:e.featureNS,featureType:e.featureType,featurePrefix:e.featurePrefix},Hw,lp("Delete"),d,f);e.nativeElements&&qp({node:g,featureNS:e.featureNS,featureType:e.featureType,featurePrefix:e.featurePrefix},Hw,lp("Native"),e.nativeElements,f);return g};ww.prototype.Qf=function(b){for(b=b.firstChild;b;b=b.nextSibling)if(1==b.nodeType)return this.Me(b);return null}; -ww.prototype.Me=function(b){if(b.firstElementChild&&b.firstElementChild.firstElementChild)for(b=b.firstElementChild.firstElementChild,b=b.firstElementChild;b;b=b.nextElementSibling)if(0!==b.childNodes.length&&(1!==b.childNodes.length||3!==b.firstChild.nodeType)){var c=[{}];this.a.Je(b,c);return Ee(c.pop().srsName)}return null};function Jw(b){b=b?b:{};this.defaultDataProjection=null;this.a=void 0!==b.splitCollection?b.splitCollection:!1}y(Jw,xt);function Kw(b){b=b.Z();return 0===b.length?"":b[0]+" "+b[1]}function Lw(b){b=b.Z();for(var c=[],d=0,e=b.length;d<e;++d)c.push(b[d][0]+" "+b[d][1]);return c.join(",")}function Mw(b){var c=[];b=b.be();for(var d=0,e=b.length;d<e;++d)c.push("("+Lw(b[d])+")");return c.join(",")}function Nw(b){var c=b.W();b=(0,Ow[c])(b);c=c.toUpperCase();return 0===b.length?c+" EMPTY":c+"("+b+")"} -var Ow={Point:Kw,LineString:Lw,Polygon:Mw,MultiPoint:function(b){var c=[];b=b.ve();for(var d=0,e=b.length;d<e;++d)c.push("("+Kw(b[d])+")");return c.join(",")},MultiLineString:function(b){var c=[];b=b.sd();for(var d=0,e=b.length;d<e;++d)c.push("("+Lw(b[d])+")");return c.join(",")},MultiPolygon:function(b){var c=[];b=b.ce();for(var d=0,e=b.length;d<e;++d)c.push("("+Mw(b[d])+")");return c.join(",")},GeometryCollection:function(b){var c=[];b=b.Ag();for(var d=0,e=b.length;d<e;++d)c.push(Nw(b[d]));return c.join(",")}}; -l=Jw.prototype;l.Dd=function(b,c){var d=this.Fd(b,c);if(d){var e=new pn;e.Ma(d);return e}return null};l.Lf=function(b,c){var d=[],e=this.Fd(b,c);this.a&&"GeometryCollection"==e.W()?d=e.c:d=[e];for(var f=[],g=0,h=d.length;g<h;++g)e=new pn,e.Ma(d[g]),f.push(e);return f};l.Fd=function(b,c){var d;d=new Pw(new Qw(b));d.a=Rw(d.f);return(d=Sw(d))?Qr(d,!1,c):null};l.Re=function(b,c){var d=b.X();return d?this.Ld(d,c):""}; -l.si=function(b,c){if(1==b.length)return this.Re(b[0],c);for(var d=[],e=0,f=b.length;e<f;++e)d.push(b[e].X());d=new gs(d);return this.Ld(d,c)};l.Ld=function(b,c){return Nw(Qr(b,!0,c))};function Qw(b){this.f=b;this.a=-1}function Tw(b,c){return"0"<=b&&"9">=b||"."==b&&!(void 0!==c&&c)} -function Rw(b){var c=b.f.charAt(++b.a),d={position:b.a,value:c};if("("==c)d.type=2;else if(","==c)d.type=5;else if(")"==c)d.type=3;else if(Tw(c)||"-"==c){d.type=4;var e,c=b.a,f=!1,g=!1;do{if("."==e)f=!0;else if("e"==e||"E"==e)g=!0;e=b.f.charAt(++b.a)}while(Tw(e,f)||!g&&("e"==e||"E"==e)||g&&("-"==e||"+"==e));b=parseFloat(b.f.substring(c,b.a--));d.value=b}else if("a"<=c&&"z">=c||"A"<=c&&"Z">=c){d.type=1;c=b.a;do e=b.f.charAt(++b.a);while("a"<=e&&"z">=e||"A"<=e&&"Z">=e);b=b.f.substring(c,b.a--).toUpperCase(); -d.value=b}else{if(" "==c||"\t"==c||"\r"==c||"\n"==c)return Rw(b);if(""===c)d.type=6;else throw Error("Unexpected character: "+c);}return d}function Pw(b){this.f=b}l=Pw.prototype;l.match=function(b){if(b=this.a.type==b)this.a=Rw(this.f);return b}; -function Sw(b){var c=b.a;if(b.match(1)){var d=c.value;if("GEOMETRYCOLLECTION"==d){a:{if(b.match(2)){c=[];do c.push(Sw(b));while(b.match(5));if(b.match(3)){b=c;break a}}else if(Uw(b)){b=[];break a}throw Error(Vw(b));}return new gs(b)}var e=Ww[d],c=Xw[d];if(!e||!c)throw Error("Invalid geometry type: "+d);b=e.call(b);return new c(b)}throw Error(Vw(b));}l.Ff=function(){if(this.match(2)){var b=Yw(this);if(this.match(3))return b}else if(Uw(this))return null;throw Error(Vw(this));}; -l.Ef=function(){if(this.match(2)){var b=Zw(this);if(this.match(3))return b}else if(Uw(this))return[];throw Error(Vw(this));};l.Gf=function(){if(this.match(2)){var b=$w(this);if(this.match(3))return b}else if(Uw(this))return[];throw Error(Vw(this));};l.Sn=function(){if(this.match(2)){var b;if(2==this.a.type)for(b=[this.Ff()];this.match(5);)b.push(this.Ff());else b=Zw(this);if(this.match(3))return b}else if(Uw(this))return[];throw Error(Vw(this));}; -l.Rn=function(){if(this.match(2)){var b=$w(this);if(this.match(3))return b}else if(Uw(this))return[];throw Error(Vw(this));};l.Tn=function(){if(this.match(2)){for(var b=[this.Gf()];this.match(5);)b.push(this.Gf());if(this.match(3))return b}else if(Uw(this))return[];throw Error(Vw(this));};function Yw(b){for(var c=[],d=0;2>d;++d){var e=b.a;if(b.match(4))c.push(e.value);else break}if(2==c.length)return c;throw Error(Vw(b));}function Zw(b){for(var c=[Yw(b)];b.match(5);)c.push(Yw(b));return c} -function $w(b){for(var c=[b.Ef()];b.match(5);)c.push(b.Ef());return c}function Uw(b){var c=1==b.a.type&&"EMPTY"==b.a.value;c&&(b.a=Rw(b.f));return c}function Vw(b){return"Unexpected `"+b.a.value+"` at position "+b.a.position+" in `"+b.f.f+"`"}var Xw={POINT:E,LINESTRING:T,POLYGON:F,MULTIPOINT:Xr,MULTILINESTRING:U,MULTIPOLYGON:V},Ww={POINT:Pw.prototype.Ff,LINESTRING:Pw.prototype.Ef,POLYGON:Pw.prototype.Gf,MULTIPOINT:Pw.prototype.Sn,MULTILINESTRING:Pw.prototype.Rn,MULTIPOLYGON:Pw.prototype.Tn};function ax(){this.version=void 0}y(ax,Uv);ax.prototype.f=function(b){for(b=b.firstChild;b;b=b.nextSibling)if(1==b.nodeType)return this.a(b);return null};ax.prototype.a=function(b){this.version=b.getAttribute("version").trim();return(b=Q({version:this.version},bx,b,[]))?b:null};function cx(b,c){return Q({},dx,b,c)}function ex(b,c){return Q({},fx,b,c)}function gx(b,c){var d=cx(b,c);if(d){var e=[zs(b.getAttribute("width")),zs(b.getAttribute("height"))];d.size=e;return d}} -function hx(b,c){return Q([],ix,b,c)} -var jx=[null,"http://www.opengis.net/wms"],bx=P(jx,{Service:N(function(b,c){return Q({},kx,b,c)}),Capability:N(function(b,c){return Q({},lx,b,c)})}),lx=P(jx,{Request:N(function(b,c){return Q({},mx,b,c)}),Exception:N(function(b,c){return Q([],nx,b,c)}),Layer:N(function(b,c){return Q({},ox,b,c)})}),kx=P(jx,{Name:N(W),Title:N(W),Abstract:N(W),KeywordList:N(hx),OnlineResource:N(Tv),ContactInformation:N(function(b,c){return Q({},px,b,c)}),Fees:N(W),AccessConstraints:N(W),LayerLimit:N(ys),MaxWidth:N(ys), -MaxHeight:N(ys)}),px=P(jx,{ContactPersonPrimary:N(function(b,c){return Q({},qx,b,c)}),ContactPosition:N(W),ContactAddress:N(function(b,c){return Q({},rx,b,c)}),ContactVoiceTelephone:N(W),ContactFacsimileTelephone:N(W),ContactElectronicMailAddress:N(W)}),qx=P(jx,{ContactPerson:N(W),ContactOrganization:N(W)}),rx=P(jx,{AddressType:N(W),Address:N(W),City:N(W),StateOrProvince:N(W),PostCode:N(W),Country:N(W)}),nx=P(jx,{Format:hp(W)}),ox=P(jx,{Name:N(W),Title:N(W),Abstract:N(W),KeywordList:N(hx),CRS:jp(W), -EX_GeographicBoundingBox:N(function(b,c){var d=Q({},sx,b,c);if(d){var e=d.westBoundLongitude,f=d.southBoundLatitude,g=d.eastBoundLongitude,d=d.northBoundLatitude;return void 0===e||void 0===f||void 0===g||void 0===d?void 0:[e,f,g,d]}}),BoundingBox:jp(function(b){var c=[xs(b.getAttribute("minx")),xs(b.getAttribute("miny")),xs(b.getAttribute("maxx")),xs(b.getAttribute("maxy"))],d=[xs(b.getAttribute("resx")),xs(b.getAttribute("resy"))];return{crs:b.getAttribute("CRS"),extent:c,res:d}}),Dimension:jp(function(b){return{name:b.getAttribute("name"), -units:b.getAttribute("units"),unitSymbol:b.getAttribute("unitSymbol"),"default":b.getAttribute("default"),multipleValues:us(b.getAttribute("multipleValues")),nearestValue:us(b.getAttribute("nearestValue")),current:us(b.getAttribute("current")),values:W(b)}}),Attribution:N(function(b,c){return Q({},tx,b,c)}),AuthorityURL:jp(function(b,c){var d=cx(b,c);if(d)return d.name=b.getAttribute("name"),d}),Identifier:jp(W),MetadataURL:jp(function(b,c){var d=cx(b,c);if(d)return d.type=b.getAttribute("type"), -d}),DataURL:jp(cx),FeatureListURL:jp(cx),Style:jp(function(b,c){return Q({},ux,b,c)}),MinScaleDenominator:N(ws),MaxScaleDenominator:N(ws),Layer:jp(function(b,c){var d=c[c.length-1],e=Q({},ox,b,c);if(e){var f=us(b.getAttribute("queryable"));void 0===f&&(f=d.queryable);e.queryable=void 0!==f?f:!1;f=zs(b.getAttribute("cascaded"));void 0===f&&(f=d.cascaded);e.cascaded=f;f=us(b.getAttribute("opaque"));void 0===f&&(f=d.opaque);e.opaque=void 0!==f?f:!1;f=us(b.getAttribute("noSubsets"));void 0===f&&(f=d.noSubsets); -e.noSubsets=void 0!==f?f:!1;(f=xs(b.getAttribute("fixedWidth")))||(f=d.fixedWidth);e.fixedWidth=f;(f=xs(b.getAttribute("fixedHeight")))||(f=d.fixedHeight);e.fixedHeight=f;["Style","CRS","AuthorityURL"].forEach(function(b){if(b in d){var c=Sb(e,b),c=c.concat(d[b]);e[b]=c}});"EX_GeographicBoundingBox BoundingBox Dimension Attribution MinScaleDenominator MaxScaleDenominator".split(" ").forEach(function(b){b in e||(e[b]=d[b])});return e}})}),tx=P(jx,{Title:N(W),OnlineResource:N(Tv),LogoURL:N(gx)}),sx= -P(jx,{westBoundLongitude:N(ws),eastBoundLongitude:N(ws),southBoundLatitude:N(ws),northBoundLatitude:N(ws)}),mx=P(jx,{GetCapabilities:N(ex),GetMap:N(ex),GetFeatureInfo:N(ex)}),fx=P(jx,{Format:jp(W),DCPType:jp(function(b,c){return Q({},vx,b,c)})}),vx=P(jx,{HTTP:N(function(b,c){return Q({},wx,b,c)})}),wx=P(jx,{Get:N(cx),Post:N(cx)}),ux=P(jx,{Name:N(W),Title:N(W),Abstract:N(W),LegendURL:jp(gx),StyleSheetURL:N(cx),StyleURL:N(cx)}),dx=P(jx,{Format:N(W),OnlineResource:N(Tv)}),ix=P(jx,{Keyword:hp(W)});function xx(){this.b="http://mapserver.gis.umn.edu/mapserver";this.a=new Es;this.defaultDataProjection=null}y(xx,ps); -xx.prototype.ic=function(b,c){var d={featureType:this.featureType,featureNS:this.featureNS};c&&Wb(d,Or(this,b,c));var e=[d];b.namespaceURI=this.b;var f=Qo(b),d=[];if(0!==b.childNodes.length){if("msGMLOutput"==f)for(var g=0,h=b.childNodes.length;g<h;g++){var k=b.childNodes[g];if(1===k.nodeType){var m=e[0],n=k.localName.replace("_layer","")+"_feature";m.featureType=n;m.featureNS=this.b;var p={};p[n]=hp(this.a.Jf,this.a);m=P([m.featureNS,null],p);k.namespaceURI=this.b;(k=Q([],m,k,e,this.a))&&kb(d,k)}}"FeatureCollection"== -f&&(e=Q([],this.a.a,b,[{}],this.a))&&(d=e)}return d};function yx(){this.b=new Vv}y(yx,Uv);yx.prototype.f=function(b){for(b=b.firstChild;b;b=b.nextSibling)if(1==b.nodeType)return this.a(b);return null};yx.prototype.a=function(b){this.version=b.getAttribute("version").trim();var c=this.b.a(b);if(!c)return null;c.version=this.version;return(c=Q(c,zx,b,[]))?c:null};function Ax(b){var c=W(b).split(" ");if(c&&2==c.length)return b=+c[0],c=+c[1],isNaN(b)||isNaN(c)?void 0:[b,c]} -var Bx=[null,"http://www.opengis.net/wmts/1.0"],Cx=[null,"http://www.opengis.net/ows/1.1"],zx=P(Bx,{Contents:N(function(b,c){return Q({},Dx,b,c)})}),Dx=P(Bx,{Layer:jp(function(b,c){return Q({},Ex,b,c)}),TileMatrixSet:jp(function(b,c){return Q({},Fx,b,c)})}),Ex=P(Bx,{Style:jp(function(b,c){var d=Q({},Gx,b,c);if(d){var e="true"===b.getAttribute("isDefault");d.isDefault=e;return d}}),Format:jp(W),TileMatrixSetLink:jp(function(b,c){return Q({},Hx,b,c)}),Dimension:jp(function(b,c){return Q({},Ix,b,c)}), -ResourceURL:jp(function(b){var c=b.getAttribute("format"),d=b.getAttribute("template");b=b.getAttribute("resourceType");var e={};c&&(e.format=c);d&&(e.template=d);b&&(e.resourceType=b);return e})},P(Cx,{Title:N(W),Abstract:N(W),WGS84BoundingBox:N(function(b,c){var d=Q([],Jx,b,c);return 2!=d.length?void 0:Ld(d)}),Identifier:N(W)})),Gx=P(Bx,{LegendURL:jp(function(b){var c={};c.format=b.getAttribute("format");c.href=Tv(b);return c})},P(Cx,{Title:N(W),Identifier:N(W)})),Hx=P(Bx,{TileMatrixSet:N(W)}), -Ix=P(Bx,{Default:N(W),Value:jp(W)},P(Cx,{Identifier:N(W)})),Jx=P(Cx,{LowerCorner:hp(Ax),UpperCorner:hp(Ax)}),Fx=P(Bx,{WellKnownScaleSet:N(W),TileMatrix:jp(function(b,c){return Q({},Kx,b,c)})},P(Cx,{SupportedCRS:N(W),Identifier:N(W)})),Kx=P(Bx,{TopLeftCorner:N(Ax),ScaleDenominator:N(ws),TileWidth:N(ys),TileHeight:N(ys),MatrixWidth:N(ys),MatrixHeight:N(ys)},P(Cx,{Identifier:N(W)}));var Lx=new ze(6378137);function Mx(b){gd.call(this);b=b||{};this.a=null;this.c=Xe;this.b=void 0;D(this,id("projection"),this.Dl,!1,this);D(this,id("tracking"),this.El,!1,this);void 0!==b.projection&&this.Yg(Ee(b.projection));void 0!==b.trackingOptions&&this.hi(b.trackingOptions);this.re(void 0!==b.tracking?b.tracking:!1)}y(Mx,gd);l=Mx.prototype;l.Y=function(){this.re(!1);Mx.ca.Y.call(this)};l.Dl=function(){var b=this.Wg();b&&(this.c=Ie(Ee("EPSG:4326"),b),this.a&&this.set("position",this.c(this.a)))}; -l.El=function(){if(Zi){var b=this.Xg();b&&void 0===this.b?this.b=ba.navigator.geolocation.watchPosition(ua(this.$n,this),ua(this.ao,this),this.Ig()):b||void 0===this.b||(ba.navigator.geolocation.clearWatch(this.b),this.b=void 0)}}; -l.$n=function(b){b=b.coords;this.set("accuracy",b.accuracy);this.set("altitude",null===b.altitude?void 0:b.altitude);this.set("altitudeAccuracy",null===b.altitudeAccuracy?void 0:b.altitudeAccuracy);this.set("heading",null===b.heading?void 0:Xa(b.heading));this.a?(this.a[0]=b.longitude,this.a[1]=b.latitude):this.a=[b.longitude,b.latitude];var c=this.c(this.a);this.set("position",c);this.set("speed",null===b.speed?void 0:b.speed);b=Jf(Lx,this.a,b.accuracy);b.pc(this.c);this.set("accuracyGeometry",b); -this.u()};l.ao=function(b){b.type="error";this.re(!1);this.s(b)};l.Dj=function(){return this.get("accuracy")};l.Ej=function(){return this.get("accuracyGeometry")||null};l.Gj=function(){return this.get("altitude")};l.Hj=function(){return this.get("altitudeAccuracy")};l.Bl=function(){return this.get("heading")};l.Cl=function(){return this.get("position")};l.Wg=function(){return this.get("projection")};l.lk=function(){return this.get("speed")};l.Xg=function(){return this.get("tracking")};l.Ig=function(){return this.get("trackingOptions")}; -l.Yg=function(b){this.set("projection",b)};l.re=function(b){this.set("tracking",b)};l.hi=function(b){this.set("trackingOptions",b)};function Nx(b,c,d){bf.call(this);this.Uf(b,c?c:0,d)}y(Nx,bf);l=Nx.prototype;l.clone=function(){var b=new Nx(null),c=this.A.slice();df(b,this.b,c);b.u();return b};l.nb=function(b,c,d,e){var f=this.A;b-=f[0];var g=c-f[1];c=b*b+g*g;if(c<e){if(0===c)for(e=0;e<this.a;++e)d[e]=f[e];else for(e=this.zf()/Math.sqrt(c),d[0]=f[0]+e*b,d[1]=f[1]+e*g,e=2;e<this.a;++e)d[e]=f[e];d.length=this.a;return c}return e};l.uc=function(b,c){var d=this.A,e=b-d[0],d=c-d[1];return e*e+d*d<=Ox(this)}; -l.wd=function(){return this.A.slice(0,this.a)};l.Wd=function(b){var c=this.A,d=c[this.a]-c[0];return Pd(c[0]-d,c[1]-d,c[0]+d,c[1]+d,b)};l.zf=function(){return Math.sqrt(Ox(this))};function Ox(b){var c=b.A[b.a]-b.A[0];b=b.A[b.a+1]-b.A[1];return c*c+b*b}l.W=function(){return"Circle"};l.Ea=function(b){var c=this.J();return oe(b,c)?(c=this.wd(),b[0]<=c[0]&&b[2]>=c[0]||b[1]<=c[1]&&b[3]>=c[1]?!0:ce(b,this.og,this)):!1}; -l.Yl=function(b){var c=this.a,d=this.A[c]-this.A[0],e=b.slice();e[c]=e[0]+d;for(d=1;d<c;++d)e[c+d]=b[d];df(this,this.b,e);this.u()};l.Uf=function(b,c,d){if(b){ef(this,d,b,0);this.A||(this.A=[]);d=this.A;b=nf(d,b);d[b++]=d[0]+c;var e;c=1;for(e=this.a;c<e;++c)d[b++]=d[c];d.length=b}else df(this,"XY",null);this.u()};l.Zl=function(b){this.A[this.a]=this.A[0]+b;this.u()};function Px(b,c,d){for(var e=[],f=b(0),g=b(1),h=c(f),k=c(g),m=[g,f],n=[k,h],p=[1,0],q={},r=1E5,t,x,z,A,B;0<--r&&0<p.length;)z=p.pop(),f=m.pop(),h=n.pop(),g=z.toString(),g in q||(e.push(h[0],h[1]),q[g]=!0),A=p.pop(),g=m.pop(),k=n.pop(),B=(z+A)/2,t=b(B),x=c(t),Va(x[0],x[1],h[0],h[1],k[0],k[1])<d?(e.push(k[0],k[1]),g=A.toString(),q[g]=!0):(p.push(A,B,B,z),n.push(k,x,x,h),m.push(g,t,t,f));return e}function Qx(b,c,d,e,f){var g=Ee("EPSG:4326");return Px(function(e){return[b,c+(d-c)*e]},We(g,e),f)} -function Rx(b,c,d,e,f){var g=Ee("EPSG:4326");return Px(function(e){return[c+(d-c)*e,b]},We(g,e),f)};function Sx(b){b=b||{};this.g=this.l=null;this.b=this.i=Infinity;this.c=this.j=-Infinity;this.C=this.v=Infinity;this.O=this.D=-Infinity;this.U=void 0!==b.targetSize?b.targetSize:100;this.na=void 0!==b.maxLines?b.maxLines:100;this.a=[];this.f=[];this.va=void 0!==b.strokeStyle?b.strokeStyle:Tx;this.B=this.o=void 0;this.G=null;this.setMap(void 0!==b.map?b.map:null)}var Tx=new Yl({color:"rgba(0,0,0,0.2)"}),Ux=[90,45,30,20,10,5,2,1,.5,.2,.1,.05,.01,.005,.002,.001]; -function Vx(b,c,d,e,f,g,h){var k=h;c=Qx(c,d,e,b.g,f);k=void 0!==b.a[k]?b.a[k]:new T(null);k.ba("XY",c);oe(k.J(),g)&&(b.a[h++]=k);return h}function Wx(b,c,d,e,f){var g=f;c=Rx(c,b.c,b.b,b.g,d);g=void 0!==b.f[g]?b.f[g]:new T(null);g.ba("XY",c);oe(g.J(),e)&&(b.f[f++]=g);return f}l=Sx.prototype;l.Fl=function(){return this.l};l.Zj=function(){return this.a};l.fk=function(){return this.f}; -l.Mg=function(b){var c=b.vectorContext,d=b.frameState,e=d.extent;b=d.viewState;var f=b.center,g=b.projection,h=b.resolution;b=d.pixelRatio;b=h*h/(4*b*b);if(!this.g||!Ve(this.g,g)){var k=Ee("EPSG:4326"),m=g.J(),n=g.j,p=Ze(n,k,g),q=n[2],r=n[1],t=n[0],x=p[3],z=p[2],A=p[1],p=p[0];this.i=n[3];this.b=q;this.j=r;this.c=t;this.v=x;this.C=z;this.D=A;this.O=p;this.o=We(k,g);this.B=We(g,k);this.G=this.B(le(m));this.g=g}k=0;g.b&&(g=g.J(),k=je(g),d=d.focus[0],d<g[0]||d>g[2])&&(k*=Math.ceil((g[0]-d)/k),e=[e[0]+ -k,e[1],e[2]+k,e[3]]);d=this.G[0];g=this.G[1];k=-1;n=Math.pow(this.U*h,2);q=[];r=[];h=0;for(m=Ux.length;h<m;++h){t=Ux[h]/2;q[0]=d-t;q[1]=g-t;r[0]=d+t;r[1]=g+t;this.o(q,q);this.o(r,r);t=Math.pow(r[0]-q[0],2)+Math.pow(r[1]-q[1],2);if(t<=n)break;k=Ux[h]}h=k;if(-1==h)this.a.length=this.f.length=0;else{d=this.B(f);f=d[0];d=d[1];g=this.na;k=[Math.max(e[0],this.O),Math.max(e[1],this.D),Math.min(e[2],this.C),Math.min(e[3],this.v)];k=Ze(k,this.g,"EPSG:4326");n=k[3];r=k[1];f=Math.floor(f/h)*h;q=Sa(f,this.c, -this.b);m=Vx(this,q,r,n,b,e,0);for(k=0;q!=this.c&&k++<g;)q=Math.max(q-h,this.c),m=Vx(this,q,r,n,b,e,m);q=Sa(f,this.c,this.b);for(k=0;q!=this.b&&k++<g;)q=Math.min(q+h,this.b),m=Vx(this,q,r,n,b,e,m);this.a.length=m;d=Math.floor(d/h)*h;f=Sa(d,this.j,this.i);m=Wx(this,f,b,e,0);for(k=0;f!=this.j&&k++<g;)f=Math.max(f-h,this.j),m=Wx(this,f,b,e,m);f=Sa(d,this.j,this.i);for(k=0;f!=this.i&&k++<g;)f=Math.min(f+h,this.i),m=Wx(this,f,b,e,m);this.f.length=m}c.bb(null,this.va);b=0;for(f=this.a.length;b<f;++b)h= -this.a[b],c.Wb(h,null);b=0;for(f=this.f.length;b<f;++b)h=this.f[b],c.Wb(h,null)};l.setMap=function(b){this.l&&(this.l.K("postcompose",this.Mg,this),this.l.render());b&&(b.H("postcompose",this.Mg,this),b.render());this.l=b};function Xx(b,c,d,e,f,g,h){ek.call(this,b,c,d,0,e);this.l=f;this.f=new Image;null!==g&&(this.f.crossOrigin=g);this.g={};this.c=null;this.state=0;this.j=h}y(Xx,ek);Xx.prototype.a=function(b){if(void 0!==b){var c;b=w(b);if(b in this.g)return this.g[b];Pb(this.g)?c=this.f:c=this.f.cloneNode(!1);return this.g[b]=c}return this.f};Xx.prototype.o=function(){this.state=3;this.c.forEach(Wc);this.c=null;fk(this)}; -Xx.prototype.G=function(){void 0===this.resolution&&(this.resolution=ke(this.extent)/this.f.height);this.state=2;this.c.forEach(Wc);this.c=null;fk(this)};Xx.prototype.load=function(){0==this.state&&(this.state=1,fk(this),this.c=[Uc(this.f,"error",this.o,!1,this),Uc(this.f,"load",this.G,!1,this)],this.j(this,this.l))};function Yx(b,c,d,e,f){uh.call(this,b,c);this.l=d;this.b=new Image;null!==e&&(this.b.crossOrigin=e);this.c={};this.j=null;this.o=f}y(Yx,uh);l=Yx.prototype;l.Y=function(){1==this.state&&Zx(this);this.f&&sc(this.f);Yx.ca.Y.call(this)};l.Ta=function(b){if(void 0!==b){var c=w(b);if(c in this.c)return this.c[c];b=Pb(this.c)?this.b:this.b.cloneNode(!1);return this.c[c]=b}return this.b};l.$a=function(){return this.l};l.Gl=function(){this.state=3;Zx(this);vh(this)}; -l.Hl=function(){this.state=this.b.naturalWidth&&this.b.naturalHeight?2:4;Zx(this);vh(this)};l.load=function(){0==this.state&&(this.state=1,vh(this),this.j=[Uc(this.b,"error",this.Gl,!1,this),Uc(this.b,"load",this.Hl,!1,this)],this.o(this,this.l))};function Zx(b){b.j.forEach(Wc);b.j=null};function $x(b,c){$c.call(this);this.a=new wr(this);var d=b;c&&(d=Cg(b));this.a.Ra(d,"dragenter",this.Jn);d!=b&&this.a.Ra(d,"dragover",this.Kn);this.a.Ra(b,"dragover",this.Ln);this.a.Ra(b,"drop",this.Mn)}y($x,$c);l=$x.prototype;l.ld=!1;l.Y=function(){$x.ca.Y.call(this);this.a.Fc()};l.Jn=function(b){var c=b.a.dataTransfer;(this.ld=!(!c||!(c.types&&(0<=ab(c.types,"Files")||0<=ab(c.types,"public.file-url"))||c.files&&0<c.files.length)))&&b.preventDefault()}; -l.Kn=function(b){this.ld&&(b.preventDefault(),b.a.dataTransfer.dropEffect="none")};l.Ln=function(b){if(this.ld){b.preventDefault();b.b();b=b.a.dataTransfer;try{b.effectAllowed="all"}catch(c){}b.dropEffect="copy"}};l.Mn=function(b){this.ld&&(b.preventDefault(),b.b(),b=new xc(b.a),b.type="drop",this.s(b))};/* - Portions of this code are from MochiKit, received by - The Closure Authors under the MIT license. All other code is Copyright - 2005-2009 The Closure Authors. All Rights Reserved. -*/ -function ay(b,c){this.g=[];this.v=b;this.B=c||null;this.c=this.a=!1;this.b=void 0;this.o=this.C=this.j=!1;this.i=0;this.f=null;this.l=0}ay.prototype.cancel=function(b){if(this.a)this.b instanceof ay&&this.b.cancel();else{if(this.f){var c=this.f;delete this.f;b?c.cancel(b):(c.l--,0>=c.l&&c.cancel())}this.v?this.v.call(this.B,this):this.o=!0;this.a||(b=new by,cy(this),dy(this,!1,b))}};ay.prototype.G=function(b,c){this.j=!1;dy(this,b,c)};function dy(b,c,d){b.a=!0;b.b=d;b.c=!c;ey(b)} -function cy(b){if(b.a){if(!b.o)throw new fy;b.o=!1}}ay.prototype.ad=function(b){cy(this);dy(this,!0,b)};function gy(b,c,d,e){b.g.push([c,d,e]);b.a&&ey(b)}ay.prototype.then=function(b,c,d){var e,f,g=new En(function(b,c){e=b;f=c});gy(this,e,function(b){b instanceof by?g.cancel():f(b)});return g.then(b,c,d)};rn(ay);function hy(b){return eb(b.g,function(b){return ka(b[1])})} -function ey(b){if(b.i&&b.a&&hy(b)){var c=b.i,d=iy[c];d&&(ba.clearTimeout(d.xa),delete iy[c]);b.i=0}b.f&&(b.f.l--,delete b.f);for(var c=b.b,e=d=!1;b.g.length&&!b.j;){var f=b.g.shift(),g=f[0],h=f[1],f=f[2];if(g=b.c?h:g)try{var k=g.call(f||b.B,c);ca(k)&&(b.c=b.c&&(k==c||k instanceof Error),b.b=c=k);if(sn(c)||"function"===typeof ba.Promise&&c instanceof ba.Promise)e=!0,b.j=!0}catch(m){c=m,b.c=!0,hy(b)||(d=!0)}}b.b=c;e&&(k=ua(b.G,b,!0),e=ua(b.G,b,!1),c instanceof ay?(gy(c,k,e),c.C=!0):c.then(k,e));d&& -(c=new jy(c),iy[c.xa]=c,b.i=c.xa)}function fy(){Aa.call(this)}y(fy,Aa);fy.prototype.message="Deferred has already fired";fy.prototype.name="AlreadyCalledError";function by(){Aa.call(this)}y(by,Aa);by.prototype.message="Deferred was canceled";by.prototype.name="CanceledError";function jy(b){this.xa=ba.setTimeout(ua(this.f,this),0);this.a=b}jy.prototype.f=function(){delete iy[this.xa];throw this.a;};var iy={};function ky(b,c){ca(b.name)?(this.name=b.name,this.code=ly[b.name]):(this.code=b.code,this.name=my(b.code));Aa.call(this,Da("%s %s",this.name,c))}y(ky,Aa);function my(b){var c=Ob(ly,function(c){return b==c});if(!ca(c))throw Error("Invalid code: "+b);return c}var ly={AbortError:3,EncodingError:5,InvalidModificationError:9,InvalidStateError:7,NotFoundError:1,NotReadableError:4,NoModificationAllowedError:6,PathExistsError:12,QuotaExceededError:10,SecurityError:2,SyntaxError:8,TypeMismatchError:11};function ny(b,c){tc.call(this,b.type,c)}y(ny,tc);function oy(){$c.call(this);this.tb=new FileReader;this.tb.onloadstart=ua(this.a,this);this.tb.onprogress=ua(this.a,this);this.tb.onload=ua(this.a,this);this.tb.onabort=ua(this.a,this);this.tb.onerror=ua(this.a,this);this.tb.onloadend=ua(this.a,this)}y(oy,$c);oy.prototype.getError=function(){return this.tb.error&&new ky(this.tb.error,"reading file")};oy.prototype.a=function(b){this.s(new ny(b,this))};oy.prototype.Y=function(){oy.ca.Y.call(this);delete this.tb}; -function py(b){var c=new ay;b.Ra("loadend",va(function(b,c){var f=c.tb.result,g=c.getError();null==f||g?(cy(b),dy(b,!1,g)):b.ad(f);c.Fc()},c,b));return c};function qy(b){b=b?b:{};Lk.call(this,{handleEvent:te});this.j=b.formatConstructors?b.formatConstructors:[];this.v=b.projection?Ee(b.projection):null;this.c=null;this.a=void 0}y(qy,Lk);qy.prototype.Y=function(){this.a&&Wc(this.a);qy.ca.Y.call(this)};qy.prototype.l=function(b){b=b.a.dataTransfer.files;var c,d,e;c=0;for(d=b.length;c<d;++c){e=b[c];var f;f=e;var g=new oy,h=py(g);g.tb.readAsText(f,"");f=h;e=va(this.o,e);gy(f,e,null,this)}}; -qy.prototype.o=function(b,c){var d=this.B,e=this.v;e||(e=d.aa().g);var d=this.j,f=[],g,h;g=0;for(h=d.length;g<h;++g){var k=new d[g],m;try{m=k.Ba(c)}catch(t){m=null}if(m){var k=k.Ia(c),k=We(k,e),n,p;n=0;for(p=m.length;n<p;++n){var q=m[n],r=q.X();r&&r.pc(k);f.push(q)}}}this.s(new ry(sy,this,b,f,e))};qy.prototype.setMap=function(b){this.a&&(Wc(this.a),this.a=void 0);this.c&&(sc(this.c),this.c=null);qy.ca.setMap.call(this,b);b&&(this.c=new $x(b.a),this.a=D(this.c,"drop",this.l,!1,this))};var sy="addfeatures"; -function ry(b,c,d,e,f){tc.call(this,b,c);this.features=e;this.file=d;this.projection=f}y(ry,tc);function ty(b,c){this.x=b;this.y=c}y(ty,yg);ty.prototype.clone=function(){return new ty(this.x,this.y)};ty.prototype.scale=yg.prototype.scale;ty.prototype.add=function(b){this.x+=b.x;this.y+=b.y;return this};ty.prototype.rotate=function(b){var c=Math.cos(b);b=Math.sin(b);var d=this.y*c+this.x*b;this.x=this.x*c-this.y*b;this.y=d;return this};function uy(b){b=b?b:{};Yk.call(this,{handleDownEvent:vy,handleDragEvent:wy,handleUpEvent:xy});this.o=b.condition?b.condition:Vk;this.a=this.c=void 0;this.l=0;this.v=void 0!==b.duration?b.duration:400}y(uy,Yk); -function wy(b){if(Xk(b)){var c=b.map,d=c.Sa();b=b.pixel;b=new ty(b[0]-d[0]/2,d[1]/2-b[1]);d=Math.atan2(b.y,b.x);b=Math.sqrt(b.x*b.x+b.y*b.y);var e=c.aa();c.render();if(void 0!==this.c){var f=d-this.c;Mk(c,e,e.Fa()-f)}this.c=d;void 0!==this.a&&(d=this.a*(e.$()/b),Ok(c,e,d));void 0!==this.a&&(this.l=this.a/b);this.a=b}} -function xy(b){if(!Xk(b))return!0;b=b.map;var c=b.aa();Sf(c,-1);var d=this.l-1,e=c.Fa(),e=c.constrainRotation(e,0);Mk(b,c,e,void 0,void 0);var e=c.$(),f=this.v,e=c.constrainResolution(e,0,d);Ok(b,c,e,void 0,f);this.l=0;return!1}function vy(b){return Xk(b)&&this.o(b)?(Sf(b.map.aa(),1),this.a=this.c=void 0,!0):!1};function yy(b,c){tc.call(this,b);this.feature=c}y(yy,tc); -function zy(b){Yk.call(this,{handleDownEvent:Ay,handleEvent:By,handleUpEvent:Cy});this.ga=null;this.T=!1;this.nc=b.source?b.source:null;this.Db=b.features?b.features:null;this.jj=b.snapTolerance?b.snapTolerance:12;this.V=b.type;this.c=Dy(this.V);this.hb=b.minPoints?b.minPoints:this.c===Ey?3:2;this.wa=b.maxPoints?b.maxPoints:Infinity;var c=b.geometryFunction;if(!c)if("Circle"===this.V)c=function(b,c){var d=c?c:new Nx([NaN,NaN]);d.Uf(b[0],Math.sqrt(vd(b[0],b[1])));return d};else{var d,c=this.c;c=== -Fy?d=E:c===Gy?d=T:c===Ey&&(d=F);c=function(b,c){var g=c;g?g.la(b):g=new d(b);return g}}this.D=c;this.U=this.v=this.a=this.O=this.l=this.o=null;this.sj=b.clickTolerance?b.clickTolerance*b.clickTolerance:36;this.oa=new H({source:new R({useSpatialIndex:!1,wrapX:b.wrapX?b.wrapX:!1}),style:b.style?b.style:Hy()});this.Eb=b.geometryName;this.Ci=b.condition?b.condition:Uk;this.pa=b.freehandCondition?b.freehandCondition:Vk;D(this,id("active"),this.ni,!1,this)}y(zy,Yk); -function Hy(){var b=em();return function(c){return b[c.X().W()]}}l=zy.prototype;l.setMap=function(b){zy.ca.setMap.call(this,b);this.ni()};function By(b){var c=!this.T;this.T&&b.type===Wj?(Iy(this,b),c=!1):b.type===Vj?c=Jy(this,b):b.type===Pj&&(c=!1);return Zk.call(this,b)&&c}function Ay(b){if(this.Ci(b))return this.ga=b.pixel,!0;if(this.c!==Gy&&this.c!==Ey||!this.pa(b))return!1;this.ga=b.pixel;this.T=!0;this.o||Ky(this,b);return!0} -function Cy(b){this.T=!1;var c=this.ga,d=b.pixel,e=c[0]-d[0],c=c[1]-d[1],d=!0;e*e+c*c<=this.sj&&(Jy(this,b),this.o?this.c===Ly?this.od():My(this,b)?this.od():Iy(this,b):(Ky(this,b),this.c===Fy&&this.od()),d=!1);return d} -function Jy(b,c){if(b.o){var d=c.coordinate,e=b.l.X(),f;b.c===Fy?f=b.a:b.c===Ey?(f=b.a[0],f=f[f.length-1],My(b,c)&&(d=b.o.slice())):(f=b.a,f=f[f.length-1]);f[0]=d[0];f[1]=d[1];b.D(b.a,e);b.O&&b.O.X().la(d);e instanceof F&&b.c!==Ey?(b.v||(b.v=new pn(new T(null))),e=e.Dg(0),d=b.v.X(),d.ba(e.b,e.ia())):b.U&&(d=b.v.X(),d.la(b.U));Ny(b)}else d=c.coordinate.slice(),b.O?b.O.X().la(d):(b.O=new pn(new E(d)),Ny(b));return!0} -function My(b,c){var d=!1;if(b.l){var e=!1,f=[b.o];b.c===Gy?e=b.a.length>b.hb:b.c===Ey&&(e=b.a[0].length>b.hb,f=[b.a[0][0],b.a[0][b.a[0].length-2]]);if(e)for(var e=c.map,g=0,h=f.length;g<h;g++){var k=f[g],m=e.Pa(k),n=c.pixel,d=n[0]-m[0],m=n[1]-m[1],n=b.T&&b.pa(c)?1:b.jj;if(d=Math.sqrt(d*d+m*m)<=n){b.o=k;break}}}return d} -function Ky(b,c){var d=c.coordinate;b.o=d;b.c===Fy?b.a=d.slice():b.c===Ey?(b.a=[[d.slice(),d.slice()]],b.U=b.a[0]):(b.a=[d.slice(),d.slice()],b.c===Ly&&(b.U=b.a));b.U&&(b.v=new pn(new T(b.U)));d=b.D(b.a);b.l=new pn;b.Eb&&b.l.yc(b.Eb);b.l.Ma(d);Ny(b);b.s(new yy("drawstart",b.l))} -function Iy(b,c){var d=c.coordinate,e=b.l.X(),f,g;if(b.c===Gy)b.o=d.slice(),g=b.a,g.push(d.slice()),f=g.length>b.wa,b.D(g,e);else if(b.c===Ey){g=b.a[0];g.push(d.slice());if(f=g.length>b.wa)b.o=g[0];b.D(b.a,e)}Ny(b);f&&b.od()}l.Ao=function(){var b=this.l.X(),c,d;this.c===Gy?(c=this.a,c.splice(-2,1),this.D(c,b)):this.c===Ey&&(c=this.a[0],c.splice(-2,1),d=this.v.X(),d.la(c),this.D(this.a,b));0===c.length&&(this.o=null);Ny(this)}; -l.od=function(){var b=Oy(this),c=this.a,d=b.X();this.c===Gy?(c.pop(),this.D(c,d)):this.c===Ey&&(c[0].pop(),c[0].push(c[0][0]),this.D(c,d));"MultiPoint"===this.V?b.Ma(new Xr([c])):"MultiLineString"===this.V?b.Ma(new U([c])):"MultiPolygon"===this.V&&b.Ma(new V([c]));this.s(new yy("drawend",b));this.Db&&this.Db.push(b);this.nc&&this.nc.Bd(b)};function Oy(b){b.o=null;var c=b.l;c&&(b.l=null,b.O=null,b.v=null,b.oa.ea().clear(!0));return c} -l.fm=function(b){var c=b.X();this.l=b;this.a=c.Z();b=this.a[this.a.length-1];this.o=b.slice();this.a.push(b.slice());Ny(this);this.s(new yy("drawstart",this.l))};l.Ac=se;function Ny(b){var c=[];b.l&&c.push(b.l);b.v&&c.push(b.v);b.O&&c.push(b.O);b=b.oa.ea();b.clear(!0);b.Ec(c)}l.ni=function(){var b=this.B,c=this.b();b&&c||Oy(this);this.oa.setMap(c?b:null)}; -function Dy(b){var c;"Point"===b||"MultiPoint"===b?c=Fy:"LineString"===b||"MultiLineString"===b?c=Gy:"Polygon"===b||"MultiPolygon"===b?c=Ey:"Circle"===b&&(c=Ly);return c}var Fy="Point",Gy="LineString",Ey="Polygon",Ly="Circle";function Py(b,c,d){tc.call(this,b);this.features=c;this.mapBrowserPointerEvent=d}y(Py,tc); -function Qy(b){Yk.call(this,{handleDownEvent:Ry,handleDragEvent:Sy,handleEvent:Ty,handleUpEvent:Uy});this.wa=b.deleteCondition?b.deleteCondition:ye(Uk,Tk);this.pa=this.c=null;this.ga=[0,0];this.D=this.T=!1;this.a=new zp;this.O=void 0!==b.pixelTolerance?b.pixelTolerance:10;this.o=this.oa=!1;this.l=null;this.U=new H({source:new R({useSpatialIndex:!1,wrapX:!!b.wrapX}),style:b.style?b.style:Vy(),updateWhileAnimating:!0,updateWhileInteracting:!0});this.V={Point:this.mm,LineString:this.eh,LinearRing:this.eh, -Polygon:this.nm,MultiPoint:this.km,MultiLineString:this.jm,MultiPolygon:this.lm,GeometryCollection:this.im};this.v=b.features;this.v.forEach(this.Af,this);D(this.v,"add",this.gm,!1,this);D(this.v,"remove",this.hm,!1,this)}y(Qy,Yk);l=Qy.prototype;l.Af=function(b){var c=b.X();c.W()in this.V&&this.V[c.W()].call(this,b,c);(c=this.B)&&Wy(this,this.ga,c);D(b,"change",this.dh,!1,this)};function Xy(b,c){b.D||(b.D=!0,b.s(new Py("modifystart",b.v,c)))} -function Yy(b,c){Zy(b,c);b.c&&0===b.v.$b()&&(b.U.ea().Rc(b.c),b.c=null);Vc(c,"change",b.dh,!1,b)}function Zy(b,c){var d=b.a,e=[];d.forEach(function(b){c===b.feature&&e.push(b)});for(var f=e.length-1;0<=f;--f)d.remove(e[f])}l.setMap=function(b){this.U.setMap(b);Qy.ca.setMap.call(this,b)};l.gm=function(b){this.Af(b.element)};l.dh=function(b){this.o||(b=b.target,Yy(this,b),this.Af(b))};l.hm=function(b){Yy(this,b.element)}; -l.mm=function(b,c){var d=c.Z(),d={feature:b,geometry:c,ka:[d,d]};this.a.ya(c.J(),d)};l.km=function(b,c){var d=c.Z(),e,f,g;f=0;for(g=d.length;f<g;++f)e=d[f],e={feature:b,geometry:c,depth:[f],index:f,ka:[e,e]},this.a.ya(c.J(),e)};l.eh=function(b,c){var d=c.Z(),e,f,g,h;e=0;for(f=d.length-1;e<f;++e)g=d.slice(e,e+2),h={feature:b,geometry:c,index:e,ka:g},this.a.ya(Ld(g),h)}; -l.jm=function(b,c){var d=c.Z(),e,f,g,h,k,m,n;h=0;for(k=d.length;h<k;++h)for(e=d[h],f=0,g=e.length-1;f<g;++f)m=e.slice(f,f+2),n={feature:b,geometry:c,depth:[h],index:f,ka:m},this.a.ya(Ld(m),n)};l.nm=function(b,c){var d=c.Z(),e,f,g,h,k,m,n;h=0;for(k=d.length;h<k;++h)for(e=d[h],f=0,g=e.length-1;f<g;++f)m=e.slice(f,f+2),n={feature:b,geometry:c,depth:[h],index:f,ka:m},this.a.ya(Ld(m),n)}; -l.lm=function(b,c){var d=c.Z(),e,f,g,h,k,m,n,p,q,r;m=0;for(n=d.length;m<n;++m)for(p=d[m],h=0,k=p.length;h<k;++h)for(e=p[h],f=0,g=e.length-1;f<g;++f)q=e.slice(f,f+2),r={feature:b,geometry:c,depth:[h,m],index:f,ka:q},this.a.ya(Ld(q),r)};l.im=function(b,c){var d,e=c.c;for(d=0;d<e.length;++d)this.V[e[d].W()].call(this,b,e[d])};function $y(b,c){var d=b.c;d?d.X().la(c):(d=new pn(new E(c)),b.c=d,b.U.ea().Bd(d))}function az(b,c){return b.index-c.index} -function Ry(b){Wy(this,b.pixel,b.map);this.l=[];this.D=!1;var c=this.c;if(c){var d=[],c=c.X().Z(),e=Ld([c]),e=Cp(this.a,e),f={};e.sort(az);for(var g=0,h=e.length;g<h;++g){var k=e[g],m=k.ka,n=w(k.feature),p=k.depth;p&&(n+="-"+p.join("-"));f[n]||(f[n]=Array(2));if(td(m[0],c)&&!f[n][0])this.l.push([k,0]),f[n][0]=k;else if(td(m[1],c)&&!f[n][1]){if("LineString"!==k.geometry.W()&&"MultiLineString"!==k.geometry.W()||!f[n][0]||0!==f[n][0].index)this.l.push([k,1]),f[n][1]=k}else w(m)in this.pa&&!f[n][0]&& -!f[n][1]&&d.push([k,c])}d.length&&Xy(this,b);for(g=d.length-1;0<=g;--g)this.el.apply(this,d[g])}return!!this.c} -function Sy(b){this.T=!1;Xy(this,b);b=b.coordinate;for(var c=0,d=this.l.length;c<d;++c){for(var e=this.l[c],f=e[0],g=f.depth,h=f.geometry,k=h.Z(),m=f.ka,e=e[1];b.length<h.ra();)b.push(0);switch(h.W()){case "Point":k=b;m[0]=m[1]=b;break;case "MultiPoint":k[f.index]=b;m[0]=m[1]=b;break;case "LineString":k[f.index+e]=b;m[e]=b;break;case "MultiLineString":k[g[0]][f.index+e]=b;m[e]=b;break;case "Polygon":k[g[0]][f.index+e]=b;m[e]=b;break;case "MultiPolygon":k[g[1]][g[0]][f.index+e]=b,m[e]=b}f=h;this.o= -!0;f.la(k);this.o=!1}$y(this,b)}function Uy(b){for(var c,d=this.l.length-1;0<=d;--d)c=this.l[d][0],Ap(this.a,Ld(c.ka),c);this.D&&(this.s(new Py("modifyend",this.v,b)),this.D=!1);return!1} -function Ty(b){if(!(b instanceof Lj))return!0;var c;b.map.aa().b.slice()[1]||b.type!=Vj||this.C||(this.ga=b.pixel,Wy(this,b.pixel,b.map));if(this.c&&this.wa(b))if(b.type==Qj&&this.T)c=!0;else{this.c.X();Xy(this,b);c=this.l;var d={},e,f,g,h,k,m,n,p,q;for(k=c.length-1;0<=k;--k)if(g=c[k],p=g[0],h=p.geometry,f=h.Z(),q=w(p.feature),p.depth&&(q+="-"+p.depth.join("-")),n=e=m=void 0,0===g[1]?(e=p,m=p.index):1==g[1]&&(n=p,m=p.index+1),q in d||(d[q]=[n,e,m]),g=d[q],void 0!==n&&(g[0]=n),void 0!==e&&(g[1]=e), -void 0!==g[0]&&void 0!==g[1]){e=f;q=!1;n=m-1;switch(h.W()){case "MultiLineString":f[p.depth[0]].splice(m,1);q=!0;break;case "LineString":f.splice(m,1);q=!0;break;case "MultiPolygon":e=e[p.depth[1]];case "Polygon":e=e[p.depth[0]],4<e.length&&(m==e.length-1&&(m=0),e.splice(m,1),q=!0,0===m&&(e.pop(),e.push(e[0]),n=e.length-1))}q&&(this.a.remove(g[0]),this.a.remove(g[1]),e=h,this.o=!0,e.la(f),this.o=!1,f={depth:p.depth,feature:p.feature,geometry:p.geometry,index:n,ka:[g[0].ka[0],g[1].ka[1]]},this.a.ya(Ld(f.ka), -f),bz(this,h,m,p.depth,-1),this.c&&(this.U.ea().Rc(this.c),this.c=null))}c=!0;this.s(new Py("modifyend",this.v,b));this.D=!1}b.type==Qj&&(this.T=!1);return Zk.call(this,b)&&!c} -function Wy(b,c,d){function e(b,c){return wd(f,b.ka)-wd(f,c.ka)}var f=d.Ga(c),g=d.Ga([c[0]-b.O,c[1]+b.O]),h=d.Ga([c[0]+b.O,c[1]-b.O]),g=Ld([g,h]),g=Cp(b.a,g);if(0<g.length){g.sort(e);var h=g[0].ka,k=qd(f,h),m=d.Pa(k);if(Math.sqrt(vd(c,m))<=b.O){c=d.Pa(h[0]);d=d.Pa(h[1]);c=vd(m,c);d=vd(m,d);b.oa=Math.sqrt(Math.min(c,d))<=b.O;b.oa&&(k=c>d?h[1]:h[0]);$y(b,k);d={};d[w(h)]=!0;c=1;for(m=g.length;c<m;++c)if(k=g[c].ka,td(h[0],k[0])&&td(h[1],k[1])||td(h[0],k[1])&&td(h[1],k[0]))d[w(k)]=!0;else break;b.pa=d; -return}}b.c&&(b.U.ea().Rc(b.c),b.c=null)} -l.el=function(b,c){for(var d=b.ka,e=b.feature,f=b.geometry,g=b.depth,h=b.index,k;c.length<f.ra();)c.push(0);switch(f.W()){case "MultiLineString":k=f.Z();k[g[0]].splice(h+1,0,c);break;case "Polygon":k=f.Z();k[g[0]].splice(h+1,0,c);break;case "MultiPolygon":k=f.Z();k[g[1]][g[0]].splice(h+1,0,c);break;case "LineString":k=f.Z();k.splice(h+1,0,c);break;default:return}this.o=!0;f.la(k);this.o=!1;k=this.a;k.remove(b);bz(this,f,h,g,1);var m={ka:[d[0],c],feature:e,geometry:f,depth:g,index:h};k.ya(Ld(m.ka), -m);this.l.push([m,1]);d={ka:[c,d[1]],feature:e,geometry:f,depth:g,index:h+1};k.ya(Ld(d.ka),d);this.l.push([d,0]);this.T=!0};function bz(b,c,d,e,f){Ep(b.a,c.J(),function(b){b.geometry===c&&(void 0===e||void 0===b.depth||rb(b.depth,e))&&b.index>d&&(b.index+=f)})}function Vy(){var b=em();return function(){return b.Point}};function cz(b,c,d,e){tc.call(this,b);this.selected=c;this.deselected=d;this.mapBrowserEvent=e}y(cz,tc); -function dz(b){Lk.call(this,{handleEvent:ez});b=b?b:{};this.C=b.condition?b.condition:Tk;this.o=b.addCondition?b.addCondition:se;this.D=b.removeCondition?b.removeCondition:se;this.O=b.toggleCondition?b.toggleCondition:Vk;this.v=b.multi?b.multi:!1;this.j=b.filter?b.filter:te;var c;if(b.layers)if(ka(b.layers))c=b.layers;else{var d=b.layers;c=function(b){return vb(d,b)}}else c=te;this.l=c;this.a={};this.c=new H({source:new R({useSpatialIndex:!1,features:b.features,wrapX:b.wrapX}),style:b.style?b.style: -fz(),updateWhileAnimating:!0,updateWhileInteracting:!0});b=this.c.ea().c;D(b,"add",this.om,!1,this);D(b,"remove",this.rm,!1,this)}y(dz,Lk);l=dz.prototype;l.pm=function(){return this.c.ea().c};l.qm=function(b){b=w(b);return this.a[b]}; -function ez(b){if(!this.C(b))return!0;var c=this.o(b),d=this.D(b),e=this.O(b),f=!c&&!d&&!e,g=b.map,h=this.c.ea().c,k=[],m=[],n=!1;if(f)g.pd(b.pixel,function(b,c){if(this.j(b,c)){m.push(b);var d=w(b);this.a[d]=c;return!this.v}},this,this.l),0<m.length&&1==h.$b()&&h.item(0)==m[0]||(n=!0,0!==h.$b()&&(k=Array.prototype.concat(h.a),h.clear()),h.uf(m),0===m.length?Qb(this.a):0<k.length&&k.forEach(function(b){b=w(b);delete this.a[b]},this));else{g.pd(b.pixel,function(b,f){if(!vb(h.a,b)){if((c||e)&&this.j(b, -f)){m.push(b);var g=w(b);this.a[g]=f}}else if(d||e)k.push(b),g=w(b),delete this.a[g]},this,this.l);for(f=k.length-1;0<=f;--f)h.remove(k[f]);h.uf(m);if(0<m.length||0<k.length)n=!0}n&&this.s(new cz("select",m,k,b));return Sk(b)}l.setMap=function(b){var c=this.B,d=this.c.ea().c;c&&d.forEach(c.li,c);dz.ca.setMap.call(this,b);this.c.setMap(b);b&&d.forEach(b.ii,b)};function fz(){var b=em();kb(b.Polygon,b.LineString);kb(b.GeometryCollection,b.LineString);return function(c){return b[c.X().W()]}} -l.om=function(b){b=b.element;var c=this.B;c&&c.ii(b)};l.rm=function(b){b=b.element;var c=this.B;c&&c.li(b)};function gz(b){Yk.call(this,{handleEvent:hz,handleDownEvent:te,handleUpEvent:iz});b=b?b:{};this.o=b.source?b.source:null;this.l=b.features?b.features:null;this.ga=[];this.D={};this.O={};this.T={};this.v={};this.U=null;this.c=void 0!==b.pixelTolerance?b.pixelTolerance:10;this.oa=ua(jz,this);this.a=new zp;this.V={Point:this.xm,LineString:this.hh,LinearRing:this.hh,Polygon:this.ym,MultiPoint:this.vm,MultiLineString:this.um,MultiPolygon:this.wm,GeometryCollection:this.tm}}y(gz,Yk);l=gz.prototype; -l.xd=function(b,c){var d=void 0!==c?c:!0,e=b.X(),f=this.V[e.W()];if(f){var g=w(b);this.T[g]=e.J(Md());f.call(this,b,e);d&&(this.O[g]=e.H("change",ua(this.Ck,this,b),this),this.D[g]=b.H(id(b.a),this.sm,this))}};l.Aj=function(b){this.xd(b)};l.Bj=function(b){this.yd(b)};l.fh=function(b){var c;b instanceof Jp?c=b.feature:b instanceof ng&&(c=b.element);this.xd(c)};l.gh=function(b){var c;b instanceof Jp?c=b.feature:b instanceof ng&&(c=b.element);this.yd(c)}; -l.sm=function(b){b=b.g;this.yd(b,!0);this.xd(b,!0)};l.Ck=function(b){if(this.C){var c=w(b);c in this.v||(this.v[c]=b)}else this.mi(b)};l.yd=function(b,c){var d=void 0!==c?c:!0,e=w(b),f=this.T[e];if(f){var g=this.a,h=[];Ep(g,f,function(c){b===c.feature&&h.push(c)});for(f=h.length-1;0<=f;--f)g.remove(h[f]);d&&(Wc(this.O[e]),delete this.O[e],Wc(this.D[e]),delete this.D[e])}}; -l.setMap=function(b){var c=this.B,d=this.ga,e;this.l?e=this.l:this.o&&(e=this.o.ze());c&&(d.forEach(ed),d.length=0,e.forEach(this.Bj,this));gz.ca.setMap.call(this,b);b&&(this.l?(d.push(this.l.H("add",this.fh,this)),d.push(this.l.H("remove",this.gh,this))):this.o&&(d.push(this.o.H("addfeature",this.fh,this)),d.push(this.o.H("removefeature",this.gh,this))),e.forEach(this.Aj,this))};l.Ac=se;l.mi=function(b){this.yd(b,!1);this.xd(b,!1)}; -l.tm=function(b,c){var d,e=c.c;for(d=0;d<e.length;++d)this.V[e[d].W()].call(this,b,e[d])};l.hh=function(b,c){var d=c.Z(),e,f,g,h;e=0;for(f=d.length-1;e<f;++e)g=d.slice(e,e+2),h={feature:b,ka:g},this.a.ya(Ld(g),h)};l.um=function(b,c){var d=c.Z(),e,f,g,h,k,m,n;h=0;for(k=d.length;h<k;++h)for(e=d[h],f=0,g=e.length-1;f<g;++f)m=e.slice(f,f+2),n={feature:b,ka:m},this.a.ya(Ld(m),n)};l.vm=function(b,c){var d=c.Z(),e,f,g;f=0;for(g=d.length;f<g;++f)e=d[f],e={feature:b,ka:[e,e]},this.a.ya(c.J(),e)}; -l.wm=function(b,c){var d=c.Z(),e,f,g,h,k,m,n,p,q,r;m=0;for(n=d.length;m<n;++m)for(p=d[m],h=0,k=p.length;h<k;++h)for(e=p[h],f=0,g=e.length-1;f<g;++f)q=e.slice(f,f+2),r={feature:b,ka:q},this.a.ya(Ld(q),r)};l.xm=function(b,c){var d=c.Z(),d={feature:b,ka:[d,d]};this.a.ya(c.J(),d)};l.ym=function(b,c){var d=c.Z(),e,f,g,h,k,m,n;h=0;for(k=d.length;h<k;++h)for(e=d[h],f=0,g=e.length-1;f<g;++f)m=e.slice(f,f+2),n={feature:b,ka:m},this.a.ya(Ld(m),n)}; -function hz(b){var c,d,e=b.pixel,f=b.coordinate;c=b.map;var g=c.Ga([e[0]-this.c,e[1]+this.c]);d=c.Ga([e[0]+this.c,e[1]-this.c]);var g=Ld([g,d]),h=Cp(this.a,g),k=!1,g=!1,m=null;d=null;0<h.length&&(this.U=f,h.sort(this.oa),h=h[0].ka,m=qd(f,h),d=c.Pa(m),Math.sqrt(vd(e,d))<=this.c&&(g=!0,e=c.Pa(h[0]),f=c.Pa(h[1]),e=vd(d,e),f=vd(d,f),k=Math.sqrt(Math.min(e,f))<=this.c))&&(m=e>f?h[1]:h[0],d=c.Pa(m),d=[Math.round(d[0]),Math.round(d[1])]);c=m;g&&(b.coordinate=c.slice(0,2),b.pixel=d);return Zk.call(this,b)} -function iz(){var b=Lb(this.v);b.length&&(b.forEach(this.mi,this),this.v={});return!1}function jz(b,c){return wd(this.U,b.ka)-wd(this.U,c.ka)};function kz(b,c,d){tc.call(this,b);this.features=c;this.coordinate=d}y(kz,tc);function lz(b){Yk.call(this,{handleDownEvent:mz,handleDragEvent:nz,handleMoveEvent:oz,handleUpEvent:pz});this.o=void 0;this.a=null;this.c=void 0!==b.features?b.features:null;this.l=null}y(lz,Yk);function mz(b){this.l=qz(this,b.pixel,b.map);return!this.a&&this.l?(this.a=b.coordinate,oz.call(this,b),this.s(new kz("translatestart",this.c,b.coordinate)),!0):!1} -function pz(b){return this.a?(this.a=null,oz.call(this,b),this.s(new kz("translateend",this.c,b.coordinate)),!0):!1}function nz(b){if(this.a){b=b.coordinate;var c=b[0]-this.a[0],d=b[1]-this.a[1];if(this.c)this.c.forEach(function(b){var e=b.X();e.Pc(c,d);b.Ma(e)});else if(this.l){var e=this.l.X();e.Pc(c,d);this.l.Ma(e)}this.a=b;this.s(new kz("translating",this.c,b))}} -function oz(b){var c=b.map.Mc();if(b=b.map.pd(b.pixel,function(b){return b})){var d=!1;this.c&&vb(this.c.a,b)&&(d=!0);this.o=c.style.cursor;c.style.cursor=this.a?"-webkit-grabbing":d?"-webkit-grab":"pointer";c.style.cursor=this.a?d?"grab":"pointer":"grabbing"}else c.style.cursor=void 0!==this.o?this.o:"",this.o=void 0}function qz(b,c,d){var e=null;c=d.pd(c,function(b){return b});b.c&&vb(b.c.a,c)&&(e=c);return e};function X(b){b=b?b:{};var c=Tb(b);delete c.gradient;delete c.radius;delete c.blur;delete c.shadow;delete c.weight;H.call(this,c);this.g=null;this.V=void 0!==b.shadow?b.shadow:250;this.T=void 0;this.U=null;D(this,id("gradient"),this.Dk,!1,this);this.Zh(b.gradient?b.gradient:rz);this.Vh(void 0!==b.blur?b.blur:15);this.kh(void 0!==b.radius?b.radius:8);D(this,[id("blur"),id("radius")],this.Ng,!1,this);this.Ng();var d=b.weight?b.weight:"weight",e;ia(d)?e=function(b){return b.get(d)}:e=d;this.c(ua(function(b){b= -e(b);b=void 0!==b?Sa(b,0,1):1;var c=255*b|0,d=this.U[c];d||(d=[new $l({image:new tk({opacity:b,src:this.T})})],this.U[c]=d);return d},this));this.set("renderOrder",null);D(this,"render",this.Vk,!1,this)}y(X,H);var rz=["#00f","#0ff","#0f0","#ff0","#f00"];l=X.prototype;l.ug=function(){return this.get("blur")};l.Bg=function(){return this.get("gradient")};l.jh=function(){return this.get("radius")}; -l.Dk=function(){for(var b=this.Bg(),c=Ni(1,256),d=c.createLinearGradient(0,0,1,256),e=1/(b.length-1),f=0,g=b.length;f<g;++f)d.addColorStop(f*e,b[f]);c.fillStyle=d;c.fillRect(0,0,1,256);this.g=c.getImageData(0,0,1,256).data};l.Ng=function(){var b=this.jh(),c=this.ug(),d=b+c+1,e=2*d,e=Ni(e,e);e.shadowOffsetX=e.shadowOffsetY=this.V;e.shadowBlur=c;e.shadowColor="#000";e.beginPath();c=d-this.V;e.arc(c,c,b,0,2*Math.PI,!0);e.fill();this.T=e.canvas.toDataURL();this.U=Array(256);this.u()}; -l.Vk=function(b){b=b.context;var c=b.canvas,c=b.getImageData(0,0,c.width,c.height),d=c.data,e,f,g;e=0;for(f=d.length;e<f;e+=4)if(g=4*d[e+3])d[e]=this.g[g],d[e+1]=this.g[g+1],d[e+2]=this.g[g+2];b.putImageData(c,0,0)};l.Vh=function(b){this.set("blur",b)};l.Zh=function(b){this.set("gradient",b)};l.kh=function(b){this.set("radius",b)};function sz(b,c,d,e,f,g,h,k,m,n){uh.call(this,f,0);this.D=void 0!==n?n:!1;this.C=h;this.j=null;this.i={};this.l=c;this.G=e;this.B=g?g:f;this.b=[];this.c=null;this.o=0;g=e.Aa(this.B);n=this.G.J();f=this.l.J();g=n?ne(g,n):g;if(0===he(g))this.state=4;else if((n=b.J())&&(f?f=ne(f,n):f=n),e=e.$(this.B[0]),e=Zm(b,d,le(g),e),!isFinite(e)||isNaN(e)||0>=e)this.state=4;else if(this.v=new bn(b,d,g,f,e*(void 0!==m?m:.5)),0===this.v.c.length)this.state=4;else if(this.o=Ih(c,e),d=dn(this.v),f&&(b.b?(d[1]=Sa(d[1], -f[1],f[3]),d[3]=Sa(d[3],f[1],f[3])):d=ne(d,f)),he(d))if(b=Dh(c,d,this.o),100>kg(b)*jg(b)){for(c=b.a;c<=b.c;c++)for(d=b.f;d<=b.b;d++)(m=k(this.o,c,d,h))&&this.b.push(m);0===this.b.length&&(this.state=4)}else this.state=3;else this.state=4}y(sz,uh);sz.prototype.Y=function(){1==this.state&&(this.c.forEach(Wc),this.c=null);sz.ca.Y.call(this)};sz.prototype.Ta=function(b){if(void 0!==b){var c=w(b);if(c in this.i)return this.i[c];b=Pb(this.i)?this.j:this.j.cloneNode(!1);return this.i[c]=b}return this.j}; -function tz(b){var c=[];b.b.forEach(function(b){b&&2==b.state&&c.push({extent:this.l.Aa(b.a),image:b.Ta()})},b);b.b.length=0;var d=b.B[0],e=b.G.Ka(d),f=ja(e)?e:e[0],e=ja(e)?e:e[1],d=b.G.$(d),g=b.l.$(b.o),h=b.G.Aa(b.B);b.j=an(f,e,b.C,g,b.l.J(),d,h,b.v,c,b.D);b.state=2;vh(b)} -sz.prototype.load=function(){if(0==this.state){this.state=1;vh(this);var b=0;this.c=[];this.b.forEach(function(c){var d=c.state;if(0==d||1==d){b++;var e;e=c.Ra("change",function(){var d=c.state;if(2==d||3==d||4==d)Wc(e),b--,0===b&&(this.c.forEach(Wc),this.c=null,tz(this))},!1,this);this.c.push(e)}},this);this.b.forEach(function(b){0==b.state&&b.load()});0===b&&tz(this)}};function uz(b,c){var d=c||{},e=d.document||document,f=document.createElement("SCRIPT"),g={Uh:f,Bc:void 0},h=new ay(vz,g),k=null,m=null!=d.timeout?d.timeout:5E3;0<m&&(k=window.setTimeout(function(){wz(f,!0);var c=new xz(yz,"Timeout reached for loading script "+b);cy(h);dy(h,!1,c)},m),g.Bc=k);f.onload=f.onreadystatechange=function(){f.readyState&&"loaded"!=f.readyState&&"complete"!=f.readyState||(wz(f,d.vj||!1,k),h.ad(null))};f.onerror=function(){wz(f,!0,k);var c=new xz(zz,"Error while loading script "+ -b);cy(h);dy(h,!1,c)};g=d.attributes||{};Wb(g,{type:"text/javascript",charset:"UTF-8",src:b});Eg(f,g);Az(e).appendChild(f);return h}function Az(b){var c=b.getElementsByTagName("HEAD");return c&&0!=c.length?c[0]:b.documentElement}function vz(){if(this&&this.Uh){var b=this.Uh;b&&"SCRIPT"==b.tagName&&wz(b,!0,this.Bc)}}function wz(b,c,d){null!=d&&ba.clearTimeout(d);b.onload=da;b.onerror=da;b.onreadystatechange=da;c&&window.setTimeout(function(){Mg(b)},0)}var zz=0,yz=1; -function xz(b,c){var d="Jsloader error (code #"+b+")";c&&(d+=": "+c);Aa.call(this,d);this.code=b}y(xz,Aa);function Bz(b,c){this.f=new Ct(b);this.a=c?c:"callback";this.Bc=5E3}var Cz=0;function Dz(b,c,d,e){c=c||null;var f="_"+(Cz++).toString(36)+wa().toString(36);ba._callbacks_||(ba._callbacks_={});var g=b.f.clone();if(c)for(var h in c)if(!c.hasOwnProperty||c.hasOwnProperty(h)){var k=g,m=h,n=c[h];ga(n)||(n=[String(n)]);Vt(k.b,m,n)}d&&(ba._callbacks_[f]=Ez(f,d),d=b.a,h="_callbacks_."+f,ga(h)||(h=[String(h)]),Vt(g.b,d,h));b=uz(g.toString(),{timeout:b.Bc,vj:!0});gy(b,null,Fz(f,c,e),void 0)} -Bz.prototype.cancel=function(b){b&&(b.wj&&b.wj.cancel(),b.xa&&Gz(b.xa,!1))};function Fz(b,c,d){return function(){Gz(b,!1);d&&d(c)}}function Ez(b,c){return function(d){Gz(b,!0);c.apply(void 0,arguments)}}function Gz(b,c){ba._callbacks_[b]&&(c?delete ba._callbacks_[b]:ba._callbacks_[b]=da)};function Y(b){Wp.call(this,{attributions:b.attributions,extent:b.extent,logo:b.logo,opaque:b.opaque,projection:b.projection,state:void 0!==b.state?b.state:void 0,tileGrid:b.tileGrid,tileLoadFunction:b.tileLoadFunction?b.tileLoadFunction:Hz,tilePixelRatio:b.tilePixelRatio,tileUrlFunction:b.tileUrlFunction,url:b.url,urls:b.urls,wrapX:b.wrapX});this.crossOrigin=void 0!==b.crossOrigin?b.crossOrigin:null;this.tileClass=void 0!==b.tileClass?b.tileClass:Yx;this.j={};this.o={};this.wa=b.reprojectionErrorThreshold; -this.T=!1}y(Y,Wp);l=Y.prototype;l.qh=function(){return sh(this.a)?!0:Jb(this.j,function(b){return sh(b)})};l.rh=function(b,c){var d=this.ud(b);th(this.a,this.a==d?c:{});Ib(this.j,function(b){th(b,b==d?c:{})})};l.ib=function(b){var c=this.b;return!this.tileGrid||c&&!Ve(c,b)?(c=w(b).toString(),c in this.o||(this.o[c]=Jh(b)),this.o[c]):this.tileGrid};l.ud=function(b){var c=this.b;if(!c||Ve(c,b))return this.a;b=w(b).toString();b in this.j||(this.j[b]=new rh);return this.j[b]}; -function Iz(b,c,d,e,f,g,h){c=[c,d,e];f=(d=Ph(b,c,g))?b.tileUrlFunction(d,f,g):void 0;f=new b.tileClass(c,void 0!==f?0:4,void 0!==f?f:"",b.crossOrigin,b.tileLoadFunction);f.key=h;D(f,"change",b.sh,!1,b);return f} -l.Pb=function(b,c,d,e,f){if(this.b&&f&&!Ve(this.b,f)){e=this.ud(f);c=[b,c,d];b=this.Ab.apply(this,c);if(qh(e,b))return e.get(b);var g=this.b;d=this.ib(g);var h=this.ib(f),k=Ph(this,c,f);f=new sz(g,d,f,h,c,k,this.v,ua(function(b,c,d,e){return Jz(this,b,c,d,e,g)},this),this.wa,this.T);e.set(b,f);return f}return Jz(this,b,c,d,e,f)}; -function Jz(b,c,d,e,f,g){var h=null,k=b.Ab(c,d,e),m=b.Cg();if(qh(b.a,k)){if(h=b.a.get(k),h.key!=m){var n=h;h.f&&h.f.key==m?(h=h.f,2==n.state&&(h.f=n)):(h=Iz(b,c,d,e,f,g,m),2==n.state?h.f=n:n.f&&2==n.f.state&&(h.f=n.f,n.f=null));h.f&&(h.f.f=null);b.a.replace(k,h)}}else h=Iz(b,c,d,e,f,g,m),b.a.set(k,h);return h}l.vb=function(b){this.T!=b&&(this.T=b,Ib(this.j,function(b){b.clear()}),this.u())};l.wb=function(b,c){var d=Ee(b);d&&(d=w(d).toString(),d in this.o||(this.o[d]=c))}; -function Hz(b,c){b.Ta().src=c};function Kz(b){Y.call(this,{crossOrigin:"anonymous",opaque:!0,projection:Ee("EPSG:3857"),reprojectionErrorThreshold:b.reprojectionErrorThreshold,state:"loading",tileLoadFunction:b.tileLoadFunction,wrapX:void 0!==b.wrapX?b.wrapX:!0});this.l=void 0!==b.culture?b.culture:"en-us";this.g=void 0!==b.maxZoom?b.maxZoom:-1;var c=new Ct("https://dev.virtualearth.net/REST/v1/Imagery/Metadata/"+b.imagerySet);Dz(new Bz(c,"jsonp"),{include:"ImageryProviders",uriScheme:"https",key:b.key},ua(this.C,this))}y(Kz,Y); -var Lz=new mg({html:'<a class="ol-attribution-bing-tos" href="http://www.microsoft.com/maps/product/terms.html">Terms of Use</a>'}); -Kz.prototype.C=function(b){if(200!=b.statusCode||"OK"!=b.statusDescription||"ValidCredentials"!=b.authenticationResultCode||1!=b.resourceSets.length||1!=b.resourceSets[0].resources.length)yh(this,"error");else{var c=b.brandLogoUri;-1==c.indexOf("https")&&(c=c.replace("http","https"));var d=b.resourceSets[0].resources[0],e=-1==this.g?d.zoomMax:this.g;b=Kh(this.b);var f=Mh({extent:b,minZoom:d.zoomMin,maxZoom:e,tileSize:d.imageWidth==d.imageHeight?d.imageWidth:[d.imageWidth,d.imageHeight]});this.tileGrid= -f;var g=this.l;this.tileUrlFunction=Tp(d.imageUrlSubdomains.map(function(b){var c=[0,0,0],e=d.imageUrl.replace("{subdomain}",b).replace("{culture}",g);return function(b){if(b)return ag(b[0],b[1],-b[2]-1,c),e.replace("{quadkey}",dg(c))}}));if(d.imageryProviders){var h=Ie(Ee("EPSG:4326"),this.b);b=d.imageryProviders.map(function(b){var c=b.attribution,d={};b.coverageAreas.forEach(function(b){var c=b.zoomMin,g=Math.min(b.zoomMax,e);b=b.bbox;b=qe([b[1],b[0],b[3],b[2]],h);var k,m;for(k=c;k<=g;++k)m=k.toString(), -c=Dh(f,b,k),m in d?d[m].push(c):d[m]=[c]});return new mg({html:c,tileRanges:d})});b.push(Lz);this.ma(b)}this.U=c;yh(this,"ready")}};function Mz(b){R.call(this,{attributions:b.attributions,extent:b.extent,logo:b.logo,projection:b.projection,wrapX:b.wrapX});this.D=void 0;this.fa=void 0!==b.distance?b.distance:20;this.C=[];this.v=b.source;this.v.H("change",Mz.prototype.oa,this)}y(Mz,R);Mz.prototype.ga=function(){return this.v};Mz.prototype.Nc=function(b,c,d){this.v.Nc(b,c,d);c!==this.D&&(this.clear(),this.D=c,Nz(this),this.Ec(this.C))};Mz.prototype.oa=function(){this.clear();Nz(this);this.Ec(this.C);this.u()}; -function Nz(b){if(void 0!==b.D){b.C.length=0;for(var c=Md(),d=b.fa*b.D,e=b.v.ze(),f={},g=0,h=e.length;g<h;g++){var k=e[g];w(k).toString()in f||(k=k.X().Z(),Xd(k,c),Qd(c,d,c),k=b.v.mf(c),k=k.filter(function(b){b=w(b).toString();return b in f?!1:f[b]=!0}),b.C.push(Oz(k)))}}}function Oz(b){for(var c=b.length,d=[0,0],e=0;e<c;e++){var f=b[e].X().Z();pd(d,f)}c=1/c;d[0]*=c;d[1]*=c;d=new pn(new E(d));d.set("features",b);return d};function Pz(b){gn.call(this,{projection:b.projection,resolutions:b.resolutions});this.ga=void 0!==b.crossOrigin?b.crossOrigin:null;this.o=void 0!==b.displayDpi?b.displayDpi:96;this.j=void 0!==b.params?b.params:{};this.V=b.url;this.c=void 0!==b.imageLoadFunction?b.imageLoadFunction:nn;this.pa=void 0!==b.hidpi?b.hidpi:!0;this.fa=void 0!==b.metersPerUnit?b.metersPerUnit:1;this.v=void 0!==b.ratio?b.ratio:1;this.wa=void 0!==b.useOverlay?b.useOverlay:!1;this.g=null;this.T=0}y(Pz,gn);l=Pz.prototype; -l.Hm=function(){return this.j}; -l.qd=function(b,c,d){c=hn(this,c);d=this.pa?d:1;var e=this.g;if(e&&this.T==this.f&&e.$()==c&&e.b==d&&Vd(e.J(),b))return e;1!=this.v&&(b=b.slice(),pe(b,this.v));var f=[je(b)/c*d,ke(b)/c*d];if(void 0!==this.V){var e=this.V,g=le(b),h=this.fa,k=je(b),m=ke(b),n=f[0],p=f[1],q=.0254/this.o,f={OPERATION:this.wa?"GETDYNAMICMAPOVERLAYIMAGE":"GETMAPIMAGE",VERSION:"2.0.0",LOCALE:"en",CLIENTAGENT:"ol.source.ImageMapGuide source",CLIP:"1",SETDISPLAYDPI:this.o,SETDISPLAYWIDTH:Math.round(f[0]),SETDISPLAYHEIGHT:Math.round(f[1]), -SETVIEWSCALE:p*k>n*m?k*h/(n*q):m*h/(p*q),SETVIEWCENTERX:g[0],SETVIEWCENTERY:g[1]};Wb(f,this.j);e=io(ko([e],f));e=new Xx(b,c,d,this.i,e,this.ga,this.c);D(e,"change",this.l,!1,this)}else e=null;this.g=e;this.T=this.f;return e};l.Gm=function(){return this.c};l.Jm=function(b){Wb(this.j,b);this.u()};l.Im=function(b){this.g=null;this.c=b;this.u()};function Qz(b){var c=void 0!==b.attributions?b.attributions:null,d=b.imageExtent,e=void 0!==b.crossOrigin?b.crossOrigin:null,f=void 0!==b.imageLoadFunction?b.imageLoadFunction:nn;gn.call(this,{attributions:c,logo:b.logo,projection:Ee(b.projection)});this.c=new Xx(d,void 0,1,c,b.url,e,f);this.g=b.imageSize?b.imageSize:null;D(this.c,"change",this.l,!1,this)}y(Qz,gn);Qz.prototype.qd=function(b){return oe(b,this.c.J())?this.c:null}; -Qz.prototype.l=function(b){if(2==this.c.state){var c=this.c.J(),d=this.c.a(),e,f;this.g?(e=this.g[0],f=this.g[1]):(e=d.width,f=d.height);c=Math.ceil(je(c)/(ke(c)/f));if(c!=e){var g=document.createElement("canvas");g.width=c;g.height=f;g.getContext("2d").drawImage(d,0,0,e,f,0,0,g.width,g.height);this.c.f=g}}Qz.ca.l.call(this,b)};function Rz(b){b=b||{};gn.call(this,{attributions:b.attributions,logo:b.logo,projection:b.projection,resolutions:b.resolutions});this.pa=void 0!==b.crossOrigin?b.crossOrigin:null;this.j=b.url;this.T=void 0!==b.imageLoadFunction?b.imageLoadFunction:nn;this.g=b.params;this.v=!0;Sz(this);this.ga=b.serverType;this.wa=void 0!==b.hidpi?b.hidpi:!0;this.c=null;this.V=[0,0];this.fa=0;this.o=void 0!==b.ratio?b.ratio:1.5}y(Rz,gn);var Tz=[101,101];l=Rz.prototype; -l.Pm=function(b,c,d,e){if(void 0!==this.j){var f=me(b,c,0,Tz),g={SERVICE:"WMS",VERSION:"1.3.0",REQUEST:"GetFeatureInfo",FORMAT:"image/png",TRANSPARENT:!0,QUERY_LAYERS:this.g.LAYERS};Wb(g,this.g,e);e=Math.floor((f[3]-b[1])/c);g[this.v?"I":"X"]=Math.floor((b[0]-f[0])/c);g[this.v?"J":"Y"]=e;return Uz(this,f,Tz,1,Ee(d),g)}};l.Rm=function(){return this.g}; -l.qd=function(b,c,d,e){if(void 0===this.j)return null;c=hn(this,c);1==d||this.wa&&void 0!==this.ga||(d=1);b=b.slice();var f=(b[0]+b[2])/2,g=(b[1]+b[3])/2,h=c/d,k=je(b)/h,h=ke(b)/h,m=this.c;if(m&&this.fa==this.f&&m.$()==c&&m.b==d&&Vd(m.J(),b))return m;if(1!=this.o){var m=this.o*je(b)/2,n=this.o*ke(b)/2;b[0]=f-m;b[1]=g-n;b[2]=f+m;b[3]=g+n}f={SERVICE:"WMS",VERSION:"1.3.0",REQUEST:"GetMap",FORMAT:"image/png",TRANSPARENT:!0};Wb(f,this.g);this.V[0]=Math.ceil(k*this.o);this.V[1]=Math.ceil(h*this.o);e=Uz(this, -b,this.V,d,e,f);this.c=new Xx(b,c,d,this.i,e,this.pa,this.T);this.fa=this.f;D(this.c,"change",this.l,!1,this);return this.c};l.Qm=function(){return this.T}; -function Uz(b,c,d,e,f,g){g[b.v?"CRS":"SRS"]=f.a;"STYLES"in b.g||(g.STYLES=new String(""));if(1!=e)switch(b.ga){case "geoserver":e=90*e+.5|0;g.FORMAT_OPTIONS="FORMAT_OPTIONS"in g?g.FORMAT_OPTIONS+(";dpi:"+e):"dpi:"+e;break;case "mapserver":g.MAP_RESOLUTION=90*e;break;case "carmentaserver":case "qgis":g.DPI=90*e}g.WIDTH=d[0];g.HEIGHT=d[1];d=f.g;var h;b.v&&"ne"==d.substr(0,2)?h=[c[1],c[0],c[3],c[2]]:h=c;g.BBOX=h.join(",");return io(ko([b.j],g))}l.Sm=function(){return this.j}; -l.Tm=function(b){this.c=null;this.T=b;this.u()};l.Um=function(b){b!=this.j&&(this.j=b,this.c=null,this.u())};l.Vm=function(b){Wb(this.g,b);Sz(this);this.c=null;this.u()};function Sz(b){b.v=0<=Qa(Rb(b.g,"VERSION","1.3.0"),"1.3")};function Vz(b){var c=void 0!==b.projection?b.projection:"EPSG:3857",d=void 0!==b.tileGrid?b.tileGrid:Mh({extent:Kh(c),maxZoom:b.maxZoom,tileSize:b.tileSize});Y.call(this,{attributions:b.attributions,crossOrigin:b.crossOrigin,logo:b.logo,projection:c,reprojectionErrorThreshold:b.reprojectionErrorThreshold,tileGrid:d,tileLoadFunction:b.tileLoadFunction,tilePixelRatio:b.tilePixelRatio,tileUrlFunction:b.tileUrlFunction,url:b.url,urls:b.urls,wrapX:void 0!==b.wrapX?b.wrapX:!0})}y(Vz,Y);function Wz(b){b=b||{};var c;void 0!==b.attributions?c=b.attributions:c=[Xz];Vz.call(this,{attributions:c,crossOrigin:void 0!==b.crossOrigin?b.crossOrigin:"anonymous",opaque:!0,maxZoom:void 0!==b.maxZoom?b.maxZoom:19,reprojectionErrorThreshold:b.reprojectionErrorThreshold,tileLoadFunction:b.tileLoadFunction,url:void 0!==b.url?b.url:"https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png",wrapX:b.wrapX})}y(Wz,Vz);var Xz=new mg({html:'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors.'});function Yz(b){b=b||{};var c=Zz[b.layer];this.g=b.layer;Vz.call(this,{attributions:c.attributions,crossOrigin:"anonymous",logo:"https://developer.mapquest.com/content/osm/mq_logo.png",maxZoom:c.maxZoom,reprojectionErrorThreshold:b.reprojectionErrorThreshold,opaque:!0,tileLoadFunction:b.tileLoadFunction,url:void 0!==b.url?b.url:"https://otile{1-4}-s.mqcdn.com/tiles/1.0.0/"+this.g+"/{z}/{x}/{y}.jpg"})}y(Yz,Vz); -var $z=new mg({html:'Tiles Courtesy of <a href="http://www.mapquest.com/">MapQuest</a>'}),Zz={osm:{maxZoom:19,attributions:[$z,Xz]},sat:{maxZoom:18,attributions:[$z,new mg({html:"Portions Courtesy NASA/JPL-Caltech and U.S. Depart. of Agriculture, Farm Service Agency"})]},hyb:{maxZoom:18,attributions:[$z,Xz]}};Yz.prototype.l=function(){return this.g};(function(){var b={},c={ja:b};(function(d){if("object"===typeof b&&"undefined"!==typeof c)c.ja=d();else{var e;"undefined"!==typeof window?e=window:"undefined"!==typeof global?e=global:"undefined"!==typeof self?e=self:e=this;e.Bp=d()}})(function(){return function e(b,c,h){function k(n,q){if(!c[n]){if(!b[n]){var r="function"==typeof require&&require;if(!q&&r)return r(n,!0);if(m)return m(n,!0);r=Error("Cannot find module '"+n+"'");throw r.code="MODULE_NOT_FOUND",r;}r=c[n]={ja:{}};b[n][0].call(r.ja,function(c){var e= -b[n][1][c];return k(e?e:c)},r,r.ja,e,b,c,h)}return c[n].ja}for(var m="function"==typeof require&&require,n=0;n<h.length;n++)k(h[n]);return k}({1:[function(b,c,g){b=b("./processor");g.Qi=b},{"./processor":2}],2:[function(b,c){function g(b){return function(c){var e=c.buffers,f=c.meta,g=c.width,h=c.height,k=e.length,m=e[0].byteLength,B;if(c.imageOps){m=Array(k);for(B=0;B<k;++B)m[B]=new ImageData(new Uint8ClampedArray(e[B]),g,h);g=b(m,f).data}else{g=new Uint8ClampedArray(m);h=Array(k);c=Array(k);for(B= -0;B<k;++B)h[B]=new Uint8ClampedArray(e[B]),c[B]=[0,0,0,0];for(e=0;e<m;e+=4){for(B=0;B<k;++B){var v=h[B];c[B][0]=v[e];c[B][1]=v[e+1];c[B][2]=v[e+2];c[B][3]=v[e+3]}B=b(c,f);g[e]=B[0];g[e+1]=B[1];g[e+2]=B[2];g[e+3]=B[3]}}return g.buffer}}function h(b,c){var e=Object.keys(b.lib||{}).map(function(c){return"var "+c+" = "+b.lib[c].toString()+";"}).concat(["var __minion__ = ("+g.toString()+")(",b.operation.toString(),");",'self.addEventListener("message", function(__event__) {',"var buffer = __minion__(__event__.data);", -"self.postMessage({buffer: buffer, meta: __event__.data.meta}, [buffer]);","});"]),e=URL.createObjectURL(new Blob(e,{type:"text/javascript"})),e=new Worker(e);e.addEventListener("message",c);return e}function k(b,c){var e=g(b.operation);return{postMessage:function(b){setTimeout(function(){c({data:{buffer:e(b),qe:b.qe}})},0)}}}function m(b){this.$e=!!b.cl;var c;0===b.threads?c=0:this.$e?c=1:c=b.threads||1;var e=[];if(c)for(var f=0;f<c;++f)e[f]=h(b,this.ig.bind(this,f));else e[0]=k(b,this.ig.bind(this, -0));this.Td=e;this.Zc=[];this.ej=b.co||Infinity;this.Rd=0;this.Dc={};this.af=null}m.prototype.bo=function(b,c,e){this.bj({tc:b,qe:c,ad:e});this.fg()};m.prototype.bj=function(b){for(this.Zc.push(b);this.Zc.length>this.ej;)this.Zc.shift().ad(null,null)};m.prototype.fg=function(){if(0===this.Rd&&0<this.Zc.length){var b=this.af=this.Zc.shift(),c=b.tc[0].width,e=b.tc[0].height,f=b.tc.map(function(b){return b.data.buffer}),g=this.Td.length;this.Rd=g;if(1===g)this.Td[0].postMessage({buffers:f,meta:b.qe, -imageOps:this.$e,width:c,height:e},f);else for(var h=4*Math.ceil(b.tc[0].data.length/4/g),k=0;k<g;++k){for(var m=k*h,B=[],v=0,L=f.length;v<L;++v)B.push(f[k].slice(m,m+h));this.Td[k].postMessage({buffers:B,meta:b.qe,imageOps:this.$e,width:c,height:e},B)}}};m.prototype.ig=function(b,c){this.xp||(this.Dc[b]=c.data,--this.Rd,0===this.Rd&&this.fj())};m.prototype.fj=function(){var b=this.af,c=this.Td.length,e,f;if(1===c)e=new Uint8ClampedArray(this.Dc[0].buffer),f=this.Dc[0].meta;else{var g=b.tc[0].data.length; -e=new Uint8ClampedArray(g);f=Array(g);for(var g=4*Math.ceil(g/4/c),h=0;h<c;++h){var k=h*g;e.set(new Uint8ClampedArray(this.Dc[h].buffer),k);f[h]=this.Dc[h].meta}}this.af=null;this.Dc={};b.ad(null,new ImageData(e,b.tc[0].width,b.tc[0].height),f);this.fg()};c.ja=m},{}]},{},[1])(1)});yp=c.ja})();function aA(b){this.T=null;this.wa=void 0!==b.operationType?b.operationType:"pixel";this.hb=void 0!==b.threads?b.threads:1;this.c=bA(b.sources);for(var c=0,d=this.c.length;c<d;++c)D(this.c[c],"change",this.u,!1,this);this.g=Ni();this.ga=new Hk(function(){return 1},ua(this.u,this));for(var c=cA(this.c),d={},e=0,f=c.length;e<f;++e)d[w(c[e].layer)]=c[e];this.j=this.o=null;this.fa={animate:!1,attributions:{},coordinateToPixelMatrix:Bd(),extent:null,focus:null,index:0,layerStates:d,layerStatesArray:c, -logos:{},pixelRatio:1,pixelToCoordinateMatrix:Bd(),postRenderFunctions:[],size:[0,0],skippedFeatureUids:{},tileQueue:this.ga,time:Date.now(),usedTiles:{},viewState:{rotation:0},viewHints:[],wantedTiles:{}};gn.call(this,{});void 0!==b.operation&&this.v(b.operation,b.lib)}y(aA,gn);aA.prototype.v=function(b,c){this.T=new yp.Qi({operation:b,cl:"image"===this.wa,co:1,lib:c,threads:this.hb});this.u()};function dA(b,c,d){var e=b.o;return!e||b.f!==e.Ho||d!==e.resolution||!ae(c,e.extent)} -aA.prototype.C=function(b,c,d,e){d=!0;for(var f,g=0,h=this.c.length;g<h;++g)if(f=this.c[g].a.ea(),"ready"!==f.B){d=!1;break}if(!d)return null;if(!dA(this,b,c))return this.j;d=this.g.canvas;f=Math.round(je(b)/c);g=Math.round(ke(b)/c);if(f!==d.width||g!==d.height)d.width=f,d.height=g;f=Tb(this.fa);f.viewState=Tb(f.viewState);var g=le(b),h=Math.round(je(b)/c),k=Math.round(ke(b)/c);f.extent=b;f.focus=le(b);f.size[0]=h;f.size[1]=k;h=f.viewState;h.center=g;h.projection=e;h.resolution=c;this.j=e=new Xm(b, -c,1,this.i,d,this.V.bind(this,f));this.o={extent:b,resolution:c,Ho:this.f};return e}; -aA.prototype.V=function(b,c){for(var d=this.c.length,e=Array(d),f=0;f<d;++f){var g;var h=this.c[f],k=b;h.Ad(k,b.layerStatesArray[f]);if(g=h.zd()){var h=h.nf(),m=Math.round(h[12]),n=Math.round(h[13]),p=k.size[0],k=k.size[1];if(g instanceof Image){if(eA){var q=eA.canvas;q.width!==p||q.height!==k?eA=Ni(p,k):eA.clearRect(0,0,p,k)}else eA=Ni(p,k);eA.drawImage(g,m,n,Math.round(g.width*h[0]),Math.round(g.height*h[5]));g=eA.getImageData(0,0,p,k)}else g=g.getContext("2d").getImageData(-m,-n,p,k)}else g=null; -if(g)e[f]=g;else return}d={};this.s(new fA(gA,b,d));this.T.bo(e,d,this.pa.bind(this,b,c));Ik(b.tileQueue,16,16)};aA.prototype.pa=function(b,c,d,e,f){d?c(d):e&&(this.s(new fA(hA,b,f)),dA(this,b.extent,b.viewState.resolution/b.pixelRatio)||this.g.putImageData(e,0,0),c(null))};var eA=null;function cA(b){return b.map(function(b){return Zj(b.a)})} -function bA(b){for(var c=b.length,d=Array(c),e=0;e<c;++e){var f=e,g=b[e],h=null;g instanceof Nh?(g=new G({source:g}),h=new Pp(g)):g instanceof gn&&(g=new Pl({source:g}),h=new Op(g));d[f]=h}return d}function fA(b,c,d){tc.call(this,b);this.extent=c.extent;this.resolution=c.viewState.resolution/c.pixelRatio;this.data=d}y(fA,tc);var gA="beforeoperations",hA="afteroperations";var iA={terrain:{ob:"jpg",opaque:!0},"terrain-background":{ob:"jpg",opaque:!0},"terrain-labels":{ob:"png",opaque:!1},"terrain-lines":{ob:"png",opaque:!1},"toner-background":{ob:"png",opaque:!0},toner:{ob:"png",opaque:!0},"toner-hybrid":{ob:"png",opaque:!1},"toner-labels":{ob:"png",opaque:!1},"toner-lines":{ob:"png",opaque:!1},"toner-lite":{ob:"png",opaque:!0},watercolor:{ob:"jpg",opaque:!0}},jA={terrain:{minZoom:4,maxZoom:18},toner:{minZoom:0,maxZoom:20},watercolor:{minZoom:3,maxZoom:16}}; -function kA(b){var c=b.layer.indexOf("-"),c=-1==c?b.layer:b.layer.slice(0,c),d=iA[b.layer];Vz.call(this,{attributions:lA,crossOrigin:"anonymous",maxZoom:jA[c].maxZoom,opaque:d.opaque,reprojectionErrorThreshold:b.reprojectionErrorThreshold,tileLoadFunction:b.tileLoadFunction,url:void 0!==b.url?b.url:"https://stamen-tiles-{a-d}.a.ssl.fastly.net/"+b.layer+"/{z}/{x}/{y}."+d.ob})}y(kA,Vz); -var lA=[new mg({html:'Map tiles by <a href="http://stamen.com/">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0/">CC BY 3.0</a>.'}),Xz];function mA(b){b=b||{};var c=void 0!==b.params?b.params:{};Y.call(this,{attributions:b.attributions,crossOrigin:b.crossOrigin,logo:b.logo,projection:b.projection,reprojectionErrorThreshold:b.reprojectionErrorThreshold,tileGrid:b.tileGrid,tileLoadFunction:b.tileLoadFunction,tileUrlFunction:ua(this.D,this),url:b.url,urls:b.urls,wrapX:void 0!==b.wrapX?b.wrapX:!0});this.g=c;this.l=Md()}y(mA,Y);mA.prototype.C=function(){return this.g}; -mA.prototype.Qb=function(b,c,d){b=mA.ca.Qb.call(this,b,c,d);return 1==c?b:ld(b,c,this.c)}; -mA.prototype.D=function(b,c,d){var e=this.tileGrid;e||(e=this.ib(d));if(!(e.a.length<=b[0])){var f=e.Aa(b,this.l),g=md(e.Ka(b[0]),this.c);1!=c&&(g=ld(g,c,this.c));e={F:"image",FORMAT:"PNG32",TRANSPARENT:!0};Wb(e,this.g);var h=this.urls;h?(d=d.a.split(":").pop(),e.SIZE=g[0]+","+g[1],e.BBOX=f.join(","),e.BBOXSR=d,e.IMAGESR=d,e.DPI=Math.round(e.DPI?e.DPI*c:90*c),b=1==h.length?h[0]:h[nd((b[1]<<b[0])+b[2],h.length)],Ca(b,"/")||(b+="/"),Ca(b,"MapServer/")?b+="export":Ca(b,"ImageServer/")&&(b+="exportImage"), -b=io(ko([b],e))):b=void 0;return b}};mA.prototype.V=function(b){Wb(this.g,b);this.u()};function nA(b,c,d){uh.call(this,b,2);this.i=c;this.c=d;this.b={}}y(nA,uh);nA.prototype.Ta=function(b){b=void 0!==b?w(b):-1;if(b in this.b)return this.b[b];var c=this.i,d=Ni(c[0],c[1]);d.strokeStyle="black";d.strokeRect(.5,.5,c[0]+.5,c[1]+.5);d.fillStyle="black";d.textAlign="center";d.textBaseline="middle";d.font="24px sans-serif";d.fillText(this.c,c[0]/2,c[1]/2);return this.b[b]=d.canvas}; -function oA(b){Nh.call(this,{opaque:!1,projection:b.projection,tileGrid:b.tileGrid,wrapX:void 0!==b.wrapX?b.wrapX:!0})}y(oA,Nh);oA.prototype.Pb=function(b,c,d){var e=this.Ab(b,c,d);if(qh(this.a,e))return this.a.get(e);var f=md(this.tileGrid.Ka(b));b=[b,c,d];c=(c=Ph(this,b))?eg(Ph(this,c)):"";f=new nA(b,f,c);this.a.set(e,f);return f};function pA(b){Y.call(this,{attributions:b.attributions,crossOrigin:b.crossOrigin,projection:Ee("EPSG:3857"),reprojectionErrorThreshold:b.reprojectionErrorThreshold,state:"loading",tileLoadFunction:b.tileLoadFunction,wrapX:void 0!==b.wrapX?b.wrapX:!0});Dz(new Bz(b.url),void 0,ua(this.l,this),ua(this.g,this))}y(pA,Y); -pA.prototype.l=function(b){var c=Ee("EPSG:4326"),d=this.b,e;void 0!==b.bounds&&(e=qe(b.bounds,Ie(c,d)));var f=b.minzoom||0,g=b.maxzoom||22;this.tileGrid=d=Mh({extent:Kh(d),maxZoom:g,minZoom:f});this.tileUrlFunction=Sp(b.tiles,d);if(void 0!==b.attribution&&!this.i){c=void 0!==e?e:c.J();e={};for(var h;f<=g;++f)h=f.toString(),e[h]=[Dh(d,c,f)];this.ma([new mg({html:b.attribution,tileRanges:e})])}yh(this,"ready")};pA.prototype.g=function(){yh(this,"error")};function qA(b){Nh.call(this,{projection:Ee("EPSG:3857"),state:"loading"});this.l=void 0!==b.preemptive?b.preemptive:!0;this.g=Up;this.j=void 0;Dz(new Bz(b.url),void 0,ua(this.Xm,this))}y(qA,Nh);l=qA.prototype;l.mk=function(){return this.j};l.zj=function(b,c,d,e,f){this.tileGrid?(c=this.tileGrid.fe(b,c),rA(this.Pb(c[0],c[1],c[2],1,this.b),b,d,e,f)):!0===f?li(function(){d.call(e,null)}):d.call(e,null)}; -l.Xm=function(b){var c=Ee("EPSG:4326"),d=this.b,e;void 0!==b.bounds&&(e=qe(b.bounds,Ie(c,d)));var f=b.minzoom||0,g=b.maxzoom||22;this.tileGrid=d=Mh({extent:Kh(d),maxZoom:g,minZoom:f});this.j=b.template;var h=b.grids;if(h){this.g=Sp(h,d);if(void 0!==b.attribution){c=void 0!==e?e:c.J();for(e={};f<=g;++f)h=f.toString(),e[h]=[Dh(d,c,f)];this.ma([new mg({html:b.attribution,tileRanges:e})])}yh(this,"ready")}else yh(this,"error")}; -l.Pb=function(b,c,d,e,f){var g=this.Ab(b,c,d);if(qh(this.a,g))return this.a.get(g);b=[b,c,d];c=Ph(this,b,f);e=this.g(c,e,f);e=new sA(b,void 0!==e?0:4,void 0!==e?e:"",this.tileGrid.Aa(b),this.l);this.a.set(g,e);return e};l.Yf=function(b,c,d){b=this.Ab(b,c,d);qh(this.a,b)&&this.a.get(b)};function sA(b,c,d,e,f){uh.call(this,b,c);this.l=d;this.b=e;this.o=f;this.j=this.i=this.c=null}y(sA,uh);l=sA.prototype;l.Ta=function(){return null}; -function tA(b,c){if(!b.c||!b.i||!b.j)return null;var d=b.c[Math.floor((1-(c[1]-b.b[1])/(b.b[3]-b.b[1]))*b.c.length)];if(!ia(d))return null;d=d.charCodeAt(Math.floor((c[0]-b.b[0])/(b.b[2]-b.b[0])*d.length));93<=d&&d--;35<=d&&d--;d-=32;return d in b.i?b.j[b.i[d]]:null}function rA(b,c,d,e,f){0==b.state&&!0===f?(Uc(b,"change",function(){d.call(e,tA(this,c))},!1,b),uA(b)):!0===f?li(function(){d.call(e,tA(this,c))},b):d.call(e,tA(b,c))}l.$a=function(){return this.l};l.Bk=function(){this.state=3;vh(this)}; -l.Wm=function(b){this.c=b.grid;this.i=b.keys;this.j=b.data;this.state=4;vh(this)};function uA(b){0==b.state&&(b.state=1,Dz(new Bz(b.l),void 0,ua(b.Wm,b),ua(b.Bk,b)))}l.load=function(){this.o&&uA(this)};function vA(b){b=b||{};var c=void 0!==b.params?b.params:{};Y.call(this,{attributions:b.attributions,crossOrigin:b.crossOrigin,logo:b.logo,opaque:!Rb(c,"TRANSPARENT",!0),projection:b.projection,reprojectionErrorThreshold:b.reprojectionErrorThreshold,tileGrid:b.tileGrid,tileLoadFunction:b.tileLoadFunction,tileUrlFunction:ua(this.$m,this),url:b.url,urls:b.urls,wrapX:void 0!==b.wrapX?b.wrapX:!0});this.C=void 0!==b.gutter?b.gutter:0;this.g=c;this.l=!0;this.D=b.serverType;this.fa=void 0!==b.hidpi?b.hidpi: -!0;this.V="";wA(this);this.ga=Md();xA(this)}y(vA,Y);l=vA.prototype; -l.Ym=function(b,c,d,e){d=Ee(d);var f=this.tileGrid;f||(f=this.ib(d));c=f.fe(b,c);if(!(f.a.length<=c[0])){var g=f.$(c[0]),h=f.Aa(c,this.ga),f=md(f.Ka(c[0]),this.c),k=this.C;0!==k&&(f=kd(f,k,this.c),h=Qd(h,g*k,h));k={SERVICE:"WMS",VERSION:"1.3.0",REQUEST:"GetFeatureInfo",FORMAT:"image/png",TRANSPARENT:!0,QUERY_LAYERS:this.g.LAYERS};Wb(k,this.g,e);e=Math.floor((h[3]-b[1])/g);k[this.l?"I":"X"]=Math.floor((b[0]-h[0])/g);k[this.l?"J":"Y"]=e;return yA(this,c,f,h,1,d,k)}};l.ae=function(){return this.C}; -l.Ab=function(b,c,d){return this.V+vA.ca.Ab.call(this,b,c,d)};l.Zm=function(){return this.g}; -function yA(b,c,d,e,f,g,h){var k=b.urls;if(k){h.WIDTH=d[0];h.HEIGHT=d[1];h[b.l?"CRS":"SRS"]=g.a;"STYLES"in b.g||(h.STYLES=new String(""));if(1!=f)switch(b.D){case "geoserver":d=90*f+.5|0;h.FORMAT_OPTIONS="FORMAT_OPTIONS"in h?h.FORMAT_OPTIONS+(";dpi:"+d):"dpi:"+d;break;case "mapserver":h.MAP_RESOLUTION=90*f;break;case "carmentaserver":case "qgis":h.DPI=90*f}g=g.g;b.l&&"ne"==g.substr(0,2)&&(b=e[0],e[0]=e[1],e[1]=b,b=e[2],e[2]=e[3],e[3]=b);h.BBOX=e.join(",");return io(ko([1==k.length?k[0]:k[nd((c[1]<< -c[0])+c[2],k.length)]],h))}}l.Qb=function(b,c,d){b=vA.ca.Qb.call(this,b,c,d);return 1!=c&&this.fa&&void 0!==this.D?ld(b,c,this.c):b};function wA(b){var c=0,d=[];if(b.urls){var e,f;e=0;for(f=b.urls.length;e<f;++e)d[c++]=b.urls[e]}for(var g in b.g)d[c++]=g+"-"+b.g[g];b.V=d.join("#")} -l.$m=function(b,c,d){var e=this.tileGrid;e||(e=this.ib(d));if(!(e.a.length<=b[0])){1==c||this.fa&&void 0!==this.D||(c=1);var f=e.$(b[0]),g=e.Aa(b,this.ga),e=md(e.Ka(b[0]),this.c),h=this.C;0!==h&&(e=kd(e,h,this.c),g=Qd(g,f*h,g));1!=c&&(e=ld(e,c,this.c));f={SERVICE:"WMS",VERSION:"1.3.0",REQUEST:"GetMap",FORMAT:"image/png",TRANSPARENT:!0};Wb(f,this.g);return yA(this,b,e,g,c,d,f)}};l.an=function(b){Wb(this.g,b);wA(this);xA(this);this.u()};function xA(b){b.l=0<=Qa(Rb(b.g,"VERSION","1.3.0"),"1.3")};function zA(b){this.j=b.matrixIds;zh.call(this,{extent:b.extent,origin:b.origin,origins:b.origins,resolutions:b.resolutions,tileSize:b.tileSize,tileSizes:b.tileSizes,sizes:b.sizes})}y(zA,zh);zA.prototype.o=function(){return this.j}; -function AA(b,c){var d=[],e=[],f=[],g=[],h=[],k;k=Ee(b.SupportedCRS.replace(/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/,"$1:$3"));var m=k.Kc(),n="ne"==k.g.substr(0,2);b.TileMatrix.sort(function(b,c){return c.ScaleDenominator-b.ScaleDenominator});b.TileMatrix.forEach(function(b){e.push(b.Identifier);var c=2.8E-4*b.ScaleDenominator/m,k=b.TileWidth,t=b.TileHeight;n?f.push([b.TopLeftCorner[1],b.TopLeftCorner[0]]):f.push(b.TopLeftCorner);d.push(c);g.push(k==t?k:[k,t]);h.push([b.MatrixWidth,-b.MatrixHeight])}); -return new zA({extent:c,origins:f,resolutions:d,matrixIds:e,tileSizes:g,sizes:h})};function Z(b){function c(b){b="KVP"==e?io(ko([b],g)):b.replace(/\{(\w+?)\}/g,function(b,c){return c.toLowerCase()in g?g[c.toLowerCase()]:b});return function(c){if(c){var d={TileMatrix:f.j[c[0]],TileCol:c[1],TileRow:-c[2]-1};Wb(d,h);c=b;return c="KVP"==e?io(ko([c],d)):c.replace(/\{(\w+?)\}/g,function(b,c){return d[c]})}}}this.ga=void 0!==b.version?b.version:"1.0.0";this.D=void 0!==b.format?b.format:"image/jpeg";this.g=void 0!==b.dimensions?b.dimensions:{};this.l="";BA(this);this.V=b.layer;this.C=b.matrixSet; -this.fa=b.style;var d=b.urls;void 0===d&&void 0!==b.url&&(d=Vp(b.url));var e=this.oa=void 0!==b.requestEncoding?b.requestEncoding:"KVP",f=b.tileGrid,g={layer:this.V,style:this.fa,tilematrixset:this.C};"KVP"==e&&Wb(g,{Service:"WMTS",Request:"GetTile",Version:this.ga,Format:this.D});var h=this.g,k=d&&0<d.length?Tp(d.map(c)):Up;Y.call(this,{attributions:b.attributions,crossOrigin:b.crossOrigin,logo:b.logo,projection:b.projection,reprojectionErrorThreshold:b.reprojectionErrorThreshold,tileClass:b.tileClass, -tileGrid:f,tileLoadFunction:b.tileLoadFunction,tilePixelRatio:b.tilePixelRatio,tileUrlFunction:k,urls:d,wrapX:void 0!==b.wrapX?b.wrapX:!1})}y(Z,Y);l=Z.prototype;l.Lj=function(){return this.g};l.bn=function(){return this.D};l.Cg=function(){return this.l};l.cn=function(){return this.V};l.Yj=function(){return this.C};l.kk=function(){return this.oa};l.dn=function(){return this.fa};l.rk=function(){return this.ga};function BA(b){var c=0,d=[],e;for(e in b.g)d[c++]=e+"-"+b.g[e];b.l=d.join("/")} -l.cp=function(b){Wb(this.g,b);BA(this);this.u()};function CA(b){b=b||{};var c=b.size,d=c[0],e=c[1],f=[],g=256;switch(void 0!==b.tierSizeCalculation?b.tierSizeCalculation:"default"){case "default":for(;d>g||e>g;)f.push([Math.ceil(d/g),Math.ceil(e/g)]),g+=g;break;case "truncated":for(;d>g||e>g;)f.push([Math.ceil(d/g),Math.ceil(e/g)]),d>>=1,e>>=1}f.push([1,1]);f.reverse();for(var g=[1],h=[0],e=1,d=f.length;e<d;e++)g.push(1<<e),h.push(f[e-1][0]*f[e-1][1]+h[e-1]);g.reverse();var c=[0,-c[1],c[0],0],c=new zh({extent:c,origin:ge(c),resolutions:g}),k=b.url; -Y.call(this,{attributions:b.attributions,crossOrigin:b.crossOrigin,logo:b.logo,reprojectionErrorThreshold:b.reprojectionErrorThreshold,tileClass:DA,tileGrid:c,tileUrlFunction:function(b){if(b){var c=b[0],d=b[1];b=-b[2]-1;return k+"TileGroup"+((d+b*f[c][0]+h[c])/256|0)+"/"+c+"-"+d+"-"+b+".jpg"}}})}y(CA,Y);function DA(b,c,d,e,f){Yx.call(this,b,c,d,e,f);this.i={}}y(DA,Yx); -DA.prototype.Ta=function(b){var c=void 0!==b?w(b).toString():"";if(c in this.i)return this.i[c];b=DA.ca.Ta.call(this,b);if(2==this.state){if(256==b.width&&256==b.height)return this.i[c]=b;var d=Ni(256,256);d.drawImage(b,0,0);return this.i[c]=d.canvas}return b};function EA(b){b=b||{};this.f=void 0!==b.initialSize?b.initialSize:256;this.b=void 0!==b.maxSize?b.maxSize:void 0!==xa?xa:2048;this.a=void 0!==b.space?b.space:1;this.g=[new FA(this.f,this.a)];this.c=this.f;this.i=[new FA(this.c,this.a)]}EA.prototype.add=function(b,c,d,e,f,g){if(c+this.a>this.b||d+this.a>this.b)return null;e=GA(this,!1,b,c,d,e,g);if(!e)return null;b=GA(this,!0,b,c,d,void 0!==f?f:ue,g);return{offsetX:e.offsetX,offsetY:e.offsetY,image:e.image,Og:b.image}}; -function GA(b,c,d,e,f,g,h){var k=c?b.i:b.g,m,n,p;n=0;for(p=k.length;n<p;++n){m=k[n];if(m=m.add(d,e,f,g,h))return m;m||n!==p-1||(c?(m=Math.min(2*b.c,b.b),b.c=m):(m=Math.min(2*b.f,b.b),b.f=m),m=new FA(m,b.a),k.push(m),++p)}}function FA(b,c){this.a=c;this.f=[{x:0,y:0,width:b,height:b}];this.c={};this.b=document.createElement("CANVAS");this.b.width=b;this.b.height=b;this.g=this.b.getContext("2d")}FA.prototype.get=function(b){return Rb(this.c,b,null)}; -FA.prototype.add=function(b,c,d,e,f){var g,h,k;h=0;for(k=this.f.length;h<k;++h)if(g=this.f[h],g.width>=c+this.a&&g.height>=d+this.a)return k={offsetX:g.x+this.a,offsetY:g.y+this.a,image:this.b},this.c[b]=k,e.call(f,this.g,g.x+this.a,g.y+this.a),b=h,c=c+this.a,d=d+this.a,f=e=void 0,g.width-c>g.height-d?(e={x:g.x+c,y:g.y,width:g.width-c,height:g.height},f={x:g.x,y:g.y+d,width:c,height:g.height-d},HA(this,b,e,f)):(e={x:g.x+c,y:g.y,width:g.width-c,height:d},f={x:g.x,y:g.y+d,width:g.width,height:g.height- -d},HA(this,b,e,f)),k;return null};function HA(b,c,d,e){c=[c,1];0<d.width&&0<d.height&&c.push(d);0<e.width&&0<e.height&&c.push(e);b.f.splice.apply(b.f,c)};function IA(b){this.v=this.c=this.g=null;this.o=void 0!==b.fill?b.fill:null;this.va=[0,0];this.a=b.points;this.b=void 0!==b.radius?b.radius:b.radius1;this.i=void 0!==b.radius2?b.radius2:this.b;this.l=void 0!==b.angle?b.angle:0;this.f=void 0!==b.stroke?b.stroke:null;this.na=this.U=this.O=null;var c=b.atlasManager,d="",e="",f=0,g=null,h,k=0;this.f&&(h=vg(this.f.a),k=this.f.f,void 0===k&&(k=1),g=this.f.b,Wi||(g=null),e=this.f.g,void 0===e&&(e="round"),d=this.f.c,void 0===d&&(d="round"),f=this.f.i,void 0=== -f&&(f=10));var m=2*(this.b+k)+1,d={strokeStyle:h,Id:k,size:m,lineCap:d,lineDash:g,lineJoin:e,miterLimit:f};if(void 0===c){this.c=document.createElement("CANVAS");this.c.height=m;this.c.width=m;var c=m=this.c.width,n=this.c.getContext("2d");this.xh(d,n,0,0);this.o?this.v=this.c:(n=this.v=document.createElement("CANVAS"),n.height=d.size,n.width=d.size,n=n.getContext("2d"),this.wh(d,n,0,0))}else m=Math.round(m),(e=!this.o)&&(n=ua(this.wh,this,d)),f=this.Jb(),n=c.add(f,m,m,ua(this.xh,this,d),n),this.c= -n.image,this.va=[n.offsetX,n.offsetY],c=n.image.width,this.v=e?n.Og:this.c;this.O=[m/2,m/2];this.U=[m,m];this.na=[c,c];sk.call(this,{opacity:1,rotateWithView:!1,rotation:void 0!==b.rotation?b.rotation:0,scale:1,snapToPixel:void 0!==b.snapToPixel?b.snapToPixel:!0})}y(IA,sk);l=IA.prototype;l.Xb=function(){return this.O};l.jn=function(){return this.l};l.kn=function(){return this.o};l.Ae=function(){return this.v};l.gc=function(){return this.c};l.rd=function(){return this.na};l.Cd=function(){return 2}; -l.Da=function(){return this.va};l.ln=function(){return this.a};l.mn=function(){return this.b};l.jk=function(){return this.i};l.Cb=function(){return this.U};l.nn=function(){return this.f};l.tf=za;l.load=za;l.Xf=za; -l.xh=function(b,c,d,e){var f;c.setTransform(1,0,0,1,0,0);c.translate(d,e);c.beginPath();this.i!==this.b&&(this.a*=2);for(d=0;d<=this.a;d++)e=2*d*Math.PI/this.a-Math.PI/2+this.l,f=0===d%2?this.b:this.i,c.lineTo(b.size/2+f*Math.cos(e),b.size/2+f*Math.sin(e));this.o&&(c.fillStyle=vg(this.o.a),c.fill());this.f&&(c.strokeStyle=b.strokeStyle,c.lineWidth=b.Id,b.lineDash&&c.setLineDash(b.lineDash),c.lineCap=b.lineCap,c.lineJoin=b.lineJoin,c.miterLimit=b.miterLimit,c.stroke());c.closePath()}; -l.wh=function(b,c,d,e){c.setTransform(1,0,0,1,0,0);c.translate(d,e);c.beginPath();this.i!==this.b&&(this.a*=2);var f;for(d=0;d<=this.a;d++)f=2*d*Math.PI/this.a-Math.PI/2+this.l,e=0===d%2?this.b:this.i,c.lineTo(b.size/2+e*Math.cos(f),b.size/2+e*Math.sin(f));c.fillStyle=Ql;c.fill();this.f&&(c.strokeStyle=b.strokeStyle,c.lineWidth=b.Id,b.lineDash&&c.setLineDash(b.lineDash),c.stroke());c.closePath()}; -l.Jb=function(){var b=this.f?this.f.Jb():"-",c=this.o?this.o.Jb():"-";this.g&&b==this.g[1]&&c==this.g[2]&&this.b==this.g[3]&&this.i==this.g[4]&&this.l==this.g[5]&&this.a==this.g[6]||(this.g=["r"+b+c+(void 0!==this.b?this.b.toString():"-")+(void 0!==this.i?this.i.toString():"-")+(void 0!==this.l?this.l.toString():"-")+(void 0!==this.a?this.a.toString():"-"),b,c,this.b,this.i,this.l,this.a]);return this.g[0]};u("ol.animation.bounce",function(b){var c=b.resolution,d=b.start?b.start:Date.now(),e=void 0!==b.duration?b.duration:1E3,f=b.easing?b.easing:Xf;return function(b,h){if(h.time<d)return h.animate=!0,h.viewHints[0]+=1,!0;if(h.time<d+e){var k=f((h.time-d)/e),m=c-h.viewState.resolution;h.animate=!0;h.viewState.resolution+=k*m;h.viewHints[0]+=1;return!0}return!1}},OPENLAYERS);u("ol.animation.pan",Yf,OPENLAYERS);u("ol.animation.rotate",Zf,OPENLAYERS);u("ol.animation.zoom",$f,OPENLAYERS); -u("ol.Attribution",mg,OPENLAYERS);mg.prototype.getHTML=mg.prototype.b;ng.prototype.element=ng.prototype.element;u("ol.Collection",og,OPENLAYERS);og.prototype.clear=og.prototype.clear;og.prototype.extend=og.prototype.uf;og.prototype.forEach=og.prototype.forEach;og.prototype.getArray=og.prototype.wl;og.prototype.item=og.prototype.item;og.prototype.getLength=og.prototype.$b;og.prototype.insertAt=og.prototype.le;og.prototype.pop=og.prototype.pop;og.prototype.push=og.prototype.push; -og.prototype.remove=og.prototype.remove;og.prototype.removeAt=og.prototype.Sf;og.prototype.setAt=og.prototype.Jo;u("ol.coordinate.add",pd,OPENLAYERS);u("ol.coordinate.createStringXY",function(b){return function(c){return xd(c,b)}},OPENLAYERS);u("ol.coordinate.format",sd,OPENLAYERS);u("ol.coordinate.rotate",ud,OPENLAYERS);u("ol.coordinate.toStringHDMS",function(b){return b?rd(b[1],"NS")+" "+rd(b[0],"EW"):""},OPENLAYERS);u("ol.coordinate.toStringXY",xd,OPENLAYERS);u("ol.DeviceOrientation",Mr,OPENLAYERS); -Mr.prototype.getAlpha=Mr.prototype.Fj;Mr.prototype.getBeta=Mr.prototype.Ij;Mr.prototype.getGamma=Mr.prototype.Oj;Mr.prototype.getHeading=Mr.prototype.xl;Mr.prototype.getTracking=Mr.prototype.Vg;Mr.prototype.setTracking=Mr.prototype.vf;u("ol.easing.easeIn",Tf,OPENLAYERS);u("ol.easing.easeOut",Uf,OPENLAYERS);u("ol.easing.inAndOut",Vf,OPENLAYERS);u("ol.easing.linear",Wf,OPENLAYERS);u("ol.easing.upAndDown",Xf,OPENLAYERS);u("ol.extent.boundingExtent",Ld,OPENLAYERS);u("ol.extent.buffer",Qd,OPENLAYERS); -u("ol.extent.containsCoordinate",Td,OPENLAYERS);u("ol.extent.containsExtent",Vd,OPENLAYERS);u("ol.extent.containsXY",Ud,OPENLAYERS);u("ol.extent.createEmpty",Md,OPENLAYERS);u("ol.extent.equals",ae,OPENLAYERS);u("ol.extent.extend",be,OPENLAYERS);u("ol.extent.getBottomLeft",de,OPENLAYERS);u("ol.extent.getBottomRight",ee,OPENLAYERS);u("ol.extent.getCenter",le,OPENLAYERS);u("ol.extent.getHeight",ke,OPENLAYERS);u("ol.extent.getIntersection",ne,OPENLAYERS); -u("ol.extent.getSize",function(b){return[b[2]-b[0],b[3]-b[1]]},OPENLAYERS);u("ol.extent.getTopLeft",ge,OPENLAYERS);u("ol.extent.getTopRight",fe,OPENLAYERS);u("ol.extent.getWidth",je,OPENLAYERS);u("ol.extent.intersects",oe,OPENLAYERS);u("ol.extent.isEmpty",ie,OPENLAYERS);u("ol.extent.applyTransform",qe,OPENLAYERS);u("ol.Feature",pn,OPENLAYERS);pn.prototype.clone=pn.prototype.clone;pn.prototype.getGeometry=pn.prototype.X;pn.prototype.getId=pn.prototype.Oa;pn.prototype.getGeometryName=pn.prototype.Qj; -pn.prototype.getStyle=pn.prototype.zl;pn.prototype.getStyleFunction=pn.prototype.ac;pn.prototype.setGeometry=pn.prototype.Ma;pn.prototype.setStyle=pn.prototype.wf;pn.prototype.setId=pn.prototype.jc;pn.prototype.setGeometryName=pn.prototype.yc;u("ol.featureloader.tile",sp,OPENLAYERS);u("ol.featureloader.xhr",tp,OPENLAYERS);u("ol.Geolocation",Mx,OPENLAYERS);Mx.prototype.getAccuracy=Mx.prototype.Dj;Mx.prototype.getAccuracyGeometry=Mx.prototype.Ej;Mx.prototype.getAltitude=Mx.prototype.Gj; -Mx.prototype.getAltitudeAccuracy=Mx.prototype.Hj;Mx.prototype.getHeading=Mx.prototype.Bl;Mx.prototype.getPosition=Mx.prototype.Cl;Mx.prototype.getProjection=Mx.prototype.Wg;Mx.prototype.getSpeed=Mx.prototype.lk;Mx.prototype.getTracking=Mx.prototype.Xg;Mx.prototype.getTrackingOptions=Mx.prototype.Ig;Mx.prototype.setProjection=Mx.prototype.Yg;Mx.prototype.setTracking=Mx.prototype.re;Mx.prototype.setTrackingOptions=Mx.prototype.hi;u("ol.Graticule",Sx,OPENLAYERS);Sx.prototype.getMap=Sx.prototype.Fl; -Sx.prototype.getMeridians=Sx.prototype.Zj;Sx.prototype.getParallels=Sx.prototype.fk;Sx.prototype.setMap=Sx.prototype.setMap;u("ol.has.DEVICE_PIXEL_RATIO",Vi,OPENLAYERS);u("ol.has.CANVAS",Xi,OPENLAYERS);u("ol.has.DEVICE_ORIENTATION",Yi,OPENLAYERS);u("ol.has.GEOLOCATION",Zi,OPENLAYERS);u("ol.has.TOUCH",$i,OPENLAYERS);u("ol.has.WEBGL",Ui,OPENLAYERS);Xx.prototype.getImage=Xx.prototype.a;Yx.prototype.getImage=Yx.prototype.Ta;u("ol.Kinetic",Jk,OPENLAYERS);u("ol.loadingstrategy.all",up,OPENLAYERS); -u("ol.loadingstrategy.bbox",function(b){return[b]},OPENLAYERS);u("ol.loadingstrategy.tile",function(b){return function(c,d){var e=Ih(b,d),f=Dh(b,c,e),g=[],e=[e,0,0];for(e[1]=f.a;e[1]<=f.c;++e[1])for(e[2]=f.f;e[2]<=f.b;++e[2])g.push(b.Aa(e));return g}},OPENLAYERS);u("ol.Map",S,OPENLAYERS);S.prototype.addControl=S.prototype.kj;S.prototype.addInteraction=S.prototype.lj;S.prototype.addLayer=S.prototype.kg;S.prototype.addOverlay=S.prototype.lg;S.prototype.beforeRender=S.prototype.Na; -S.prototype.forEachFeatureAtPixel=S.prototype.pd;S.prototype.forEachLayerAtPixel=S.prototype.Jl;S.prototype.hasFeatureAtPixel=S.prototype.bl;S.prototype.getEventCoordinate=S.prototype.Mj;S.prototype.getEventPixel=S.prototype.$d;S.prototype.getTarget=S.prototype.xf;S.prototype.getTargetElement=S.prototype.Mc;S.prototype.getCoordinateFromPixel=S.prototype.Ga;S.prototype.getControls=S.prototype.Kj;S.prototype.getOverlays=S.prototype.dk;S.prototype.getOverlayById=S.prototype.ck; -S.prototype.getInteractions=S.prototype.Rj;S.prototype.getLayerGroup=S.prototype.rc;S.prototype.getLayers=S.prototype.Zg;S.prototype.getPixelFromCoordinate=S.prototype.Pa;S.prototype.getSize=S.prototype.Sa;S.prototype.getView=S.prototype.aa;S.prototype.getViewport=S.prototype.sk;S.prototype.renderSync=S.prototype.Fo;S.prototype.render=S.prototype.render;S.prototype.removeControl=S.prototype.yo;S.prototype.removeInteraction=S.prototype.zo;S.prototype.removeLayer=S.prototype.Bo; -S.prototype.removeOverlay=S.prototype.Co;S.prototype.setLayerGroup=S.prototype.$h;S.prototype.setSize=S.prototype.Vf;S.prototype.setTarget=S.prototype.Kl;S.prototype.setView=S.prototype.To;S.prototype.updateSize=S.prototype.Vc;Kj.prototype.originalEvent=Kj.prototype.originalEvent;Kj.prototype.pixel=Kj.prototype.pixel;Kj.prototype.coordinate=Kj.prototype.coordinate;Kj.prototype.dragging=Kj.prototype.dragging;Kj.prototype.preventDefault=Kj.prototype.preventDefault;Kj.prototype.stopPropagation=Kj.prototype.b; -nh.prototype.map=nh.prototype.map;nh.prototype.frameState=nh.prototype.frameState;fd.prototype.key=fd.prototype.key;fd.prototype.oldValue=fd.prototype.oldValue;u("ol.Object",gd,OPENLAYERS);gd.prototype.get=gd.prototype.get;gd.prototype.getKeys=gd.prototype.P;gd.prototype.getProperties=gd.prototype.R;gd.prototype.set=gd.prototype.set;gd.prototype.setProperties=gd.prototype.I;gd.prototype.unset=gd.prototype.S;u("ol.Observable",dd,OPENLAYERS);u("ol.Observable.unByKey",ed,OPENLAYERS); -dd.prototype.changed=dd.prototype.u;dd.prototype.dispatchEvent=dd.prototype.s;dd.prototype.getRevision=dd.prototype.L;dd.prototype.on=dd.prototype.H;dd.prototype.once=dd.prototype.M;dd.prototype.un=dd.prototype.K;dd.prototype.unByKey=dd.prototype.N;u("ol.inherits",y,OPENLAYERS);u("ol.Overlay",jr,OPENLAYERS);jr.prototype.getElement=jr.prototype.se;jr.prototype.getId=jr.prototype.Oa;jr.prototype.getMap=jr.prototype.te;jr.prototype.getOffset=jr.prototype.Gg;jr.prototype.getPosition=jr.prototype.$g; -jr.prototype.getPositioning=jr.prototype.Hg;jr.prototype.setElement=jr.prototype.Xh;jr.prototype.setMap=jr.prototype.setMap;jr.prototype.setOffset=jr.prototype.bi;jr.prototype.setPosition=jr.prototype.yf;jr.prototype.setPositioning=jr.prototype.ei;u("ol.render.toContext",function(b,c){var d=b.canvas,e=c?c:{},f=e.pixelRatio||Vi;if(e=e.size)d.width=e[0]*f,d.height=e[1]*f,d.style.width=e[0]+"px",d.style.height=e[1]+"px";d=[0,0,d.width,d.height];e=gk(Bd(),0,0,f,f,0,0,0);return new gm(b,f,d,e,0)},OPENLAYERS); -u("ol.size.toSize",md,OPENLAYERS);uh.prototype.getTileCoord=uh.prototype.g;Co.prototype.getFormat=Co.prototype.Ll;Co.prototype.setLoader=Co.prototype.ai;u("ol.View",Nf,OPENLAYERS);Nf.prototype.constrainCenter=Nf.prototype.Xd;Nf.prototype.constrainResolution=Nf.prototype.constrainResolution;Nf.prototype.constrainRotation=Nf.prototype.constrainRotation;Nf.prototype.getCenter=Nf.prototype.Ua;Nf.prototype.calculateExtent=Nf.prototype.$c;Nf.prototype.getProjection=Nf.prototype.Ml; -Nf.prototype.getResolution=Nf.prototype.$;Nf.prototype.getRotation=Nf.prototype.Fa;Nf.prototype.getZoom=Nf.prototype.uk;Nf.prototype.fit=Nf.prototype.kf;Nf.prototype.centerOn=Nf.prototype.uj;Nf.prototype.rotate=Nf.prototype.rotate;Nf.prototype.setCenter=Nf.prototype.kb;Nf.prototype.setResolution=Nf.prototype.Ub;Nf.prototype.setRotation=Nf.prototype.ue;Nf.prototype.setZoom=Nf.prototype.Wo;u("ol.xml.getAllTextContent",Mo,OPENLAYERS);u("ol.xml.parse",fp,OPENLAYERS);rq.prototype.getGL=rq.prototype.Gn; -rq.prototype.useProgram=rq.prototype.He;u("ol.tilegrid.TileGrid",zh,OPENLAYERS);zh.prototype.getMaxZoom=zh.prototype.Eg;zh.prototype.getMinZoom=zh.prototype.Fg;zh.prototype.getOrigin=zh.prototype.Da;zh.prototype.getResolution=zh.prototype.$;zh.prototype.getResolutions=zh.prototype.zh;zh.prototype.getTileCoordExtent=zh.prototype.Aa;zh.prototype.getTileCoordForCoordAndResolution=zh.prototype.fe;zh.prototype.getTileCoordForCoordAndZ=zh.prototype.ge;zh.prototype.getTileSize=zh.prototype.Ka; -u("ol.tilegrid.createXYZ",Mh,OPENLAYERS);u("ol.tilegrid.WMTS",zA,OPENLAYERS);zA.prototype.getMatrixIds=zA.prototype.o;u("ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet",AA,OPENLAYERS);u("ol.style.AtlasManager",EA,OPENLAYERS);u("ol.style.Circle",Zl,OPENLAYERS);Zl.prototype.getFill=Zl.prototype.en;Zl.prototype.getImage=Zl.prototype.gc;Zl.prototype.getRadius=Zl.prototype.fn;Zl.prototype.getStroke=Zl.prototype.gn;u("ol.style.Fill",Tl,OPENLAYERS);Tl.prototype.getColor=Tl.prototype.b; -Tl.prototype.setColor=Tl.prototype.c;u("ol.style.Icon",tk,OPENLAYERS);tk.prototype.getAnchor=tk.prototype.Xb;tk.prototype.getImage=tk.prototype.gc;tk.prototype.getOrigin=tk.prototype.Da;tk.prototype.getSrc=tk.prototype.hn;tk.prototype.getSize=tk.prototype.Cb;tk.prototype.load=tk.prototype.load;u("ol.style.Image",sk,OPENLAYERS);sk.prototype.getOpacity=sk.prototype.Be;sk.prototype.getRotateWithView=sk.prototype.de;sk.prototype.getRotation=sk.prototype.Ce;sk.prototype.getScale=sk.prototype.De; -sk.prototype.getSnapToPixel=sk.prototype.ee;sk.prototype.setOpacity=sk.prototype.Ee;sk.prototype.setRotation=sk.prototype.Fe;sk.prototype.setScale=sk.prototype.Ge;u("ol.style.RegularShape",IA,OPENLAYERS);IA.prototype.getAnchor=IA.prototype.Xb;IA.prototype.getAngle=IA.prototype.jn;IA.prototype.getFill=IA.prototype.kn;IA.prototype.getImage=IA.prototype.gc;IA.prototype.getOrigin=IA.prototype.Da;IA.prototype.getPoints=IA.prototype.ln;IA.prototype.getRadius=IA.prototype.mn;IA.prototype.getRadius2=IA.prototype.jk; -IA.prototype.getSize=IA.prototype.Cb;IA.prototype.getStroke=IA.prototype.nn;u("ol.style.Stroke",Yl,OPENLAYERS);Yl.prototype.getColor=Yl.prototype.pn;Yl.prototype.getLineCap=Yl.prototype.Uj;Yl.prototype.getLineDash=Yl.prototype.qn;Yl.prototype.getLineJoin=Yl.prototype.Vj;Yl.prototype.getMiterLimit=Yl.prototype.$j;Yl.prototype.getWidth=Yl.prototype.rn;Yl.prototype.setColor=Yl.prototype.sn;Yl.prototype.setLineCap=Yl.prototype.Oo;Yl.prototype.setLineDash=Yl.prototype.tn;Yl.prototype.setLineJoin=Yl.prototype.Po; -Yl.prototype.setMiterLimit=Yl.prototype.Qo;Yl.prototype.setWidth=Yl.prototype.Uo;u("ol.style.Style",$l,OPENLAYERS);$l.prototype.getGeometry=$l.prototype.X;$l.prototype.getGeometryFunction=$l.prototype.Pj;$l.prototype.getFill=$l.prototype.vn;$l.prototype.getImage=$l.prototype.wn;$l.prototype.getStroke=$l.prototype.xn;$l.prototype.getText=$l.prototype.Ca;$l.prototype.getZIndex=$l.prototype.yn;$l.prototype.setGeometry=$l.prototype.yh;$l.prototype.setZIndex=$l.prototype.zn;u("ol.style.Text",Wt,OPENLAYERS); -Wt.prototype.getFont=Wt.prototype.Nj;Wt.prototype.getOffsetX=Wt.prototype.ak;Wt.prototype.getOffsetY=Wt.prototype.bk;Wt.prototype.getFill=Wt.prototype.An;Wt.prototype.getRotation=Wt.prototype.Bn;Wt.prototype.getScale=Wt.prototype.Cn;Wt.prototype.getStroke=Wt.prototype.Dn;Wt.prototype.getText=Wt.prototype.Ca;Wt.prototype.getTextAlign=Wt.prototype.nk;Wt.prototype.getTextBaseline=Wt.prototype.pk;Wt.prototype.setFont=Wt.prototype.Lo;Wt.prototype.setOffsetX=Wt.prototype.ci;Wt.prototype.setOffsetY=Wt.prototype.di; -Wt.prototype.setFill=Wt.prototype.Ko;Wt.prototype.setRotation=Wt.prototype.En;Wt.prototype.setScale=Wt.prototype.Fn;Wt.prototype.setStroke=Wt.prototype.Ro;Wt.prototype.setText=Wt.prototype.fi;Wt.prototype.setTextAlign=Wt.prototype.gi;Wt.prototype.setTextBaseline=Wt.prototype.So;u("ol.Sphere",ze,OPENLAYERS);ze.prototype.geodesicArea=ze.prototype.f;ze.prototype.haversineDistance=ze.prototype.a;u("ol.source.BingMaps",Kz,OPENLAYERS);u("ol.source.BingMaps.TOS_ATTRIBUTION",Lz,OPENLAYERS); -u("ol.source.Cluster",Mz,OPENLAYERS);Mz.prototype.getSource=Mz.prototype.ga;u("ol.source.ImageCanvas",on,OPENLAYERS);u("ol.source.ImageMapGuide",Pz,OPENLAYERS);Pz.prototype.getParams=Pz.prototype.Hm;Pz.prototype.getImageLoadFunction=Pz.prototype.Gm;Pz.prototype.updateParams=Pz.prototype.Jm;Pz.prototype.setImageLoadFunction=Pz.prototype.Im;u("ol.source.Image",gn,OPENLAYERS);jn.prototype.image=jn.prototype.image;u("ol.source.ImageStatic",Qz,OPENLAYERS);u("ol.source.ImageVector",Mp,OPENLAYERS); -Mp.prototype.getSource=Mp.prototype.Km;Mp.prototype.getStyle=Mp.prototype.Lm;Mp.prototype.getStyleFunction=Mp.prototype.Mm;Mp.prototype.setStyle=Mp.prototype.ph;u("ol.source.ImageWMS",Rz,OPENLAYERS);Rz.prototype.getGetFeatureInfoUrl=Rz.prototype.Pm;Rz.prototype.getParams=Rz.prototype.Rm;Rz.prototype.getImageLoadFunction=Rz.prototype.Qm;Rz.prototype.getUrl=Rz.prototype.Sm;Rz.prototype.setImageLoadFunction=Rz.prototype.Tm;Rz.prototype.setUrl=Rz.prototype.Um;Rz.prototype.updateParams=Rz.prototype.Vm; -u("ol.source.MapQuest",Yz,OPENLAYERS);Yz.prototype.getLayer=Yz.prototype.l;u("ol.source.OSM",Wz,OPENLAYERS);u("ol.source.OSM.ATTRIBUTION",Xz,OPENLAYERS);u("ol.source.Raster",aA,OPENLAYERS);aA.prototype.setOperation=aA.prototype.v;fA.prototype.extent=fA.prototype.extent;fA.prototype.resolution=fA.prototype.resolution;fA.prototype.data=fA.prototype.data;u("ol.source.Source",wh,OPENLAYERS);wh.prototype.getAttributions=wh.prototype.sa;wh.prototype.getLogo=wh.prototype.qa;wh.prototype.getProjection=wh.prototype.ta; -wh.prototype.getState=wh.prototype.ua;wh.prototype.setAttributions=wh.prototype.ma;u("ol.source.Stamen",kA,OPENLAYERS);u("ol.source.TileArcGISRest",mA,OPENLAYERS);mA.prototype.getParams=mA.prototype.C;mA.prototype.updateParams=mA.prototype.V;u("ol.source.TileDebug",oA,OPENLAYERS);u("ol.source.TileImage",Y,OPENLAYERS);Y.prototype.setRenderReprojectionEdges=Y.prototype.vb;Y.prototype.setTileGridForProjection=Y.prototype.wb;u("ol.source.TileJSON",pA,OPENLAYERS);u("ol.source.Tile",Nh,OPENLAYERS); -Nh.prototype.getTileGrid=Nh.prototype.Ha;Qh.prototype.tile=Qh.prototype.tile;u("ol.source.TileUTFGrid",qA,OPENLAYERS);qA.prototype.getTemplate=qA.prototype.mk;qA.prototype.forDataAtCoordinateAndResolution=qA.prototype.zj;u("ol.source.TileWMS",vA,OPENLAYERS);vA.prototype.getGetFeatureInfoUrl=vA.prototype.Ym;vA.prototype.getParams=vA.prototype.Zm;vA.prototype.updateParams=vA.prototype.an;Wp.prototype.getTileLoadFunction=Wp.prototype.Xa;Wp.prototype.getTileUrlFunction=Wp.prototype.Ya; -Wp.prototype.getUrls=Wp.prototype.Za;Wp.prototype.setTileLoadFunction=Wp.prototype.eb;Wp.prototype.setTileUrlFunction=Wp.prototype.Ja;Wp.prototype.setUrl=Wp.prototype.Va;Wp.prototype.setUrls=Wp.prototype.Wa;u("ol.source.Vector",R,OPENLAYERS);R.prototype.addFeature=R.prototype.Bd;R.prototype.addFeatures=R.prototype.Ec;R.prototype.clear=R.prototype.clear;R.prototype.forEachFeature=R.prototype.sg;R.prototype.forEachFeatureInExtent=R.prototype.pb;R.prototype.forEachFeatureIntersectingExtent=R.prototype.tg; -R.prototype.getFeaturesCollection=R.prototype.zg;R.prototype.getFeatures=R.prototype.ze;R.prototype.getFeaturesAtCoordinate=R.prototype.yg;R.prototype.getFeaturesInExtent=R.prototype.mf;R.prototype.getClosestFeatureToCoordinate=R.prototype.vg;R.prototype.getExtent=R.prototype.J;R.prototype.getFeatureById=R.prototype.xg;R.prototype.removeFeature=R.prototype.Rc;Jp.prototype.feature=Jp.prototype.feature;u("ol.source.VectorTile",Xp,OPENLAYERS);u("ol.source.WMTS",Z,OPENLAYERS); -Z.prototype.getDimensions=Z.prototype.Lj;Z.prototype.getFormat=Z.prototype.bn;Z.prototype.getLayer=Z.prototype.cn;Z.prototype.getMatrixSet=Z.prototype.Yj;Z.prototype.getRequestEncoding=Z.prototype.kk;Z.prototype.getStyle=Z.prototype.dn;Z.prototype.getVersion=Z.prototype.rk;Z.prototype.updateDimensions=Z.prototype.cp; -u("ol.source.WMTS.optionsFromCapabilities",function(b,c){var d=fb(b.Contents.Layer,function(b){return b.Identifier==c.layer}),e=b.Contents.TileMatrixSet,f,g;f=1<d.TileMatrixSetLink.length?"projection"in c?gb(d.TileMatrixSetLink,function(b){return fb(e,function(c){return c.Identifier==b.TileMatrixSet}).SupportedCRS.replace(/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/,"$1:$3")==c.projection}):gb(d.TileMatrixSetLink,function(b){return b.TileMatrixSet==c.matrixSet}):0;0>f&&(f=0);g=d.TileMatrixSetLink[f].TileMatrixSet; -var h=d.Format[0];"format"in c&&(h=c.format);f=gb(d.Style,function(b){return"style"in c?b.Title==c.style:b.isDefault});0>f&&(f=0);f=d.Style[f].Identifier;var k={};"Dimension"in d&&d.Dimension.forEach(function(b){var c=b.Identifier,d=b.Default;void 0===d&&(d=b.Value[0]);k[c]=d});var m=fb(b.Contents.TileMatrixSet,function(b){return b.Identifier==g}),n;n="projection"in c?Ee(c.projection):Ee(m.SupportedCRS.replace(/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/,"$1:$3"));var p=d.WGS84BoundingBox,q,r;void 0!==p&& -(r=Ee("EPSG:4326").J(),r=p[0]==r[0]&&p[2]==r[2],q=Ze(p,"EPSG:4326",n),(p=n.J())&&(Vd(p,q)||(q=void 0)));var m=AA(m,q),t=[];q=c.requestEncoding;q=void 0!==q?q:"";if(b.hasOwnProperty("OperationsMetadata")&&b.OperationsMetadata.hasOwnProperty("GetTile")&&0!==q.indexOf("REST"))for(var d=b.OperationsMetadata.GetTile.DCP.HTTP.Get,p=0,x=d.length;p<x;++p){var z=fb(d[p].Constraint,function(b){return"GetEncoding"==b.name}).AllowedValues.Value;0<z.length&&vb(z,"KVP")&&(q="KVP",t.push(d[p].href))}else q="REST", -d.ResourceURL.forEach(function(b){"tile"==b.resourceType&&(h=b.format,t.push(b.template))});return{urls:t,layer:c.layer,matrixSet:g,format:h,projection:n,requestEncoding:q,tileGrid:m,style:f,dimensions:k,wrapX:r}},OPENLAYERS);u("ol.source.XYZ",Vz,OPENLAYERS);u("ol.source.Zoomify",CA,OPENLAYERS);bk.prototype.vectorContext=bk.prototype.vectorContext;bk.prototype.frameState=bk.prototype.frameState;bk.prototype.context=bk.prototype.context;bk.prototype.glContext=bk.prototype.glContext; -Sm.prototype.get=Sm.prototype.get;Sm.prototype.getExtent=Sm.prototype.J;Sm.prototype.getGeometry=Sm.prototype.X;Sm.prototype.getProperties=Sm.prototype.Cm;Sm.prototype.getType=Sm.prototype.W;u("ol.render.VectorContext",ak,OPENLAYERS);Oq.prototype.drawAsync=Oq.prototype.md;Oq.prototype.drawCircleGeometry=Oq.prototype.Gc;Oq.prototype.drawFeature=Oq.prototype.jf;Oq.prototype.drawGeometryCollectionGeometry=Oq.prototype.Yd;Oq.prototype.drawPointGeometry=Oq.prototype.Hb; -Oq.prototype.drawLineStringGeometry=Oq.prototype.Wb;Oq.prototype.drawMultiLineStringGeometry=Oq.prototype.Hc;Oq.prototype.drawMultiPointGeometry=Oq.prototype.Gb;Oq.prototype.drawMultiPolygonGeometry=Oq.prototype.Ic;Oq.prototype.drawPolygonGeometry=Oq.prototype.Jc;Oq.prototype.drawText=Oq.prototype.Ib;Oq.prototype.setFillStrokeStyle=Oq.prototype.bb;Oq.prototype.setImageStyle=Oq.prototype.ub;Oq.prototype.setTextStyle=Oq.prototype.cb;gm.prototype.drawAsync=gm.prototype.md; -gm.prototype.drawCircleGeometry=gm.prototype.Gc;gm.prototype.drawFeature=gm.prototype.jf;gm.prototype.drawPointGeometry=gm.prototype.Hb;gm.prototype.drawMultiPointGeometry=gm.prototype.Gb;gm.prototype.drawLineStringGeometry=gm.prototype.Wb;gm.prototype.drawMultiLineStringGeometry=gm.prototype.Hc;gm.prototype.drawPolygonGeometry=gm.prototype.Jc;gm.prototype.drawMultiPolygonGeometry=gm.prototype.Ic;gm.prototype.setFillStrokeStyle=gm.prototype.bb;gm.prototype.setImageStyle=gm.prototype.ub; -gm.prototype.setTextStyle=gm.prototype.cb;u("ol.proj.common.add",Ol,OPENLAYERS);u("ol.proj.METERS_PER_UNIT",Be,OPENLAYERS);u("ol.proj.Projection",Ce,OPENLAYERS);Ce.prototype.getCode=Ce.prototype.Jj;Ce.prototype.getExtent=Ce.prototype.J;Ce.prototype.getUnits=Ce.prototype.Am;Ce.prototype.getMetersPerUnit=Ce.prototype.Kc;Ce.prototype.getWorldExtent=Ce.prototype.tk;Ce.prototype.isGlobal=Ce.prototype.gl;Ce.prototype.setGlobal=Ce.prototype.No;Ce.prototype.setExtent=Ce.prototype.Bm; -Ce.prototype.setWorldExtent=Ce.prototype.Vo;Ce.prototype.setGetPointResolution=Ce.prototype.Mo;Ce.prototype.getPointResolution=Ce.prototype.getPointResolution;u("ol.proj.addEquivalentProjections",Fe,OPENLAYERS);u("ol.proj.addProjection",Se,OPENLAYERS);u("ol.proj.addCoordinateTransforms",Ge,OPENLAYERS);u("ol.proj.fromLonLat",function(b,c){return Ye(b,"EPSG:4326",void 0!==c?c:"EPSG:3857")},OPENLAYERS);u("ol.proj.toLonLat",function(b,c){return Ye(b,void 0!==c?c:"EPSG:3857","EPSG:4326")},OPENLAYERS); -u("ol.proj.get",Ee,OPENLAYERS);u("ol.proj.getTransform",We,OPENLAYERS);u("ol.proj.transform",Ye,OPENLAYERS);u("ol.proj.transformExtent",Ze,OPENLAYERS);u("ol.layer.Heatmap",X,OPENLAYERS);X.prototype.getBlur=X.prototype.ug;X.prototype.getGradient=X.prototype.Bg;X.prototype.getRadius=X.prototype.jh;X.prototype.setBlur=X.prototype.Vh;X.prototype.setGradient=X.prototype.Zh;X.prototype.setRadius=X.prototype.kh;u("ol.layer.Image",Pl,OPENLAYERS);Pl.prototype.getSource=Pl.prototype.ea; -u("ol.layer.Layer",ck,OPENLAYERS);ck.prototype.getSource=ck.prototype.ea;ck.prototype.setMap=ck.prototype.setMap;ck.prototype.setSource=ck.prototype.zc;u("ol.layer.Base",Yj,OPENLAYERS);Yj.prototype.getExtent=Yj.prototype.J;Yj.prototype.getMaxResolution=Yj.prototype.Nb;Yj.prototype.getMinResolution=Yj.prototype.Ob;Yj.prototype.getOpacity=Yj.prototype.Rb;Yj.prototype.getVisible=Yj.prototype.rb;Yj.prototype.getZIndex=Yj.prototype.Sb;Yj.prototype.setExtent=Yj.prototype.cc; -Yj.prototype.setMaxResolution=Yj.prototype.kc;Yj.prototype.setMinResolution=Yj.prototype.lc;Yj.prototype.setOpacity=Yj.prototype.dc;Yj.prototype.setVisible=Yj.prototype.ec;Yj.prototype.setZIndex=Yj.prototype.fc;u("ol.layer.Group",Hl,OPENLAYERS);Hl.prototype.getLayers=Hl.prototype.Qc;Hl.prototype.setLayers=Hl.prototype.ih;u("ol.layer.Tile",G,OPENLAYERS);G.prototype.getPreload=G.prototype.a;G.prototype.getSource=G.prototype.ea;G.prototype.setPreload=G.prototype.c; -G.prototype.getUseInterimTilesOnError=G.prototype.b;G.prototype.setUseInterimTilesOnError=G.prototype.g;u("ol.layer.Vector",H,OPENLAYERS);H.prototype.getSource=H.prototype.ea;H.prototype.getStyle=H.prototype.C;H.prototype.getStyleFunction=H.prototype.D;H.prototype.setStyle=H.prototype.c;u("ol.layer.VectorTile",I,OPENLAYERS);I.prototype.getPreload=I.prototype.g;I.prototype.getSource=I.prototype.ea;I.prototype.getUseInterimTilesOnError=I.prototype.U;I.prototype.setPreload=I.prototype.T; -I.prototype.setUseInterimTilesOnError=I.prototype.V;u("ol.interaction.DoubleClickZoom",Pk,OPENLAYERS);u("ol.interaction.DoubleClickZoom.handleEvent",Qk,OPENLAYERS);u("ol.interaction.DragAndDrop",qy,OPENLAYERS);u("ol.interaction.DragAndDrop.handleEvent",te,OPENLAYERS);ry.prototype.features=ry.prototype.features;ry.prototype.file=ry.prototype.file;ry.prototype.projection=ry.prototype.projection;ll.prototype.coordinate=ll.prototype.coordinate;u("ol.interaction.DragBox",ml,OPENLAYERS); -ml.prototype.getGeometry=ml.prototype.X;u("ol.interaction.DragPan",al,OPENLAYERS);u("ol.interaction.DragRotateAndZoom",uy,OPENLAYERS);u("ol.interaction.DragRotate",el,OPENLAYERS);u("ol.interaction.DragZoom",rl,OPENLAYERS);yy.prototype.feature=yy.prototype.feature;u("ol.interaction.Draw",zy,OPENLAYERS);u("ol.interaction.Draw.handleEvent",By,OPENLAYERS);zy.prototype.removeLastPoint=zy.prototype.Ao;zy.prototype.finishDrawing=zy.prototype.od;zy.prototype.extend=zy.prototype.fm; -u("ol.interaction.Draw.createRegularPolygon",function(b,c){return function(d,e){var f=d[0],g=d[1],h=Math.sqrt(vd(f,g)),k=e?e:Lf(new Nx(f),b);Mf(k,f,h,c?c:Math.atan((g[1]-f[1])/(g[0]-f[0])));return k}},OPENLAYERS);u("ol.interaction.Interaction",Lk,OPENLAYERS);Lk.prototype.getActive=Lk.prototype.b;Lk.prototype.getMap=Lk.prototype.i;Lk.prototype.setActive=Lk.prototype.g;u("ol.interaction.defaults",Gl,OPENLAYERS);u("ol.interaction.KeyboardPan",sl,OPENLAYERS); -u("ol.interaction.KeyboardPan.handleEvent",tl,OPENLAYERS);u("ol.interaction.KeyboardZoom",ul,OPENLAYERS);u("ol.interaction.KeyboardZoom.handleEvent",vl,OPENLAYERS);Py.prototype.features=Py.prototype.features;Py.prototype.mapBrowserPointerEvent=Py.prototype.mapBrowserPointerEvent;u("ol.interaction.Modify",Qy,OPENLAYERS);u("ol.interaction.Modify.handleEvent",Ty,OPENLAYERS);u("ol.interaction.MouseWheelZoom",wl,OPENLAYERS);u("ol.interaction.MouseWheelZoom.handleEvent",xl,OPENLAYERS); -wl.prototype.setMouseAnchor=wl.prototype.D;u("ol.interaction.PinchRotate",yl,OPENLAYERS);u("ol.interaction.PinchZoom",Cl,OPENLAYERS);u("ol.interaction.Pointer",Yk,OPENLAYERS);u("ol.interaction.Pointer.handleEvent",Zk,OPENLAYERS);cz.prototype.selected=cz.prototype.selected;cz.prototype.deselected=cz.prototype.deselected;cz.prototype.mapBrowserEvent=cz.prototype.mapBrowserEvent;u("ol.interaction.Select",dz,OPENLAYERS);dz.prototype.getFeatures=dz.prototype.pm;dz.prototype.getLayer=dz.prototype.qm; -u("ol.interaction.Select.handleEvent",ez,OPENLAYERS);dz.prototype.setMap=dz.prototype.setMap;u("ol.interaction.Snap",gz,OPENLAYERS);gz.prototype.addFeature=gz.prototype.xd;gz.prototype.removeFeature=gz.prototype.yd;kz.prototype.features=kz.prototype.features;kz.prototype.coordinate=kz.prototype.coordinate;u("ol.interaction.Translate",lz,OPENLAYERS);u("ol.geom.Circle",Nx,OPENLAYERS);Nx.prototype.clone=Nx.prototype.clone;Nx.prototype.getCenter=Nx.prototype.wd;Nx.prototype.getRadius=Nx.prototype.zf; -Nx.prototype.getType=Nx.prototype.W;Nx.prototype.intersectsExtent=Nx.prototype.Ea;Nx.prototype.setCenter=Nx.prototype.Yl;Nx.prototype.setCenterAndRadius=Nx.prototype.Uf;Nx.prototype.setRadius=Nx.prototype.Zl;Nx.prototype.transform=Nx.prototype.lb;u("ol.geom.Geometry",$e,OPENLAYERS);$e.prototype.getClosestPoint=$e.prototype.qb;$e.prototype.getExtent=$e.prototype.J;$e.prototype.simplify=$e.prototype.xb;$e.prototype.transform=$e.prototype.lb;u("ol.geom.GeometryCollection",gs,OPENLAYERS); -gs.prototype.clone=gs.prototype.clone;gs.prototype.getGeometries=gs.prototype.Ag;gs.prototype.getType=gs.prototype.W;gs.prototype.intersectsExtent=gs.prototype.Ea;gs.prototype.setGeometries=gs.prototype.Yh;gs.prototype.applyTransform=gs.prototype.pc;gs.prototype.translate=gs.prototype.Pc;u("ol.geom.LinearRing",vf,OPENLAYERS);vf.prototype.clone=vf.prototype.clone;vf.prototype.getArea=vf.prototype.bm;vf.prototype.getCoordinates=vf.prototype.Z;vf.prototype.getType=vf.prototype.W; -vf.prototype.setCoordinates=vf.prototype.la;u("ol.geom.LineString",T,OPENLAYERS);T.prototype.appendCoordinate=T.prototype.mj;T.prototype.clone=T.prototype.clone;T.prototype.forEachSegment=T.prototype.Cj;T.prototype.getCoordinateAtM=T.prototype.$l;T.prototype.getCoordinates=T.prototype.Z;T.prototype.getLength=T.prototype.am;T.prototype.getType=T.prototype.W;T.prototype.intersectsExtent=T.prototype.Ea;T.prototype.setCoordinates=T.prototype.la;u("ol.geom.MultiLineString",U,OPENLAYERS); -U.prototype.appendLineString=U.prototype.nj;U.prototype.clone=U.prototype.clone;U.prototype.getCoordinateAtM=U.prototype.cm;U.prototype.getCoordinates=U.prototype.Z;U.prototype.getLineString=U.prototype.Wj;U.prototype.getLineStrings=U.prototype.sd;U.prototype.getType=U.prototype.W;U.prototype.intersectsExtent=U.prototype.Ea;U.prototype.setCoordinates=U.prototype.la;u("ol.geom.MultiPoint",Xr,OPENLAYERS);Xr.prototype.appendPoint=Xr.prototype.pj;Xr.prototype.clone=Xr.prototype.clone; -Xr.prototype.getCoordinates=Xr.prototype.Z;Xr.prototype.getPoint=Xr.prototype.gk;Xr.prototype.getPoints=Xr.prototype.ve;Xr.prototype.getType=Xr.prototype.W;Xr.prototype.intersectsExtent=Xr.prototype.Ea;Xr.prototype.setCoordinates=Xr.prototype.la;u("ol.geom.MultiPolygon",V,OPENLAYERS);V.prototype.appendPolygon=V.prototype.qj;V.prototype.clone=V.prototype.clone;V.prototype.getArea=V.prototype.dm;V.prototype.getCoordinates=V.prototype.Z;V.prototype.getInteriorPoints=V.prototype.Tj; -V.prototype.getPolygon=V.prototype.ik;V.prototype.getPolygons=V.prototype.ce;V.prototype.getType=V.prototype.W;V.prototype.intersectsExtent=V.prototype.Ea;V.prototype.setCoordinates=V.prototype.la;u("ol.geom.Point",E,OPENLAYERS);E.prototype.clone=E.prototype.clone;E.prototype.getCoordinates=E.prototype.Z;E.prototype.getType=E.prototype.W;E.prototype.intersectsExtent=E.prototype.Ea;E.prototype.setCoordinates=E.prototype.la;u("ol.geom.Polygon",F,OPENLAYERS);F.prototype.appendLinearRing=F.prototype.oj; -F.prototype.clone=F.prototype.clone;F.prototype.getArea=F.prototype.em;F.prototype.getCoordinates=F.prototype.Z;F.prototype.getInteriorPoint=F.prototype.Sj;F.prototype.getLinearRingCount=F.prototype.Xj;F.prototype.getLinearRing=F.prototype.Dg;F.prototype.getLinearRings=F.prototype.be;F.prototype.getType=F.prototype.W;F.prototype.intersectsExtent=F.prototype.Ea;F.prototype.setCoordinates=F.prototype.la;u("ol.geom.Polygon.circular",Jf,OPENLAYERS);u("ol.geom.Polygon.fromExtent",Kf,OPENLAYERS); -u("ol.geom.Polygon.fromCircle",Lf,OPENLAYERS);u("ol.geom.SimpleGeometry",bf,OPENLAYERS);bf.prototype.getFirstCoordinate=bf.prototype.Kb;bf.prototype.getLastCoordinate=bf.prototype.Lb;bf.prototype.getLayout=bf.prototype.Mb;bf.prototype.applyTransform=bf.prototype.pc;bf.prototype.translate=bf.prototype.Pc;u("ol.format.EsriJSON",$r,OPENLAYERS);$r.prototype.readFeature=$r.prototype.Tb;$r.prototype.readFeatures=$r.prototype.Ba;$r.prototype.readGeometry=$r.prototype.Tc;$r.prototype.readProjection=$r.prototype.Ia; -$r.prototype.writeGeometry=$r.prototype.Xc;$r.prototype.writeGeometryObject=$r.prototype.Ue;$r.prototype.writeFeature=$r.prototype.Kd;$r.prototype.writeFeatureObject=$r.prototype.Wc;$r.prototype.writeFeatures=$r.prototype.Vb;$r.prototype.writeFeaturesObject=$r.prototype.Se;u("ol.format.Feature",Nr,OPENLAYERS);u("ol.format.GeoJSON",ks,OPENLAYERS);ks.prototype.readFeature=ks.prototype.Tb;ks.prototype.readFeatures=ks.prototype.Ba;ks.prototype.readGeometry=ks.prototype.Tc; -ks.prototype.readProjection=ks.prototype.Ia;ks.prototype.writeFeature=ks.prototype.Kd;ks.prototype.writeFeatureObject=ks.prototype.Wc;ks.prototype.writeFeatures=ks.prototype.Vb;ks.prototype.writeFeaturesObject=ks.prototype.Se;ks.prototype.writeGeometry=ks.prototype.Xc;ks.prototype.writeGeometryObject=ks.prototype.Ue;u("ol.format.GPX",Os,OPENLAYERS);Os.prototype.readFeature=Os.prototype.Tb;Os.prototype.readFeatures=Os.prototype.Ba;Os.prototype.readProjection=Os.prototype.Ia; -Os.prototype.writeFeatures=Os.prototype.Vb;Os.prototype.writeFeaturesNode=Os.prototype.f;u("ol.format.IGC",yt,OPENLAYERS);yt.prototype.readFeature=yt.prototype.Tb;yt.prototype.readFeatures=yt.prototype.Ba;yt.prototype.readProjection=yt.prototype.Ia;u("ol.format.KML",Xt,OPENLAYERS);Xt.prototype.readFeature=Xt.prototype.Tb;Xt.prototype.readFeatures=Xt.prototype.Ba;Xt.prototype.readName=Xt.prototype.po;Xt.prototype.readNetworkLinks=Xt.prototype.qo;Xt.prototype.readProjection=Xt.prototype.Ia; -Xt.prototype.writeFeatures=Xt.prototype.Vb;Xt.prototype.writeFeaturesNode=Xt.prototype.f;u("ol.format.MVT",Lv,OPENLAYERS);Lv.prototype.setLayers=Lv.prototype.g;u("ol.format.OSMXML",Nv,OPENLAYERS);Nv.prototype.readFeatures=Nv.prototype.Ba;Nv.prototype.readProjection=Nv.prototype.Ia;u("ol.format.Polyline",lw,OPENLAYERS);u("ol.format.Polyline.encodeDeltas",mw,OPENLAYERS);u("ol.format.Polyline.decodeDeltas",ow,OPENLAYERS);u("ol.format.Polyline.encodeFloats",nw,OPENLAYERS); -u("ol.format.Polyline.decodeFloats",pw,OPENLAYERS);lw.prototype.readFeature=lw.prototype.Tb;lw.prototype.readFeatures=lw.prototype.Ba;lw.prototype.readGeometry=lw.prototype.Tc;lw.prototype.readProjection=lw.prototype.Ia;lw.prototype.writeGeometry=lw.prototype.Xc;u("ol.format.TopoJSON",qw,OPENLAYERS);qw.prototype.readFeatures=qw.prototype.Ba;qw.prototype.readProjection=qw.prototype.Ia;u("ol.format.WFS",ww,OPENLAYERS);ww.prototype.readFeatures=ww.prototype.Ba;ww.prototype.readTransactionResponse=ww.prototype.j; -ww.prototype.readFeatureCollectionMetadata=ww.prototype.i;ww.prototype.writeGetFeature=ww.prototype.l;ww.prototype.writeTransaction=ww.prototype.B;ww.prototype.readProjection=ww.prototype.Ia;u("ol.format.WKT",Jw,OPENLAYERS);Jw.prototype.readFeature=Jw.prototype.Tb;Jw.prototype.readFeatures=Jw.prototype.Ba;Jw.prototype.readGeometry=Jw.prototype.Tc;Jw.prototype.writeFeature=Jw.prototype.Kd;Jw.prototype.writeFeatures=Jw.prototype.Vb;Jw.prototype.writeGeometry=Jw.prototype.Xc; -u("ol.format.WMSCapabilities",ax,OPENLAYERS);ax.prototype.read=ax.prototype.read;u("ol.format.WMSGetFeatureInfo",xx,OPENLAYERS);xx.prototype.readFeatures=xx.prototype.Ba;u("ol.format.WMTSCapabilities",yx,OPENLAYERS);yx.prototype.read=yx.prototype.read;u("ol.format.GML2",Es,OPENLAYERS);u("ol.format.GML3",Fs,OPENLAYERS);Fs.prototype.writeGeometryNode=Fs.prototype.o;Fs.prototype.writeFeatures=Fs.prototype.Vb;Fs.prototype.writeFeaturesNode=Fs.prototype.f;u("ol.format.GML",Fs,OPENLAYERS); -Fs.prototype.writeFeatures=Fs.prototype.Vb;Fs.prototype.writeFeaturesNode=Fs.prototype.f;ss.prototype.readFeatures=ss.prototype.Ba;u("ol.events.condition.altKeyOnly",function(b){b=b.a;return b.f&&!b.l&&!b.c},OPENLAYERS);u("ol.events.condition.altShiftKeysOnly",Rk,OPENLAYERS);u("ol.events.condition.always",te,OPENLAYERS);u("ol.events.condition.click",function(b){return b.type==Oj},OPENLAYERS);u("ol.events.condition.never",se,OPENLAYERS);u("ol.events.condition.pointerMove",Sk,OPENLAYERS); -u("ol.events.condition.singleClick",Tk,OPENLAYERS);u("ol.events.condition.doubleClick",function(b){return b.type==Pj},OPENLAYERS);u("ol.events.condition.noModifierKeys",Uk,OPENLAYERS);u("ol.events.condition.platformModifierKeyOnly",function(b){b=b.a;return!b.f&&b.l&&!b.c},OPENLAYERS);u("ol.events.condition.shiftKeyOnly",Vk,OPENLAYERS);u("ol.events.condition.targetNotEditable",Wk,OPENLAYERS);u("ol.events.condition.mouseOnly",Xk,OPENLAYERS);u("ol.control.Attribution",Rh,OPENLAYERS); -u("ol.control.Attribution.render",Sh,OPENLAYERS);Rh.prototype.getCollapsible=Rh.prototype.Ol;Rh.prototype.setCollapsible=Rh.prototype.Rl;Rh.prototype.setCollapsed=Rh.prototype.Ql;Rh.prototype.getCollapsed=Rh.prototype.Nl;u("ol.control.Control",oh,OPENLAYERS);oh.prototype.getMap=oh.prototype.g;oh.prototype.setMap=oh.prototype.setMap;oh.prototype.setTarget=oh.prototype.c;u("ol.control.defaults",Xh,OPENLAYERS);u("ol.control.FullScreen",bi,OPENLAYERS);u("ol.control.MousePosition",di,OPENLAYERS); -u("ol.control.MousePosition.render",ei,OPENLAYERS);di.prototype.getCoordinateFormat=di.prototype.wg;di.prototype.getProjection=di.prototype.ah;di.prototype.setCoordinateFormat=di.prototype.Wh;di.prototype.setProjection=di.prototype.bh;u("ol.control.OverviewMap",nr,OPENLAYERS);u("ol.control.OverviewMap.render",or,OPENLAYERS);nr.prototype.getCollapsible=nr.prototype.Ul;nr.prototype.setCollapsible=nr.prototype.Xl;nr.prototype.setCollapsed=nr.prototype.Wl;nr.prototype.getCollapsed=nr.prototype.Tl; -nr.prototype.getOverviewMap=nr.prototype.ek;u("ol.control.Rotate",Uh,OPENLAYERS);u("ol.control.Rotate.render",Vh,OPENLAYERS);u("ol.control.ScaleLine",sr,OPENLAYERS);sr.prototype.getUnits=sr.prototype.D;u("ol.control.ScaleLine.render",tr,OPENLAYERS);sr.prototype.setUnits=sr.prototype.T;u("ol.control.Zoom",Wh,OPENLAYERS);u("ol.control.ZoomSlider",Gr,OPENLAYERS);u("ol.control.ZoomSlider.render",Ir,OPENLAYERS);u("ol.control.ZoomToExtent",Lr,OPENLAYERS);u("ol.color.asArray",tg,OPENLAYERS); -u("ol.color.asString",vg,OPENLAYERS);gd.prototype.changed=gd.prototype.u;gd.prototype.dispatchEvent=gd.prototype.s;gd.prototype.getRevision=gd.prototype.L;gd.prototype.on=gd.prototype.H;gd.prototype.once=gd.prototype.M;gd.prototype.un=gd.prototype.K;gd.prototype.unByKey=gd.prototype.N;og.prototype.get=og.prototype.get;og.prototype.getKeys=og.prototype.P;og.prototype.getProperties=og.prototype.R;og.prototype.set=og.prototype.set;og.prototype.setProperties=og.prototype.I;og.prototype.unset=og.prototype.S; -og.prototype.changed=og.prototype.u;og.prototype.dispatchEvent=og.prototype.s;og.prototype.getRevision=og.prototype.L;og.prototype.on=og.prototype.H;og.prototype.once=og.prototype.M;og.prototype.un=og.prototype.K;og.prototype.unByKey=og.prototype.N;Mr.prototype.get=Mr.prototype.get;Mr.prototype.getKeys=Mr.prototype.P;Mr.prototype.getProperties=Mr.prototype.R;Mr.prototype.set=Mr.prototype.set;Mr.prototype.setProperties=Mr.prototype.I;Mr.prototype.unset=Mr.prototype.S;Mr.prototype.changed=Mr.prototype.u; -Mr.prototype.dispatchEvent=Mr.prototype.s;Mr.prototype.getRevision=Mr.prototype.L;Mr.prototype.on=Mr.prototype.H;Mr.prototype.once=Mr.prototype.M;Mr.prototype.un=Mr.prototype.K;Mr.prototype.unByKey=Mr.prototype.N;pn.prototype.get=pn.prototype.get;pn.prototype.getKeys=pn.prototype.P;pn.prototype.getProperties=pn.prototype.R;pn.prototype.set=pn.prototype.set;pn.prototype.setProperties=pn.prototype.I;pn.prototype.unset=pn.prototype.S;pn.prototype.changed=pn.prototype.u;pn.prototype.dispatchEvent=pn.prototype.s; -pn.prototype.getRevision=pn.prototype.L;pn.prototype.on=pn.prototype.H;pn.prototype.once=pn.prototype.M;pn.prototype.un=pn.prototype.K;pn.prototype.unByKey=pn.prototype.N;Mx.prototype.get=Mx.prototype.get;Mx.prototype.getKeys=Mx.prototype.P;Mx.prototype.getProperties=Mx.prototype.R;Mx.prototype.set=Mx.prototype.set;Mx.prototype.setProperties=Mx.prototype.I;Mx.prototype.unset=Mx.prototype.S;Mx.prototype.changed=Mx.prototype.u;Mx.prototype.dispatchEvent=Mx.prototype.s;Mx.prototype.getRevision=Mx.prototype.L; -Mx.prototype.on=Mx.prototype.H;Mx.prototype.once=Mx.prototype.M;Mx.prototype.un=Mx.prototype.K;Mx.prototype.unByKey=Mx.prototype.N;Yx.prototype.getTileCoord=Yx.prototype.g;S.prototype.get=S.prototype.get;S.prototype.getKeys=S.prototype.P;S.prototype.getProperties=S.prototype.R;S.prototype.set=S.prototype.set;S.prototype.setProperties=S.prototype.I;S.prototype.unset=S.prototype.S;S.prototype.changed=S.prototype.u;S.prototype.dispatchEvent=S.prototype.s;S.prototype.getRevision=S.prototype.L; -S.prototype.on=S.prototype.H;S.prototype.once=S.prototype.M;S.prototype.un=S.prototype.K;S.prototype.unByKey=S.prototype.N;Kj.prototype.map=Kj.prototype.map;Kj.prototype.frameState=Kj.prototype.frameState;Lj.prototype.originalEvent=Lj.prototype.originalEvent;Lj.prototype.pixel=Lj.prototype.pixel;Lj.prototype.coordinate=Lj.prototype.coordinate;Lj.prototype.dragging=Lj.prototype.dragging;Lj.prototype.preventDefault=Lj.prototype.preventDefault;Lj.prototype.stopPropagation=Lj.prototype.b; -Lj.prototype.map=Lj.prototype.map;Lj.prototype.frameState=Lj.prototype.frameState;jr.prototype.get=jr.prototype.get;jr.prototype.getKeys=jr.prototype.P;jr.prototype.getProperties=jr.prototype.R;jr.prototype.set=jr.prototype.set;jr.prototype.setProperties=jr.prototype.I;jr.prototype.unset=jr.prototype.S;jr.prototype.changed=jr.prototype.u;jr.prototype.dispatchEvent=jr.prototype.s;jr.prototype.getRevision=jr.prototype.L;jr.prototype.on=jr.prototype.H;jr.prototype.once=jr.prototype.M; -jr.prototype.un=jr.prototype.K;jr.prototype.unByKey=jr.prototype.N;Co.prototype.getTileCoord=Co.prototype.g;Nf.prototype.get=Nf.prototype.get;Nf.prototype.getKeys=Nf.prototype.P;Nf.prototype.getProperties=Nf.prototype.R;Nf.prototype.set=Nf.prototype.set;Nf.prototype.setProperties=Nf.prototype.I;Nf.prototype.unset=Nf.prototype.S;Nf.prototype.changed=Nf.prototype.u;Nf.prototype.dispatchEvent=Nf.prototype.s;Nf.prototype.getRevision=Nf.prototype.L;Nf.prototype.on=Nf.prototype.H;Nf.prototype.once=Nf.prototype.M; -Nf.prototype.un=Nf.prototype.K;Nf.prototype.unByKey=Nf.prototype.N;zA.prototype.getMaxZoom=zA.prototype.Eg;zA.prototype.getMinZoom=zA.prototype.Fg;zA.prototype.getOrigin=zA.prototype.Da;zA.prototype.getResolution=zA.prototype.$;zA.prototype.getResolutions=zA.prototype.zh;zA.prototype.getTileCoordExtent=zA.prototype.Aa;zA.prototype.getTileCoordForCoordAndResolution=zA.prototype.fe;zA.prototype.getTileCoordForCoordAndZ=zA.prototype.ge;zA.prototype.getTileSize=zA.prototype.Ka; -Zl.prototype.getOpacity=Zl.prototype.Be;Zl.prototype.getRotateWithView=Zl.prototype.de;Zl.prototype.getRotation=Zl.prototype.Ce;Zl.prototype.getScale=Zl.prototype.De;Zl.prototype.getSnapToPixel=Zl.prototype.ee;Zl.prototype.setOpacity=Zl.prototype.Ee;Zl.prototype.setRotation=Zl.prototype.Fe;Zl.prototype.setScale=Zl.prototype.Ge;tk.prototype.getOpacity=tk.prototype.Be;tk.prototype.getRotateWithView=tk.prototype.de;tk.prototype.getRotation=tk.prototype.Ce;tk.prototype.getScale=tk.prototype.De; -tk.prototype.getSnapToPixel=tk.prototype.ee;tk.prototype.setOpacity=tk.prototype.Ee;tk.prototype.setRotation=tk.prototype.Fe;tk.prototype.setScale=tk.prototype.Ge;IA.prototype.getOpacity=IA.prototype.Be;IA.prototype.getRotateWithView=IA.prototype.de;IA.prototype.getRotation=IA.prototype.Ce;IA.prototype.getScale=IA.prototype.De;IA.prototype.getSnapToPixel=IA.prototype.ee;IA.prototype.setOpacity=IA.prototype.Ee;IA.prototype.setRotation=IA.prototype.Fe;IA.prototype.setScale=IA.prototype.Ge; -wh.prototype.get=wh.prototype.get;wh.prototype.getKeys=wh.prototype.P;wh.prototype.getProperties=wh.prototype.R;wh.prototype.set=wh.prototype.set;wh.prototype.setProperties=wh.prototype.I;wh.prototype.unset=wh.prototype.S;wh.prototype.changed=wh.prototype.u;wh.prototype.dispatchEvent=wh.prototype.s;wh.prototype.getRevision=wh.prototype.L;wh.prototype.on=wh.prototype.H;wh.prototype.once=wh.prototype.M;wh.prototype.un=wh.prototype.K;wh.prototype.unByKey=wh.prototype.N;Nh.prototype.getAttributions=Nh.prototype.sa; -Nh.prototype.getLogo=Nh.prototype.qa;Nh.prototype.getProjection=Nh.prototype.ta;Nh.prototype.getState=Nh.prototype.ua;Nh.prototype.setAttributions=Nh.prototype.ma;Nh.prototype.get=Nh.prototype.get;Nh.prototype.getKeys=Nh.prototype.P;Nh.prototype.getProperties=Nh.prototype.R;Nh.prototype.set=Nh.prototype.set;Nh.prototype.setProperties=Nh.prototype.I;Nh.prototype.unset=Nh.prototype.S;Nh.prototype.changed=Nh.prototype.u;Nh.prototype.dispatchEvent=Nh.prototype.s;Nh.prototype.getRevision=Nh.prototype.L; -Nh.prototype.on=Nh.prototype.H;Nh.prototype.once=Nh.prototype.M;Nh.prototype.un=Nh.prototype.K;Nh.prototype.unByKey=Nh.prototype.N;Wp.prototype.getTileGrid=Wp.prototype.Ha;Wp.prototype.getAttributions=Wp.prototype.sa;Wp.prototype.getLogo=Wp.prototype.qa;Wp.prototype.getProjection=Wp.prototype.ta;Wp.prototype.getState=Wp.prototype.ua;Wp.prototype.setAttributions=Wp.prototype.ma;Wp.prototype.get=Wp.prototype.get;Wp.prototype.getKeys=Wp.prototype.P;Wp.prototype.getProperties=Wp.prototype.R; -Wp.prototype.set=Wp.prototype.set;Wp.prototype.setProperties=Wp.prototype.I;Wp.prototype.unset=Wp.prototype.S;Wp.prototype.changed=Wp.prototype.u;Wp.prototype.dispatchEvent=Wp.prototype.s;Wp.prototype.getRevision=Wp.prototype.L;Wp.prototype.on=Wp.prototype.H;Wp.prototype.once=Wp.prototype.M;Wp.prototype.un=Wp.prototype.K;Wp.prototype.unByKey=Wp.prototype.N;Y.prototype.getTileLoadFunction=Y.prototype.Xa;Y.prototype.getTileUrlFunction=Y.prototype.Ya;Y.prototype.getUrls=Y.prototype.Za; -Y.prototype.setTileLoadFunction=Y.prototype.eb;Y.prototype.setTileUrlFunction=Y.prototype.Ja;Y.prototype.setUrl=Y.prototype.Va;Y.prototype.setUrls=Y.prototype.Wa;Y.prototype.getTileGrid=Y.prototype.Ha;Y.prototype.getAttributions=Y.prototype.sa;Y.prototype.getLogo=Y.prototype.qa;Y.prototype.getProjection=Y.prototype.ta;Y.prototype.getState=Y.prototype.ua;Y.prototype.setAttributions=Y.prototype.ma;Y.prototype.get=Y.prototype.get;Y.prototype.getKeys=Y.prototype.P;Y.prototype.getProperties=Y.prototype.R; -Y.prototype.set=Y.prototype.set;Y.prototype.setProperties=Y.prototype.I;Y.prototype.unset=Y.prototype.S;Y.prototype.changed=Y.prototype.u;Y.prototype.dispatchEvent=Y.prototype.s;Y.prototype.getRevision=Y.prototype.L;Y.prototype.on=Y.prototype.H;Y.prototype.once=Y.prototype.M;Y.prototype.un=Y.prototype.K;Y.prototype.unByKey=Y.prototype.N;Kz.prototype.setRenderReprojectionEdges=Kz.prototype.vb;Kz.prototype.setTileGridForProjection=Kz.prototype.wb;Kz.prototype.getTileLoadFunction=Kz.prototype.Xa; -Kz.prototype.getTileUrlFunction=Kz.prototype.Ya;Kz.prototype.getUrls=Kz.prototype.Za;Kz.prototype.setTileLoadFunction=Kz.prototype.eb;Kz.prototype.setTileUrlFunction=Kz.prototype.Ja;Kz.prototype.setUrl=Kz.prototype.Va;Kz.prototype.setUrls=Kz.prototype.Wa;Kz.prototype.getTileGrid=Kz.prototype.Ha;Kz.prototype.getAttributions=Kz.prototype.sa;Kz.prototype.getLogo=Kz.prototype.qa;Kz.prototype.getProjection=Kz.prototype.ta;Kz.prototype.getState=Kz.prototype.ua;Kz.prototype.setAttributions=Kz.prototype.ma; -Kz.prototype.get=Kz.prototype.get;Kz.prototype.getKeys=Kz.prototype.P;Kz.prototype.getProperties=Kz.prototype.R;Kz.prototype.set=Kz.prototype.set;Kz.prototype.setProperties=Kz.prototype.I;Kz.prototype.unset=Kz.prototype.S;Kz.prototype.changed=Kz.prototype.u;Kz.prototype.dispatchEvent=Kz.prototype.s;Kz.prototype.getRevision=Kz.prototype.L;Kz.prototype.on=Kz.prototype.H;Kz.prototype.once=Kz.prototype.M;Kz.prototype.un=Kz.prototype.K;Kz.prototype.unByKey=Kz.prototype.N;R.prototype.getAttributions=R.prototype.sa; -R.prototype.getLogo=R.prototype.qa;R.prototype.getProjection=R.prototype.ta;R.prototype.getState=R.prototype.ua;R.prototype.setAttributions=R.prototype.ma;R.prototype.get=R.prototype.get;R.prototype.getKeys=R.prototype.P;R.prototype.getProperties=R.prototype.R;R.prototype.set=R.prototype.set;R.prototype.setProperties=R.prototype.I;R.prototype.unset=R.prototype.S;R.prototype.changed=R.prototype.u;R.prototype.dispatchEvent=R.prototype.s;R.prototype.getRevision=R.prototype.L;R.prototype.on=R.prototype.H; -R.prototype.once=R.prototype.M;R.prototype.un=R.prototype.K;R.prototype.unByKey=R.prototype.N;Mz.prototype.addFeature=Mz.prototype.Bd;Mz.prototype.addFeatures=Mz.prototype.Ec;Mz.prototype.clear=Mz.prototype.clear;Mz.prototype.forEachFeature=Mz.prototype.sg;Mz.prototype.forEachFeatureInExtent=Mz.prototype.pb;Mz.prototype.forEachFeatureIntersectingExtent=Mz.prototype.tg;Mz.prototype.getFeaturesCollection=Mz.prototype.zg;Mz.prototype.getFeatures=Mz.prototype.ze;Mz.prototype.getFeaturesAtCoordinate=Mz.prototype.yg; -Mz.prototype.getFeaturesInExtent=Mz.prototype.mf;Mz.prototype.getClosestFeatureToCoordinate=Mz.prototype.vg;Mz.prototype.getExtent=Mz.prototype.J;Mz.prototype.getFeatureById=Mz.prototype.xg;Mz.prototype.removeFeature=Mz.prototype.Rc;Mz.prototype.getAttributions=Mz.prototype.sa;Mz.prototype.getLogo=Mz.prototype.qa;Mz.prototype.getProjection=Mz.prototype.ta;Mz.prototype.getState=Mz.prototype.ua;Mz.prototype.setAttributions=Mz.prototype.ma;Mz.prototype.get=Mz.prototype.get;Mz.prototype.getKeys=Mz.prototype.P; -Mz.prototype.getProperties=Mz.prototype.R;Mz.prototype.set=Mz.prototype.set;Mz.prototype.setProperties=Mz.prototype.I;Mz.prototype.unset=Mz.prototype.S;Mz.prototype.changed=Mz.prototype.u;Mz.prototype.dispatchEvent=Mz.prototype.s;Mz.prototype.getRevision=Mz.prototype.L;Mz.prototype.on=Mz.prototype.H;Mz.prototype.once=Mz.prototype.M;Mz.prototype.un=Mz.prototype.K;Mz.prototype.unByKey=Mz.prototype.N;gn.prototype.getAttributions=gn.prototype.sa;gn.prototype.getLogo=gn.prototype.qa; -gn.prototype.getProjection=gn.prototype.ta;gn.prototype.getState=gn.prototype.ua;gn.prototype.setAttributions=gn.prototype.ma;gn.prototype.get=gn.prototype.get;gn.prototype.getKeys=gn.prototype.P;gn.prototype.getProperties=gn.prototype.R;gn.prototype.set=gn.prototype.set;gn.prototype.setProperties=gn.prototype.I;gn.prototype.unset=gn.prototype.S;gn.prototype.changed=gn.prototype.u;gn.prototype.dispatchEvent=gn.prototype.s;gn.prototype.getRevision=gn.prototype.L;gn.prototype.on=gn.prototype.H; -gn.prototype.once=gn.prototype.M;gn.prototype.un=gn.prototype.K;gn.prototype.unByKey=gn.prototype.N;on.prototype.getAttributions=on.prototype.sa;on.prototype.getLogo=on.prototype.qa;on.prototype.getProjection=on.prototype.ta;on.prototype.getState=on.prototype.ua;on.prototype.setAttributions=on.prototype.ma;on.prototype.get=on.prototype.get;on.prototype.getKeys=on.prototype.P;on.prototype.getProperties=on.prototype.R;on.prototype.set=on.prototype.set;on.prototype.setProperties=on.prototype.I; -on.prototype.unset=on.prototype.S;on.prototype.changed=on.prototype.u;on.prototype.dispatchEvent=on.prototype.s;on.prototype.getRevision=on.prototype.L;on.prototype.on=on.prototype.H;on.prototype.once=on.prototype.M;on.prototype.un=on.prototype.K;on.prototype.unByKey=on.prototype.N;Pz.prototype.getAttributions=Pz.prototype.sa;Pz.prototype.getLogo=Pz.prototype.qa;Pz.prototype.getProjection=Pz.prototype.ta;Pz.prototype.getState=Pz.prototype.ua;Pz.prototype.setAttributions=Pz.prototype.ma; -Pz.prototype.get=Pz.prototype.get;Pz.prototype.getKeys=Pz.prototype.P;Pz.prototype.getProperties=Pz.prototype.R;Pz.prototype.set=Pz.prototype.set;Pz.prototype.setProperties=Pz.prototype.I;Pz.prototype.unset=Pz.prototype.S;Pz.prototype.changed=Pz.prototype.u;Pz.prototype.dispatchEvent=Pz.prototype.s;Pz.prototype.getRevision=Pz.prototype.L;Pz.prototype.on=Pz.prototype.H;Pz.prototype.once=Pz.prototype.M;Pz.prototype.un=Pz.prototype.K;Pz.prototype.unByKey=Pz.prototype.N;Qz.prototype.getAttributions=Qz.prototype.sa; -Qz.prototype.getLogo=Qz.prototype.qa;Qz.prototype.getProjection=Qz.prototype.ta;Qz.prototype.getState=Qz.prototype.ua;Qz.prototype.setAttributions=Qz.prototype.ma;Qz.prototype.get=Qz.prototype.get;Qz.prototype.getKeys=Qz.prototype.P;Qz.prototype.getProperties=Qz.prototype.R;Qz.prototype.set=Qz.prototype.set;Qz.prototype.setProperties=Qz.prototype.I;Qz.prototype.unset=Qz.prototype.S;Qz.prototype.changed=Qz.prototype.u;Qz.prototype.dispatchEvent=Qz.prototype.s;Qz.prototype.getRevision=Qz.prototype.L; -Qz.prototype.on=Qz.prototype.H;Qz.prototype.once=Qz.prototype.M;Qz.prototype.un=Qz.prototype.K;Qz.prototype.unByKey=Qz.prototype.N;Mp.prototype.getAttributions=Mp.prototype.sa;Mp.prototype.getLogo=Mp.prototype.qa;Mp.prototype.getProjection=Mp.prototype.ta;Mp.prototype.getState=Mp.prototype.ua;Mp.prototype.setAttributions=Mp.prototype.ma;Mp.prototype.get=Mp.prototype.get;Mp.prototype.getKeys=Mp.prototype.P;Mp.prototype.getProperties=Mp.prototype.R;Mp.prototype.set=Mp.prototype.set; -Mp.prototype.setProperties=Mp.prototype.I;Mp.prototype.unset=Mp.prototype.S;Mp.prototype.changed=Mp.prototype.u;Mp.prototype.dispatchEvent=Mp.prototype.s;Mp.prototype.getRevision=Mp.prototype.L;Mp.prototype.on=Mp.prototype.H;Mp.prototype.once=Mp.prototype.M;Mp.prototype.un=Mp.prototype.K;Mp.prototype.unByKey=Mp.prototype.N;Rz.prototype.getAttributions=Rz.prototype.sa;Rz.prototype.getLogo=Rz.prototype.qa;Rz.prototype.getProjection=Rz.prototype.ta;Rz.prototype.getState=Rz.prototype.ua; -Rz.prototype.setAttributions=Rz.prototype.ma;Rz.prototype.get=Rz.prototype.get;Rz.prototype.getKeys=Rz.prototype.P;Rz.prototype.getProperties=Rz.prototype.R;Rz.prototype.set=Rz.prototype.set;Rz.prototype.setProperties=Rz.prototype.I;Rz.prototype.unset=Rz.prototype.S;Rz.prototype.changed=Rz.prototype.u;Rz.prototype.dispatchEvent=Rz.prototype.s;Rz.prototype.getRevision=Rz.prototype.L;Rz.prototype.on=Rz.prototype.H;Rz.prototype.once=Rz.prototype.M;Rz.prototype.un=Rz.prototype.K; -Rz.prototype.unByKey=Rz.prototype.N;Vz.prototype.setRenderReprojectionEdges=Vz.prototype.vb;Vz.prototype.setTileGridForProjection=Vz.prototype.wb;Vz.prototype.getTileLoadFunction=Vz.prototype.Xa;Vz.prototype.getTileUrlFunction=Vz.prototype.Ya;Vz.prototype.getUrls=Vz.prototype.Za;Vz.prototype.setTileLoadFunction=Vz.prototype.eb;Vz.prototype.setTileUrlFunction=Vz.prototype.Ja;Vz.prototype.setUrl=Vz.prototype.Va;Vz.prototype.setUrls=Vz.prototype.Wa;Vz.prototype.getTileGrid=Vz.prototype.Ha; -Vz.prototype.getAttributions=Vz.prototype.sa;Vz.prototype.getLogo=Vz.prototype.qa;Vz.prototype.getProjection=Vz.prototype.ta;Vz.prototype.getState=Vz.prototype.ua;Vz.prototype.setAttributions=Vz.prototype.ma;Vz.prototype.get=Vz.prototype.get;Vz.prototype.getKeys=Vz.prototype.P;Vz.prototype.getProperties=Vz.prototype.R;Vz.prototype.set=Vz.prototype.set;Vz.prototype.setProperties=Vz.prototype.I;Vz.prototype.unset=Vz.prototype.S;Vz.prototype.changed=Vz.prototype.u;Vz.prototype.dispatchEvent=Vz.prototype.s; -Vz.prototype.getRevision=Vz.prototype.L;Vz.prototype.on=Vz.prototype.H;Vz.prototype.once=Vz.prototype.M;Vz.prototype.un=Vz.prototype.K;Vz.prototype.unByKey=Vz.prototype.N;Yz.prototype.setRenderReprojectionEdges=Yz.prototype.vb;Yz.prototype.setTileGridForProjection=Yz.prototype.wb;Yz.prototype.getTileLoadFunction=Yz.prototype.Xa;Yz.prototype.getTileUrlFunction=Yz.prototype.Ya;Yz.prototype.getUrls=Yz.prototype.Za;Yz.prototype.setTileLoadFunction=Yz.prototype.eb;Yz.prototype.setTileUrlFunction=Yz.prototype.Ja; -Yz.prototype.setUrl=Yz.prototype.Va;Yz.prototype.setUrls=Yz.prototype.Wa;Yz.prototype.getTileGrid=Yz.prototype.Ha;Yz.prototype.getAttributions=Yz.prototype.sa;Yz.prototype.getLogo=Yz.prototype.qa;Yz.prototype.getProjection=Yz.prototype.ta;Yz.prototype.getState=Yz.prototype.ua;Yz.prototype.setAttributions=Yz.prototype.ma;Yz.prototype.get=Yz.prototype.get;Yz.prototype.getKeys=Yz.prototype.P;Yz.prototype.getProperties=Yz.prototype.R;Yz.prototype.set=Yz.prototype.set;Yz.prototype.setProperties=Yz.prototype.I; -Yz.prototype.unset=Yz.prototype.S;Yz.prototype.changed=Yz.prototype.u;Yz.prototype.dispatchEvent=Yz.prototype.s;Yz.prototype.getRevision=Yz.prototype.L;Yz.prototype.on=Yz.prototype.H;Yz.prototype.once=Yz.prototype.M;Yz.prototype.un=Yz.prototype.K;Yz.prototype.unByKey=Yz.prototype.N;Wz.prototype.setRenderReprojectionEdges=Wz.prototype.vb;Wz.prototype.setTileGridForProjection=Wz.prototype.wb;Wz.prototype.getTileLoadFunction=Wz.prototype.Xa;Wz.prototype.getTileUrlFunction=Wz.prototype.Ya; -Wz.prototype.getUrls=Wz.prototype.Za;Wz.prototype.setTileLoadFunction=Wz.prototype.eb;Wz.prototype.setTileUrlFunction=Wz.prototype.Ja;Wz.prototype.setUrl=Wz.prototype.Va;Wz.prototype.setUrls=Wz.prototype.Wa;Wz.prototype.getTileGrid=Wz.prototype.Ha;Wz.prototype.getAttributions=Wz.prototype.sa;Wz.prototype.getLogo=Wz.prototype.qa;Wz.prototype.getProjection=Wz.prototype.ta;Wz.prototype.getState=Wz.prototype.ua;Wz.prototype.setAttributions=Wz.prototype.ma;Wz.prototype.get=Wz.prototype.get; -Wz.prototype.getKeys=Wz.prototype.P;Wz.prototype.getProperties=Wz.prototype.R;Wz.prototype.set=Wz.prototype.set;Wz.prototype.setProperties=Wz.prototype.I;Wz.prototype.unset=Wz.prototype.S;Wz.prototype.changed=Wz.prototype.u;Wz.prototype.dispatchEvent=Wz.prototype.s;Wz.prototype.getRevision=Wz.prototype.L;Wz.prototype.on=Wz.prototype.H;Wz.prototype.once=Wz.prototype.M;Wz.prototype.un=Wz.prototype.K;Wz.prototype.unByKey=Wz.prototype.N;aA.prototype.getAttributions=aA.prototype.sa; -aA.prototype.getLogo=aA.prototype.qa;aA.prototype.getProjection=aA.prototype.ta;aA.prototype.getState=aA.prototype.ua;aA.prototype.setAttributions=aA.prototype.ma;aA.prototype.get=aA.prototype.get;aA.prototype.getKeys=aA.prototype.P;aA.prototype.getProperties=aA.prototype.R;aA.prototype.set=aA.prototype.set;aA.prototype.setProperties=aA.prototype.I;aA.prototype.unset=aA.prototype.S;aA.prototype.changed=aA.prototype.u;aA.prototype.dispatchEvent=aA.prototype.s;aA.prototype.getRevision=aA.prototype.L; -aA.prototype.on=aA.prototype.H;aA.prototype.once=aA.prototype.M;aA.prototype.un=aA.prototype.K;aA.prototype.unByKey=aA.prototype.N;kA.prototype.setRenderReprojectionEdges=kA.prototype.vb;kA.prototype.setTileGridForProjection=kA.prototype.wb;kA.prototype.getTileLoadFunction=kA.prototype.Xa;kA.prototype.getTileUrlFunction=kA.prototype.Ya;kA.prototype.getUrls=kA.prototype.Za;kA.prototype.setTileLoadFunction=kA.prototype.eb;kA.prototype.setTileUrlFunction=kA.prototype.Ja;kA.prototype.setUrl=kA.prototype.Va; -kA.prototype.setUrls=kA.prototype.Wa;kA.prototype.getTileGrid=kA.prototype.Ha;kA.prototype.getAttributions=kA.prototype.sa;kA.prototype.getLogo=kA.prototype.qa;kA.prototype.getProjection=kA.prototype.ta;kA.prototype.getState=kA.prototype.ua;kA.prototype.setAttributions=kA.prototype.ma;kA.prototype.get=kA.prototype.get;kA.prototype.getKeys=kA.prototype.P;kA.prototype.getProperties=kA.prototype.R;kA.prototype.set=kA.prototype.set;kA.prototype.setProperties=kA.prototype.I;kA.prototype.unset=kA.prototype.S; -kA.prototype.changed=kA.prototype.u;kA.prototype.dispatchEvent=kA.prototype.s;kA.prototype.getRevision=kA.prototype.L;kA.prototype.on=kA.prototype.H;kA.prototype.once=kA.prototype.M;kA.prototype.un=kA.prototype.K;kA.prototype.unByKey=kA.prototype.N;mA.prototype.setRenderReprojectionEdges=mA.prototype.vb;mA.prototype.setTileGridForProjection=mA.prototype.wb;mA.prototype.getTileLoadFunction=mA.prototype.Xa;mA.prototype.getTileUrlFunction=mA.prototype.Ya;mA.prototype.getUrls=mA.prototype.Za; -mA.prototype.setTileLoadFunction=mA.prototype.eb;mA.prototype.setTileUrlFunction=mA.prototype.Ja;mA.prototype.setUrl=mA.prototype.Va;mA.prototype.setUrls=mA.prototype.Wa;mA.prototype.getTileGrid=mA.prototype.Ha;mA.prototype.getAttributions=mA.prototype.sa;mA.prototype.getLogo=mA.prototype.qa;mA.prototype.getProjection=mA.prototype.ta;mA.prototype.getState=mA.prototype.ua;mA.prototype.setAttributions=mA.prototype.ma;mA.prototype.get=mA.prototype.get;mA.prototype.getKeys=mA.prototype.P; -mA.prototype.getProperties=mA.prototype.R;mA.prototype.set=mA.prototype.set;mA.prototype.setProperties=mA.prototype.I;mA.prototype.unset=mA.prototype.S;mA.prototype.changed=mA.prototype.u;mA.prototype.dispatchEvent=mA.prototype.s;mA.prototype.getRevision=mA.prototype.L;mA.prototype.on=mA.prototype.H;mA.prototype.once=mA.prototype.M;mA.prototype.un=mA.prototype.K;mA.prototype.unByKey=mA.prototype.N;oA.prototype.getTileGrid=oA.prototype.Ha;oA.prototype.getAttributions=oA.prototype.sa; -oA.prototype.getLogo=oA.prototype.qa;oA.prototype.getProjection=oA.prototype.ta;oA.prototype.getState=oA.prototype.ua;oA.prototype.setAttributions=oA.prototype.ma;oA.prototype.get=oA.prototype.get;oA.prototype.getKeys=oA.prototype.P;oA.prototype.getProperties=oA.prototype.R;oA.prototype.set=oA.prototype.set;oA.prototype.setProperties=oA.prototype.I;oA.prototype.unset=oA.prototype.S;oA.prototype.changed=oA.prototype.u;oA.prototype.dispatchEvent=oA.prototype.s;oA.prototype.getRevision=oA.prototype.L; -oA.prototype.on=oA.prototype.H;oA.prototype.once=oA.prototype.M;oA.prototype.un=oA.prototype.K;oA.prototype.unByKey=oA.prototype.N;pA.prototype.setRenderReprojectionEdges=pA.prototype.vb;pA.prototype.setTileGridForProjection=pA.prototype.wb;pA.prototype.getTileLoadFunction=pA.prototype.Xa;pA.prototype.getTileUrlFunction=pA.prototype.Ya;pA.prototype.getUrls=pA.prototype.Za;pA.prototype.setTileLoadFunction=pA.prototype.eb;pA.prototype.setTileUrlFunction=pA.prototype.Ja;pA.prototype.setUrl=pA.prototype.Va; -pA.prototype.setUrls=pA.prototype.Wa;pA.prototype.getTileGrid=pA.prototype.Ha;pA.prototype.getAttributions=pA.prototype.sa;pA.prototype.getLogo=pA.prototype.qa;pA.prototype.getProjection=pA.prototype.ta;pA.prototype.getState=pA.prototype.ua;pA.prototype.setAttributions=pA.prototype.ma;pA.prototype.get=pA.prototype.get;pA.prototype.getKeys=pA.prototype.P;pA.prototype.getProperties=pA.prototype.R;pA.prototype.set=pA.prototype.set;pA.prototype.setProperties=pA.prototype.I;pA.prototype.unset=pA.prototype.S; -pA.prototype.changed=pA.prototype.u;pA.prototype.dispatchEvent=pA.prototype.s;pA.prototype.getRevision=pA.prototype.L;pA.prototype.on=pA.prototype.H;pA.prototype.once=pA.prototype.M;pA.prototype.un=pA.prototype.K;pA.prototype.unByKey=pA.prototype.N;qA.prototype.getTileGrid=qA.prototype.Ha;qA.prototype.getAttributions=qA.prototype.sa;qA.prototype.getLogo=qA.prototype.qa;qA.prototype.getProjection=qA.prototype.ta;qA.prototype.getState=qA.prototype.ua;qA.prototype.setAttributions=qA.prototype.ma; -qA.prototype.get=qA.prototype.get;qA.prototype.getKeys=qA.prototype.P;qA.prototype.getProperties=qA.prototype.R;qA.prototype.set=qA.prototype.set;qA.prototype.setProperties=qA.prototype.I;qA.prototype.unset=qA.prototype.S;qA.prototype.changed=qA.prototype.u;qA.prototype.dispatchEvent=qA.prototype.s;qA.prototype.getRevision=qA.prototype.L;qA.prototype.on=qA.prototype.H;qA.prototype.once=qA.prototype.M;qA.prototype.un=qA.prototype.K;qA.prototype.unByKey=qA.prototype.N; -vA.prototype.setRenderReprojectionEdges=vA.prototype.vb;vA.prototype.setTileGridForProjection=vA.prototype.wb;vA.prototype.getTileLoadFunction=vA.prototype.Xa;vA.prototype.getTileUrlFunction=vA.prototype.Ya;vA.prototype.getUrls=vA.prototype.Za;vA.prototype.setTileLoadFunction=vA.prototype.eb;vA.prototype.setTileUrlFunction=vA.prototype.Ja;vA.prototype.setUrl=vA.prototype.Va;vA.prototype.setUrls=vA.prototype.Wa;vA.prototype.getTileGrid=vA.prototype.Ha;vA.prototype.getAttributions=vA.prototype.sa; -vA.prototype.getLogo=vA.prototype.qa;vA.prototype.getProjection=vA.prototype.ta;vA.prototype.getState=vA.prototype.ua;vA.prototype.setAttributions=vA.prototype.ma;vA.prototype.get=vA.prototype.get;vA.prototype.getKeys=vA.prototype.P;vA.prototype.getProperties=vA.prototype.R;vA.prototype.set=vA.prototype.set;vA.prototype.setProperties=vA.prototype.I;vA.prototype.unset=vA.prototype.S;vA.prototype.changed=vA.prototype.u;vA.prototype.dispatchEvent=vA.prototype.s;vA.prototype.getRevision=vA.prototype.L; -vA.prototype.on=vA.prototype.H;vA.prototype.once=vA.prototype.M;vA.prototype.un=vA.prototype.K;vA.prototype.unByKey=vA.prototype.N;Xp.prototype.getTileLoadFunction=Xp.prototype.Xa;Xp.prototype.getTileUrlFunction=Xp.prototype.Ya;Xp.prototype.getUrls=Xp.prototype.Za;Xp.prototype.setTileLoadFunction=Xp.prototype.eb;Xp.prototype.setTileUrlFunction=Xp.prototype.Ja;Xp.prototype.setUrl=Xp.prototype.Va;Xp.prototype.setUrls=Xp.prototype.Wa;Xp.prototype.getTileGrid=Xp.prototype.Ha; -Xp.prototype.getAttributions=Xp.prototype.sa;Xp.prototype.getLogo=Xp.prototype.qa;Xp.prototype.getProjection=Xp.prototype.ta;Xp.prototype.getState=Xp.prototype.ua;Xp.prototype.setAttributions=Xp.prototype.ma;Xp.prototype.get=Xp.prototype.get;Xp.prototype.getKeys=Xp.prototype.P;Xp.prototype.getProperties=Xp.prototype.R;Xp.prototype.set=Xp.prototype.set;Xp.prototype.setProperties=Xp.prototype.I;Xp.prototype.unset=Xp.prototype.S;Xp.prototype.changed=Xp.prototype.u;Xp.prototype.dispatchEvent=Xp.prototype.s; -Xp.prototype.getRevision=Xp.prototype.L;Xp.prototype.on=Xp.prototype.H;Xp.prototype.once=Xp.prototype.M;Xp.prototype.un=Xp.prototype.K;Xp.prototype.unByKey=Xp.prototype.N;Z.prototype.setRenderReprojectionEdges=Z.prototype.vb;Z.prototype.setTileGridForProjection=Z.prototype.wb;Z.prototype.getTileLoadFunction=Z.prototype.Xa;Z.prototype.getTileUrlFunction=Z.prototype.Ya;Z.prototype.getUrls=Z.prototype.Za;Z.prototype.setTileLoadFunction=Z.prototype.eb;Z.prototype.setTileUrlFunction=Z.prototype.Ja; -Z.prototype.setUrl=Z.prototype.Va;Z.prototype.setUrls=Z.prototype.Wa;Z.prototype.getTileGrid=Z.prototype.Ha;Z.prototype.getAttributions=Z.prototype.sa;Z.prototype.getLogo=Z.prototype.qa;Z.prototype.getProjection=Z.prototype.ta;Z.prototype.getState=Z.prototype.ua;Z.prototype.setAttributions=Z.prototype.ma;Z.prototype.get=Z.prototype.get;Z.prototype.getKeys=Z.prototype.P;Z.prototype.getProperties=Z.prototype.R;Z.prototype.set=Z.prototype.set;Z.prototype.setProperties=Z.prototype.I; -Z.prototype.unset=Z.prototype.S;Z.prototype.changed=Z.prototype.u;Z.prototype.dispatchEvent=Z.prototype.s;Z.prototype.getRevision=Z.prototype.L;Z.prototype.on=Z.prototype.H;Z.prototype.once=Z.prototype.M;Z.prototype.un=Z.prototype.K;Z.prototype.unByKey=Z.prototype.N;CA.prototype.setRenderReprojectionEdges=CA.prototype.vb;CA.prototype.setTileGridForProjection=CA.prototype.wb;CA.prototype.getTileLoadFunction=CA.prototype.Xa;CA.prototype.getTileUrlFunction=CA.prototype.Ya;CA.prototype.getUrls=CA.prototype.Za; -CA.prototype.setTileLoadFunction=CA.prototype.eb;CA.prototype.setTileUrlFunction=CA.prototype.Ja;CA.prototype.setUrl=CA.prototype.Va;CA.prototype.setUrls=CA.prototype.Wa;CA.prototype.getTileGrid=CA.prototype.Ha;CA.prototype.getAttributions=CA.prototype.sa;CA.prototype.getLogo=CA.prototype.qa;CA.prototype.getProjection=CA.prototype.ta;CA.prototype.getState=CA.prototype.ua;CA.prototype.setAttributions=CA.prototype.ma;CA.prototype.get=CA.prototype.get;CA.prototype.getKeys=CA.prototype.P; -CA.prototype.getProperties=CA.prototype.R;CA.prototype.set=CA.prototype.set;CA.prototype.setProperties=CA.prototype.I;CA.prototype.unset=CA.prototype.S;CA.prototype.changed=CA.prototype.u;CA.prototype.dispatchEvent=CA.prototype.s;CA.prototype.getRevision=CA.prototype.L;CA.prototype.on=CA.prototype.H;CA.prototype.once=CA.prototype.M;CA.prototype.un=CA.prototype.K;CA.prototype.unByKey=CA.prototype.N;sz.prototype.getTileCoord=sz.prototype.g;jk.prototype.changed=jk.prototype.u; -jk.prototype.dispatchEvent=jk.prototype.s;jk.prototype.getRevision=jk.prototype.L;jk.prototype.on=jk.prototype.H;jk.prototype.once=jk.prototype.M;jk.prototype.un=jk.prototype.K;jk.prototype.unByKey=jk.prototype.N;Tq.prototype.changed=Tq.prototype.u;Tq.prototype.dispatchEvent=Tq.prototype.s;Tq.prototype.getRevision=Tq.prototype.L;Tq.prototype.on=Tq.prototype.H;Tq.prototype.once=Tq.prototype.M;Tq.prototype.un=Tq.prototype.K;Tq.prototype.unByKey=Tq.prototype.N;Wq.prototype.changed=Wq.prototype.u; -Wq.prototype.dispatchEvent=Wq.prototype.s;Wq.prototype.getRevision=Wq.prototype.L;Wq.prototype.on=Wq.prototype.H;Wq.prototype.once=Wq.prototype.M;Wq.prototype.un=Wq.prototype.K;Wq.prototype.unByKey=Wq.prototype.N;br.prototype.changed=br.prototype.u;br.prototype.dispatchEvent=br.prototype.s;br.prototype.getRevision=br.prototype.L;br.prototype.on=br.prototype.H;br.prototype.once=br.prototype.M;br.prototype.un=br.prototype.K;br.prototype.unByKey=br.prototype.N;dr.prototype.changed=dr.prototype.u; -dr.prototype.dispatchEvent=dr.prototype.s;dr.prototype.getRevision=dr.prototype.L;dr.prototype.on=dr.prototype.H;dr.prototype.once=dr.prototype.M;dr.prototype.un=dr.prototype.K;dr.prototype.unByKey=dr.prototype.N;cq.prototype.changed=cq.prototype.u;cq.prototype.dispatchEvent=cq.prototype.s;cq.prototype.getRevision=cq.prototype.L;cq.prototype.on=cq.prototype.H;cq.prototype.once=cq.prototype.M;cq.prototype.un=cq.prototype.K;cq.prototype.unByKey=cq.prototype.N;dq.prototype.changed=dq.prototype.u; -dq.prototype.dispatchEvent=dq.prototype.s;dq.prototype.getRevision=dq.prototype.L;dq.prototype.on=dq.prototype.H;dq.prototype.once=dq.prototype.M;dq.prototype.un=dq.prototype.K;dq.prototype.unByKey=dq.prototype.N;eq.prototype.changed=eq.prototype.u;eq.prototype.dispatchEvent=eq.prototype.s;eq.prototype.getRevision=eq.prototype.L;eq.prototype.on=eq.prototype.H;eq.prototype.once=eq.prototype.M;eq.prototype.un=eq.prototype.K;eq.prototype.unByKey=eq.prototype.N;gq.prototype.changed=gq.prototype.u; -gq.prototype.dispatchEvent=gq.prototype.s;gq.prototype.getRevision=gq.prototype.L;gq.prototype.on=gq.prototype.H;gq.prototype.once=gq.prototype.M;gq.prototype.un=gq.prototype.K;gq.prototype.unByKey=gq.prototype.N;um.prototype.changed=um.prototype.u;um.prototype.dispatchEvent=um.prototype.s;um.prototype.getRevision=um.prototype.L;um.prototype.on=um.prototype.H;um.prototype.once=um.prototype.M;um.prototype.un=um.prototype.K;um.prototype.unByKey=um.prototype.N;Op.prototype.changed=Op.prototype.u; -Op.prototype.dispatchEvent=Op.prototype.s;Op.prototype.getRevision=Op.prototype.L;Op.prototype.on=Op.prototype.H;Op.prototype.once=Op.prototype.M;Op.prototype.un=Op.prototype.K;Op.prototype.unByKey=Op.prototype.N;Pp.prototype.changed=Pp.prototype.u;Pp.prototype.dispatchEvent=Pp.prototype.s;Pp.prototype.getRevision=Pp.prototype.L;Pp.prototype.on=Pp.prototype.H;Pp.prototype.once=Pp.prototype.M;Pp.prototype.un=Pp.prototype.K;Pp.prototype.unByKey=Pp.prototype.N;Qp.prototype.changed=Qp.prototype.u; -Qp.prototype.dispatchEvent=Qp.prototype.s;Qp.prototype.getRevision=Qp.prototype.L;Qp.prototype.on=Qp.prototype.H;Qp.prototype.once=Qp.prototype.M;Qp.prototype.un=Qp.prototype.K;Qp.prototype.unByKey=Qp.prototype.N;Zp.prototype.changed=Zp.prototype.u;Zp.prototype.dispatchEvent=Zp.prototype.s;Zp.prototype.getRevision=Zp.prototype.L;Zp.prototype.on=Zp.prototype.H;Zp.prototype.once=Zp.prototype.M;Zp.prototype.un=Zp.prototype.K;Zp.prototype.unByKey=Zp.prototype.N;Yj.prototype.get=Yj.prototype.get; -Yj.prototype.getKeys=Yj.prototype.P;Yj.prototype.getProperties=Yj.prototype.R;Yj.prototype.set=Yj.prototype.set;Yj.prototype.setProperties=Yj.prototype.I;Yj.prototype.unset=Yj.prototype.S;Yj.prototype.changed=Yj.prototype.u;Yj.prototype.dispatchEvent=Yj.prototype.s;Yj.prototype.getRevision=Yj.prototype.L;Yj.prototype.on=Yj.prototype.H;Yj.prototype.once=Yj.prototype.M;Yj.prototype.un=Yj.prototype.K;Yj.prototype.unByKey=Yj.prototype.N;ck.prototype.getExtent=ck.prototype.J; -ck.prototype.getMaxResolution=ck.prototype.Nb;ck.prototype.getMinResolution=ck.prototype.Ob;ck.prototype.getOpacity=ck.prototype.Rb;ck.prototype.getVisible=ck.prototype.rb;ck.prototype.getZIndex=ck.prototype.Sb;ck.prototype.setExtent=ck.prototype.cc;ck.prototype.setMaxResolution=ck.prototype.kc;ck.prototype.setMinResolution=ck.prototype.lc;ck.prototype.setOpacity=ck.prototype.dc;ck.prototype.setVisible=ck.prototype.ec;ck.prototype.setZIndex=ck.prototype.fc;ck.prototype.get=ck.prototype.get; -ck.prototype.getKeys=ck.prototype.P;ck.prototype.getProperties=ck.prototype.R;ck.prototype.set=ck.prototype.set;ck.prototype.setProperties=ck.prototype.I;ck.prototype.unset=ck.prototype.S;ck.prototype.changed=ck.prototype.u;ck.prototype.dispatchEvent=ck.prototype.s;ck.prototype.getRevision=ck.prototype.L;ck.prototype.on=ck.prototype.H;ck.prototype.once=ck.prototype.M;ck.prototype.un=ck.prototype.K;ck.prototype.unByKey=ck.prototype.N;H.prototype.setMap=H.prototype.setMap;H.prototype.setSource=H.prototype.zc; -H.prototype.getExtent=H.prototype.J;H.prototype.getMaxResolution=H.prototype.Nb;H.prototype.getMinResolution=H.prototype.Ob;H.prototype.getOpacity=H.prototype.Rb;H.prototype.getVisible=H.prototype.rb;H.prototype.getZIndex=H.prototype.Sb;H.prototype.setExtent=H.prototype.cc;H.prototype.setMaxResolution=H.prototype.kc;H.prototype.setMinResolution=H.prototype.lc;H.prototype.setOpacity=H.prototype.dc;H.prototype.setVisible=H.prototype.ec;H.prototype.setZIndex=H.prototype.fc;H.prototype.get=H.prototype.get; -H.prototype.getKeys=H.prototype.P;H.prototype.getProperties=H.prototype.R;H.prototype.set=H.prototype.set;H.prototype.setProperties=H.prototype.I;H.prototype.unset=H.prototype.S;H.prototype.changed=H.prototype.u;H.prototype.dispatchEvent=H.prototype.s;H.prototype.getRevision=H.prototype.L;H.prototype.on=H.prototype.H;H.prototype.once=H.prototype.M;H.prototype.un=H.prototype.K;H.prototype.unByKey=H.prototype.N;X.prototype.getSource=X.prototype.ea;X.prototype.getStyle=X.prototype.C; -X.prototype.getStyleFunction=X.prototype.D;X.prototype.setStyle=X.prototype.c;X.prototype.setMap=X.prototype.setMap;X.prototype.setSource=X.prototype.zc;X.prototype.getExtent=X.prototype.J;X.prototype.getMaxResolution=X.prototype.Nb;X.prototype.getMinResolution=X.prototype.Ob;X.prototype.getOpacity=X.prototype.Rb;X.prototype.getVisible=X.prototype.rb;X.prototype.getZIndex=X.prototype.Sb;X.prototype.setExtent=X.prototype.cc;X.prototype.setMaxResolution=X.prototype.kc;X.prototype.setMinResolution=X.prototype.lc; -X.prototype.setOpacity=X.prototype.dc;X.prototype.setVisible=X.prototype.ec;X.prototype.setZIndex=X.prototype.fc;X.prototype.get=X.prototype.get;X.prototype.getKeys=X.prototype.P;X.prototype.getProperties=X.prototype.R;X.prototype.set=X.prototype.set;X.prototype.setProperties=X.prototype.I;X.prototype.unset=X.prototype.S;X.prototype.changed=X.prototype.u;X.prototype.dispatchEvent=X.prototype.s;X.prototype.getRevision=X.prototype.L;X.prototype.on=X.prototype.H;X.prototype.once=X.prototype.M; -X.prototype.un=X.prototype.K;X.prototype.unByKey=X.prototype.N;Pl.prototype.setMap=Pl.prototype.setMap;Pl.prototype.setSource=Pl.prototype.zc;Pl.prototype.getExtent=Pl.prototype.J;Pl.prototype.getMaxResolution=Pl.prototype.Nb;Pl.prototype.getMinResolution=Pl.prototype.Ob;Pl.prototype.getOpacity=Pl.prototype.Rb;Pl.prototype.getVisible=Pl.prototype.rb;Pl.prototype.getZIndex=Pl.prototype.Sb;Pl.prototype.setExtent=Pl.prototype.cc;Pl.prototype.setMaxResolution=Pl.prototype.kc; -Pl.prototype.setMinResolution=Pl.prototype.lc;Pl.prototype.setOpacity=Pl.prototype.dc;Pl.prototype.setVisible=Pl.prototype.ec;Pl.prototype.setZIndex=Pl.prototype.fc;Pl.prototype.get=Pl.prototype.get;Pl.prototype.getKeys=Pl.prototype.P;Pl.prototype.getProperties=Pl.prototype.R;Pl.prototype.set=Pl.prototype.set;Pl.prototype.setProperties=Pl.prototype.I;Pl.prototype.unset=Pl.prototype.S;Pl.prototype.changed=Pl.prototype.u;Pl.prototype.dispatchEvent=Pl.prototype.s;Pl.prototype.getRevision=Pl.prototype.L; -Pl.prototype.on=Pl.prototype.H;Pl.prototype.once=Pl.prototype.M;Pl.prototype.un=Pl.prototype.K;Pl.prototype.unByKey=Pl.prototype.N;Hl.prototype.getExtent=Hl.prototype.J;Hl.prototype.getMaxResolution=Hl.prototype.Nb;Hl.prototype.getMinResolution=Hl.prototype.Ob;Hl.prototype.getOpacity=Hl.prototype.Rb;Hl.prototype.getVisible=Hl.prototype.rb;Hl.prototype.getZIndex=Hl.prototype.Sb;Hl.prototype.setExtent=Hl.prototype.cc;Hl.prototype.setMaxResolution=Hl.prototype.kc;Hl.prototype.setMinResolution=Hl.prototype.lc; -Hl.prototype.setOpacity=Hl.prototype.dc;Hl.prototype.setVisible=Hl.prototype.ec;Hl.prototype.setZIndex=Hl.prototype.fc;Hl.prototype.get=Hl.prototype.get;Hl.prototype.getKeys=Hl.prototype.P;Hl.prototype.getProperties=Hl.prototype.R;Hl.prototype.set=Hl.prototype.set;Hl.prototype.setProperties=Hl.prototype.I;Hl.prototype.unset=Hl.prototype.S;Hl.prototype.changed=Hl.prototype.u;Hl.prototype.dispatchEvent=Hl.prototype.s;Hl.prototype.getRevision=Hl.prototype.L;Hl.prototype.on=Hl.prototype.H; -Hl.prototype.once=Hl.prototype.M;Hl.prototype.un=Hl.prototype.K;Hl.prototype.unByKey=Hl.prototype.N;G.prototype.setMap=G.prototype.setMap;G.prototype.setSource=G.prototype.zc;G.prototype.getExtent=G.prototype.J;G.prototype.getMaxResolution=G.prototype.Nb;G.prototype.getMinResolution=G.prototype.Ob;G.prototype.getOpacity=G.prototype.Rb;G.prototype.getVisible=G.prototype.rb;G.prototype.getZIndex=G.prototype.Sb;G.prototype.setExtent=G.prototype.cc;G.prototype.setMaxResolution=G.prototype.kc; -G.prototype.setMinResolution=G.prototype.lc;G.prototype.setOpacity=G.prototype.dc;G.prototype.setVisible=G.prototype.ec;G.prototype.setZIndex=G.prototype.fc;G.prototype.get=G.prototype.get;G.prototype.getKeys=G.prototype.P;G.prototype.getProperties=G.prototype.R;G.prototype.set=G.prototype.set;G.prototype.setProperties=G.prototype.I;G.prototype.unset=G.prototype.S;G.prototype.changed=G.prototype.u;G.prototype.dispatchEvent=G.prototype.s;G.prototype.getRevision=G.prototype.L;G.prototype.on=G.prototype.H; -G.prototype.once=G.prototype.M;G.prototype.un=G.prototype.K;G.prototype.unByKey=G.prototype.N;I.prototype.getStyle=I.prototype.C;I.prototype.getStyleFunction=I.prototype.D;I.prototype.setStyle=I.prototype.c;I.prototype.setMap=I.prototype.setMap;I.prototype.setSource=I.prototype.zc;I.prototype.getExtent=I.prototype.J;I.prototype.getMaxResolution=I.prototype.Nb;I.prototype.getMinResolution=I.prototype.Ob;I.prototype.getOpacity=I.prototype.Rb;I.prototype.getVisible=I.prototype.rb; -I.prototype.getZIndex=I.prototype.Sb;I.prototype.setExtent=I.prototype.cc;I.prototype.setMaxResolution=I.prototype.kc;I.prototype.setMinResolution=I.prototype.lc;I.prototype.setOpacity=I.prototype.dc;I.prototype.setVisible=I.prototype.ec;I.prototype.setZIndex=I.prototype.fc;I.prototype.get=I.prototype.get;I.prototype.getKeys=I.prototype.P;I.prototype.getProperties=I.prototype.R;I.prototype.set=I.prototype.set;I.prototype.setProperties=I.prototype.I;I.prototype.unset=I.prototype.S; -I.prototype.changed=I.prototype.u;I.prototype.dispatchEvent=I.prototype.s;I.prototype.getRevision=I.prototype.L;I.prototype.on=I.prototype.H;I.prototype.once=I.prototype.M;I.prototype.un=I.prototype.K;I.prototype.unByKey=I.prototype.N;Lk.prototype.get=Lk.prototype.get;Lk.prototype.getKeys=Lk.prototype.P;Lk.prototype.getProperties=Lk.prototype.R;Lk.prototype.set=Lk.prototype.set;Lk.prototype.setProperties=Lk.prototype.I;Lk.prototype.unset=Lk.prototype.S;Lk.prototype.changed=Lk.prototype.u; -Lk.prototype.dispatchEvent=Lk.prototype.s;Lk.prototype.getRevision=Lk.prototype.L;Lk.prototype.on=Lk.prototype.H;Lk.prototype.once=Lk.prototype.M;Lk.prototype.un=Lk.prototype.K;Lk.prototype.unByKey=Lk.prototype.N;Pk.prototype.getActive=Pk.prototype.b;Pk.prototype.getMap=Pk.prototype.i;Pk.prototype.setActive=Pk.prototype.g;Pk.prototype.get=Pk.prototype.get;Pk.prototype.getKeys=Pk.prototype.P;Pk.prototype.getProperties=Pk.prototype.R;Pk.prototype.set=Pk.prototype.set;Pk.prototype.setProperties=Pk.prototype.I; -Pk.prototype.unset=Pk.prototype.S;Pk.prototype.changed=Pk.prototype.u;Pk.prototype.dispatchEvent=Pk.prototype.s;Pk.prototype.getRevision=Pk.prototype.L;Pk.prototype.on=Pk.prototype.H;Pk.prototype.once=Pk.prototype.M;Pk.prototype.un=Pk.prototype.K;Pk.prototype.unByKey=Pk.prototype.N;qy.prototype.getActive=qy.prototype.b;qy.prototype.getMap=qy.prototype.i;qy.prototype.setActive=qy.prototype.g;qy.prototype.get=qy.prototype.get;qy.prototype.getKeys=qy.prototype.P;qy.prototype.getProperties=qy.prototype.R; -qy.prototype.set=qy.prototype.set;qy.prototype.setProperties=qy.prototype.I;qy.prototype.unset=qy.prototype.S;qy.prototype.changed=qy.prototype.u;qy.prototype.dispatchEvent=qy.prototype.s;qy.prototype.getRevision=qy.prototype.L;qy.prototype.on=qy.prototype.H;qy.prototype.once=qy.prototype.M;qy.prototype.un=qy.prototype.K;qy.prototype.unByKey=qy.prototype.N;Yk.prototype.getActive=Yk.prototype.b;Yk.prototype.getMap=Yk.prototype.i;Yk.prototype.setActive=Yk.prototype.g;Yk.prototype.get=Yk.prototype.get; -Yk.prototype.getKeys=Yk.prototype.P;Yk.prototype.getProperties=Yk.prototype.R;Yk.prototype.set=Yk.prototype.set;Yk.prototype.setProperties=Yk.prototype.I;Yk.prototype.unset=Yk.prototype.S;Yk.prototype.changed=Yk.prototype.u;Yk.prototype.dispatchEvent=Yk.prototype.s;Yk.prototype.getRevision=Yk.prototype.L;Yk.prototype.on=Yk.prototype.H;Yk.prototype.once=Yk.prototype.M;Yk.prototype.un=Yk.prototype.K;Yk.prototype.unByKey=Yk.prototype.N;ml.prototype.getActive=ml.prototype.b;ml.prototype.getMap=ml.prototype.i; -ml.prototype.setActive=ml.prototype.g;ml.prototype.get=ml.prototype.get;ml.prototype.getKeys=ml.prototype.P;ml.prototype.getProperties=ml.prototype.R;ml.prototype.set=ml.prototype.set;ml.prototype.setProperties=ml.prototype.I;ml.prototype.unset=ml.prototype.S;ml.prototype.changed=ml.prototype.u;ml.prototype.dispatchEvent=ml.prototype.s;ml.prototype.getRevision=ml.prototype.L;ml.prototype.on=ml.prototype.H;ml.prototype.once=ml.prototype.M;ml.prototype.un=ml.prototype.K;ml.prototype.unByKey=ml.prototype.N; -al.prototype.getActive=al.prototype.b;al.prototype.getMap=al.prototype.i;al.prototype.setActive=al.prototype.g;al.prototype.get=al.prototype.get;al.prototype.getKeys=al.prototype.P;al.prototype.getProperties=al.prototype.R;al.prototype.set=al.prototype.set;al.prototype.setProperties=al.prototype.I;al.prototype.unset=al.prototype.S;al.prototype.changed=al.prototype.u;al.prototype.dispatchEvent=al.prototype.s;al.prototype.getRevision=al.prototype.L;al.prototype.on=al.prototype.H;al.prototype.once=al.prototype.M; -al.prototype.un=al.prototype.K;al.prototype.unByKey=al.prototype.N;uy.prototype.getActive=uy.prototype.b;uy.prototype.getMap=uy.prototype.i;uy.prototype.setActive=uy.prototype.g;uy.prototype.get=uy.prototype.get;uy.prototype.getKeys=uy.prototype.P;uy.prototype.getProperties=uy.prototype.R;uy.prototype.set=uy.prototype.set;uy.prototype.setProperties=uy.prototype.I;uy.prototype.unset=uy.prototype.S;uy.prototype.changed=uy.prototype.u;uy.prototype.dispatchEvent=uy.prototype.s; -uy.prototype.getRevision=uy.prototype.L;uy.prototype.on=uy.prototype.H;uy.prototype.once=uy.prototype.M;uy.prototype.un=uy.prototype.K;uy.prototype.unByKey=uy.prototype.N;el.prototype.getActive=el.prototype.b;el.prototype.getMap=el.prototype.i;el.prototype.setActive=el.prototype.g;el.prototype.get=el.prototype.get;el.prototype.getKeys=el.prototype.P;el.prototype.getProperties=el.prototype.R;el.prototype.set=el.prototype.set;el.prototype.setProperties=el.prototype.I;el.prototype.unset=el.prototype.S; -el.prototype.changed=el.prototype.u;el.prototype.dispatchEvent=el.prototype.s;el.prototype.getRevision=el.prototype.L;el.prototype.on=el.prototype.H;el.prototype.once=el.prototype.M;el.prototype.un=el.prototype.K;el.prototype.unByKey=el.prototype.N;rl.prototype.getGeometry=rl.prototype.X;rl.prototype.getActive=rl.prototype.b;rl.prototype.getMap=rl.prototype.i;rl.prototype.setActive=rl.prototype.g;rl.prototype.get=rl.prototype.get;rl.prototype.getKeys=rl.prototype.P;rl.prototype.getProperties=rl.prototype.R; -rl.prototype.set=rl.prototype.set;rl.prototype.setProperties=rl.prototype.I;rl.prototype.unset=rl.prototype.S;rl.prototype.changed=rl.prototype.u;rl.prototype.dispatchEvent=rl.prototype.s;rl.prototype.getRevision=rl.prototype.L;rl.prototype.on=rl.prototype.H;rl.prototype.once=rl.prototype.M;rl.prototype.un=rl.prototype.K;rl.prototype.unByKey=rl.prototype.N;zy.prototype.getActive=zy.prototype.b;zy.prototype.getMap=zy.prototype.i;zy.prototype.setActive=zy.prototype.g;zy.prototype.get=zy.prototype.get; -zy.prototype.getKeys=zy.prototype.P;zy.prototype.getProperties=zy.prototype.R;zy.prototype.set=zy.prototype.set;zy.prototype.setProperties=zy.prototype.I;zy.prototype.unset=zy.prototype.S;zy.prototype.changed=zy.prototype.u;zy.prototype.dispatchEvent=zy.prototype.s;zy.prototype.getRevision=zy.prototype.L;zy.prototype.on=zy.prototype.H;zy.prototype.once=zy.prototype.M;zy.prototype.un=zy.prototype.K;zy.prototype.unByKey=zy.prototype.N;sl.prototype.getActive=sl.prototype.b;sl.prototype.getMap=sl.prototype.i; -sl.prototype.setActive=sl.prototype.g;sl.prototype.get=sl.prototype.get;sl.prototype.getKeys=sl.prototype.P;sl.prototype.getProperties=sl.prototype.R;sl.prototype.set=sl.prototype.set;sl.prototype.setProperties=sl.prototype.I;sl.prototype.unset=sl.prototype.S;sl.prototype.changed=sl.prototype.u;sl.prototype.dispatchEvent=sl.prototype.s;sl.prototype.getRevision=sl.prototype.L;sl.prototype.on=sl.prototype.H;sl.prototype.once=sl.prototype.M;sl.prototype.un=sl.prototype.K;sl.prototype.unByKey=sl.prototype.N; -ul.prototype.getActive=ul.prototype.b;ul.prototype.getMap=ul.prototype.i;ul.prototype.setActive=ul.prototype.g;ul.prototype.get=ul.prototype.get;ul.prototype.getKeys=ul.prototype.P;ul.prototype.getProperties=ul.prototype.R;ul.prototype.set=ul.prototype.set;ul.prototype.setProperties=ul.prototype.I;ul.prototype.unset=ul.prototype.S;ul.prototype.changed=ul.prototype.u;ul.prototype.dispatchEvent=ul.prototype.s;ul.prototype.getRevision=ul.prototype.L;ul.prototype.on=ul.prototype.H;ul.prototype.once=ul.prototype.M; -ul.prototype.un=ul.prototype.K;ul.prototype.unByKey=ul.prototype.N;Qy.prototype.getActive=Qy.prototype.b;Qy.prototype.getMap=Qy.prototype.i;Qy.prototype.setActive=Qy.prototype.g;Qy.prototype.get=Qy.prototype.get;Qy.prototype.getKeys=Qy.prototype.P;Qy.prototype.getProperties=Qy.prototype.R;Qy.prototype.set=Qy.prototype.set;Qy.prototype.setProperties=Qy.prototype.I;Qy.prototype.unset=Qy.prototype.S;Qy.prototype.changed=Qy.prototype.u;Qy.prototype.dispatchEvent=Qy.prototype.s; -Qy.prototype.getRevision=Qy.prototype.L;Qy.prototype.on=Qy.prototype.H;Qy.prototype.once=Qy.prototype.M;Qy.prototype.un=Qy.prototype.K;Qy.prototype.unByKey=Qy.prototype.N;wl.prototype.getActive=wl.prototype.b;wl.prototype.getMap=wl.prototype.i;wl.prototype.setActive=wl.prototype.g;wl.prototype.get=wl.prototype.get;wl.prototype.getKeys=wl.prototype.P;wl.prototype.getProperties=wl.prototype.R;wl.prototype.set=wl.prototype.set;wl.prototype.setProperties=wl.prototype.I;wl.prototype.unset=wl.prototype.S; -wl.prototype.changed=wl.prototype.u;wl.prototype.dispatchEvent=wl.prototype.s;wl.prototype.getRevision=wl.prototype.L;wl.prototype.on=wl.prototype.H;wl.prototype.once=wl.prototype.M;wl.prototype.un=wl.prototype.K;wl.prototype.unByKey=wl.prototype.N;yl.prototype.getActive=yl.prototype.b;yl.prototype.getMap=yl.prototype.i;yl.prototype.setActive=yl.prototype.g;yl.prototype.get=yl.prototype.get;yl.prototype.getKeys=yl.prototype.P;yl.prototype.getProperties=yl.prototype.R;yl.prototype.set=yl.prototype.set; -yl.prototype.setProperties=yl.prototype.I;yl.prototype.unset=yl.prototype.S;yl.prototype.changed=yl.prototype.u;yl.prototype.dispatchEvent=yl.prototype.s;yl.prototype.getRevision=yl.prototype.L;yl.prototype.on=yl.prototype.H;yl.prototype.once=yl.prototype.M;yl.prototype.un=yl.prototype.K;yl.prototype.unByKey=yl.prototype.N;Cl.prototype.getActive=Cl.prototype.b;Cl.prototype.getMap=Cl.prototype.i;Cl.prototype.setActive=Cl.prototype.g;Cl.prototype.get=Cl.prototype.get;Cl.prototype.getKeys=Cl.prototype.P; -Cl.prototype.getProperties=Cl.prototype.R;Cl.prototype.set=Cl.prototype.set;Cl.prototype.setProperties=Cl.prototype.I;Cl.prototype.unset=Cl.prototype.S;Cl.prototype.changed=Cl.prototype.u;Cl.prototype.dispatchEvent=Cl.prototype.s;Cl.prototype.getRevision=Cl.prototype.L;Cl.prototype.on=Cl.prototype.H;Cl.prototype.once=Cl.prototype.M;Cl.prototype.un=Cl.prototype.K;Cl.prototype.unByKey=Cl.prototype.N;dz.prototype.getActive=dz.prototype.b;dz.prototype.getMap=dz.prototype.i;dz.prototype.setActive=dz.prototype.g; -dz.prototype.get=dz.prototype.get;dz.prototype.getKeys=dz.prototype.P;dz.prototype.getProperties=dz.prototype.R;dz.prototype.set=dz.prototype.set;dz.prototype.setProperties=dz.prototype.I;dz.prototype.unset=dz.prototype.S;dz.prototype.changed=dz.prototype.u;dz.prototype.dispatchEvent=dz.prototype.s;dz.prototype.getRevision=dz.prototype.L;dz.prototype.on=dz.prototype.H;dz.prototype.once=dz.prototype.M;dz.prototype.un=dz.prototype.K;dz.prototype.unByKey=dz.prototype.N;gz.prototype.getActive=gz.prototype.b; -gz.prototype.getMap=gz.prototype.i;gz.prototype.setActive=gz.prototype.g;gz.prototype.get=gz.prototype.get;gz.prototype.getKeys=gz.prototype.P;gz.prototype.getProperties=gz.prototype.R;gz.prototype.set=gz.prototype.set;gz.prototype.setProperties=gz.prototype.I;gz.prototype.unset=gz.prototype.S;gz.prototype.changed=gz.prototype.u;gz.prototype.dispatchEvent=gz.prototype.s;gz.prototype.getRevision=gz.prototype.L;gz.prototype.on=gz.prototype.H;gz.prototype.once=gz.prototype.M;gz.prototype.un=gz.prototype.K; -gz.prototype.unByKey=gz.prototype.N;lz.prototype.getActive=lz.prototype.b;lz.prototype.getMap=lz.prototype.i;lz.prototype.setActive=lz.prototype.g;lz.prototype.get=lz.prototype.get;lz.prototype.getKeys=lz.prototype.P;lz.prototype.getProperties=lz.prototype.R;lz.prototype.set=lz.prototype.set;lz.prototype.setProperties=lz.prototype.I;lz.prototype.unset=lz.prototype.S;lz.prototype.changed=lz.prototype.u;lz.prototype.dispatchEvent=lz.prototype.s;lz.prototype.getRevision=lz.prototype.L; -lz.prototype.on=lz.prototype.H;lz.prototype.once=lz.prototype.M;lz.prototype.un=lz.prototype.K;lz.prototype.unByKey=lz.prototype.N;$e.prototype.get=$e.prototype.get;$e.prototype.getKeys=$e.prototype.P;$e.prototype.getProperties=$e.prototype.R;$e.prototype.set=$e.prototype.set;$e.prototype.setProperties=$e.prototype.I;$e.prototype.unset=$e.prototype.S;$e.prototype.changed=$e.prototype.u;$e.prototype.dispatchEvent=$e.prototype.s;$e.prototype.getRevision=$e.prototype.L;$e.prototype.on=$e.prototype.H; -$e.prototype.once=$e.prototype.M;$e.prototype.un=$e.prototype.K;$e.prototype.unByKey=$e.prototype.N;bf.prototype.getClosestPoint=bf.prototype.qb;bf.prototype.getExtent=bf.prototype.J;bf.prototype.simplify=bf.prototype.xb;bf.prototype.transform=bf.prototype.lb;bf.prototype.get=bf.prototype.get;bf.prototype.getKeys=bf.prototype.P;bf.prototype.getProperties=bf.prototype.R;bf.prototype.set=bf.prototype.set;bf.prototype.setProperties=bf.prototype.I;bf.prototype.unset=bf.prototype.S; -bf.prototype.changed=bf.prototype.u;bf.prototype.dispatchEvent=bf.prototype.s;bf.prototype.getRevision=bf.prototype.L;bf.prototype.on=bf.prototype.H;bf.prototype.once=bf.prototype.M;bf.prototype.un=bf.prototype.K;bf.prototype.unByKey=bf.prototype.N;Nx.prototype.getFirstCoordinate=Nx.prototype.Kb;Nx.prototype.getLastCoordinate=Nx.prototype.Lb;Nx.prototype.getLayout=Nx.prototype.Mb;Nx.prototype.getClosestPoint=Nx.prototype.qb;Nx.prototype.getExtent=Nx.prototype.J;Nx.prototype.simplify=Nx.prototype.xb; -Nx.prototype.get=Nx.prototype.get;Nx.prototype.getKeys=Nx.prototype.P;Nx.prototype.getProperties=Nx.prototype.R;Nx.prototype.set=Nx.prototype.set;Nx.prototype.setProperties=Nx.prototype.I;Nx.prototype.unset=Nx.prototype.S;Nx.prototype.changed=Nx.prototype.u;Nx.prototype.dispatchEvent=Nx.prototype.s;Nx.prototype.getRevision=Nx.prototype.L;Nx.prototype.on=Nx.prototype.H;Nx.prototype.once=Nx.prototype.M;Nx.prototype.un=Nx.prototype.K;Nx.prototype.unByKey=Nx.prototype.N;gs.prototype.getClosestPoint=gs.prototype.qb; -gs.prototype.getExtent=gs.prototype.J;gs.prototype.simplify=gs.prototype.xb;gs.prototype.transform=gs.prototype.lb;gs.prototype.get=gs.prototype.get;gs.prototype.getKeys=gs.prototype.P;gs.prototype.getProperties=gs.prototype.R;gs.prototype.set=gs.prototype.set;gs.prototype.setProperties=gs.prototype.I;gs.prototype.unset=gs.prototype.S;gs.prototype.changed=gs.prototype.u;gs.prototype.dispatchEvent=gs.prototype.s;gs.prototype.getRevision=gs.prototype.L;gs.prototype.on=gs.prototype.H; -gs.prototype.once=gs.prototype.M;gs.prototype.un=gs.prototype.K;gs.prototype.unByKey=gs.prototype.N;vf.prototype.getFirstCoordinate=vf.prototype.Kb;vf.prototype.getLastCoordinate=vf.prototype.Lb;vf.prototype.getLayout=vf.prototype.Mb;vf.prototype.getClosestPoint=vf.prototype.qb;vf.prototype.getExtent=vf.prototype.J;vf.prototype.simplify=vf.prototype.xb;vf.prototype.transform=vf.prototype.lb;vf.prototype.get=vf.prototype.get;vf.prototype.getKeys=vf.prototype.P;vf.prototype.getProperties=vf.prototype.R; -vf.prototype.set=vf.prototype.set;vf.prototype.setProperties=vf.prototype.I;vf.prototype.unset=vf.prototype.S;vf.prototype.changed=vf.prototype.u;vf.prototype.dispatchEvent=vf.prototype.s;vf.prototype.getRevision=vf.prototype.L;vf.prototype.on=vf.prototype.H;vf.prototype.once=vf.prototype.M;vf.prototype.un=vf.prototype.K;vf.prototype.unByKey=vf.prototype.N;T.prototype.getFirstCoordinate=T.prototype.Kb;T.prototype.getLastCoordinate=T.prototype.Lb;T.prototype.getLayout=T.prototype.Mb; -T.prototype.getClosestPoint=T.prototype.qb;T.prototype.getExtent=T.prototype.J;T.prototype.simplify=T.prototype.xb;T.prototype.transform=T.prototype.lb;T.prototype.get=T.prototype.get;T.prototype.getKeys=T.prototype.P;T.prototype.getProperties=T.prototype.R;T.prototype.set=T.prototype.set;T.prototype.setProperties=T.prototype.I;T.prototype.unset=T.prototype.S;T.prototype.changed=T.prototype.u;T.prototype.dispatchEvent=T.prototype.s;T.prototype.getRevision=T.prototype.L;T.prototype.on=T.prototype.H; -T.prototype.once=T.prototype.M;T.prototype.un=T.prototype.K;T.prototype.unByKey=T.prototype.N;U.prototype.getFirstCoordinate=U.prototype.Kb;U.prototype.getLastCoordinate=U.prototype.Lb;U.prototype.getLayout=U.prototype.Mb;U.prototype.getClosestPoint=U.prototype.qb;U.prototype.getExtent=U.prototype.J;U.prototype.simplify=U.prototype.xb;U.prototype.transform=U.prototype.lb;U.prototype.get=U.prototype.get;U.prototype.getKeys=U.prototype.P;U.prototype.getProperties=U.prototype.R;U.prototype.set=U.prototype.set; -U.prototype.setProperties=U.prototype.I;U.prototype.unset=U.prototype.S;U.prototype.changed=U.prototype.u;U.prototype.dispatchEvent=U.prototype.s;U.prototype.getRevision=U.prototype.L;U.prototype.on=U.prototype.H;U.prototype.once=U.prototype.M;U.prototype.un=U.prototype.K;U.prototype.unByKey=U.prototype.N;Xr.prototype.getFirstCoordinate=Xr.prototype.Kb;Xr.prototype.getLastCoordinate=Xr.prototype.Lb;Xr.prototype.getLayout=Xr.prototype.Mb;Xr.prototype.getClosestPoint=Xr.prototype.qb; -Xr.prototype.getExtent=Xr.prototype.J;Xr.prototype.simplify=Xr.prototype.xb;Xr.prototype.transform=Xr.prototype.lb;Xr.prototype.get=Xr.prototype.get;Xr.prototype.getKeys=Xr.prototype.P;Xr.prototype.getProperties=Xr.prototype.R;Xr.prototype.set=Xr.prototype.set;Xr.prototype.setProperties=Xr.prototype.I;Xr.prototype.unset=Xr.prototype.S;Xr.prototype.changed=Xr.prototype.u;Xr.prototype.dispatchEvent=Xr.prototype.s;Xr.prototype.getRevision=Xr.prototype.L;Xr.prototype.on=Xr.prototype.H; -Xr.prototype.once=Xr.prototype.M;Xr.prototype.un=Xr.prototype.K;Xr.prototype.unByKey=Xr.prototype.N;V.prototype.getFirstCoordinate=V.prototype.Kb;V.prototype.getLastCoordinate=V.prototype.Lb;V.prototype.getLayout=V.prototype.Mb;V.prototype.getClosestPoint=V.prototype.qb;V.prototype.getExtent=V.prototype.J;V.prototype.simplify=V.prototype.xb;V.prototype.transform=V.prototype.lb;V.prototype.get=V.prototype.get;V.prototype.getKeys=V.prototype.P;V.prototype.getProperties=V.prototype.R; -V.prototype.set=V.prototype.set;V.prototype.setProperties=V.prototype.I;V.prototype.unset=V.prototype.S;V.prototype.changed=V.prototype.u;V.prototype.dispatchEvent=V.prototype.s;V.prototype.getRevision=V.prototype.L;V.prototype.on=V.prototype.H;V.prototype.once=V.prototype.M;V.prototype.un=V.prototype.K;V.prototype.unByKey=V.prototype.N;E.prototype.getFirstCoordinate=E.prototype.Kb;E.prototype.getLastCoordinate=E.prototype.Lb;E.prototype.getLayout=E.prototype.Mb;E.prototype.getClosestPoint=E.prototype.qb; -E.prototype.getExtent=E.prototype.J;E.prototype.simplify=E.prototype.xb;E.prototype.transform=E.prototype.lb;E.prototype.get=E.prototype.get;E.prototype.getKeys=E.prototype.P;E.prototype.getProperties=E.prototype.R;E.prototype.set=E.prototype.set;E.prototype.setProperties=E.prototype.I;E.prototype.unset=E.prototype.S;E.prototype.changed=E.prototype.u;E.prototype.dispatchEvent=E.prototype.s;E.prototype.getRevision=E.prototype.L;E.prototype.on=E.prototype.H;E.prototype.once=E.prototype.M; -E.prototype.un=E.prototype.K;E.prototype.unByKey=E.prototype.N;F.prototype.getFirstCoordinate=F.prototype.Kb;F.prototype.getLastCoordinate=F.prototype.Lb;F.prototype.getLayout=F.prototype.Mb;F.prototype.getClosestPoint=F.prototype.qb;F.prototype.getExtent=F.prototype.J;F.prototype.simplify=F.prototype.xb;F.prototype.transform=F.prototype.lb;F.prototype.get=F.prototype.get;F.prototype.getKeys=F.prototype.P;F.prototype.getProperties=F.prototype.R;F.prototype.set=F.prototype.set; -F.prototype.setProperties=F.prototype.I;F.prototype.unset=F.prototype.S;F.prototype.changed=F.prototype.u;F.prototype.dispatchEvent=F.prototype.s;F.prototype.getRevision=F.prototype.L;F.prototype.on=F.prototype.H;F.prototype.once=F.prototype.M;F.prototype.un=F.prototype.K;F.prototype.unByKey=F.prototype.N;Es.prototype.readFeatures=Es.prototype.Ba;Fs.prototype.readFeatures=Fs.prototype.Ba;Fs.prototype.readFeatures=Fs.prototype.Ba;oh.prototype.get=oh.prototype.get;oh.prototype.getKeys=oh.prototype.P; -oh.prototype.getProperties=oh.prototype.R;oh.prototype.set=oh.prototype.set;oh.prototype.setProperties=oh.prototype.I;oh.prototype.unset=oh.prototype.S;oh.prototype.changed=oh.prototype.u;oh.prototype.dispatchEvent=oh.prototype.s;oh.prototype.getRevision=oh.prototype.L;oh.prototype.on=oh.prototype.H;oh.prototype.once=oh.prototype.M;oh.prototype.un=oh.prototype.K;oh.prototype.unByKey=oh.prototype.N;Rh.prototype.getMap=Rh.prototype.g;Rh.prototype.setMap=Rh.prototype.setMap;Rh.prototype.setTarget=Rh.prototype.c; -Rh.prototype.get=Rh.prototype.get;Rh.prototype.getKeys=Rh.prototype.P;Rh.prototype.getProperties=Rh.prototype.R;Rh.prototype.set=Rh.prototype.set;Rh.prototype.setProperties=Rh.prototype.I;Rh.prototype.unset=Rh.prototype.S;Rh.prototype.changed=Rh.prototype.u;Rh.prototype.dispatchEvent=Rh.prototype.s;Rh.prototype.getRevision=Rh.prototype.L;Rh.prototype.on=Rh.prototype.H;Rh.prototype.once=Rh.prototype.M;Rh.prototype.un=Rh.prototype.K;Rh.prototype.unByKey=Rh.prototype.N;bi.prototype.getMap=bi.prototype.g; -bi.prototype.setMap=bi.prototype.setMap;bi.prototype.setTarget=bi.prototype.c;bi.prototype.get=bi.prototype.get;bi.prototype.getKeys=bi.prototype.P;bi.prototype.getProperties=bi.prototype.R;bi.prototype.set=bi.prototype.set;bi.prototype.setProperties=bi.prototype.I;bi.prototype.unset=bi.prototype.S;bi.prototype.changed=bi.prototype.u;bi.prototype.dispatchEvent=bi.prototype.s;bi.prototype.getRevision=bi.prototype.L;bi.prototype.on=bi.prototype.H;bi.prototype.once=bi.prototype.M;bi.prototype.un=bi.prototype.K; -bi.prototype.unByKey=bi.prototype.N;di.prototype.getMap=di.prototype.g;di.prototype.setMap=di.prototype.setMap;di.prototype.setTarget=di.prototype.c;di.prototype.get=di.prototype.get;di.prototype.getKeys=di.prototype.P;di.prototype.getProperties=di.prototype.R;di.prototype.set=di.prototype.set;di.prototype.setProperties=di.prototype.I;di.prototype.unset=di.prototype.S;di.prototype.changed=di.prototype.u;di.prototype.dispatchEvent=di.prototype.s;di.prototype.getRevision=di.prototype.L; -di.prototype.on=di.prototype.H;di.prototype.once=di.prototype.M;di.prototype.un=di.prototype.K;di.prototype.unByKey=di.prototype.N;nr.prototype.getMap=nr.prototype.g;nr.prototype.setMap=nr.prototype.setMap;nr.prototype.setTarget=nr.prototype.c;nr.prototype.get=nr.prototype.get;nr.prototype.getKeys=nr.prototype.P;nr.prototype.getProperties=nr.prototype.R;nr.prototype.set=nr.prototype.set;nr.prototype.setProperties=nr.prototype.I;nr.prototype.unset=nr.prototype.S;nr.prototype.changed=nr.prototype.u; -nr.prototype.dispatchEvent=nr.prototype.s;nr.prototype.getRevision=nr.prototype.L;nr.prototype.on=nr.prototype.H;nr.prototype.once=nr.prototype.M;nr.prototype.un=nr.prototype.K;nr.prototype.unByKey=nr.prototype.N;Uh.prototype.getMap=Uh.prototype.g;Uh.prototype.setMap=Uh.prototype.setMap;Uh.prototype.setTarget=Uh.prototype.c;Uh.prototype.get=Uh.prototype.get;Uh.prototype.getKeys=Uh.prototype.P;Uh.prototype.getProperties=Uh.prototype.R;Uh.prototype.set=Uh.prototype.set;Uh.prototype.setProperties=Uh.prototype.I; -Uh.prototype.unset=Uh.prototype.S;Uh.prototype.changed=Uh.prototype.u;Uh.prototype.dispatchEvent=Uh.prototype.s;Uh.prototype.getRevision=Uh.prototype.L;Uh.prototype.on=Uh.prototype.H;Uh.prototype.once=Uh.prototype.M;Uh.prototype.un=Uh.prototype.K;Uh.prototype.unByKey=Uh.prototype.N;sr.prototype.getMap=sr.prototype.g;sr.prototype.setMap=sr.prototype.setMap;sr.prototype.setTarget=sr.prototype.c;sr.prototype.get=sr.prototype.get;sr.prototype.getKeys=sr.prototype.P;sr.prototype.getProperties=sr.prototype.R; -sr.prototype.set=sr.prototype.set;sr.prototype.setProperties=sr.prototype.I;sr.prototype.unset=sr.prototype.S;sr.prototype.changed=sr.prototype.u;sr.prototype.dispatchEvent=sr.prototype.s;sr.prototype.getRevision=sr.prototype.L;sr.prototype.on=sr.prototype.H;sr.prototype.once=sr.prototype.M;sr.prototype.un=sr.prototype.K;sr.prototype.unByKey=sr.prototype.N;Wh.prototype.getMap=Wh.prototype.g;Wh.prototype.setMap=Wh.prototype.setMap;Wh.prototype.setTarget=Wh.prototype.c;Wh.prototype.get=Wh.prototype.get; -Wh.prototype.getKeys=Wh.prototype.P;Wh.prototype.getProperties=Wh.prototype.R;Wh.prototype.set=Wh.prototype.set;Wh.prototype.setProperties=Wh.prototype.I;Wh.prototype.unset=Wh.prototype.S;Wh.prototype.changed=Wh.prototype.u;Wh.prototype.dispatchEvent=Wh.prototype.s;Wh.prototype.getRevision=Wh.prototype.L;Wh.prototype.on=Wh.prototype.H;Wh.prototype.once=Wh.prototype.M;Wh.prototype.un=Wh.prototype.K;Wh.prototype.unByKey=Wh.prototype.N;Gr.prototype.getMap=Gr.prototype.g;Gr.prototype.setMap=Gr.prototype.setMap; -Gr.prototype.setTarget=Gr.prototype.c;Gr.prototype.get=Gr.prototype.get;Gr.prototype.getKeys=Gr.prototype.P;Gr.prototype.getProperties=Gr.prototype.R;Gr.prototype.set=Gr.prototype.set;Gr.prototype.setProperties=Gr.prototype.I;Gr.prototype.unset=Gr.prototype.S;Gr.prototype.changed=Gr.prototype.u;Gr.prototype.dispatchEvent=Gr.prototype.s;Gr.prototype.getRevision=Gr.prototype.L;Gr.prototype.on=Gr.prototype.H;Gr.prototype.once=Gr.prototype.M;Gr.prototype.un=Gr.prototype.K;Gr.prototype.unByKey=Gr.prototype.N; -Lr.prototype.getMap=Lr.prototype.g;Lr.prototype.setMap=Lr.prototype.setMap;Lr.prototype.setTarget=Lr.prototype.c;Lr.prototype.get=Lr.prototype.get;Lr.prototype.getKeys=Lr.prototype.P;Lr.prototype.getProperties=Lr.prototype.R;Lr.prototype.set=Lr.prototype.set;Lr.prototype.setProperties=Lr.prototype.I;Lr.prototype.unset=Lr.prototype.S;Lr.prototype.changed=Lr.prototype.u;Lr.prototype.dispatchEvent=Lr.prototype.s;Lr.prototype.getRevision=Lr.prototype.L;Lr.prototype.on=Lr.prototype.H; -Lr.prototype.once=Lr.prototype.M;Lr.prototype.un=Lr.prototype.K;Lr.prototype.unByKey=Lr.prototype.N; +d=f+(h<<21&4294967295|h>>>11);h=c+(f^(d|~g))+e[4]+4149444226&4294967295;c=d+(h<<6&4294967295|h>>>26);h=g+(d^(c|~f))+e[11]+3174756917&4294967295;g=c+(h<<10&4294967295|h>>>22);h=f+(c^(g|~d))+e[2]+718787259&4294967295;f=g+(h<<15&4294967295|h>>>17);h=d+(g^(f|~c))+e[9]+3951481745&4294967295;a.b[0]=a.b[0]+c&4294967295;a.b[1]=a.b[1]+(f+(h<<21&4294967295|h>>>11))&4294967295;a.b[2]=a.b[2]+f&4294967295;a.b[3]=a.b[3]+g&4294967295} +function fk(a,c){var d;void 0===d&&(d=c.length);for(var e=d-a.a,f=a.c,g=a.g,h=0;h<d;){if(0==g)for(;h<=e;)ek(a,c,h),h+=a.a;if(ea(c))for(;h<d;){if(f[g++]=c.charCodeAt(h++),g==a.a){ek(a,f);g=0;break}}else for(;h<d;)if(f[g++]=c[h++],g==a.a){ek(a,f);g=0;break}}a.g=g;a.f+=d};function gk(a){a=a||{};this.b=void 0!==a.color?a.color:null;this.f=a.lineCap;this.g=void 0!==a.lineDash?a.lineDash:null;this.c=a.lineJoin;this.i=a.miterLimit;this.a=a.width;this.l=void 0}l=gk.prototype;l.En=function(){return this.b};l.$j=function(){return this.f};l.Fn=function(){return this.g};l.ak=function(){return this.c};l.fk=function(){return this.i};l.Gn=function(){return this.a};l.Hn=function(a){this.b=a;this.l=void 0};l.Zo=function(a){this.f=a;this.l=void 0}; +l.In=function(a){this.g=a;this.l=void 0};l.$o=function(a){this.c=a;this.l=void 0};l.ap=function(a){this.i=a;this.l=void 0};l.fp=function(a){this.a=a;this.l=void 0}; +function hk(a){if(void 0===a.l){var c="s"+(a.b?He(a.b):"-")+","+(void 0!==a.f?a.f.toString():"-")+","+(a.g?a.g.toString():"-")+","+(void 0!==a.c?a.c:"-")+","+(void 0!==a.i?a.i.toString():"-")+","+(void 0!==a.a?a.a.toString():"-"),d=new dk;fk(d,c);c=Array((56>d.g?d.a:2*d.a)-d.g);c[0]=128;for(var e=1;e<c.length-8;++e)c[e]=0;for(var f=8*d.f,e=c.length-8;e<c.length;++e)c[e]=f&255,f/=256;fk(d,c);c=Array(16);for(e=f=0;4>e;++e)for(var g=0;32>g;g+=8)c[f++]=d.b[e]>>>g&255;if(8192>=c.length)d=String.fromCharCode.apply(null, +c);else for(d="",e=0;e<c.length;e+=8192)f=Be(c,e,e+8192),d+=String.fromCharCode.apply(null,f);a.l=d}return a.l};function ik(a){a=a||{};this.l=this.f=this.c=null;this.g=void 0!==a.fill?a.fill:null;this.b=void 0!==a.stroke?a.stroke:null;this.a=a.radius;this.B=[0,0];this.s=this.N=this.o=null;var c=a.atlasManager,d,e=null,f,g=0;this.b&&(f=He(this.b.b),g=this.b.a,void 0===g&&(g=1),e=this.b.g,Zg||(e=null));var h=2*(this.a+g)+1;f={strokeStyle:f,wd:g,size:h,lineDash:e};if(void 0===c)c=Mg(h,h),this.f=c.canvas,d=h=this.f.width,this.Bh(f,c,0,0),this.g?this.l=this.f:(c=Mg(f.size,f.size),this.l=c.canvas,this.Ah(f,c,0,0)); +else{h=Math.round(h);(e=!this.g)&&(d=this.Ah.bind(this,f));var g=this.b?hk(this.b):"-",k=this.g?bk(this.g):"-";this.c&&g==this.c[1]&&k==this.c[2]&&this.a==this.c[3]||(this.c=["c"+g+k+(void 0!==this.a?this.a.toString():"-"),g,k,this.a]);c=c.add(this.c[0],h,h,this.Bh.bind(this,f),d);this.f=c.image;this.B=[c.offsetX,c.offsetY];d=c.image.width;this.l=e?c.Ng:this.f}this.o=[h/2,h/2];this.N=[h,h];this.s=[d,d];ti.call(this,{opacity:1,rotateWithView:!1,rotation:0,scale:1,snapToPixel:void 0!==a.snapToPixel? +a.snapToPixel:!0})}y(ik,ti);l=ik.prototype;l.Tb=function(){return this.o};l.vn=function(){return this.g};l.ke=function(){return this.l};l.ec=function(){return this.f};l.od=function(){return 2};l.fd=function(){return this.s};l.Fa=function(){return this.B};l.wn=function(){return this.a};l.Bb=function(){return this.N};l.xn=function(){return this.b};l.kf=pa;l.load=pa;l.Tf=pa; +l.Bh=function(a,c,d,e){c.setTransform(1,0,0,1,0,0);c.translate(d,e);c.beginPath();c.arc(a.size/2,a.size/2,this.a,0,2*Math.PI,!0);this.g&&(c.fillStyle=Je(this.g.b),c.fill());this.b&&(c.strokeStyle=a.strokeStyle,c.lineWidth=a.wd,a.lineDash&&c.setLineDash(a.lineDash),c.stroke());c.closePath()}; +l.Ah=function(a,c,d,e){c.setTransform(1,0,0,1,0,0);c.translate(d,e);c.beginPath();c.arc(a.size/2,a.size/2,this.a,0,2*Math.PI,!0);c.fillStyle=He(Wj);c.fill();this.b&&(c.strokeStyle=a.strokeStyle,c.lineWidth=a.wd,a.lineDash&&c.setLineDash(a.lineDash),c.stroke());c.closePath()};function jk(a){a=a||{};this.i=null;this.g=kk;void 0!==a.geometry&&this.Eh(a.geometry);this.c=void 0!==a.fill?a.fill:null;this.a=void 0!==a.image?a.image:null;this.f=void 0!==a.stroke?a.stroke:null;this.l=void 0!==a.text?a.text:null;this.b=a.zIndex}l=jk.prototype;l.W=function(){return this.i};l.Vj=function(){return this.g};l.Jn=function(){return this.c};l.Kn=function(){return this.a};l.Ln=function(){return this.f};l.Ea=function(){return this.l};l.Mn=function(){return this.b}; +l.Eh=function(a){ga(a)?this.g=a:"string"===typeof a?this.g=function(c){return c.get(a)}:a?void 0!==a&&(this.g=function(){return a}):this.g=kk;this.i=a};l.Nn=function(a){this.b=a};function lk(a){if(!ga(a)){var c;c=Array.isArray(a)?a:[a];a=function(){return c}}return a}var mk=null;function nk(){if(!mk){var a=new ak({color:"rgba(255,255,255,0.4)"}),c=new gk({color:"#3399CC",width:1.25});mk=[new jk({image:new ik({fill:a,stroke:c,radius:5}),fill:a,stroke:c})]}return mk} +function ok(){var a={},c=[255,255,255,1],d=[0,153,255,1];a.Polygon=[new jk({fill:new ak({color:[255,255,255,.5]})})];a.MultiPolygon=a.Polygon;a.LineString=[new jk({stroke:new gk({color:c,width:5})}),new jk({stroke:new gk({color:d,width:3})})];a.MultiLineString=a.LineString;a.Circle=a.Polygon.concat(a.LineString);a.Point=[new jk({image:new ik({radius:6,fill:new ak({color:d}),stroke:new gk({color:c,width:1.5})}),zIndex:Infinity})];a.MultiPoint=a.Point;a.GeometryCollection=a.Polygon.concat(a.LineString, +a.Point);return a}function kk(a){return a.W()};function H(a){a=a?a:{};var c=Pa({},a);delete c.style;delete c.renderBuffer;delete c.updateWhileAnimating;delete c.updateWhileInteracting;di.call(this,c);this.a=void 0!==a.renderBuffer?a.renderBuffer:100;this.B=null;this.i=void 0;this.l(a.style);this.S=void 0!==a.updateWhileAnimating?a.updateWhileAnimating:!1;this.T=void 0!==a.updateWhileInteracting?a.updateWhileInteracting:!1}y(H,di);function pk(a){return a.get("renderOrder")}H.prototype.M=function(){return this.B};H.prototype.N=function(){return this.i}; +H.prototype.l=function(a){this.B=void 0!==a?a:nk;this.i=null===a?void 0:lk(this.B);this.u()};function I(a){a=a?a:{};var c=Pa({},a);delete c.preload;delete c.useInterimTilesOnError;H.call(this,c);this.Y(a.preload?a.preload:0);this.ea(a.useInterimTilesOnError?a.useInterimTilesOnError:!0);this.s=a.renderMode||"hybrid"}y(I,H);I.prototype.f=function(){return this.get("preload")};I.prototype.c=function(){return this.get("useInterimTilesOnError")};I.prototype.Y=function(a){this.set("preload",a)};I.prototype.ea=function(a){this.set("useInterimTilesOnError",a)};function qk(a,c,d,e,f){this.f=a;this.B=c;this.c=d;this.N=e;this.Cc=f;this.i=this.b=this.a=this.ea=this.Qa=this.Y=null;this.na=this.wa=this.v=this.ya=this.va=this.R=0;this.Cb=!1;this.l=this.ta=0;this.xa=!1;this.S=0;this.g="";this.j=this.M=this.pb=this.Ra=0;this.T=this.s=this.o=null;this.U=[];this.Db=hd()}y(qk,bi); +function rk(a,c,d){if(a.i){c=rd(c,0,d,2,a.N,a.U);d=a.f;var e=a.Db,f=d.globalAlpha;1!=a.v&&(d.globalAlpha=f*a.v);var g=a.ta;a.Cb&&(g+=a.Cc);var h,k;h=0;for(k=c.length;h<k;h+=2){var m=c[h]-a.R,n=c[h+1]-a.va;a.xa&&(m=Math.round(m),n=Math.round(n));if(0!==g||1!=a.l){var p=m+a.R,q=n+a.va;hi(e,p,q,a.l,a.l,g,-p,-q);d.setTransform(e[0],e[1],e[4],e[5],e[12],e[13])}d.drawImage(a.i,a.wa,a.na,a.S,a.ya,m,n,a.S,a.ya)}0===g&&1==a.l||d.setTransform(1,0,0,1,0,0);1!=a.v&&(d.globalAlpha=f)}} +function sk(a,c,d,e){var f=0;if(a.T&&""!==a.g){a.o&&tk(a,a.o);a.s&&uk(a,a.s);var g=a.T,h=a.f,k=a.ea;k?(k.font!=g.font&&(k.font=h.font=g.font),k.textAlign!=g.textAlign&&(k.textAlign=h.textAlign=g.textAlign),k.textBaseline!=g.textBaseline&&(k.textBaseline=h.textBaseline=g.textBaseline)):(h.font=g.font,h.textAlign=g.textAlign,h.textBaseline=g.textBaseline,a.ea={font:g.font,textAlign:g.textAlign,textBaseline:g.textBaseline});c=rd(c,f,d,e,a.N,a.U);for(g=a.f;f<d;f+=e){h=c[f]+a.Ra;k=c[f+1]+a.pb;if(0!==a.M|| +1!=a.j){var m=hi(a.Db,h,k,a.j,a.j,a.M,-h,-k);g.setTransform(m[0],m[1],m[4],m[5],m[12],m[13])}a.s&&g.strokeText(a.g,h,k);a.o&&g.fillText(a.g,h,k)}0===a.M&&1==a.j||g.setTransform(1,0,0,1,0,0)}}function vk(a,c,d,e,f,g){var h=a.f;a=rd(c,d,e,f,a.N,a.U);h.moveTo(a[0],a[1]);c=a.length;g&&(c-=2);for(d=2;d<c;d+=2)h.lineTo(a[d],a[d+1]);g&&h.closePath();return e}function wk(a,c,d,e,f){var g,h;g=0;for(h=e.length;g<h;++g)d=vk(a,c,d,e[g],f,!0);return d}l=qk.prototype; +l.Md=function(a){if(wc(this.c,a.O())){if(this.a||this.b){this.a&&tk(this,this.a);this.b&&uk(this,this.b);var c;c=this.N;var d=this.U,e=a.ga();c=e?rd(e,0,e.length,a.ua(),c,d):null;d=c[2]-c[0];e=c[3]-c[1];d=Math.sqrt(d*d+e*e);e=this.f;e.beginPath();e.arc(c[0],c[1],d,0,2*Math.PI);this.a&&e.fill();this.b&&e.stroke()}""!==this.g&&sk(this,a.ld(),2,2)}};l.md=function(a){this.Ob(a.c,a.f);this.Pb(a.a);this.Rb(a.Ea())}; +l.nc=function(a){switch(a.X()){case "Point":this.pc(a);break;case "LineString":this.cd(a);break;case "Polygon":this.Ye(a);break;case "MultiPoint":this.oc(a);break;case "MultiLineString":this.We(a);break;case "MultiPolygon":this.Xe(a);break;case "GeometryCollection":this.Ve(a);break;case "Circle":this.Md(a)}};l.Ue=function(a,c){var d=(0,c.g)(a);d&&wc(this.c,d.O())&&(this.md(c),this.nc(d))};l.Ve=function(a){a=a.c;var c,d;c=0;for(d=a.length;c<d;++c)this.nc(a[c])}; +l.pc=function(a){var c=a.ga();a=a.ua();this.i&&rk(this,c,c.length);""!==this.g&&sk(this,c,c.length,a)};l.oc=function(a){var c=a.ga();a=a.ua();this.i&&rk(this,c,c.length);""!==this.g&&sk(this,c,c.length,a)};l.cd=function(a){if(wc(this.c,a.O())){if(this.b){uk(this,this.b);var c=this.f,d=a.ga();c.beginPath();vk(this,d,0,d.length,a.ua(),!1);c.stroke()}""!==this.g&&(a=xk(a),sk(this,a,2,2))}}; +l.We=function(a){var c=a.O();if(wc(this.c,c)){if(this.b){uk(this,this.b);var c=this.f,d=a.ga(),e=0,f=a.zb(),g=a.ua();c.beginPath();var h,k;h=0;for(k=f.length;h<k;++h)e=vk(this,d,e,f[h],g,!1);c.stroke()}""!==this.g&&(a=yk(a),sk(this,a,a.length,2))}};l.Ye=function(a){if(wc(this.c,a.O())){if(this.b||this.a){this.a&&tk(this,this.a);this.b&&uk(this,this.b);var c=this.f;c.beginPath();wk(this,a.Kb(),0,a.zb(),a.ua());this.a&&c.fill();this.b&&c.stroke()}""!==this.g&&(a=Xd(a),sk(this,a,2,2))}}; +l.Xe=function(a){if(wc(this.c,a.O())){if(this.b||this.a){this.a&&tk(this,this.a);this.b&&uk(this,this.b);var c=this.f,d=zk(a),e=0,f=a.i,g=a.ua(),h,k;h=0;for(k=f.length;h<k;++h){var m=f[h];c.beginPath();e=wk(this,d,e,m,g);this.a&&c.fill();this.b&&c.stroke()}}""!==this.g&&(a=Ak(a),sk(this,a,a.length,2))}};function tk(a,c){var d=a.f,e=a.Y;e?e.fillStyle!=c.fillStyle&&(e.fillStyle=d.fillStyle=c.fillStyle):(d.fillStyle=c.fillStyle,a.Y={fillStyle:c.fillStyle})} +function uk(a,c){var d=a.f,e=a.Qa;e?(e.lineCap!=c.lineCap&&(e.lineCap=d.lineCap=c.lineCap),Zg&&!Ab(e.lineDash,c.lineDash)&&d.setLineDash(e.lineDash=c.lineDash),e.lineJoin!=c.lineJoin&&(e.lineJoin=d.lineJoin=c.lineJoin),e.lineWidth!=c.lineWidth&&(e.lineWidth=d.lineWidth=c.lineWidth),e.miterLimit!=c.miterLimit&&(e.miterLimit=d.miterLimit=c.miterLimit),e.strokeStyle!=c.strokeStyle&&(e.strokeStyle=d.strokeStyle=c.strokeStyle)):(d.lineCap=c.lineCap,Zg&&d.setLineDash(c.lineDash),d.lineJoin=c.lineJoin,d.lineWidth= +c.lineWidth,d.miterLimit=c.miterLimit,d.strokeStyle=c.strokeStyle,a.Qa={lineCap:c.lineCap,lineDash:c.lineDash,lineJoin:c.lineJoin,lineWidth:c.lineWidth,miterLimit:c.miterLimit,strokeStyle:c.strokeStyle})} +l.Ob=function(a,c){if(a){var d=a.b;this.a={fillStyle:Je(d?d:Wj)}}else this.a=null;if(c){var d=c.b,e=c.f,f=c.g,g=c.c,h=c.a,k=c.i;this.b={lineCap:void 0!==e?e:"round",lineDash:f?f:Xj,lineJoin:void 0!==g?g:"round",lineWidth:this.B*(void 0!==h?h:1),miterLimit:void 0!==k?k:10,strokeStyle:He(d?d:Yj)}}else this.b=null}; +l.Pb=function(a){if(a){var c=a.Tb(),d=a.ec(1),e=a.Fa(),f=a.Bb();this.R=c[0];this.va=c[1];this.ya=f[1];this.i=d;this.v=a.v;this.wa=e[0];this.na=e[1];this.Cb=a.U;this.ta=a.j;this.l=a.i;this.xa=a.M;this.S=f[0]}else this.i=null}; +l.Rb=function(a){if(a){var c=a.b;c?(c=c.b,this.o={fillStyle:Je(c?c:Wj)}):this.o=null;var d=a.l;if(d){var c=d.b,e=d.f,f=d.g,g=d.c,h=d.a,d=d.i;this.s={lineCap:void 0!==e?e:"round",lineDash:f?f:Xj,lineJoin:void 0!==g?g:"round",lineWidth:void 0!==h?h:1,miterLimit:void 0!==d?d:10,strokeStyle:He(c?c:Yj)}}else this.s=null;var c=a.g,e=a.f,f=a.c,g=a.i,h=a.a,d=a.Ea(),k=a.o;a=a.j;this.T={font:void 0!==c?c:"10px sans-serif",textAlign:void 0!==k?k:"center",textBaseline:void 0!==a?a:"middle"};this.g=void 0!==d? +d:"";this.Ra=void 0!==e?this.B*e:0;this.pb=void 0!==f?this.B*f:0;this.M=void 0!==g?g:0;this.j=this.B*(void 0!==h?h:1)}else this.g=""};function Bk(a){ki.call(this,a);this.R=hd()}y(Bk,ki); +Bk.prototype.i=function(a,c,d){Ck(this,"precompose",d,a,void 0);var e=this.f?this.f.a():null;if(e){var f=c.extent,g=void 0!==f;if(g){var h=a.pixelRatio,k=a.size[0]*h,m=a.size[1]*h,n=a.viewState.rotation,p=oc(f),q=nc(f),r=mc(f),f=lc(f);ji(a.coordinateToPixelMatrix,p,p);ji(a.coordinateToPixelMatrix,q,q);ji(a.coordinateToPixelMatrix,r,r);ji(a.coordinateToPixelMatrix,f,f);d.save();Zj(d,-n,k/2,m/2);d.beginPath();d.moveTo(p[0]*h,p[1]*h);d.lineTo(q[0]*h,q[1]*h);d.lineTo(r[0]*h,r[1]*h);d.lineTo(f[0]*h,f[1]* +h);d.clip();Zj(d,n,k/2,m/2)}h=this.s;k=d.globalAlpha;d.globalAlpha=c.opacity;d.drawImage(e,0,0,+e.width,+e.height,Math.round(h[12]),Math.round(h[13]),Math.round(e.width*h[0]),Math.round(e.height*h[5]));d.globalAlpha=k;g&&d.restore()}Dk(this,d,a)}; +function Ck(a,c,d,e,f){var g=a.a;if(lb(g,c)){var h=e.size[0]*e.pixelRatio,k=e.size[1]*e.pixelRatio,m=e.viewState.rotation;Zj(d,-m,h/2,k/2);a=void 0!==f?f:Ek(a,e,0);a=new qk(d,e.pixelRatio,e.extent,a,e.viewState.rotation);g.b(new ci(c,g,a,e,d,null));Zj(d,m,h/2,k/2)}}function Dk(a,c,d,e){Ck(a,"postcompose",c,d,e)}function Ek(a,c,d){var e=c.viewState,f=c.pixelRatio;return hi(a.R,f*c.size[0]/2,f*c.size[1]/2,f/e.resolution,-f/e.resolution,-e.rotation,-e.center[0]+d,-e.center[1])};var Fk=["Polygon","LineString","Image","Text"];function Gk(a,c,d){this.na=a;this.T=c;this.f=null;this.c=0;this.resolution=d;this.ya=this.va=null;this.a=[];this.coordinates=[];this.Qa=hd();this.b=[];this.Y=[];this.ea=hd();this.wa=hd()}y(Gk,bi); +function Hk(a,c,d,e,f,g){var h=a.coordinates.length,k=a.$e(),m=[c[d],c[d+1]],n=[NaN,NaN],p=!0,q,r,u;for(q=d+f;q<e;q+=f)n[0]=c[q],n[1]=c[q+1],u=dc(k,n),u!==r?(p&&(a.coordinates[h++]=m[0],a.coordinates[h++]=m[1]),a.coordinates[h++]=n[0],a.coordinates[h++]=n[1],p=!1):1===u?(a.coordinates[h++]=n[0],a.coordinates[h++]=n[1],p=!1):p=!0,m[0]=n[0],m[1]=n[1],r=u;q===d+f&&(a.coordinates[h++]=m[0],a.coordinates[h++]=m[1]);g&&(a.coordinates[h++]=c[d],a.coordinates[h++]=c[d+1]);return h} +function Ik(a,c){a.va=[0,c,0];a.a.push(a.va);a.ya=[0,c,0];a.b.push(a.ya)} +function Jk(a,c,d,e,f,g,h,k,m){var n;ii(e,a.Qa)?n=a.Y:(n=rd(a.coordinates,0,a.coordinates.length,2,e,a.Y),kd(a.Qa,e));e=!Sa(g);var p=0,q=h.length,r=0,u,v=a.ea;a=a.wa;for(var x,z,E,B;p<q;){var A=h[p],G,O,L,R;switch(A[0]){case 0:r=A[1];e&&g[w(r).toString()]||!r.W()?p=A[2]:void 0===m||wc(m,r.W().O())?++p:p=A[2];break;case 1:c.beginPath();++p;break;case 2:r=A[1];u=n[r];A=n[r+1];E=n[r+2]-u;r=n[r+3]-A;c.arc(u,A,Math.sqrt(E*E+r*r),0,2*Math.PI,!0);++p;break;case 3:c.closePath();++p;break;case 4:r=A[1];u= +A[2];G=A[3];L=A[4]*d;var Wa=A[5]*d,J=A[6];O=A[7];var ua=A[8],Ta=A[9];E=A[11];B=A[12];var kb=A[13],Ka=A[14];for(A[10]&&(E+=f);r<u;r+=2){A=n[r]-L;R=n[r+1]-Wa;kb&&(A=Math.round(A),R=Math.round(R));if(1!=B||0!==E){var Ia=A+L,xc=R+Wa;hi(v,Ia,xc,B,B,E,-Ia,-xc);c.transform(v[0],v[1],v[4],v[5],v[12],v[13])}Ia=c.globalAlpha;1!=O&&(c.globalAlpha=Ia*O);var xc=Ka+ua>G.width?G.width-ua:Ka,Pc=J+Ta>G.height?G.height-Ta:J;c.drawImage(G,ua,Ta,xc,Pc,A,R,xc*d,Pc*d);1!=O&&(c.globalAlpha=Ia);if(1!=B||0!==E)nd(v,a),c.transform(a[0], +a[1],a[4],a[5],a[12],a[13])}++p;break;case 5:r=A[1];u=A[2];L=A[3];Wa=A[4]*d;J=A[5]*d;E=A[6];B=A[7]*d;G=A[8];for(O=A[9];r<u;r+=2){A=n[r]+Wa;R=n[r+1]+J;if(1!=B||0!==E)hi(v,A,R,B,B,E,-A,-R),c.transform(v[0],v[1],v[4],v[5],v[12],v[13]);ua=L.split("\n");Ta=ua.length;1<Ta?(kb=Math.round(1.5*c.measureText("M").width),R-=(Ta-1)/2*kb):kb=0;for(Ka=0;Ka<Ta;Ka++)Ia=ua[Ka],O&&c.strokeText(Ia,A,R),G&&c.fillText(Ia,A,R),R+=kb;if(1!=B||0!==E)nd(v,a),c.transform(a[0],a[1],a[4],a[5],a[12],a[13])}++p;break;case 6:if(void 0!== +k&&(r=A[1],r=k(r)))return r;++p;break;case 7:c.fill();++p;break;case 8:r=A[1];u=A[2];A=n[r];R=n[r+1];E=A+.5|0;B=R+.5|0;if(E!==x||B!==z)c.moveTo(A,R),x=E,z=B;for(r+=2;r<u;r+=2)if(A=n[r],R=n[r+1],E=A+.5|0,B=R+.5|0,E!==x||B!==z)c.lineTo(A,R),x=E,z=B;++p;break;case 9:c.fillStyle=A[1];++p;break;case 10:x=void 0!==A[7]?A[7]:!0;z=A[2];c.strokeStyle=A[1];c.lineWidth=x?z*d:z;c.lineCap=A[3];c.lineJoin=A[4];c.miterLimit=A[5];Zg&&c.setLineDash(A[6]);z=x=NaN;++p;break;case 11:c.font=A[1];c.textAlign=A[2];c.textBaseline= +A[3];++p;break;case 12:c.stroke();++p;break;default:++p}}}Gk.prototype.Pa=function(a,c,d,e,f){Jk(this,a,c,d,e,f,this.a,void 0)};function Kk(a){var c=a.b;c.reverse();var d,e=c.length,f,g,h=-1;for(d=0;d<e;++d)if(f=c[d],g=f[0],6==g)h=d;else if(0==g){f[2]=d;f=a.b;for(g=d;h<g;){var k=f[h];f[h]=f[g];f[g]=k;++h;--g}h=-1}}function Lk(a,c){a.va[2]=a.a.length;a.va=null;a.ya[2]=a.b.length;a.ya=null;var d=[6,c];a.a.push(d);a.b.push(d)}Gk.prototype.fe=pa;Gk.prototype.$e=function(){return this.T}; +function Mk(a,c,d){Gk.call(this,a,c,d);this.o=this.S=null;this.R=this.N=this.M=this.B=this.U=this.v=this.s=this.j=this.l=this.i=this.g=void 0}y(Mk,Gk);Mk.prototype.pc=function(a,c){if(this.o){Ik(this,c);var d=a.ga(),e=this.coordinates.length,d=Hk(this,d,0,d.length,a.ua(),!1);this.a.push([4,e,d,this.o,this.g,this.i,this.l,this.j,this.s,this.v,this.U,this.B,this.M,this.N,this.R]);this.b.push([4,e,d,this.S,this.g,this.i,this.l,this.j,this.s,this.v,this.U,this.B,this.M,this.N,this.R]);Lk(this,c)}}; +Mk.prototype.oc=function(a,c){if(this.o){Ik(this,c);var d=a.ga(),e=this.coordinates.length,d=Hk(this,d,0,d.length,a.ua(),!1);this.a.push([4,e,d,this.o,this.g,this.i,this.l,this.j,this.s,this.v,this.U,this.B,this.M,this.N,this.R]);this.b.push([4,e,d,this.S,this.g,this.i,this.l,this.j,this.s,this.v,this.U,this.B,this.M,this.N,this.R]);Lk(this,c)}};Mk.prototype.fe=function(){Kk(this);this.i=this.g=void 0;this.o=this.S=null;this.R=this.N=this.B=this.U=this.v=this.s=this.j=this.M=this.l=void 0}; +Mk.prototype.Pb=function(a){var c=a.Tb(),d=a.Bb(),e=a.ke(1),f=a.ec(1),g=a.Fa();this.g=c[0];this.i=c[1];this.S=e;this.o=f;this.l=d[1];this.j=a.v;this.s=g[0];this.v=g[1];this.U=a.U;this.B=a.j;this.M=a.i;this.N=a.M;this.R=d[0]};function Nk(a,c,d){Gk.call(this,a,c,d);this.g={ad:void 0,Wc:void 0,Xc:null,Yc:void 0,Zc:void 0,$c:void 0,jf:0,strokeStyle:void 0,lineCap:void 0,lineDash:null,lineJoin:void 0,lineWidth:void 0,miterLimit:void 0}}y(Nk,Gk); +function Ok(a,c,d,e,f){var g=a.coordinates.length;c=Hk(a,c,d,e,f,!1);g=[8,g,c];a.a.push(g);a.b.push(g);return e}l=Nk.prototype;l.$e=function(){this.f||(this.f=Zb(this.T),0<this.c&&Yb(this.f,this.resolution*(this.c+1)/2,this.f));return this.f}; +function Pk(a){var c=a.g,d=c.strokeStyle,e=c.lineCap,f=c.lineDash,g=c.lineJoin,h=c.lineWidth,k=c.miterLimit;c.ad==d&&c.Wc==e&&Ab(c.Xc,f)&&c.Yc==g&&c.Zc==h&&c.$c==k||(c.jf!=a.coordinates.length&&(a.a.push([12]),c.jf=a.coordinates.length),a.a.push([10,d,h,e,g,k,f],[1]),c.ad=d,c.Wc=e,c.Xc=f,c.Yc=g,c.Zc=h,c.$c=k)} +l.cd=function(a,c){var d=this.g,e=d.lineWidth;void 0!==d.strokeStyle&&void 0!==e&&(Pk(this),Ik(this,c),this.b.push([10,d.strokeStyle,d.lineWidth,d.lineCap,d.lineJoin,d.miterLimit,d.lineDash],[1]),d=a.ga(),Ok(this,d,0,d.length,a.ua()),this.b.push([12]),Lk(this,c))}; +l.We=function(a,c){var d=this.g,e=d.lineWidth;if(void 0!==d.strokeStyle&&void 0!==e){Pk(this);Ik(this,c);this.b.push([10,d.strokeStyle,d.lineWidth,d.lineCap,d.lineJoin,d.miterLimit,d.lineDash],[1]);var d=a.zb(),e=a.ga(),f=a.ua(),g=0,h,k;h=0;for(k=d.length;h<k;++h)g=Ok(this,e,g,d[h],f);this.b.push([12]);Lk(this,c)}};l.fe=function(){this.g.jf!=this.coordinates.length&&this.a.push([12]);Kk(this);this.g=null}; +l.Ob=function(a,c){var d=c.b;this.g.strokeStyle=He(d?d:Yj);d=c.f;this.g.lineCap=void 0!==d?d:"round";d=c.g;this.g.lineDash=d?d:Xj;d=c.c;this.g.lineJoin=void 0!==d?d:"round";d=c.a;this.g.lineWidth=void 0!==d?d:1;d=c.i;this.g.miterLimit=void 0!==d?d:10;this.g.lineWidth>this.c&&(this.c=this.g.lineWidth,this.f=null)}; +function Qk(a,c,d){Gk.call(this,a,c,d);this.g={qg:void 0,ad:void 0,Wc:void 0,Xc:null,Yc:void 0,Zc:void 0,$c:void 0,fillStyle:void 0,strokeStyle:void 0,lineCap:void 0,lineDash:null,lineJoin:void 0,lineWidth:void 0,miterLimit:void 0}}y(Qk,Gk); +function Rk(a,c,d,e,f){var g=a.g,h=[1];a.a.push(h);a.b.push(h);var k,h=0;for(k=e.length;h<k;++h){var m=e[h],n=a.coordinates.length;d=Hk(a,c,d,m,f,!0);d=[8,n,d];n=[3];a.a.push(d,n);a.b.push(d,n);d=m}c=[7];a.b.push(c);void 0!==g.fillStyle&&a.a.push(c);void 0!==g.strokeStyle&&(g=[12],a.a.push(g),a.b.push(g));return d}l=Qk.prototype; +l.Md=function(a,c){var d=this.g,e=d.strokeStyle;if(void 0!==d.fillStyle||void 0!==e){Sk(this);Ik(this,c);this.b.push([9,He(Wj)]);void 0!==d.strokeStyle&&this.b.push([10,d.strokeStyle,d.lineWidth,d.lineCap,d.lineJoin,d.miterLimit,d.lineDash]);var f=a.ga(),e=this.coordinates.length;Hk(this,f,0,f.length,a.ua(),!1);f=[1];e=[2,e];this.a.push(f,e);this.b.push(f,e);e=[7];this.b.push(e);void 0!==d.fillStyle&&this.a.push(e);void 0!==d.strokeStyle&&(d=[12],this.a.push(d),this.b.push(d));Lk(this,c)}}; +l.Ye=function(a,c){var d=this.g,e=d.strokeStyle;if(void 0!==d.fillStyle||void 0!==e)Sk(this),Ik(this,c),this.b.push([9,He(Wj)]),void 0!==d.strokeStyle&&this.b.push([10,d.strokeStyle,d.lineWidth,d.lineCap,d.lineJoin,d.miterLimit,d.lineDash]),d=a.zb(),e=a.Kb(),Rk(this,e,0,d,a.ua()),Lk(this,c)}; +l.Xe=function(a,c){var d=this.g,e=d.strokeStyle;if(void 0!==d.fillStyle||void 0!==e){Sk(this);Ik(this,c);this.b.push([9,He(Wj)]);void 0!==d.strokeStyle&&this.b.push([10,d.strokeStyle,d.lineWidth,d.lineCap,d.lineJoin,d.miterLimit,d.lineDash]);var d=a.i,e=zk(a),f=a.ua(),g=0,h,k;h=0;for(k=d.length;h<k;++h)g=Rk(this,e,g,d[h],f);Lk(this,c)}};l.fe=function(){Kk(this);this.g=null;var a=this.na;if(0!==a){var c=this.coordinates,d,e;d=0;for(e=c.length;d<e;++d)c[d]=a*Math.round(c[d]/a)}}; +l.$e=function(){this.f||(this.f=Zb(this.T),0<this.c&&Yb(this.f,this.resolution*(this.c+1)/2,this.f));return this.f}; +l.Ob=function(a,c){var d=this.g;if(a){var e=a.b;d.fillStyle=Je(e?e:Wj)}else d.fillStyle=void 0;c?(e=c.b,d.strokeStyle=He(e?e:Yj),e=c.f,d.lineCap=void 0!==e?e:"round",e=c.g,d.lineDash=e?e.slice():Xj,e=c.c,d.lineJoin=void 0!==e?e:"round",e=c.a,d.lineWidth=void 0!==e?e:1,e=c.i,d.miterLimit=void 0!==e?e:10,d.lineWidth>this.c&&(this.c=d.lineWidth,this.f=null)):(d.strokeStyle=void 0,d.lineCap=void 0,d.lineDash=null,d.lineJoin=void 0,d.lineWidth=void 0,d.miterLimit=void 0)}; +function Sk(a){var c=a.g,d=c.fillStyle,e=c.strokeStyle,f=c.lineCap,g=c.lineDash,h=c.lineJoin,k=c.lineWidth,m=c.miterLimit;void 0!==d&&c.qg!=d&&(a.a.push([9,d]),c.qg=c.fillStyle);void 0===e||c.ad==e&&c.Wc==f&&c.Xc==g&&c.Yc==h&&c.Zc==k&&c.$c==m||(a.a.push([10,e,k,f,h,m,g]),c.ad=e,c.Wc=f,c.Xc=g,c.Yc=h,c.Zc=k,c.$c=m)}function Tk(a,c,d){Gk.call(this,a,c,d);this.N=this.M=this.B=null;this.o="";this.U=this.v=this.s=this.j=0;this.l=this.i=this.g=null}y(Tk,Gk); +function Uk(a,c,d,e,f){if(""!==a.o&&a.l&&(a.g||a.i)){if(a.g){var g=a.g,h=a.B;if(!h||h.fillStyle!=g.fillStyle){var k=[9,g.fillStyle];a.a.push(k);a.b.push(k);h?h.fillStyle=g.fillStyle:a.B={fillStyle:g.fillStyle}}}a.i&&(g=a.i,h=a.M,h&&h.lineCap==g.lineCap&&h.lineDash==g.lineDash&&h.lineJoin==g.lineJoin&&h.lineWidth==g.lineWidth&&h.miterLimit==g.miterLimit&&h.strokeStyle==g.strokeStyle||(k=[10,g.strokeStyle,g.lineWidth,g.lineCap,g.lineJoin,g.miterLimit,g.lineDash,!1],a.a.push(k),a.b.push(k),h?(h.lineCap= +g.lineCap,h.lineDash=g.lineDash,h.lineJoin=g.lineJoin,h.lineWidth=g.lineWidth,h.miterLimit=g.miterLimit,h.strokeStyle=g.strokeStyle):a.M={lineCap:g.lineCap,lineDash:g.lineDash,lineJoin:g.lineJoin,lineWidth:g.lineWidth,miterLimit:g.miterLimit,strokeStyle:g.strokeStyle}));g=a.l;h=a.N;h&&h.font==g.font&&h.textAlign==g.textAlign&&h.textBaseline==g.textBaseline||(k=[11,g.font,g.textAlign,g.textBaseline],a.a.push(k),a.b.push(k),h?(h.font=g.font,h.textAlign=g.textAlign,h.textBaseline=g.textBaseline):a.N= +{font:g.font,textAlign:g.textAlign,textBaseline:g.textBaseline});Ik(a,f);g=a.coordinates.length;c=Hk(a,c,0,d,e,!1);c=[5,g,c,a.o,a.j,a.s,a.v,a.U,!!a.g,!!a.i];a.a.push(c);a.b.push(c);Lk(a,f)}} +Tk.prototype.Rb=function(a){if(a){var c=a.b;c?(c=c.b,c=Je(c?c:Wj),this.g?this.g.fillStyle=c:this.g={fillStyle:c}):this.g=null;var d=a.l;if(d){var c=d.b,e=d.f,f=d.g,g=d.c,h=d.a,d=d.i,e=void 0!==e?e:"round",f=f?f.slice():Xj,g=void 0!==g?g:"round",h=void 0!==h?h:1,d=void 0!==d?d:10,c=He(c?c:Yj);if(this.i){var k=this.i;k.lineCap=e;k.lineDash=f;k.lineJoin=g;k.lineWidth=h;k.miterLimit=d;k.strokeStyle=c}else this.i={lineCap:e,lineDash:f,lineJoin:g,lineWidth:h,miterLimit:d,strokeStyle:c}}else this.i=null; +var m=a.g,c=a.f,e=a.c,f=a.i,h=a.a,d=a.Ea(),g=a.o,k=a.j;a=void 0!==m?m:"10px sans-serif";g=void 0!==g?g:"center";k=void 0!==k?k:"middle";this.l?(m=this.l,m.font=a,m.textAlign=g,m.textBaseline=k):this.l={font:a,textAlign:g,textBaseline:k};this.o=void 0!==d?d:"";this.j=void 0!==c?c:0;this.s=void 0!==e?e:0;this.v=void 0!==f?f:0;this.U=void 0!==h?h:1}else this.o=""};function Vk(a,c,d,e){this.o=a;this.g=c;this.l=d;this.f=e;this.a={};this.c=Mg(1,1);this.i=hd()} +function Wk(a){for(var c in a.a){var d=a.a[c],e;for(e in d)d[e].fe()}}Vk.prototype.oa=function(a,c,d,e,f){var g=this.i;hi(g,.5,.5,1/c,-1/c,-d,-a[0],-a[1]);var h=this.c;h.clearRect(0,0,1,1);var k;void 0!==this.f&&(k=Wb(),Xb(k,a),Yb(k,c*this.f,k));return Xk(this,h,g,d,e,function(a){if(0<h.getImageData(0,0,1,1).data[3]){if(a=f(a))return a;h.clearRect(0,0,1,1)}},k)}; +Vk.prototype.b=function(a,c){var d=void 0!==a?a.toString():"0",e=this.a[d];void 0===e&&(e={},this.a[d]=e);d=e[c];void 0===d&&(d=new Yk[c](this.o,this.g,this.l),e[c]=d);return d};Vk.prototype.Sa=function(){return Sa(this.a)}; +Vk.prototype.Pa=function(a,c,d,e,f,g){var h=Object.keys(this.a).map(Number);h.sort(tb);var k=this.g,m=k[0],n=k[1],p=k[2],k=k[3],m=[m,n,m,k,p,k,p,n];rd(m,0,8,2,d,m);a.save();a.beginPath();a.moveTo(m[0],m[1]);a.lineTo(m[2],m[3]);a.lineTo(m[4],m[5]);a.lineTo(m[6],m[7]);a.closePath();a.clip();g=g?g:Fk;for(var q,r,m=0,n=h.length;m<n;++m)for(q=this.a[h[m].toString()],p=0,k=g.length;p<k;++p)r=q[g[p]],void 0!==r&&r.Pa(a,c,d,e,f);a.restore()}; +function Xk(a,c,d,e,f,g,h){var k=Object.keys(a.a).map(Number);k.sort(function(a,c){return c-a});var m,n,p,q,r;m=0;for(n=k.length;m<n;++m)for(q=a.a[k[m].toString()],p=Fk.length-1;0<=p;--p)if(r=q[Fk[p]],void 0!==r&&(r=Jk(r,c,1,d,e,f,r.b,g,h)))return r}var Yk={Image:Mk,LineString:Nk,Polygon:Qk,Text:Tk};function Zk(a,c,d,e){this.g=a;this.b=c;this.c=d;this.f=e}l=Zk.prototype;l.get=function(a){return this.f[a]};l.zb=function(){return this.c};l.O=function(){this.a||(this.a="Point"===this.g?fc(this.b):gc(this.b,0,this.b.length,2));return this.a};l.Kb=function(){return this.b};l.ga=Zk.prototype.Kb;l.W=function(){return this};l.Hm=function(){return this.f};l.hd=Zk.prototype.W;l.ua=function(){return 2};l.$b=pa;l.X=function(){return this.g};function $k(a,c){return w(a)-w(c)}function al(a,c){var d=.5*a/c;return d*d}function bl(a,c,d,e,f,g){var h=!1,k,m;if(k=d.a)m=k.od(),2==m||3==m?k.Tf(f,g):(0==m&&k.load(),k.kf(f,g),h=!0);if(f=(0,d.g)(c))e=f.hd(e),(0,cl[e.X()])(a,e,d,c);return h} +var cl={Point:function(a,c,d,e){var f=d.a;if(f){if(2!=f.od())return;var g=a.b(d.b,"Image");g.Pb(f);g.pc(c,e)}if(f=d.Ea())a=a.b(d.b,"Text"),a.Rb(f),Uk(a,c.ga(),2,2,e)},LineString:function(a,c,d,e){var f=d.f;if(f){var g=a.b(d.b,"LineString");g.Ob(null,f);g.cd(c,e)}if(f=d.Ea())a=a.b(d.b,"Text"),a.Rb(f),Uk(a,xk(c),2,2,e)},Polygon:function(a,c,d,e){var f=d.c,g=d.f;if(f||g){var h=a.b(d.b,"Polygon");h.Ob(f,g);h.Ye(c,e)}if(f=d.Ea())a=a.b(d.b,"Text"),a.Rb(f),Uk(a,Xd(c),2,2,e)},MultiPoint:function(a,c,d,e){var f= +d.a;if(f){if(2!=f.od())return;var g=a.b(d.b,"Image");g.Pb(f);g.oc(c,e)}if(f=d.Ea())a=a.b(d.b,"Text"),a.Rb(f),d=c.ga(),Uk(a,d,d.length,c.ua(),e)},MultiLineString:function(a,c,d,e){var f=d.f;if(f){var g=a.b(d.b,"LineString");g.Ob(null,f);g.We(c,e)}if(f=d.Ea())a=a.b(d.b,"Text"),a.Rb(f),c=yk(c),Uk(a,c,c.length,2,e)},MultiPolygon:function(a,c,d,e){var f=d.c,g=d.f;if(g||f){var h=a.b(d.b,"Polygon");h.Ob(f,g);h.Xe(c,e)}if(f=d.Ea())a=a.b(d.b,"Text"),a.Rb(f),c=Ak(c),Uk(a,c,c.length,2,e)},GeometryCollection:function(a, +c,d,e){c=c.c;var f,g;f=0;for(g=c.length;f<g;++f)(0,cl[c[f].X()])(a,c[f],d,e)},Circle:function(a,c,d,e){var f=d.c,g=d.f;if(f||g){var h=a.b(d.b,"Polygon");h.Ob(f,g);h.Md(c,e)}if(f=d.Ea())a=a.b(d.b,"Text"),a.Rb(f),Uk(a,c.ld(),2,2,e)}};function dl(a,c,d,e,f,g){this.c=void 0!==g?g:null;fi.call(this,a,c,d,void 0!==g?0:2,e);this.g=f}y(dl,fi);dl.prototype.i=function(a){this.state=a?3:2;gi(this)};dl.prototype.load=function(){0==this.state&&(this.state=1,gi(this),this.c(this.i.bind(this)))};dl.prototype.a=function(){return this.g};var el,fl=aa.navigator,gl=aa.chrome,hl=-1<fl.userAgent.indexOf("OPR"),il=-1<fl.userAgent.indexOf("Edge");el=!(!fl.userAgent.match("CriOS")&&null!==gl&&void 0!==gl&&"Google Inc."===fl.vendor&&0==hl&&0==il);function jl(a,c,d,e){var f=bd(d,c,a);d=c.getPointResolution(e,d);c=c.Vb();void 0!==c&&(d*=c);c=a.Vb();void 0!==c&&(d/=c);a=a.getPointResolution(d,f)/d;isFinite(a)&&0<a&&(d/=a);return d}function kl(a,c,d,e){a=d-a;c=e-c;var f=Math.sqrt(a*a+c*c);return[Math.round(d+a/f),Math.round(e+c/f)]} +function ll(a,c,d,e,f,g,h,k,m,n,p){var q=Mg(Math.round(d*a),Math.round(d*c));if(0===m.length)return q.canvas;q.scale(d,d);var r=Wb();m.forEach(function(a){jc(r,a.extent)});var u=Mg(Math.round(d*rc(r)/e),Math.round(d*sc(r)/e)),v=d/e;m.forEach(function(a){u.drawImage(a.image,n,n,a.image.width-2*n,a.image.height-2*n,(a.extent[0]-r[0])*v,-(a.extent[3]-r[3])*v,rc(a.extent)*v,sc(a.extent)*v)});var x=oc(h);k.f.forEach(function(a){var c=a.source,f=a.target,h=c[1][0],k=c[1][1],m=c[2][0],n=c[2][1];a=(f[0][0]- +x[0])/g;var p=-(f[0][1]-x[1])/g,v=(f[1][0]-x[0])/g,J=-(f[1][1]-x[1])/g,ua=(f[2][0]-x[0])/g,Ta=-(f[2][1]-x[1])/g,f=c[0][0],c=c[0][1],h=h-f,k=k-c,m=m-f,n=n-c;a:{h=[[h,k,0,0,v-a],[m,n,0,0,ua-a],[0,0,h,k,J-p],[0,0,m,n,Ta-p]];k=h.length;for(m=0;m<k;m++){for(var n=m,kb=Math.abs(h[m][m]),Ka=m+1;Ka<k;Ka++){var Ia=Math.abs(h[Ka][m]);Ia>kb&&(kb=Ia,n=Ka)}if(0===kb){h=null;break a}kb=h[n];h[n]=h[m];h[m]=kb;for(n=m+1;n<k;n++)for(kb=-h[n][m]/h[m][m],Ka=m;Ka<k+1;Ka++)h[n][Ka]=m==Ka?0:h[n][Ka]+kb*h[m][Ka]}m=Array(k); +for(n=k-1;0<=n;n--)for(m[n]=h[n][k]/h[n][n],kb=n-1;0<=kb;kb--)h[kb][k]-=h[kb][n]*m[n];h=m}h&&(q.save(),q.beginPath(),el?(m=(a+v+ua)/3,n=(p+J+Ta)/3,k=kl(m,n,a,p),v=kl(m,n,v,J),ua=kl(m,n,ua,Ta),q.moveTo(k[0],k[1]),q.lineTo(v[0],v[1]),q.lineTo(ua[0],ua[1])):(q.moveTo(a,p),q.lineTo(v,J),q.lineTo(ua,Ta)),q.closePath(),q.clip(),q.transform(h[0],h[2],h[1],h[3],a,p),q.translate(r[0]-f,r[3]-c),q.scale(e/d,-e/d),q.drawImage(u.canvas,0,0),q.restore())});p&&(q.save(),q.strokeStyle="black",q.lineWidth=1,k.f.forEach(function(a){var c= +a.target;a=(c[0][0]-x[0])/g;var d=-(c[0][1]-x[1])/g,e=(c[1][0]-x[0])/g,f=-(c[1][1]-x[1])/g,h=(c[2][0]-x[0])/g,c=-(c[2][1]-x[1])/g;q.beginPath();q.moveTo(a,d);q.lineTo(e,f);q.lineTo(h,c);q.closePath();q.stroke()}),q.restore());return q.canvas};function ml(a,c,d,e,f){this.g=a;this.c=c;var g={},h=$c(this.c,this.g);this.a=function(a){var c=a[0]+"/"+a[1];g[c]||(g[c]=h(a));return g[c]};this.i=e;this.s=f*f;this.f=[];this.o=!1;this.j=this.g.a&&!!e&&!!this.g.O()&&rc(e)==rc(this.g.O());this.b=this.g.O()?rc(this.g.O()):null;this.l=this.c.O()?rc(this.c.O()):null;a=oc(d);c=nc(d);e=mc(d);d=lc(d);f=this.a(a);var k=this.a(c),m=this.a(e),n=this.a(d);nl(this,a,c,e,d,f,k,m,n,10);if(this.o){var p=Infinity;this.f.forEach(function(a){p=Math.min(p,a.source[0][0], +a.source[1][0],a.source[2][0])});this.f.forEach(function(a){if(Math.max(a.source[0][0],a.source[1][0],a.source[2][0])-p>this.b/2){var c=[[a.source[0][0],a.source[0][1]],[a.source[1][0],a.source[1][1]],[a.source[2][0],a.source[2][1]]];c[0][0]-p>this.b/2&&(c[0][0]-=this.b);c[1][0]-p>this.b/2&&(c[1][0]-=this.b);c[2][0]-p>this.b/2&&(c[2][0]-=this.b);Math.max(c[0][0],c[1][0],c[2][0])-Math.min(c[0][0],c[1][0],c[2][0])<this.b/2&&(a.source=c)}},this)}g={}} +function nl(a,c,d,e,f,g,h,k,m,n){var p=Vb([g,h,k,m]),q=a.b?rc(p)/a.b:null,r=a.g.a&&.5<q&&1>q,u=!1;if(0<n){if(a.c.g&&a.l)var v=Vb([c,d,e,f]),u=u|.25<rc(v)/a.l;!r&&a.g.g&&q&&(u|=.25<q)}if(u||!a.i||wc(p,a.i)){if(!(u||isFinite(g[0])&&isFinite(g[1])&&isFinite(h[0])&&isFinite(h[1])&&isFinite(k[0])&&isFinite(k[1])&&isFinite(m[0])&&isFinite(m[1])))if(0<n)u=!0;else return;if(0<n&&(u||(q=a.a([(c[0]+e[0])/2,(c[1]+e[1])/2]),p=r?(Ja(g[0],a.b)+Ja(k[0],a.b))/2-Ja(q[0],a.b):(g[0]+k[0])/2-q[0],q=(g[1]+k[1])/2-q[1], +u=p*p+q*q>a.s),u)){Math.abs(c[0]-e[0])<=Math.abs(c[1]-e[1])?(r=[(d[0]+e[0])/2,(d[1]+e[1])/2],p=a.a(r),q=[(f[0]+c[0])/2,(f[1]+c[1])/2],u=a.a(q),nl(a,c,d,r,q,g,h,p,u,n-1),nl(a,q,r,e,f,u,p,k,m,n-1)):(r=[(c[0]+d[0])/2,(c[1]+d[1])/2],p=a.a(r),q=[(e[0]+f[0])/2,(e[1]+f[1])/2],u=a.a(q),nl(a,c,r,q,f,g,p,u,m,n-1),nl(a,r,d,e,q,p,h,k,u,n-1));return}if(r){if(!a.j)return;a.o=!0}a.f.push({source:[g,k,m],target:[c,e,f]});a.f.push({source:[g,h,k],target:[c,d,e]})}} +function pl(a){var c=Wb();a.f.forEach(function(a){a=a.source;Xb(c,a[0]);Xb(c,a[1]);Xb(c,a[2])});return c};function ql(a,c,d,e,f,g){this.v=c;this.s=a.O();var h=c.O(),k=h?vc(d,h):d,h=jl(a,c,tc(k),e);this.o=new ml(a,c,k,this.s,.5*h);this.c=e;this.g=d;a=pl(this.o);this.j=(this.nb=g(a,h,f))?this.nb.f:1;this.vd=this.i=null;f=2;g=[];this.nb&&(f=0,g=this.nb.l);fi.call(this,d,e,this.j,f,g)}y(ql,fi);ql.prototype.fa=function(){1==this.state&&(Xa(this.vd),this.vd=null);ql.ia.fa.call(this)};ql.prototype.a=function(){return this.i}; +ql.prototype.ud=function(){var a=this.nb.V();2==a&&(this.i=ll(rc(this.g)/this.c,sc(this.g)/this.c,this.j,this.nb.$(),0,this.c,this.g,this.o,[{extent:this.nb.O(),image:this.nb.a()}],0));this.state=a;gi(this)};ql.prototype.load=function(){if(0==this.state){this.state=1;gi(this);var a=this.nb.V();2==a||3==a?this.ud():(this.vd=C(this.nb,"change",function(){var a=this.nb.V();if(2==a||3==a)Xa(this.vd),this.vd=null,this.ud()},this),this.nb.load())}};function rl(a){Vf.call(this,{attributions:a.attributions,extent:a.extent,logo:a.logo,projection:a.projection,state:a.state});this.M=void 0!==a.resolutions?a.resolutions:null;this.a=null;this.na=0}y(rl,Vf);function sl(a,c){if(a.M){var d=vb(a.M,c,0);c=a.M[d]}return c} +rl.prototype.B=function(a,c,d,e){var f=this.f;if(f&&e&&!Zc(f,e)){if(this.a){if(this.na==this.g&&Zc(this.a.v,e)&&this.a.$()==c&&this.a.f==d&&ic(this.a.O(),a))return this.a;fb(this.a);this.a=null}this.a=new ql(f,e,a,c,d,function(a,c,d){return this.Hc(a,c,d,f)}.bind(this));this.na=this.g;return this.a}f&&(e=f);return this.Hc(a,c,d,e)};rl.prototype.o=function(a){a=a.target;switch(a.V()){case 1:this.b(new tl(ul,a));break;case 2:this.b(new tl(vl,a));break;case 3:this.b(new tl(wl,a))}}; +function xl(a,c){a.a().src=c}function tl(a,c){gb.call(this,a);this.image=c}y(tl,gb);var ul="imageloadstart",vl="imageloadend",wl="imageloaderror";function yl(a){rl.call(this,{attributions:a.attributions,logo:a.logo,projection:a.projection,resolutions:a.resolutions,state:a.state});this.ea=a.canvasFunction;this.T=null;this.Y=0;this.ta=void 0!==a.ratio?a.ratio:1.5}y(yl,rl);yl.prototype.Hc=function(a,c,d,e){c=sl(this,c);var f=this.T;if(f&&this.Y==this.g&&f.$()==c&&f.f==d&&cc(f.O(),a))return f;a=a.slice();yc(a,this.ta);(e=this.ea(a,c,d,[rc(a)/c*d,sc(a)/c*d],e))&&(f=new dl(a,c,d,this.l,e));this.T=f;this.Y=this.g;return f};function zl(a){pb.call(this);this.i=void 0;this.a="geometry";this.c=null;this.l=void 0;this.f=null;C(this,rb(this.a),this.Wd,this);void 0!==a&&(a instanceof dd||!a?this.Ta(a):this.C(a))}y(zl,pb);l=zl.prototype;l.clone=function(){var a=new zl(this.L());a.zc(this.a);var c=this.W();c&&a.Ta(c.clone());(c=this.c)&&a.nf(c);return a};l.W=function(){return this.get(this.a)};l.Wa=function(){return this.i};l.Wj=function(){return this.a};l.Fl=function(){return this.c};l.$b=function(){return this.l};l.Gl=function(){this.u()}; +l.Wd=function(){this.f&&(Xa(this.f),this.f=null);var a=this.W();a&&(this.f=C(a,"change",this.Gl,this));this.u()};l.Ta=function(a){this.set(this.a,a)};l.nf=function(a){this.l=(this.c=a)?Al(a):void 0;this.u()};l.hc=function(a){this.i=a;this.u()};l.zc=function(a){cb(this,rb(this.a),this.Wd,this);this.a=a;C(this,rb(this.a),this.Wd,this);this.Wd()};function Al(a){if(!ga(a)){var c;c=Array.isArray(a)?a:[a];a=function(){return c}}return a};function Bl(a,c,d,e,f){Qf.call(this,a,c);this.g=Mg();this.l=e;this.c=null;this.f={bd:!1,Pf:null,Xh:-1,Qf:-1,td:null,oi:[]};this.v=f;this.j=d}y(Bl,Qf);l=Bl.prototype;l.ab=function(){return-1==this.f.Qf?null:this.g.canvas};l.Ql=function(){return this.l};l.gb=function(){return this.j};l.load=function(){0==this.state&&(this.state=1,Rf(this),this.v(this,this.j),this.s(null,NaN,null))};l.bi=function(a){this.c=a;this.state=2;Rf(this)};l.rf=function(a){this.o=a};l.fi=function(a){this.s=a};var Cl=document.implementation.createDocument("","",null);function Dl(a,c){return Cl.createElementNS(a,c)}function El(a,c){return Fl(a,c,[]).join("")}function Fl(a,c,d){if(4==a.nodeType||3==a.nodeType)c?d.push(String(a.nodeValue).replace(/(\r\n|\r|\n)/g,"")):d.push(a.nodeValue);else for(a=a.firstChild;a;a=a.nextSibling)Fl(a,c,d);return d}function Gl(a){return a instanceof Document}function Hl(a){return a instanceof Node}function Il(a){return(new DOMParser).parseFromString(a,"application/xml")} +function Jl(a,c){return function(d,e){var f=a.call(c,d,e);void 0!==f&&xb(e[e.length-1],f)}}function Kl(a,c){return function(d,e){var f=a.call(void 0!==c?c:this,d,e);void 0!==f&&e[e.length-1].push(f)}}function Ll(a,c){return function(d,e){var f=a.call(void 0!==c?c:this,d,e);void 0!==f&&(e[e.length-1]=f)}}function Ml(a){return function(c,d){var e=a.call(this,c,d);if(void 0!==e){var f=d[d.length-1],g=c.localName,h;g in f?h=f[g]:h=f[g]=[];h.push(e)}}} +function K(a,c){return function(d,e){var f=a.call(this,d,e);void 0!==f&&(e[e.length-1][void 0!==c?c:d.localName]=f)}}function M(a,c){return function(d,e,f){a.call(void 0!==c?c:this,d,e,f);f[f.length-1].node.appendChild(d)}}function Nl(a){var c,d;return function(e,f,g){if(void 0===c){c={};var h={};h[e.localName]=a;c[e.namespaceURI]=h;d=Ol(e.localName)}Pl(c,d,f,g)}}function Ol(a,c){return function(d,e,f){d=e[e.length-1].node;e=a;void 0===e&&(e=f);f=c;void 0===c&&(f=d.namespaceURI);return Dl(f,e)}} +var Ql=Ol();function Rl(a,c){for(var d=c.length,e=Array(d),f=0;f<d;++f)e[f]=a[c[f]];return e}function N(a,c,d){d=void 0!==d?d:{};var e,f;e=0;for(f=a.length;e<f;++e)d[a[e]]=c;return d}function Sl(a,c,d,e){for(c=c.firstElementChild;c;c=c.nextElementSibling){var f=a[c.namespaceURI];void 0!==f&&(f=f[c.localName],void 0!==f&&f.call(e,c,d))}}function P(a,c,d,e,f){e.push(a);Sl(c,d,e,f);return e.pop()} +function Pl(a,c,d,e,f,g){for(var h=(void 0!==f?f:d).length,k,m,n=0;n<h;++n)k=d[n],void 0!==k&&(m=c.call(g,k,e,void 0!==f?f[n]:void 0),void 0!==m&&a[m.namespaceURI][m.localName].call(g,m,k,e))}function Tl(a,c,d,e,f,g,h){f.push(a);Pl(c,d,e,f,g,h);f.pop()};function Ul(a,c,d,e){return function(f,g,h){var k=new XMLHttpRequest;k.open("GET",ga(a)?a(f,g,h):a,!0);"arraybuffer"==c.X()&&(k.responseType="arraybuffer");k.onload=function(){if(200<=k.status&&300>k.status){var a=c.X(),f;"json"==a||"text"==a?f=k.responseText:"xml"==a?(f=k.responseXML)||(f=Il(k.responseText)):"arraybuffer"==a&&(f=k.response);f&&d.call(this,c.Ca(f,{featureProjection:h}),c.Oa(f))}else e.call(this)}.bind(this);k.send()}} +function Vl(a,c){return Ul(a,c,function(a,c){this.rf(c);this.bi(a)},function(){this.state=3;Rf(this)})}function Wl(a,c){return Ul(a,c,function(a){this.Ec(a)},pa)};function Xl(){return[[-Infinity,-Infinity,Infinity,Infinity]]};var Yl,Zl,$l,am; +(function(){var a={ha:{}};(function(){function c(a,d){if(!(this instanceof c))return new c(a,d);this.Pe=Math.max(4,a||9);this.dg=Math.max(2,Math.ceil(.4*this.Pe));d&&this.hj(d);this.clear()}function d(a,c){a.bbox=e(a,0,a.children.length,c)}function e(a,c,d,e){for(var g=[Infinity,Infinity,-Infinity,-Infinity],h;c<d;c++)h=a.children[c],f(g,a.Ja?e(h):h.bbox);return g}function f(a,c){a[0]=Math.min(a[0],c[0]);a[1]=Math.min(a[1],c[1]);a[2]=Math.max(a[2],c[2]);a[3]=Math.max(a[3],c[3])}function g(a,c){return a.bbox[0]- +c.bbox[0]}function h(a,c){return a.bbox[1]-c.bbox[1]}function k(a){return(a[2]-a[0])*(a[3]-a[1])}function m(a){return a[2]-a[0]+(a[3]-a[1])}function n(a,c){return a[0]<=c[0]&&a[1]<=c[1]&&c[2]<=a[2]&&c[3]<=a[3]}function p(a,c){return c[0]<=a[2]&&c[1]<=a[3]&&c[2]>=a[0]&&c[3]>=a[1]}function q(a,c,d,e,f){for(var g=[c,d],h;g.length;)d=g.pop(),c=g.pop(),d-c<=e||(h=c+Math.ceil((d-c)/e/2)*e,r(a,c,d,h,f),g.push(c,h,h,d))}function r(a,c,d,e,f){for(var g,h,k,m,n;d>c;){600<d-c&&(g=d-c+1,h=e-c+1,k=Math.log(g), +m=.5*Math.exp(2*k/3),n=.5*Math.sqrt(k*m*(g-m)/g)*(0>h-g/2?-1:1),k=Math.max(c,Math.floor(e-h*m/g+n)),h=Math.min(d,Math.floor(e+(g-h)*m/g+n)),r(a,k,h,e,f));g=a[e];h=c;m=d;u(a,c,e);for(0<f(a[d],g)&&u(a,c,d);h<m;){u(a,h,m);h++;for(m--;0>f(a[h],g);)h++;for(;0<f(a[m],g);)m--}0===f(a[c],g)?u(a,c,m):(m++,u(a,m,d));m<=e&&(c=m+1);e<=m&&(d=m-1)}}function u(a,c,d){var e=a[c];a[c]=a[d];a[d]=e}c.prototype={all:function(){return this.Zf(this.data,[])},search:function(a){var c=this.data,d=[],e=this.ib;if(!p(a,c.bbox))return d; +for(var f=[],g,h,k,m;c;){g=0;for(h=c.children.length;g<h;g++)k=c.children[g],m=c.Ja?e(k):k.bbox,p(a,m)&&(c.Ja?d.push(k):n(a,m)?this.Zf(k,d):f.push(k));c=f.pop()}return d},load:function(a){if(!a||!a.length)return this;if(a.length<this.dg){for(var c=0,d=a.length;c<d;c++)this.za(a[c]);return this}a=this.ag(a.slice(),0,a.length-1,0);this.data.children.length?this.data.height===a.height?this.fg(this.data,a):(this.data.height<a.height&&(c=this.data,this.data=a,a=c),this.cg(a,this.data.height-a.height-1, +!0)):this.data=a;return this},za:function(a){a&&this.cg(a,this.data.height-1);return this},clear:function(){this.data={children:[],height:1,bbox:[Infinity,Infinity,-Infinity,-Infinity],Ja:!0};return this},remove:function(a){if(!a)return this;for(var c=this.data,d=this.ib(a),e=[],f=[],g,h,k,m;c||e.length;){c||(c=e.pop(),h=e[e.length-1],g=f.pop(),m=!0);if(c.Ja&&(k=c.children.indexOf(a),-1!==k)){c.children.splice(k,1);e.push(c);this.fj(e);break}m||c.Ja||!n(c.bbox,d)?h?(g++,c=h.children[g],m=!1):c=null: +(e.push(c),f.push(g),g=0,h=c,c=c.children[0])}return this},ib:function(a){return a},Re:function(a,c){return a[0]-c[0]},Se:function(a,c){return a[1]-c[1]},toJSON:function(){return this.data},Zf:function(a,c){for(var d=[];a;)a.Ja?c.push.apply(c,a.children):d.push.apply(d,a.children),a=d.pop();return c},ag:function(a,c,e,f){var g=e-c+1,h=this.Pe,k;if(g<=h)return k={children:a.slice(c,e+1),height:1,bbox:null,Ja:!0},d(k,this.ib),k;f||(f=Math.ceil(Math.log(g)/Math.log(h)),h=Math.ceil(g/Math.pow(h,f-1))); +k={children:[],height:f,bbox:null,Ja:!1};var g=Math.ceil(g/h),h=g*Math.ceil(Math.sqrt(h)),m,n,p;for(q(a,c,e,h,this.Re);c<=e;c+=h)for(n=Math.min(c+h-1,e),q(a,c,n,g,this.Se),m=c;m<=n;m+=g)p=Math.min(m+g-1,n),k.children.push(this.ag(a,m,p,f-1));d(k,this.ib);return k},ej:function(a,c,d,e){for(var f,g,h,m,n,p,q,r;;){e.push(c);if(c.Ja||e.length-1===d)break;q=r=Infinity;f=0;for(g=c.children.length;f<g;f++)h=c.children[f],n=k(h.bbox),p=h.bbox,p=(Math.max(p[2],a[2])-Math.min(p[0],a[0]))*(Math.max(p[3],a[3])- +Math.min(p[1],a[1]))-n,p<r?(r=p,q=n<q?n:q,m=h):p===r&&n<q&&(q=n,m=h);c=m||c.children[0]}return c},cg:function(a,c,d){var e=this.ib;d=d?a.bbox:e(a);var e=[],g=this.ej(d,this.data,c,e);g.children.push(a);for(f(g.bbox,d);0<=c;)if(e[c].children.length>this.Pe)this.nj(e,c),c--;else break;this.bj(d,e,c)},nj:function(a,c){var e=a[c],f=e.children.length,g=this.dg;this.cj(e,g,f);f=this.dj(e,g,f);f={children:e.children.splice(f,e.children.length-f),height:e.height,bbox:null,Ja:!1};e.Ja&&(f.Ja=!0);d(e,this.ib); +d(f,this.ib);c?a[c-1].children.push(f):this.fg(e,f)},fg:function(a,c){this.data={children:[a,c],height:a.height+1,bbox:null,Ja:!1};d(this.data,this.ib)},dj:function(a,c,d){var f,g,h,m,n,p,q;n=p=Infinity;for(f=c;f<=d-c;f++)g=e(a,0,f,this.ib),h=e(a,f,d,this.ib),m=Math.max(0,Math.min(g[2],h[2])-Math.max(g[0],h[0]))*Math.max(0,Math.min(g[3],h[3])-Math.max(g[1],h[1])),g=k(g)+k(h),m<n?(n=m,q=f,p=g<p?g:p):m===n&&g<p&&(p=g,q=f);return q},cj:function(a,c,d){var e=a.Ja?this.Re:g,f=a.Ja?this.Se:h,k=this.$f(a, +c,d,e);c=this.$f(a,c,d,f);k<c&&a.children.sort(e)},$f:function(a,c,d,g){a.children.sort(g);g=this.ib;var h=e(a,0,c,g),k=e(a,d-c,d,g),n=m(h)+m(k),p,q;for(p=c;p<d-c;p++)q=a.children[p],f(h,a.Ja?g(q):q.bbox),n+=m(h);for(p=d-c-1;p>=c;p--)q=a.children[p],f(k,a.Ja?g(q):q.bbox),n+=m(k);return n},bj:function(a,c,d){for(;0<=d;d--)f(c[d].bbox,a)},fj:function(a){for(var c=a.length-1,e;0<=c;c--)0===a[c].children.length?0<c?(e=a[c-1].children,e.splice(e.indexOf(a[c]),1)):this.clear():d(a[c],this.ib)},hj:function(a){var c= +["return a"," - b",";"];this.Re=new Function("a","b",c.join(a[0]));this.Se=new Function("a","b",c.join(a[1]));this.ib=new Function("a","return [a"+a.join(", a")+"];")}};"undefined"!==typeof a?a.ha=c:"undefined"!==typeof self?self.b=c:window.b=c})();Yl=a.ha})();function bm(a){this.a=Yl(a);this.b={}}l=bm.prototype;l.za=function(a,c){var d=[a[0],a[1],a[2],a[3],c];this.a.za(d);this.b[w(c)]=d};l.load=function(a,c){for(var d=Array(c.length),e=0,f=c.length;e<f;e++){var g=a[e],h=c[e],g=[g[0],g[1],g[2],g[3],h];d[e]=g;this.b[w(h)]=g}this.a.load(d)};l.remove=function(a){a=w(a);var c=this.b[a];delete this.b[a];return null!==this.a.remove(c)};function cm(a,c,d){var e=w(d);ic(a.b[e].slice(0,4),c)||(a.remove(d),a.za(c,d))} +function dm(a){return a.a.all().map(function(a){return a[4]})}function em(a,c){return a.a.search(c).map(function(a){return a[4]})}l.forEach=function(a,c){return fm(dm(this),a,c)};function gm(a,c,d,e){return fm(em(a,c),d,e)}function fm(a,c,d){for(var e,f=0,g=a.length;f<g&&!(e=c.call(d,a[f]));f++);return e}l.Sa=function(){return Sa(this.b)};l.clear=function(){this.a.clear();this.b={}};l.O=function(){return this.a.data.bbox};function Q(a){a=a||{};Vf.call(this,{attributions:a.attributions,logo:a.logo,projection:void 0,state:"ready",wrapX:void 0!==a.wrapX?a.wrapX:!0});this.S=pa;this.na=a.format;this.T=a.url;void 0!==a.loader?this.S=a.loader:void 0!==this.T&&(this.S=Wl(this.T,this.na));this.pb=void 0!==a.strategy?a.strategy:Xl;var c=void 0!==a.useSpatialIndex?a.useSpatialIndex:!0;this.a=c?new bm:null;this.Y=new bm;this.i={};this.o={};this.j={};this.s={};this.c=null;var d,e;a.features instanceof we?(d=a.features,e=d.a):Array.isArray(a.features)&& +(e=a.features);c||void 0!==d||(d=new we(e));void 0!==e&&hm(this,e);void 0!==d&&im(this,d)}y(Q,Vf);l=Q.prototype;l.qb=function(a){var c=w(a).toString();if(jm(this,c,a)){km(this,c,a);var d=a.W();d?(c=d.O(),this.a&&this.a.za(c,a)):this.i[c]=a;this.b(new lm("addfeature",a))}this.u()};function km(a,c,d){a.s[c]=[C(d,"change",a.zh,a),C(d,"propertychange",a.zh,a)]}function jm(a,c,d){var e=!0,f=d.Wa();void 0!==f?f.toString()in a.o?e=!1:a.o[f.toString()]=d:a.j[c]=d;return e}l.Ec=function(a){hm(this,a);this.u()}; +function hm(a,c){var d,e,f,g,h=[],k=[],m=[];e=0;for(f=c.length;e<f;e++)g=c[e],d=w(g).toString(),jm(a,d,g)&&k.push(g);e=0;for(f=k.length;e<f;e++){g=k[e];d=w(g).toString();km(a,d,g);var n=g.W();n?(d=n.O(),h.push(d),m.push(g)):a.i[d]=g}a.a&&a.a.load(h,m);e=0;for(f=k.length;e<f;e++)a.b(new lm("addfeature",k[e]))} +function im(a,c){var d=!1;C(a,"addfeature",function(a){d||(d=!0,c.push(a.feature),d=!1)});C(a,"removefeature",function(a){d||(d=!0,c.remove(a.feature),d=!1)});C(c,"add",function(a){d||(a=a.element,d=!0,this.qb(a),d=!1)},a);C(c,"remove",function(a){d||(a=a.element,d=!0,this.kb(a),d=!1)},a);a.c=c} +l.clear=function(a){if(a){for(var c in this.s)this.s[c].forEach(Xa);this.c||(this.s={},this.o={},this.j={})}else if(this.a){this.a.forEach(this.Of,this);for(var d in this.i)this.Of(this.i[d])}this.c&&this.c.clear();this.a&&this.a.clear();this.Y.clear();this.i={};this.b(new lm("clear"));this.u()};l.sg=function(a,c){if(this.a)return this.a.forEach(a,c);if(this.c)return this.c.forEach(a,c)};function mm(a,c,d){a.tb([c[0],c[1],c[0],c[1]],function(a){if(a.W().og(c))return d.call(void 0,a)})} +l.tb=function(a,c,d){if(this.a)return gm(this.a,a,c,d);if(this.c)return this.c.forEach(c,d)};l.tg=function(a,c,d){return this.tb(a,function(e){if(e.W().Ia(a)&&(e=c.call(d,e)))return e})};l.Ag=function(){return this.c};l.je=function(){var a;this.c?a=this.c.a:this.a&&(a=dm(this.a),Sa(this.i)||xb(a,Ra(this.i)));return a};l.zg=function(a){var c=[];mm(this,a,function(a){c.push(a)});return c};l.af=function(a){return em(this.a,a)}; +l.vg=function(a,c){var d=a[0],e=a[1],f=null,g=[NaN,NaN],h=Infinity,k=[-Infinity,-Infinity,Infinity,Infinity],m=c?c:Ac;gm(this.a,k,function(a){if(m(a)){var c=a.W(),q=h;h=c.rb(d,e,g,h);h<q&&(f=a,a=Math.sqrt(h),k[0]=d-a,k[1]=e-a,k[2]=d+a,k[3]=e+a)}});return f};l.O=function(){return this.a.O()};l.yg=function(a){a=this.o[a.toString()];return void 0!==a?a:null};l.xh=function(){return this.na};l.yh=function(){return this.T}; +l.zh=function(a){a=a.target;var c=w(a).toString(),d=a.W();d?(d=d.O(),c in this.i?(delete this.i[c],this.a&&this.a.za(d,a)):this.a&&cm(this.a,d,a)):c in this.i||(this.a&&this.a.remove(a),this.i[c]=a);d=a.Wa();void 0!==d?(d=d.toString(),c in this.j?(delete this.j[c],this.o[d]=a):this.o[d]!==a&&(nm(this,a),this.o[d]=a)):c in this.j||(nm(this,a),this.j[c]=a);this.u();this.b(new lm("changefeature",a))};l.Sa=function(){return this.a.Sa()&&Sa(this.i)}; +l.Kc=function(a,c,d){var e=this.Y;a=this.pb(a,c);var f,g;f=0;for(g=a.length;f<g;++f){var h=a[f];gm(e,h,function(a){return cc(a.extent,h)})||(this.S.call(this,h,c,d),e.za(h,{extent:h.slice()}))}};l.kb=function(a){var c=w(a).toString();c in this.i?delete this.i[c]:this.a&&this.a.remove(a);this.Of(a);this.u()};l.Of=function(a){var c=w(a).toString();this.s[c].forEach(Xa);delete this.s[c];var d=a.Wa();void 0!==d?delete this.o[d.toString()]:delete this.j[c];this.b(new lm("removefeature",a))}; +function nm(a,c){for(var d in a.o)if(a.o[d]===c){delete a.o[d];break}}function lm(a,c){gb.call(this,a);this.feature=c}y(lm,gb);function om(a){this.c=a.source;this.xa=hd();this.i=Mg();this.j=[0,0];this.v=null;yl.call(this,{attributions:a.attributions,canvasFunction:this.zj.bind(this),logo:a.logo,projection:a.projection,ratio:a.ratio,resolutions:a.resolutions,state:this.c.V()});this.S=null;this.s=void 0;this.sh(a.style);C(this.c,"change",this.Zm,this)}y(om,yl);l=om.prototype; +l.zj=function(a,c,d,e,f){var g=new Vk(.5*c/d,a,c);this.c.Kc(a,c,f);var h=!1;this.c.tb(a,function(a){var e;if(!(e=h)){var f;(e=a.$b())?f=e.call(a,c):this.s&&(f=this.s(a,c));if(f){var p,q=!1;Array.isArray(f)||(f=[f]);e=0;for(p=f.length;e<p;++e)q=bl(g,a,f[e],al(c,d),this.Ym,this)||q;e=q}else e=!1}h=e},this);Wk(g);if(h)return null;this.j[0]!=e[0]||this.j[1]!=e[1]?(this.i.canvas.width=e[0],this.i.canvas.height=e[1],this.j[0]=e[0],this.j[1]=e[1]):this.i.clearRect(0,0,e[0],e[1]);a=pm(this,tc(a),c,d,e);g.Pa(this.i, +d,a,0,{});this.v=g;return this.i.canvas};l.oa=function(a,c,d,e,f){if(this.v){var g={};return this.v.oa(a,c,0,e,function(a){var c=w(a).toString();if(!(c in g))return g[c]=!0,f(a)})}};l.Vm=function(){return this.c};l.Wm=function(){return this.S};l.Xm=function(){return this.s};function pm(a,c,d,e,f){return hi(a.xa,f[0]/2,f[1]/2,e/d,-e/d,0,-c[0],-c[1])}l.Ym=function(){this.u()};l.Zm=function(){Xf(this,this.c.V())};l.sh=function(a){this.S=void 0!==a?a:nk;this.s=a?lk(this.S):void 0;this.u()};function qm(a){Bk.call(this,a);this.f=null;this.s=hd();this.o=this.c=null}y(qm,Bk);qm.prototype.oa=function(a,c,d,e){var f=this.a;return f.da().oa(a,c.viewState.resolution,c.viewState.rotation,c.skippedFeatureUids,function(a){return d.call(e,a,f)})}; +qm.prototype.xc=function(a,c,d,e){if(this.f&&this.f.a())if(this.a.da()instanceof om){if(a=a.slice(),ji(c.pixelToCoordinateMatrix,a,a),this.oa(a,c,Ac,this))return d.call(e,this.a)}else if(this.c||(this.c=hd(),nd(this.s,this.c)),c=[0,0],ji(this.c,a,c),this.o||(this.o=Mg(1,1)),this.o.clearRect(0,0,1,1),this.o.drawImage(this.f?this.f.a():null,c[0],c[1],1,1,0,0,1,1),0<this.o.getImageData(0,0,1,1).data[3])return d.call(e,this.a)}; +qm.prototype.l=function(a,c){var d=a.pixelRatio,e=a.viewState,f=e.center,g=e.resolution,h=this.a.da(),k=a.viewHints,m=a.extent;void 0!==c.extent&&(m=vc(m,c.extent));k[0]||k[1]||qc(m)||(e=h.B(m,g,d,e.projection))&&mi(this,e)&&(this.f=e);if(this.f){var e=this.f,k=e.O(),m=e.$(),n=e.f,g=d*m/(g*n);hi(this.s,d*a.size[0]/2,d*a.size[1]/2,g,g,0,n*(k[0]-f[0])/m,n*(f[1]-k[3])/m);this.c=null;oi(a.attributions,e.l);pi(a,h)}return!!this.f};function rm(a){Bk.call(this,a);this.c=Mg();this.o=null;this.j=Wb();this.S=[0,0,0];this.N=hd();this.M=0}y(rm,Bk);rm.prototype.i=function(a,c,d){var e=Ek(this,a,0);Ck(this,"precompose",d,a,e);sm(this,d,a,c);Dk(this,d,a,e)}; +rm.prototype.l=function(a,c){function d(a){a=a.V();return 2==a||4==a||3==a&&!u}var e=a.pixelRatio,f=a.viewState,g=f.projection,h=this.a,k=h.da(),m=k.fb(g),n=gg(m,f.resolution,this.M),p=m.$(n),q=f.center;p==f.resolution?(q=ri(q,p,a.size),f=uc(q,p,f.rotation,a.size)):f=a.extent;void 0!==c.extent&&(f=vc(f,c.extent));if(qc(f))return!1;p=dg(m,f,p);q={};q[n]={};var r=this.Ld(k,g,q),u=h.c(),v=Wb(),x=new qe(0,0,0,0),z,E,B,A;for(B=p.b;B<=p.a;++B)for(A=p.g;A<=p.f;++A)z=k.Wb(n,B,A,e,g),!d(z)&&z.a&&(z=z.a),d(z)? +q[n][z.ja.toString()]=z:(E=ag(m,z.ja,r,x,v),E||(z=cg(m,z.ja,x,v))&&r(n+1,z));r=Object.keys(q).map(Number);r.sort(tb);var v=[],G,x=0;for(B=r.length;x<B;++x)for(G in z=r[x],A=q[z],A)z=A[G],2==z.V()&&v.push(z);this.o=v;qi(a.usedTiles,k,n,p);si(a,k,m,e,g,f,n,h.f());ni(a,k);pi(a,k);return!0};rm.prototype.xc=function(a,c,d,e){var f=this.c.canvas,g=c.size;f.width=g[0];f.height=g[1];this.i(c,ai(this.a),this.c);if(0<this.c.getImageData(a[0],a[1],1,1).data[3])return d.call(e,this.a)}; +function sm(a,c,d,e){var f=d.pixelRatio,g=d.viewState,h=g.center,k=g.projection,m=g.resolution,g=g.rotation,n=d.size,p=Math.round(f*n[0]/2),q=Math.round(f*n[1]/2),n=f/m,r=a.a,u=r.da(),v=u.Od(k),x=u.fb(k),r=lb(r,"render"),z=c,E,B,A,G;if(g||r)z=a.c,E=z.canvas,G=gg(x,m),A=u.Ud(G,f,k),G=Uf(x.Ha(G)),A=A[0]/G[0],m=c.canvas.width*A,B=c.canvas.height*A,G=Math.round(Math.sqrt(m*m+B*B)),E.width!=G?E.width=E.height=G:z.clearRect(0,0,G,G),E=(G-m)/2/A,B=(G-B)/2/A,n*=A,p=Math.round(A*(p+E)),q=Math.round(A*(q+B)); +m=z.globalAlpha;z.globalAlpha=e.opacity;var O=a.o,L;e=u.ef(k)&&1==e.opacity;e||(O.reverse(),L=[]);for(var R=0,Wa=O.length;R<Wa;++R){var J=O[R],ua=J.ja,Ta=x.Ba(ua,a.j),kb=ua[0],Ka=lc(x.Ba(x.kd(h,kb,a.S))),ua=Math.round(rc(Ta)*n),Ia=Math.round(sc(Ta)*n),xc=Math.round((Ta[0]-Ka[0])*n/ua)*ua+p+Math.round((Ka[0]-h[0])*n),Ta=Math.round((Ka[1]-Ta[3])*n/Ia)*Ia+q+Math.round((h[1]-Ka[1])*n);if(!e){Ka=[xc,Ta,xc+ua,Ta+Ia];z.save();for(var Pc=0,qt=L.length;Pc<qt;++Pc){var Ze=L[Pc];wc(Ka,Ze)&&(z.beginPath(),z.moveTo(Ka[0], +Ka[1]),z.lineTo(Ka[0],Ka[3]),z.lineTo(Ka[2],Ka[3]),z.lineTo(Ka[2],Ka[1]),z.moveTo(Ze[0],Ze[1]),z.lineTo(Ze[2],Ze[1]),z.lineTo(Ze[2],Ze[3]),z.lineTo(Ze[0],Ze[3]),z.closePath(),z.clip())}L.push(Ka)}kb=u.Ud(kb,f,k);z.drawImage(J.ab(),v,v,kb[0],kb[1],xc,Ta,ua,Ia);e||z.restore()}r&&(f=E-p/A+p,k=B-q/A+q,h=hi(a.N,G/2-f,G/2-k,n,-n,-g,-h[0]+f/n,-h[1]-k/n),Ck(a,"render",z,d,h));(g||r)&&c.drawImage(z.canvas,-Math.round(E),-Math.round(B),G/A,G/A);z.globalAlpha=m};function tm(a){Bk.call(this,a);this.c=!1;this.M=-1;this.B=NaN;this.v=Wb();this.o=this.U=null;this.j=Mg()}y(tm,Bk); +tm.prototype.i=function(a,c,d){var e=a.extent,f=a.pixelRatio,g=c.Lc?a.skippedFeatureUids:{},h=a.viewState,k=h.projection,h=h.rotation,m=k.O(),n=this.a.da(),p=Ek(this,a,0);Ck(this,"precompose",d,a,p);var q=this.o;if(q&&!q.Sa()){var r;lb(this.a,"render")?(this.j.canvas.width=d.canvas.width,this.j.canvas.height=d.canvas.height,r=this.j):r=d;var u=r.globalAlpha;r.globalAlpha=c.opacity;c=a.size[0]*f;var v=a.size[1]*f;Zj(r,-h,c/2,v/2);q.Pa(r,f,p,h,g);if(n.N&&k.a&&!cc(m,e)){for(var k=e[0],n=rc(m),x=0;k< +m[0];)--x,p=n*x,p=Ek(this,a,p),q.Pa(r,f,p,h,g),k+=n;x=0;for(k=e[2];k>m[2];)++x,p=n*x,p=Ek(this,a,p),q.Pa(r,f,p,h,g),k-=n;p=Ek(this,a,0)}Zj(r,h,c/2,v/2);r!=d&&(Ck(this,"render",r,a,p),d.drawImage(r.canvas,0,0));r.globalAlpha=u}Dk(this,d,a,p)};tm.prototype.oa=function(a,c,d,e){if(this.o){var f=this.a,g={};return this.o.oa(a,c.viewState.resolution,c.viewState.rotation,{},function(a){var c=w(a).toString();if(!(c in g))return g[c]=!0,d.call(e,a,f)})}};tm.prototype.N=function(){li(this)}; +tm.prototype.l=function(a){function c(a){var c,e=a.$b();e?c=e.call(a,n):(e=d.i)&&(c=e(a,n));if(c){if(c){e=!1;if(Array.isArray(c))for(var f=0,g=c.length;f<g;++f)e=bl(r,a,c[f],al(n,p),this.N,this)||e;else e=bl(r,a,c,al(n,p),this.N,this)||e;a=e}else a=!1;this.c=this.c||a}}var d=this.a,e=d.da();oi(a.attributions,e.l);pi(a,e);var f=a.viewHints[0],g=a.viewHints[1],h=d.S,k=d.T;if(!this.c&&!h&&f||!k&&g)return!0;var m=a.extent,k=a.viewState,f=k.projection,n=k.resolution,p=a.pixelRatio,g=d.g,q=d.a,h=pk(d); +void 0===h&&(h=$k);m=Yb(m,q*n);q=k.projection.O();e.N&&k.projection.a&&!cc(q,a.extent)&&(a=Math.max(rc(m)/2,rc(q)),m[0]=q[0]-a,m[2]=q[2]+a);if(!this.c&&this.B==n&&this.M==g&&this.U==h&&cc(this.v,m))return!0;this.o=null;this.c=!1;var r=new Vk(.5*n/p,m,n,d.a);e.Kc(m,n,f);if(h){var u=[];e.tb(m,function(a){u.push(a)},this);u.sort(h);u.forEach(c,this)}else e.tb(m,c,this);Wk(r);this.B=n;this.M=g;this.U=h;this.v=m;this.o=r;return!0};function um(a,c){var d=/\{z\}/g,e=/\{x\}/g,f=/\{y\}/g,g=/\{-y\}/g;return function(h){if(h)return a.replace(d,h[0].toString()).replace(e,h[1].toString()).replace(f,function(){return(-h[2]-1).toString()}).replace(g,function(){var a=c.a?c.a[h[0]]:null;return(a.f-a.g+1+h[2]).toString()})}}function vm(a,c){for(var d=a.length,e=Array(d),f=0;f<d;++f)e[f]=um(a[f],c);return wm(e)}function wm(a){return 1===a.length?a[0]:function(c,d,e){if(c)return a[Ja((c[1]<<c[0])+c[2],a.length)](c,d,e)}}function xm(){} +function ym(a){var c=[],d=/\{(\d)-(\d)\}/.exec(a)||/\{([a-z])-([a-z])\}/.exec(a);if(d){var e=d[2].charCodeAt(0),f;for(f=d[1].charCodeAt(0);f<=e;++f)c.push(a.replace(d[0],String.fromCharCode(f)))}else c.push(a);return c};function zm(a){lg.call(this,{attributions:a.attributions,cacheSize:a.cacheSize,extent:a.extent,logo:a.logo,opaque:a.opaque,projection:a.projection,state:a.state,tileGrid:a.tileGrid,tilePixelRatio:a.tilePixelRatio,wrapX:a.wrapX});this.tileLoadFunction=a.tileLoadFunction;this.tileUrlFunction=this.qc?this.qc.bind(this):xm;this.urls=null;a.urls?this.Ua(a.urls):a.url&&this.Na(a.url);a.tileUrlFunction&&this.La(a.tileUrlFunction)}y(zm,lg);l=zm.prototype;l.Xa=function(){return this.tileLoadFunction}; +l.Ya=function(){return this.tileUrlFunction};l.Za=function(){return this.urls};l.wh=function(a){a=a.target;switch(a.V()){case 1:this.b(new pg("tileloadstart",a));break;case 2:this.b(new pg("tileloadend",a));break;case 3:this.b(new pg("tileloaderror",a))}};l.cb=function(a){this.a.clear();this.tileLoadFunction=a;this.u()};l.La=function(a,c){this.tileUrlFunction=a;"undefined"!==typeof c?ng(this,c):this.u()}; +l.Na=function(a){var c=this.urls=ym(a);this.La(this.qc?this.qc.bind(this):vm(c,this.tileGrid),a)};l.Ua=function(a){this.urls=a;var c=a.join("\n");this.La(this.qc?this.qc.bind(this):vm(a,this.tileGrid),c)};l.Uf=function(a,c,d){a=this.Ab(a,c,d);Lf(this.a,a)&&this.a.get(a)};function Am(a){zm.call(this,{attributions:a.attributions,cacheSize:void 0!==a.cacheSize?a.cacheSize:128,extent:a.extent,logo:a.logo,opaque:!1,projection:a.projection,state:a.state,tileGrid:a.tileGrid,tileLoadFunction:a.tileLoadFunction?a.tileLoadFunction:Bm,tileUrlFunction:a.tileUrlFunction,tilePixelRatio:a.tilePixelRatio,url:a.url,urls:a.urls,wrapX:void 0===a.wrapX?!0:a.wrapX});this.c=a.format?a.format:null;this.tileClass=a.tileClass?a.tileClass:Bl}y(Am,zm); +Am.prototype.Wb=function(a,c,d,e,f){var g=this.Ab(a,c,d);if(Lf(this.a,g))return this.a.get(g);a=[a,c,d];e=(c=og(this,a,f))?this.tileUrlFunction(c,e,f):void 0;e=new this.tileClass(a,void 0!==e?0:4,void 0!==e?e:"",this.c,this.tileLoadFunction);C(e,"change",this.wh,this);this.a.set(g,e);return e};Am.prototype.Ud=function(a,c){var d=Uf(this.tileGrid.Ha(a));return[d[0]*c,d[1]*c]};function Bm(a,c){a.fi(Vl(c,a.l))};var Cm={image:Fk,hybrid:["Polygon","LineString"]},Dm={hybrid:["Image","Text"],vector:Fk};function Em(a){rm.call(this,a);this.U=!1;this.v=hd();this.M="vector"==a.s?1:0}y(Em,rm); +Em.prototype.i=function(a,c,d){var e=Ek(this,a,0);Ck(this,"precompose",d,a,e);var f=this.a.s;"vector"!==f&&sm(this,d,a,c);if("image"!==f){var g=this.a,f=Dm[g.s],h=a.pixelRatio,k=c.Lc?a.skippedFeatureUids:{},m=a.viewState,n=m.center,p=m.rotation,q=a.size,m=h/m.resolution,r=g.da(),u=r.Xb(h),v=Ek(this,a,0);lb(g,"render")?(this.c.canvas.width=d.canvas.width,this.c.canvas.height=d.canvas.height,g=this.c):g=d;var x=g.globalAlpha;g.globalAlpha=c.opacity;c=this.o;var r=r.tileGrid,z,E,B,A,G,O,L,R;E=0;for(B= +c.length;E<B;++E)A=c[E],L=A.f,G=r.Ba(A.ja,this.j),z=A.ja[0],O="tile-pixels"==A.o.vb(),z=r.$(z),R=z/u,z=Math.round(h*q[0]/2),A=Math.round(h*q[1]/2),O?(G=oc(G),G=hi(this.v,z,A,m*R,m*R,p,(G[0]-n[0])/R,(n[1]-G[1])/R)):G=v,Zj(g,-p,z,A),L.td.Pa(g,h,G,p,k,f),Zj(g,p,z,A);g!=d&&(Ck(this,"render",g,a,v),d.drawImage(g.canvas,0,0));g.globalAlpha=x}Dk(this,d,a,e)}; +function Fm(a,c,d){function e(a){var c,d=a.$b();d?c=d.call(a,v):(d=f.i)&&(c=d(a,v));if(c){Array.isArray(c)||(c=[c]);var d=E,e=z;if(c){var g=!1;if(Array.isArray(c))for(var h=0,k=c.length;h<k;++h)g=bl(e,a,c[h],d,this.B,this)||g;else g=bl(e,a,c,d,this.B,this)||g;a=g}else a=!1;this.U=this.U||a;m.bd=m.bd||a}}var f=a.a,g=d.pixelRatio;d=d.viewState.projection;var h=f.g,k=pk(f)||null,m=c.f;if(m.bd||m.Xh!=h||m.Pf!=k){m.td=null;m.bd=!1;var n=f.da(),p=n.tileGrid,q=c.ja,r=c.o,u="tile-pixels"==r.vb(),v=p.$(q[0]), +x;u?(u=n=n.Xb(g),p=Uf(p.Ha(q[0])),p=[0,0,p[0]*u,p[1]*u]):(n=v,p=p.Ba(q),Zc(d,r)||(x=!0,c.rf(d)));m.bd=!1;var z=new Vk(0,p,n,f.a),E=al(n,g);c=c.c;k&&k!==m.Pf&&c.sort(k);p=0;for(q=c.length;p<q;++p)g=c[p],x&&g.W().hb(r,d),e.call(a,g);Wk(z);m.Xh=h;m.Pf=k;m.td=z;m.resolution=NaN}} +Em.prototype.oa=function(a,c,d,e){var f=c.pixelRatio,g=c.viewState.resolution;c=c.viewState.rotation;var h=this.a,k={},m=this.o,n=h.da(),p=n.tileGrid,q,r,u,v,x,z;u=0;for(v=m.length;u<v;++u)z=m[u],r=z.ja,x=n.tileGrid.Ba(r,this.j),ac(x,a)&&("tile-pixels"===z.o.vb()?(x=oc(x),g=n.Xb(f),r=p.$(r[0])/g,r=[(a[0]-x[0])/r,(x[1]-a[1])/r]):r=a,z=z.f.td,q=q||z.oa(r,g,c,{},function(a){var c=w(a).toString();if(!(c in k))return k[c]=!0,d.call(e,a,h)}));return q};Em.prototype.B=function(){li(this)}; +Em.prototype.l=function(a,c){var d=Em.ia.l.call(this,a,c);if(d)for(var e=Object.keys(a.ze||{}),f=0,g=this.o.length;f<g;++f){var h=this.o[f];Fm(this,h,a);var k=h,h=a,m=this.a,n=Cm[m.s];if(n){var p=h.pixelRatio,q=k.f,r=m.g;if(!Ab(q.oi,e)||q.Qf!==r){q.oi=e;q.Qf=r;var r=k.g,u=m.da(),v=u.tileGrid,x=k.ja[0],z=v.$(x),m=Uf(v.Ha(x)),x=v.$(x),E=x/z,B=m[0]*p*E,A=m[1]*p*E;r.canvas.width=B/E+.5;r.canvas.height=A/E+.5;r.scale(1/E,1/E);r.translate(B/2,A/2);E="tile-pixels"==k.o.vb();z=p/z;u=u.Xb(p);x/=u;k=v.Ba(k.ja, +this.j);v=void 0;E?v=hi(this.v,0,0,z*x,z*x,0,-m[0]*u/2,-m[1]*u/2):(k=tc(k),v=hi(this.v,0,0,z,-z,0,-k[0],-k[1]));q.td.Pa(r,p,v,0,h.skippedFeatureUids||{},n)}}}return d};function Gm(a,c){yi.call(this,0,c);this.f=Mg();this.b=this.f.canvas;this.b.style.width="100%";this.b.style.height="100%";this.b.className="ol-unselectable";tf(a,this.b,0);this.a=!0;this.c=hd()}y(Gm,yi);Gm.prototype.Te=function(a){return a instanceof Uj?new qm(a):a instanceof Vj?new rm(a):a instanceof I?new Em(a):a instanceof H?new tm(a):null}; +function Hm(a,c,d){var e=a.i,f=a.f;if(lb(e,c)){var g=d.extent,h=d.pixelRatio,k=d.viewState.rotation,m=d.pixelRatio,n=d.viewState,p=n.resolution;a=hi(a.c,a.b.width/2,a.b.height/2,m/p,-m/p,-n.rotation,-n.center[0],-n.center[1]);g=new qk(f,h,g,a,k);e.b(new ci(c,e,g,d,f,null))}}Gm.prototype.X=function(){return"canvas"}; +Gm.prototype.xe=function(a){if(a){var c=this.f,d=a.pixelRatio,e=Math.round(a.size[0]*d),d=Math.round(a.size[1]*d);this.b.width!=e||this.b.height!=d?(this.b.width=e,this.b.height=d):c.clearRect(0,0,e,d);var f=a.viewState.rotation;zi(a);Hm(this,"precompose",a);var g=a.layerStatesArray;Bb(g);Zj(c,f,e/2,d/2);var h=a.viewState.resolution,k,m,n,p;k=0;for(m=g.length;k<m;++k)p=g[k],n=p.layer,n=Bi(this,n),ei(p,h)&&"ready"==p.R&&n.l(a,p)&&n.i(a,p,c);Zj(c,-f,e/2,d/2);Hm(this,"postcompose",a);this.a||(Cf(this.b, +!0),this.a=!0);Ci(this,a);a.postRenderFunctions.push(Ai)}else this.a&&(Cf(this.b,!1),this.a=!1)};function Im(a,c){ki.call(this,a);this.target=c}y(Im,ki);Im.prototype.Id=pa;Im.prototype.oh=pa;function Jm(a){var c=document.createElement("DIV");c.style.position="absolute";Im.call(this,a,c);this.f=null;this.c=jd()}y(Jm,Im);Jm.prototype.oa=function(a,c,d,e){var f=this.a;return f.da().oa(a,c.viewState.resolution,c.viewState.rotation,c.skippedFeatureUids,function(a){return d.call(e,a,f)})};Jm.prototype.Id=function(){sf(this.target);this.f=null}; +Jm.prototype.uf=function(a,c){var d=a.viewState,e=d.center,f=d.resolution,g=d.rotation,h=this.f,k=this.a.da(),m=a.viewHints,n=a.extent;void 0!==c.extent&&(n=vc(n,c.extent));m[0]||m[1]||qc(n)||(d=k.B(n,f,a.pixelRatio,d.projection))&&mi(this,d)&&(h=d);h&&(m=h.O(),n=h.$(),d=hd(),hi(d,a.size[0]/2,a.size[1]/2,n/f,n/f,g,(m[0]-e[0])/n,(e[1]-m[3])/n),h!=this.f&&(e=h.a(this),e.style.maxWidth="none",e.style.position="absolute",sf(this.target),this.target.appendChild(e),this.f=h),ii(d,this.c)||(Qg(this.target, +d),kd(this.c,d)),oi(a.attributions,h.l),pi(a,k));return!0};function Km(a){var c=document.createElement("DIV");c.style.position="absolute";Im.call(this,a,c);this.c=!0;this.l=1;this.i=0;this.f={}}y(Km,Im);Km.prototype.Id=function(){sf(this.target);this.i=0}; +Km.prototype.uf=function(a,c){if(!c.visible)return this.c&&(Cf(this.target,!1),this.c=!1),!0;var d=a.pixelRatio,e=a.viewState,f=e.projection,g=this.a,h=g.da(),k=h.fb(f),m=h.Od(f),n=gg(k,e.resolution),p=k.$(n),q=e.center,r;p==e.resolution?(q=ri(q,p,a.size),r=uc(q,p,e.rotation,a.size)):r=a.extent;void 0!==c.extent&&(r=vc(r,c.extent));var p=dg(k,r,p),u={};u[n]={};var v=this.Ld(h,f,u),x=g.c(),z=Wb(),E=new qe(0,0,0,0),B,A,G,O;for(G=p.b;G<=p.a;++G)for(O=p.g;O<=p.f;++O)B=h.Wb(n,G,O,d,f),A=B.V(),A=2==A|| +4==A||3==A&&!x,!A&&B.a&&(B=B.a),A=B.V(),2==A?u[n][B.ja.toString()]=B:4==A||3==A&&!x||(A=ag(k,B.ja,v,E,z),A||(B=cg(k,B.ja,E,z))&&v(n+1,B));var L;if(this.i!=h.g){for(L in this.f)x=this.f[+L],uf(x.target);this.f={};this.i=h.g}z=Object.keys(u).map(Number);z.sort(tb);var v={},R;G=0;for(O=z.length;G<O;++G){L=z[G];L in this.f?x=this.f[L]:(x=k.kd(q,L),x=new Lm(k,x),v[L]=!0,this.f[L]=x);L=u[L];for(R in L){B=x;A=L[R];var Wa=m,J=A.ja,ua=J[0],Ta=J[1],kb=J[2],J=J.toString();if(!(J in B.a)){var ua=Uf(B.c.Ha(ua), +B.o),Ka=A.ab(B),Ia=Ka.style;Ia.maxWidth="none";var xc=void 0,Pc=void 0;0<Wa?(xc=document.createElement("DIV"),Pc=xc.style,Pc.overflow="hidden",Pc.width=ua[0]+"px",Pc.height=ua[1]+"px",Ia.position="absolute",Ia.left=-Wa+"px",Ia.top=-Wa+"px",Ia.width=ua[0]+2*Wa+"px",Ia.height=ua[1]+2*Wa+"px",xc.appendChild(Ka)):(Ia.width=ua[0]+"px",Ia.height=ua[1]+"px",xc=Ka,Pc=Ia);Pc.position="absolute";Pc.left=(Ta-B.g[1])*ua[0]+"px";Pc.top=(B.g[2]-kb)*ua[1]+"px";B.b||(B.b=document.createDocumentFragment());B.b.appendChild(xc); +B.a[J]=A}}x.b&&(x.target.appendChild(x.b),x.b=null)}m=Object.keys(this.f).map(Number);m.sort(tb);G=hd();R=0;for(z=m.length;R<z;++R)if(L=m[R],x=this.f[L],L in u)if(B=x.$(),O=x.Fa(),hi(G,a.size[0]/2,a.size[1]/2,B/e.resolution,B/e.resolution,e.rotation,(O[0]-q[0])/B,(q[1]-O[1])/B),x.setTransform(G),L in v){for(--L;0<=L;--L)if(L in this.f){O=this.f[L].target;O.parentNode&&O.parentNode.insertBefore(x.target,O.nextSibling);break}0>L&&tf(this.target,x.target,0)}else{if(!a.viewHints[0]&&!a.viewHints[1]){A= +bg(x.c,r,x.g[0],E);L=[];B=O=void 0;for(B in x.a)O=x.a[B],A.contains(O.ja)||L.push(O);Wa=A=void 0;A=0;for(Wa=L.length;A<Wa;++A)O=L[A],B=O.ja.toString(),uf(O.ab(x)),delete x.a[B]}}else uf(x.target),delete this.f[L];c.opacity!=this.l&&(this.l=this.target.style.opacity=c.opacity);c.visible&&!this.c&&(Cf(this.target,!0),this.c=!0);qi(a.usedTiles,h,n,p);si(a,h,k,d,f,r,n,g.f());ni(a,h);pi(a,h);return!0}; +function Lm(a,c){this.target=document.createElement("DIV");this.target.style.position="absolute";this.target.style.width="100%";this.target.style.height="100%";this.c=a;this.g=c;this.i=oc(a.Ba(c));this.l=a.$(c[0]);this.a={};this.b=null;this.f=jd();this.o=[0,0]}Lm.prototype.Fa=function(){return this.i};Lm.prototype.$=function(){return this.l};Lm.prototype.setTransform=function(a){ii(a,this.f)||(Qg(this.target,a),kd(this.f,a))};function Mm(a){this.i=Mg();var c=this.i.canvas;c.style.maxWidth="none";c.style.position="absolute";Im.call(this,a,c);this.f=!1;this.l=-1;this.s=NaN;this.o=Wb();this.c=this.j=null;this.U=hd();this.v=hd()}y(Mm,Im);l=Mm.prototype;l.Id=function(){var a=this.i.canvas;a.width=a.width;this.l=0}; +l.oh=function(a,c){var d=a.viewState,e=d.center,f=d.rotation,g=d.resolution,d=a.pixelRatio,h=a.size[0],k=a.size[1],m=h*d,n=k*d,e=hi(this.U,d*h/2,d*k/2,d/g,-d/g,-f,-e[0],-e[1]),g=this.i;g.canvas.width=m;g.canvas.height=n;h=hi(this.v,0,0,1/d,1/d,0,-(m-h)/2*d,-(n-k)/2*d);Qg(g.canvas,h);Nm(this,"precompose",a,e);(h=this.c)&&!h.Sa()&&(g.globalAlpha=c.opacity,h.Pa(g,d,e,f,c.Lc?a.skippedFeatureUids:{}),Nm(this,"render",a,e));Nm(this,"postcompose",a,e)}; +function Nm(a,c,d,e){var f=a.i;a=a.a;lb(a,c)&&(e=new qk(f,d.pixelRatio,d.extent,e,d.viewState.rotation),a.b(new ci(c,a,e,d,f,null)))}l.oa=function(a,c,d,e){if(this.c){var f=this.a,g={};return this.c.oa(a,c.viewState.resolution,c.viewState.rotation,{},function(a){var c=w(a).toString();if(!(c in g))return g[c]=!0,d.call(e,a,f)})}};l.ph=function(){li(this)}; +l.uf=function(a){function c(a){var c,e=a.$b();e?c=e.call(a,m):(e=d.i)&&(c=e(a,m));if(c){if(c){e=!1;if(Array.isArray(c))for(var f=0,g=c.length;f<g;++f)e=bl(p,a,c[f],al(m,n),this.ph,this)||e;else e=bl(p,a,c,al(m,n),this.ph,this)||e;a=e}else a=!1;this.f=this.f||a}}var d=this.a,e=d.da();oi(a.attributions,e.l);pi(a,e);var f=a.viewHints[0],g=a.viewHints[1],h=d.S,k=d.T;if(!this.f&&!h&&f||!k&&g)return!0;var g=a.extent,h=a.viewState,f=h.projection,m=h.resolution,n=a.pixelRatio;a=d.g;k=d.a;h=pk(d);void 0=== +h&&(h=$k);g=Yb(g,k*m);if(!this.f&&this.s==m&&this.l==a&&this.j==h&&cc(this.o,g))return!0;this.c=null;this.f=!1;var p=new Vk(.5*m/n,g,m,d.a);e.Kc(g,m,f);if(h){var q=[];e.tb(g,function(a){q.push(a)},this);q.sort(h);q.forEach(c,this)}else e.tb(g,c,this);Wk(p);this.s=m;this.l=a;this.j=h;this.o=g;this.c=p;return!0};function Om(a,c){yi.call(this,0,c);this.f=Mg();var d=this.f.canvas;d.style.position="absolute";d.style.width="100%";d.style.height="100%";d.className="ol-unselectable";tf(a,d,0);this.c=hd();this.b=document.createElement("DIV");this.b.className="ol-unselectable";d=this.b.style;d.position="absolute";d.width="100%";d.height="100%";C(this.b,"touchstart",ib);tf(a,this.b,0);this.a=!0}y(Om,yi);Om.prototype.fa=function(){uf(this.b);Om.ia.fa.call(this)}; +Om.prototype.Te=function(a){if(a instanceof Uj)a=new Jm(a);else if(a instanceof Vj)a=new Km(a);else if(a instanceof H)a=new Mm(a);else return null;return a};function Pm(a,c,d){var e=a.i;if(lb(e,c)){var f=d.extent,g=d.pixelRatio,h=d.viewState,k=h.rotation,m=a.f,n=m.canvas;hi(a.c,n.width/2,n.height/2,g/h.resolution,-g/h.resolution,-h.rotation,-h.center[0],-h.center[1]);a=new qk(m,g,f,a.c,k);e.b(new ci(c,e,a,d,m,null))}}Om.prototype.X=function(){return"dom"}; +Om.prototype.xe=function(a){if(a){var c=this.i;if(lb(c,"precompose")||lb(c,"postcompose")){var c=this.f.canvas,d=a.pixelRatio;c.width=a.size[0]*d;c.height=a.size[1]*d}Pm(this,"precompose",a);c=a.layerStatesArray;Bb(c);var d=a.viewState.resolution,e,f,g,h;e=0;for(f=c.length;e<f;++e)h=c[e],g=h.layer,g=Bi(this,g),tf(this.b,g.target,e),ei(h,d)&&"ready"==h.R?g.uf(a,h)&&g.oh(a,h):g.Id();var c=a.layerStates,k;for(k in this.g)k in c||(g=this.g[k],uf(g.target));this.a||(Cf(this.b,!0),this.a=!0);zi(a);Ci(this, +a);a.postRenderFunctions.push(Ai);Pm(this,"postcompose",a)}else this.a&&(Cf(this.b,!1),this.a=!1)};function Qm(a){this.b=a}function Rm(a){this.b=a}y(Rm,Qm);Rm.prototype.X=function(){return 35632};function Sm(a){this.b=a}y(Sm,Qm);Sm.prototype.X=function(){return 35633};function Tm(){this.b="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;}"}y(Tm,Rm);ba(Tm); +function Um(){this.b="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.);gl_Position=h*vec4(c,0.,1.)+offsets;a=d;b=f;}"}y(Um,Sm);ba(Um); +function Vm(a,c){this.o=a.getUniformLocation(c,"j");this.j=a.getUniformLocation(c,"i");this.i=a.getUniformLocation(c,"k");this.l=a.getUniformLocation(c,"h");this.b=a.getAttribLocation(c,"e");this.a=a.getAttribLocation(c,"f");this.f=a.getAttribLocation(c,"c");this.g=a.getAttribLocation(c,"g");this.c=a.getAttribLocation(c,"d")};function Wm(a){this.b=void 0!==a?a:[]};function Xm(a,c){this.l=a;this.b=c;this.a={};this.c={};this.f={};this.j=this.s=this.i=this.o=null;(this.g=ub(oa,"OES_element_index_uint"))&&c.getExtension("OES_element_index_uint");C(this.l,"webglcontextlost",this.Vn,this);C(this.l,"webglcontextrestored",this.Wn,this)}y(Xm,eb); +function Ym(a,c,d){var e=a.b,f=d.b,g=String(w(d));if(g in a.a)e.bindBuffer(c,a.a[g].buffer);else{var h=e.createBuffer();e.bindBuffer(c,h);var k;34962==c?k=new Float32Array(f):34963==c&&(k=a.g?new Uint32Array(f):new Uint16Array(f));e.bufferData(c,k,35044);a.a[g]={Eb:d,buffer:h}}}function Zm(a,c){var d=a.b,e=String(w(c)),f=a.a[e];d.isContextLost()||d.deleteBuffer(f.buffer);delete a.a[e]}l=Xm.prototype; +l.fa=function(){db(this.l);var a=this.b;if(!a.isContextLost()){for(var c in this.a)a.deleteBuffer(this.a[c].buffer);for(c in this.f)a.deleteProgram(this.f[c]);for(c in this.c)a.deleteShader(this.c[c]);a.deleteFramebuffer(this.i);a.deleteRenderbuffer(this.j);a.deleteTexture(this.s)}};l.Un=function(){return this.b}; +function $m(a){if(!a.i){var c=a.b,d=c.createFramebuffer();c.bindFramebuffer(c.FRAMEBUFFER,d);var e=an(c,1,1),f=c.createRenderbuffer();c.bindRenderbuffer(c.RENDERBUFFER,f);c.renderbufferStorage(c.RENDERBUFFER,c.DEPTH_COMPONENT16,1,1);c.framebufferTexture2D(c.FRAMEBUFFER,c.COLOR_ATTACHMENT0,c.TEXTURE_2D,e,0);c.framebufferRenderbuffer(c.FRAMEBUFFER,c.DEPTH_ATTACHMENT,c.RENDERBUFFER,f);c.bindTexture(c.TEXTURE_2D,null);c.bindRenderbuffer(c.RENDERBUFFER,null);c.bindFramebuffer(c.FRAMEBUFFER,null);a.i=d; +a.s=e;a.j=f}return a.i}function bn(a,c){var d=String(w(c));if(d in a.c)return a.c[d];var e=a.b,f=e.createShader(c.X());e.shaderSource(f,c.b);e.compileShader(f);return a.c[d]=f}function cn(a,c,d){var e=w(c)+"/"+w(d);if(e in a.f)return a.f[e];var f=a.b,g=f.createProgram();f.attachShader(g,bn(a,c));f.attachShader(g,bn(a,d));f.linkProgram(g);return a.f[e]=g}l.Vn=function(){Qa(this.a);Qa(this.c);Qa(this.f);this.j=this.s=this.i=this.o=null};l.Wn=function(){}; +l.re=function(a){if(a==this.o)return!1;this.b.useProgram(a);this.o=a;return!0};function dn(a,c,d){var e=a.createTexture();a.bindTexture(a.TEXTURE_2D,e);a.texParameteri(a.TEXTURE_2D,a.TEXTURE_MAG_FILTER,a.LINEAR);a.texParameteri(a.TEXTURE_2D,a.TEXTURE_MIN_FILTER,a.LINEAR);void 0!==c&&a.texParameteri(3553,10242,c);void 0!==d&&a.texParameteri(3553,10243,d);return e}function an(a,c,d){var e=dn(a,void 0,void 0);a.texImage2D(a.TEXTURE_2D,0,a.RGBA,c,d,0,a.RGBA,a.UNSIGNED_BYTE,null);return e} +function en(a,c){var d=dn(a,33071,33071);a.texImage2D(a.TEXTURE_2D,0,a.RGBA,a.RGBA,a.UNSIGNED_BYTE,c);return d};function fn(a,c){this.M=this.B=void 0;this.j=tc(c);this.U=[];this.i=[];this.R=void 0;this.c=[];this.f=[];this.ya=this.va=void 0;this.a=[];this.N=this.o=null;this.S=void 0;this.ta=jd();this.xa=jd();this.Y=this.T=void 0;this.Ra=jd();this.wa=this.ea=this.Qa=void 0;this.Cb=[];this.l=[];this.b=[];this.v=null;this.g=[];this.s=[];this.na=void 0}y(fn,bi); +function gn(a,c){var d=a.v,e=a.o,f=a.Cb,g=a.l,h=c.b;return function(){if(!h.isContextLost()){var a,m;a=0;for(m=f.length;a<m;++a)h.deleteTexture(f[a]);a=0;for(m=g.length;a<m;++a)h.deleteTexture(g[a])}Zm(c,d);Zm(c,e)}} +function hn(a,c,d,e){var f=a.B,g=a.M,h=a.R,k=a.va,m=a.ya,n=a.S,p=a.T,q=a.Y,r=a.Qa?1:0,u=a.ea,v=a.wa,x=a.na,z=Math.cos(u),u=Math.sin(u),E=a.a.length,B=a.b.length,A,G,O,L,R,Wa;for(A=0;A<d;A+=e)R=c[A]-a.j[0],Wa=c[A+1]-a.j[1],G=B/8,O=-v*f,L=-v*(h-g),a.b[B++]=R,a.b[B++]=Wa,a.b[B++]=O*z-L*u,a.b[B++]=O*u+L*z,a.b[B++]=p/m,a.b[B++]=(q+h)/k,a.b[B++]=n,a.b[B++]=r,O=v*(x-f),L=-v*(h-g),a.b[B++]=R,a.b[B++]=Wa,a.b[B++]=O*z-L*u,a.b[B++]=O*u+L*z,a.b[B++]=(p+x)/m,a.b[B++]=(q+h)/k,a.b[B++]=n,a.b[B++]=r,O=v*(x-f),L= +v*g,a.b[B++]=R,a.b[B++]=Wa,a.b[B++]=O*z-L*u,a.b[B++]=O*u+L*z,a.b[B++]=(p+x)/m,a.b[B++]=q/k,a.b[B++]=n,a.b[B++]=r,O=-v*f,L=v*g,a.b[B++]=R,a.b[B++]=Wa,a.b[B++]=O*z-L*u,a.b[B++]=O*u+L*z,a.b[B++]=p/m,a.b[B++]=q/k,a.b[B++]=n,a.b[B++]=r,a.a[E++]=G,a.a[E++]=G+1,a.a[E++]=G+2,a.a[E++]=G,a.a[E++]=G+2,a.a[E++]=G+3}fn.prototype.oc=function(a,c){this.g.push(this.a.length);this.s.push(c);var d=a.ga();hn(this,d,d.length,a.ua())}; +fn.prototype.pc=function(a,c){this.g.push(this.a.length);this.s.push(c);var d=a.ga();hn(this,d,d.length,a.ua())};function jn(a,c){var d=c.b;a.U.push(a.a.length);a.i.push(a.a.length);a.v=new Wm(a.b);Ym(c,34962,a.v);a.o=new Wm(a.a);Ym(c,34963,a.o);var e={};kn(a.Cb,a.c,e,d);kn(a.l,a.f,e,d);a.B=void 0;a.M=void 0;a.R=void 0;a.c=null;a.f=null;a.va=void 0;a.ya=void 0;a.a=null;a.S=void 0;a.T=void 0;a.Y=void 0;a.Qa=void 0;a.ea=void 0;a.wa=void 0;a.b=null;a.na=void 0} +function kn(a,c,d,e){var f,g,h,k=c.length;for(h=0;h<k;++h)f=c[h],g=w(f).toString(),g in d?f=d[g]:(f=en(e,f),d[g]=f),a[h]=f} +fn.prototype.Pa=function(a,c,d,e,f,g,h,k,m,n,p){g=a.b;Ym(a,34962,this.v);Ym(a,34963,this.o);var q=Tm.Ub(),r=Um.Ub(),r=cn(a,q,r);this.N?q=this.N:this.N=q=new Vm(g,r);a.re(r);g.enableVertexAttribArray(q.f);g.vertexAttribPointer(q.f,2,5126,!1,32,0);g.enableVertexAttribArray(q.b);g.vertexAttribPointer(q.b,2,5126,!1,32,8);g.enableVertexAttribArray(q.c);g.vertexAttribPointer(q.c,2,5126,!1,32,16);g.enableVertexAttribArray(q.a);g.vertexAttribPointer(q.a,1,5126,!1,32,24);g.enableVertexAttribArray(q.g);g.vertexAttribPointer(q.g, +1,5126,!1,32,28);r=this.Ra;hi(r,0,0,2/(d*f[0]),2/(d*f[1]),-e,-(c[0]-this.j[0]),-(c[1]-this.j[1]));c=this.xa;d=2/f[0];f=2/f[1];ld(c);c[0]=d;c[5]=f;c[10]=1;c[15]=1;f=this.ta;ld(f);0!==e&&qd(f,-e);g.uniformMatrix4fv(q.l,!1,r);g.uniformMatrix4fv(q.j,!1,c);g.uniformMatrix4fv(q.o,!1,f);g.uniform1f(q.i,h);var u;if(void 0===m)ln(this,g,a,k,this.Cb,this.U);else{if(n)a:{e=a.g?5125:5123;a=a.g?4:2;f=this.g.length-1;for(h=this.l.length-1;0<=h;--h)for(g.bindTexture(3553,this.l[h]),n=0<h?this.i[h-1]:0,c=this.i[h];0<= +f&&this.g[f]>=n;){u=this.g[f];d=this.s[f];r=w(d).toString();if(void 0===k[r]&&d.W()&&(void 0===p||wc(p,d.W().O()))&&(g.clear(g.COLOR_BUFFER_BIT|g.DEPTH_BUFFER_BIT),g.drawElements(4,c-u,e,u*a),c=m(d))){k=c;break a}c=u;f--}k=void 0}else g.clear(g.COLOR_BUFFER_BIT|g.DEPTH_BUFFER_BIT),ln(this,g,a,k,this.l,this.i),k=(k=m(null))?k:void 0;u=k}g.disableVertexAttribArray(q.f);g.disableVertexAttribArray(q.b);g.disableVertexAttribArray(q.c);g.disableVertexAttribArray(q.a);g.disableVertexAttribArray(q.g);return u}; +function ln(a,c,d,e,f,g){var h=d.g?5125:5123;d=d.g?4:2;if(Sa(e)){var k;a=0;e=f.length;for(k=0;a<e;++a){c.bindTexture(3553,f[a]);var m=g[a];c.drawElements(4,m-k,h,k*d);k=m}}else{k=0;var n,m=0;for(n=f.length;m<n;++m){c.bindTexture(3553,f[m]);for(var p=0<m?g[m-1]:0,q=g[m],r=p;k<a.g.length&&a.g[k]<=q;){var u=w(a.s[k]).toString();void 0!==e[u]?(r!==p&&c.drawElements(4,p-r,h,r*d),p=r=k===a.g.length-1?q:a.g[k+1]):p=k===a.g.length-1?q:a.g[k+1];k++}r!==p&&c.drawElements(4,p-r,h,r*d)}}} +fn.prototype.Pb=function(a){var c=a.Tb(),d=a.ec(1),e=a.fd(),f=a.ke(1),g=a.v,h=a.Fa(),k=a.U,m=a.j,n=a.Bb();a=a.i;var p;0===this.c.length?this.c.push(d):(p=this.c[this.c.length-1],w(p)!=w(d)&&(this.U.push(this.a.length),this.c.push(d)));0===this.f.length?this.f.push(f):(p=this.f[this.f.length-1],w(p)!=w(f)&&(this.i.push(this.a.length),this.f.push(f)));this.B=c[0];this.M=c[1];this.R=n[1];this.va=e[1];this.ya=e[0];this.S=g;this.T=h[0];this.Y=h[1];this.ea=m;this.Qa=k;this.wa=a;this.na=n[0]}; +function mn(a,c,d){this.f=c;this.c=a;this.g=d;this.a={}}function nn(a,c){var d=[],e;for(e in a.a)d.push(gn(a.a[e],c));return function(){for(var a=d.length,c,e=0;e<a;e++)c=d[e].apply(this,arguments);return c}}function on(a,c){for(var d in a.a)jn(a.a[d],c)}mn.prototype.b=function(a,c){var d=this.a[c];void 0===d&&(d=new pn[c](this.c,this.f),this.a[c]=d);return d};mn.prototype.Sa=function(){return Sa(this.a)}; +mn.prototype.Pa=function(a,c,d,e,f,g,h,k){var m,n,p;m=0;for(n=Fk.length;m<n;++m)p=this.a[Fk[m]],void 0!==p&&p.Pa(a,c,d,e,f,g,h,k,void 0,!1)};function qn(a,c,d,e,f,g,h,k,m,n,p){var q=rn,r,u;for(r=Fk.length-1;0<=r;--r)if(u=a.a[Fk[r]],void 0!==u&&(u=u.Pa(c,d,e,f,q,g,h,k,m,n,p)))return u} +mn.prototype.oa=function(a,c,d,e,f,g,h,k,m,n){var p=c.b;p.bindFramebuffer(p.FRAMEBUFFER,$m(c));var q;void 0!==this.g&&(q=Yb(fc(a),e*this.g));return qn(this,c,a,e,f,h,k,m,function(a){var c=new Uint8Array(4);p.readPixels(0,0,1,1,p.RGBA,p.UNSIGNED_BYTE,c);if(0<c[3]&&(a=n(a)))return a},!0,q)}; +function sn(a,c,d,e,f,g,h,k){var m=d.b;m.bindFramebuffer(m.FRAMEBUFFER,$m(d));return void 0!==qn(a,d,c,e,f,g,h,k,function(){var a=new Uint8Array(4);m.readPixels(0,0,1,1,m.RGBA,m.UNSIGNED_BYTE,a);return 0<a[3]},!1)}var pn={Image:fn},rn=[1,1];function tn(a,c,d,e,f,g,h){this.b=a;this.f=c;this.g=g;this.c=h;this.o=f;this.l=e;this.i=d;this.a=null}y(tn,bi);l=tn.prototype;l.md=function(a){this.Pb(a.a)};l.nc=function(a){switch(a.X()){case "Point":this.pc(a,null);break;case "MultiPoint":this.oc(a,null);break;case "GeometryCollection":this.Ve(a,null)}};l.Ue=function(a,c){var d=(0,c.g)(a);d&&wc(this.g,d.O())&&(this.md(c),this.nc(d))};l.Ve=function(a){a=a.c;var c,d;c=0;for(d=a.length;c<d;++c)this.nc(a[c])}; +l.pc=function(a,c){var d=this.b,e=(new mn(1,this.g)).b(0,"Image");e.Pb(this.a);e.pc(a,c);jn(e,d);e.Pa(this.b,this.f,this.i,this.l,this.o,this.c,1,{},void 0,!1);gn(e,d)()};l.oc=function(a,c){var d=this.b,e=(new mn(1,this.g)).b(0,"Image");e.Pb(this.a);e.oc(a,c);jn(e,d);e.Pa(this.b,this.f,this.i,this.l,this.o,this.c,1,{},void 0,!1);gn(e,d)()};l.Pb=function(a){this.a=a};function un(){this.b="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;}"}y(un,Rm);ba(un);function vn(){this.b="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;}"}y(vn,Sm);ba(vn); +function wn(a,c){this.g=a.getUniformLocation(c,"f");this.f=a.getUniformLocation(c,"e");this.i=a.getUniformLocation(c,"d");this.c=a.getUniformLocation(c,"g");this.b=a.getAttribLocation(c,"b");this.a=a.getAttribLocation(c,"c")};function xn(a,c){ki.call(this,c);this.f=a;this.S=new Wm([-1,-1,0,0,1,-1,1,0,-1,1,0,1,1,1,1,1]);this.i=this.ob=null;this.l=void 0;this.s=hd();this.U=jd();this.v=null}y(xn,ki); +function yn(a,c,d){var e=a.f.f;if(void 0===a.l||a.l!=d){c.postRenderFunctions.push(function(a,c,d){a.isContextLost()||(a.deleteFramebuffer(c),a.deleteTexture(d))}.bind(null,e,a.i,a.ob));c=an(e,d,d);var f=e.createFramebuffer();e.bindFramebuffer(36160,f);e.framebufferTexture2D(36160,36064,3553,c,0);a.ob=c;a.i=f;a.l=d}else e.bindFramebuffer(36160,a.i)} +xn.prototype.qh=function(a,c,d){zn(this,"precompose",d,a);Ym(d,34962,this.S);var e=d.b,f=un.Ub(),g=vn.Ub(),f=cn(d,f,g);this.v?g=this.v:this.v=g=new wn(e,f);d.re(f)&&(e.enableVertexAttribArray(g.b),e.vertexAttribPointer(g.b,2,5126,!1,16,0),e.enableVertexAttribArray(g.a),e.vertexAttribPointer(g.a,2,5126,!1,16,8),e.uniform1i(g.c,0));e.uniformMatrix4fv(g.i,!1,this.s);e.uniformMatrix4fv(g.f,!1,this.U);e.uniform1f(g.g,c.opacity);e.bindTexture(3553,this.ob);e.drawArrays(5,0,4);zn(this,"postcompose",d,a)}; +function zn(a,c,d,e){a=a.a;if(lb(a,c)){var f=e.viewState;a.b(new ci(c,a,new tn(d,f.center,f.resolution,f.rotation,e.size,e.extent,e.pixelRatio),e,null,d))}}xn.prototype.vf=function(){this.i=this.ob=null;this.l=void 0};function An(a,c){xn.call(this,a,c);this.j=this.o=this.c=null}y(An,xn);function Bn(a,c){var d=c.a();return en(a.f.f,d)}An.prototype.oa=function(a,c,d,e){var f=this.a;return f.da().oa(a,c.viewState.resolution,c.viewState.rotation,c.skippedFeatureUids,function(a){return d.call(e,a,f)})}; +An.prototype.wf=function(a,c){var d=this.f.f,e=a.pixelRatio,f=a.viewState,g=f.center,h=f.resolution,k=f.rotation,m=this.c,n=this.ob,p=this.a.da(),q=a.viewHints,r=a.extent;void 0!==c.extent&&(r=vc(r,c.extent));q[0]||q[1]||qc(r)||(f=p.B(r,h,e,f.projection))&&mi(this,f)&&(m=f,n=Bn(this,f),this.ob&&a.postRenderFunctions.push(function(a,c){a.isContextLost()||a.deleteTexture(c)}.bind(null,d,this.ob)));m&&(d=this.f.c.l,Cn(this,d.width,d.height,e,g,h,k,m.O()),this.j=null,e=this.s,ld(e),pd(e,1,-1),od(e,0, +-1),this.c=m,this.ob=n,oi(a.attributions,m.l),pi(a,p));return!0};function Cn(a,c,d,e,f,g,h,k){c*=g;d*=g;a=a.U;ld(a);pd(a,2*e/c,2*e/d);qd(a,-h);od(a,k[0]-f[0],k[1]-f[1]);pd(a,(k[2]-k[0])/2,(k[3]-k[1])/2);od(a,1,1)}An.prototype.ge=function(a,c){return void 0!==this.oa(a,c,Ac,this)}; +An.prototype.xc=function(a,c,d,e){if(this.c&&this.c.a())if(this.a.da()instanceof om){if(a=a.slice(),ji(c.pixelToCoordinateMatrix,a,a),this.oa(a,c,Ac,this))return d.call(e,this.a)}else{var f=[this.c.a().width,this.c.a().height];if(!this.j){var g=c.size;c=hd();ld(c);od(c,-1,-1);pd(c,2/g[0],2/g[1]);od(c,0,g[1]);pd(c,1,-1);g=hd();nd(this.U,g);var h=hd();ld(h);od(h,0,f[1]);pd(h,1,-1);pd(h,f[0]/2,f[1]/2);od(h,1,1);var k=hd();md(h,g,k);md(k,c,k);this.j=k}c=[0,0];ji(this.j,a,c);if(!(0>c[0]||c[0]>f[0]||0> +c[1]||c[1]>f[1])&&(this.o||(this.o=Mg(1,1)),this.o.clearRect(0,0,1,1),this.o.drawImage(this.c.a(),c[0],c[1],1,1,0,0,1,1),0<this.o.getImageData(0,0,1,1).data[3]))return d.call(e,this.a)}};function Dn(){this.b="precision mediump float;varying vec2 a;uniform sampler2D e;void main(void){gl_FragColor=texture2D(e,a);}"}y(Dn,Rm);ba(Dn);function En(){this.b="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;}"}y(En,Sm);ba(En);function Fn(a,c){this.g=a.getUniformLocation(c,"e");this.f=a.getUniformLocation(c,"d");this.b=a.getAttribLocation(c,"b");this.a=a.getAttribLocation(c,"c")};function Gn(a,c){xn.call(this,a,c);this.N=Dn.Ub();this.T=En.Ub();this.c=null;this.M=new Wm([0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,0]);this.B=this.o=null;this.j=-1;this.R=[0,0]}y(Gn,xn);l=Gn.prototype;l.fa=function(){Zm(this.f.c,this.M);Gn.ia.fa.call(this)};l.Ld=function(a,c,d){var e=this.f;return function(f,g){return mg(a,c,f,g,function(a){var c=Lf(e.a,a.gb());c&&(d[f]||(d[f]={}),d[f][a.ja.toString()]=a);return c})}};l.vf=function(){Gn.ia.vf.call(this);this.c=null}; +l.wf=function(a,c,d){var e=this.f,f=d.b,g=a.viewState,h=g.projection,k=this.a,m=k.da(),n=m.fb(h),p=gg(n,g.resolution),q=n.$(p),r=m.Ud(p,a.pixelRatio,h),u=r[0]/Uf(n.Ha(p),this.R)[0],v=q/u,x=m.Od(h),z=g.center,E;q==g.resolution?(z=ri(z,q,a.size),E=uc(z,q,g.rotation,a.size)):E=a.extent;q=dg(n,E,q);if(this.o&&se(this.o,q)&&this.j==m.g)v=this.B;else{var B=[q.a-q.b+1,q.f-q.g+1],A=Math.pow(2,Math.ceil(Math.log(Math.max(B[0]*r[0],B[1]*r[1]))/Math.LN2)),B=v*A,G=n.Fa(p),O=G[0]+q.b*r[0]*v,v=G[1]+q.g*r[1]*v, +v=[O,v,O+B,v+B];yn(this,a,A);f.viewport(0,0,A,A);f.clearColor(0,0,0,0);f.clear(16384);f.disable(3042);A=cn(d,this.N,this.T);d.re(A);this.c||(this.c=new Fn(f,A));Ym(d,34962,this.M);f.enableVertexAttribArray(this.c.b);f.vertexAttribPointer(this.c.b,2,5126,!1,16,0);f.enableVertexAttribArray(this.c.a);f.vertexAttribPointer(this.c.a,2,5126,!1,16,8);f.uniform1i(this.c.g,0);d={};d[p]={};var L=this.Ld(m,h,d),R=k.c(),A=!0,O=Wb(),Wa=new qe(0,0,0,0),J,ua,Ta;for(ua=q.b;ua<=q.a;++ua)for(Ta=q.g;Ta<=q.f;++Ta){G= +m.Wb(p,ua,Ta,u,h);if(void 0!==c.extent&&(J=n.Ba(G.ja,O),!wc(J,c.extent)))continue;J=G.V();J=2==J||4==J||3==J&&!R;!J&&G.a&&(G=G.a);J=G.V();if(2==J){if(Lf(e.a,G.gb())){d[p][G.ja.toString()]=G;continue}}else if(4==J||3==J&&!R)continue;A=!1;J=ag(n,G.ja,L,Wa,O);J||(G=cg(n,G.ja,Wa,O))&&L(p+1,G)}c=Object.keys(d).map(Number);c.sort(tb);for(var L=new Float32Array(4),kb,Ka,Ia,R=0,Wa=c.length;R<Wa;++R)for(kb in Ka=d[c[R]],Ka)G=Ka[kb],J=n.Ba(G.ja,O),ua=2*(J[2]-J[0])/B,Ta=2*(J[3]-J[1])/B,Ia=2*(J[0]-v[0])/B-1, +J=2*(J[1]-v[1])/B-1,gd(L,ua,Ta,Ia,J),f.uniform4fv(this.c.f,L),Hn(e,G,r,x*u),f.drawArrays(5,0,4);A?(this.o=q,this.B=v,this.j=m.g):(this.B=this.o=null,this.j=-1,a.animate=!0)}qi(a.usedTiles,m,p,q);var xc=e.o;si(a,m,n,u,h,E,p,k.f(),function(a){var c;(c=2!=a.V()||Lf(e.a,a.gb()))||(c=a.gb()in xc.g);c||xc.f([a,fg(n,a.ja),n.$(a.ja[0]),r,x*u])},this);ni(a,m);pi(a,m);f=this.s;ld(f);od(f,(z[0]-v[0])/(v[2]-v[0]),(z[1]-v[1])/(v[3]-v[1]));0!==g.rotation&&qd(f,g.rotation);pd(f,a.size[0]*g.resolution/(v[2]-v[0]), +a.size[1]*g.resolution/(v[3]-v[1]));od(f,-.5,-.5);return!0};l.xc=function(a,c,d,e){if(this.i){var f=[0,0];ji(this.s,[a[0]/c.size[0],(c.size[1]-a[1])/c.size[1]],f);a=[f[0]*this.l,f[1]*this.l];c=this.f.c.b;c.bindFramebuffer(c.FRAMEBUFFER,this.i);f=new Uint8Array(4);c.readPixels(a[0],a[1],1,1,c.RGBA,c.UNSIGNED_BYTE,f);if(0<f[3])return d.call(e,this.a)}};function In(a,c){xn.call(this,a,c);this.j=!1;this.R=-1;this.N=NaN;this.B=Wb();this.o=this.c=this.M=null}y(In,xn);l=In.prototype;l.qh=function(a,c,d){this.o=c;var e=a.viewState,f=this.c;f&&!f.Sa()&&f.Pa(d,e.center,e.resolution,e.rotation,a.size,a.pixelRatio,c.opacity,c.Lc?a.skippedFeatureUids:{})};l.fa=function(){var a=this.c;a&&(nn(a,this.f.c)(),this.c=null);In.ia.fa.call(this)}; +l.oa=function(a,c,d,e){if(this.c&&this.o){var f=c.viewState,g=this.a,h={};return this.c.oa(a,this.f.c,f.center,f.resolution,f.rotation,c.size,c.pixelRatio,this.o.opacity,{},function(a){var c=w(a).toString();if(!(c in h))return h[c]=!0,d.call(e,a,g)})}};l.ge=function(a,c){if(this.c&&this.o){var d=c.viewState;return sn(this.c,a,this.f.c,d.resolution,d.rotation,c.pixelRatio,this.o.opacity,c.skippedFeatureUids)}return!1}; +l.xc=function(a,c,d,e){a=a.slice();ji(c.pixelToCoordinateMatrix,a,a);if(this.ge(a,c))return d.call(e,this.a)};l.rh=function(){li(this)}; +l.wf=function(a,c,d){function e(a){var c,d=a.$b();d?c=d.call(a,n):(d=f.i)&&(c=d(a,n));if(c){if(c){d=!1;if(Array.isArray(c))for(var e=0,g=c.length;e<g;++e)d=bl(r,a,c[e],al(n,p),this.rh,this)||d;else d=bl(r,a,c,al(n,p),this.rh,this)||d;a=d}else a=!1;this.j=this.j||a}}var f=this.a;c=f.da();oi(a.attributions,c.l);pi(a,c);var g=a.viewHints[0],h=a.viewHints[1],k=f.S,m=f.T;if(!this.j&&!k&&g||!m&&h)return!0;var h=a.extent,k=a.viewState,g=k.projection,n=k.resolution,p=a.pixelRatio,k=f.g,q=f.a,m=pk(f);void 0=== +m&&(m=$k);h=Yb(h,q*n);if(!this.j&&this.N==n&&this.R==k&&this.M==m&&cc(this.B,h))return!0;this.c&&a.postRenderFunctions.push(nn(this.c,d));this.j=!1;var r=new mn(.5*n/p,h,f.a);c.Kc(h,n,g);if(m){var u=[];c.tb(h,function(a){u.push(a)},this);u.sort(m);u.forEach(e,this)}else c.tb(h,e,this);on(r,d);this.N=n;this.R=k;this.M=m;this.B=h;this.c=r;return!0};function Jn(a,c){yi.call(this,0,c);this.b=document.createElement("CANVAS");this.b.style.width="100%";this.b.style.height="100%";this.b.className="ol-unselectable";tf(a,this.b,0);this.U=this.B=0;this.M=Mg();this.j=!0;this.f=Sg(this.b,{antialias:!0,depth:!1,failIfMajorPerformanceCaveat:!0,preserveDrawingBuffer:!1,stencil:!0});this.c=new Xm(this.b,this.f);C(this.b,"webglcontextlost",this.Jm,this);C(this.b,"webglcontextrestored",this.Km,this);this.a=new Kf;this.v=null;this.o=new Di(function(a){var c= +a[1];a=a[2];var f=c[0]-this.v[0],c=c[1]-this.v[1];return 65536*Math.log(a)+Math.sqrt(f*f+c*c)/a}.bind(this),function(a){return a[0].gb()});this.N=function(){if(!this.o.Sa()){Hi(this.o);var a=Ei(this.o);Hn(this,a[0],a[3],a[4])}return!1}.bind(this);this.l=0;Kn(this)}y(Jn,yi); +function Hn(a,c,d,e){var f=a.f,g=c.gb();if(Lf(a.a,g))a=a.a.get(g),f.bindTexture(3553,a.ob),9729!=a.Rg&&(f.texParameteri(3553,10240,9729),a.Rg=9729),9729!=a.Tg&&(f.texParameteri(3553,10240,9729),a.Tg=9729);else{var h=f.createTexture();f.bindTexture(3553,h);if(0<e){var k=a.M.canvas,m=a.M;a.B!==d[0]||a.U!==d[1]?(k.width=d[0],k.height=d[1],a.B=d[0],a.U=d[1]):m.clearRect(0,0,d[0],d[1]);m.drawImage(c.ab(),e,e,d[0],d[1],0,0,d[0],d[1]);f.texImage2D(3553,0,6408,6408,5121,k)}else f.texImage2D(3553,0,6408,6408, +5121,c.ab());f.texParameteri(3553,10240,9729);f.texParameteri(3553,10241,9729);f.texParameteri(3553,10242,33071);f.texParameteri(3553,10243,33071);a.a.set(g,{ob:h,Rg:9729,Tg:9729})}}l=Jn.prototype;l.Te=function(a){return a instanceof Uj?new An(this,a):a instanceof Vj?new Gn(this,a):a instanceof H?new In(this,a):null};function Ln(a,c,d){var e=a.i;if(lb(e,c)){a=a.c;var f=d.viewState;e.b(new ci(c,e,new tn(a,f.center,f.resolution,f.rotation,d.size,d.extent,d.pixelRatio),d,null,a))}} +l.fa=function(){var a=this.f;a.isContextLost()||this.a.forEach(function(c){c&&a.deleteTexture(c.ob)});fb(this.c);Jn.ia.fa.call(this)};l.Cj=function(a,c){for(var d=this.f,e;1024<this.a.rc()-this.l;){if(e=this.a.b.kc)d.deleteTexture(e.ob);else if(+this.a.b.Yb==c.index)break;else--this.l;this.a.pop()}};l.X=function(){return"webgl"};l.Jm=function(a){a.preventDefault();this.a.clear();this.l=0;a=this.g;for(var c in a)a[c].vf()};l.Km=function(){Kn(this);this.i.render()}; +function Kn(a){a=a.f;a.activeTexture(33984);a.blendFuncSeparate(770,771,1,771);a.disable(2884);a.disable(2929);a.disable(3089);a.disable(2960)} +l.xe=function(a){var c=this.c,d=this.f;if(d.isContextLost())return!1;if(!a)return this.j&&(Cf(this.b,!1),this.j=!1),!1;this.v=a.focus;this.a.set((-a.index).toString(),null);++this.l;Ln(this,"precompose",a);var e=[],f=a.layerStatesArray;Bb(f);var g=a.viewState.resolution,h,k,m,n;h=0;for(k=f.length;h<k;++h)n=f[h],ei(n,g)&&"ready"==n.R&&(m=Bi(this,n.layer),m.wf(a,n,c)&&e.push(n));f=a.size[0]*a.pixelRatio;g=a.size[1]*a.pixelRatio;if(this.b.width!=f||this.b.height!=g)this.b.width=f,this.b.height=g;d.bindFramebuffer(36160, +null);d.clearColor(0,0,0,0);d.clear(16384);d.enable(3042);d.viewport(0,0,this.b.width,this.b.height);h=0;for(k=e.length;h<k;++h)n=e[h],m=Bi(this,n.layer),m.qh(a,n,c);this.j||(Cf(this.b,!0),this.j=!0);zi(a);1024<this.a.rc()-this.l&&a.postRenderFunctions.push(this.Cj.bind(this));this.o.Sa()||(a.postRenderFunctions.push(this.N),a.animate=!0);Ln(this,"postcompose",a);Ci(this,a);a.postRenderFunctions.push(Ai)}; +l.oa=function(a,c,d,e,f,g){var h;if(this.f.isContextLost())return!1;var k=c.viewState,m=c.layerStatesArray,n;for(n=m.length-1;0<=n;--n){h=m[n];var p=h.layer;if(ei(h,k.resolution)&&f.call(g,p)&&(h=Bi(this,p).oa(a,c,d,e)))return h}};l.nh=function(a,c,d,e){var f=!1;if(this.f.isContextLost())return!1;var g=c.viewState,h=c.layerStatesArray,k;for(k=h.length-1;0<=k;--k){var m=h[k],n=m.layer;if(ei(m,g.resolution)&&d.call(e,n)&&(f=Bi(this,n).ge(a,c)))return!0}return f}; +l.mh=function(a,c,d,e,f){if(this.f.isContextLost())return!1;var g=c.viewState,h,k=c.layerStatesArray,m;for(m=k.length-1;0<=m;--m){h=k[m];var n=h.layer;if(ei(h,g.resolution)&&f.call(e,n)&&(h=Bi(this,n).xc(a,c,d,e)))return h}};var Mn=["canvas","webgl","dom"]; +function S(a){pb.call(this);var c=Nn(a);this.Db=void 0!==a.loadTilesWhileAnimating?a.loadTilesWhileAnimating:!1;this.Cc=void 0!==a.loadTilesWhileInteracting?a.loadTilesWhileInteracting:!1;this.Ke=void 0!==a.pixelRatio?a.pixelRatio:Yg;this.Je=c.logos;this.Y=function(){this.i=void 0;this.Oo.call(this,Date.now())}.bind(this);this.Ra=hd();this.Le=hd();this.pb=0;this.f=null;this.xa=Wb();this.N=this.S=null;this.a=document.createElement("DIV");this.a.className="ol-viewport"+(ch?" ol-touch":"");this.a.style.position= +"relative";this.a.style.overflow="hidden";this.a.style.width="100%";this.a.style.height="100%";this.a.style.msTouchAction="none";this.a.style.touchAction="none";this.B=document.createElement("DIV");this.B.className="ol-overlaycontainer";this.a.appendChild(this.B);this.v=document.createElement("DIV");this.v.className="ol-overlaycontainer-stopevent";a=["click","dblclick","mousedown","touchstart","mspointerdown",Wh,"mousewheel","wheel"];for(var d=0,e=a.length;d<e;++d)C(this.v,a[d],hb);this.a.appendChild(this.v); +this.wa=new Oh(this);for(var f in Zh)C(this.wa,Zh[f],this.Kg,this);this.ea=c.keyboardEventTarget;this.s=null;C(this.a,"wheel",this.Jc,this);C(this.a,"mousewheel",this.Jc,this);this.o=c.controls;this.l=c.interactions;this.j=c.overlays;this.yf={};this.M=new c.Qo(this.a,this);this.T=null;this.R=[];this.ta=[];this.na=new Ii(this.xk.bind(this),this.dl.bind(this));this.ze={};C(this,rb("layergroup"),this.Kk,this);C(this,rb("view"),this.el,this);C(this,rb("size"),this.al,this);C(this,rb("target"),this.cl, +this);this.C(c.values);this.o.forEach(function(a){a.setMap(this)},this);C(this.o,"add",function(a){a.element.setMap(this)},this);C(this.o,"remove",function(a){a.element.setMap(null)},this);this.l.forEach(function(a){a.setMap(this)},this);C(this.l,"add",function(a){a.element.setMap(this)},this);C(this.l,"remove",function(a){a.element.setMap(null)},this);this.j.forEach(this.ig,this);C(this.j,"add",function(a){this.ig(a.element)},this);C(this.j,"remove",function(a){var c=a.element.Wa();void 0!==c&&delete this.yf[c.toString()]; +a.element.setMap(null)},this)}y(S,pb);l=S.prototype;l.pj=function(a){this.o.push(a)};l.qj=function(a){this.l.push(a)};l.gg=function(a){this.sc().Oc().push(a)};l.hg=function(a){this.j.push(a)};l.ig=function(a){var c=a.Wa();void 0!==c&&(this.yf[c.toString()]=a);a.setMap(this)};l.Va=function(a){this.render();Array.prototype.push.apply(this.R,arguments)}; +l.fa=function(){fb(this.wa);fb(this.M);cb(this.a,"wheel",this.Jc,this);cb(this.a,"mousewheel",this.Jc,this);void 0!==this.c&&(qa.removeEventListener("resize",this.c,!1),this.c=void 0);this.i&&(qa.cancelAnimationFrame(this.i),this.i=void 0);this.$g(null);S.ia.fa.call(this)};l.ed=function(a,c,d,e,f){if(this.f)return a=this.Ma(a),this.M.oa(a,this.f,c,void 0!==d?d:null,void 0!==e?e:Ac,void 0!==f?f:null)}; +l.Pl=function(a,c,d,e,f){if(this.f)return this.M.mh(a,this.f,c,void 0!==d?d:null,void 0!==e?e:Ac,void 0!==f?f:null)};l.gl=function(a,c,d){if(!this.f)return!1;a=this.Ma(a);return this.M.nh(a,this.f,void 0!==c?c:Ac,void 0!==d?d:null)};l.Sj=function(a){return this.Ma(this.Nd(a))};l.Nd=function(a){var c=this.a.getBoundingClientRect();a=a.changedTouches?a.changedTouches[0]:a;return[a.clientX-c.left,a.clientY-c.top]};l.pf=function(){return this.get("target")}; +l.tc=function(){var a=this.pf();return void 0!==a?mf(a):null};l.Ma=function(a){var c=this.f;return c?(a=a.slice(),ji(c.pixelToCoordinateMatrix,a,a)):null};l.Qj=function(){return this.o};l.jk=function(){return this.j};l.ik=function(a){a=this.yf[a.toString()];return void 0!==a?a:null};l.Xj=function(){return this.l};l.sc=function(){return this.get("layergroup")};l.Zg=function(){return this.sc().Oc()};l.Da=function(a){var c=this.f;return c?(a=a.slice(0,2),ji(c.coordinateToPixelMatrix,a,a)):null}; +l.$a=function(){return this.get("size")};l.aa=function(){return this.get("view")};l.zk=function(){return this.a};l.xk=function(a,c,d,e){var f=this.f;if(!(f&&c in f.wantedTiles&&f.wantedTiles[c][a.ja.toString()]))return Infinity;a=d[0]-f.focus[0];d=d[1]-f.focus[1];return 65536*Math.log(e)+Math.sqrt(a*a+d*d)/e};l.Jc=function(a,c){var d=new Mh(c||a.type,this,a);this.Kg(d)}; +l.Kg=function(a){if(this.f){this.T=a.coordinate;a.frameState=this.f;var c=this.l.a,d;if(!1!==this.b(a))for(d=c.length-1;0<=d;d--){var e=c[d];if(e.f()&&!e.handleEvent(a))break}}};l.Zk=function(){var a=this.f,c=this.na;if(!c.Sa()){var d=16,e=d;if(a){var f=a.viewHints;f[0]&&(d=this.Db?8:0,e=2);f[1]&&(d=this.Cc?8:0,e=2)}c.i<d&&(Hi(c),Ji(c,d,e))}c=this.ta;d=0;for(e=c.length;d<e;++d)c[d](this,a);c.length=0};l.al=function(){this.render()}; +l.cl=function(){var a;this.pf()&&(a=this.tc());if(this.s){for(var c=0,d=this.s.length;c<d;++c)Xa(this.s[c]);this.s=null}a?(a.appendChild(this.a),a=this.ea?this.ea:a,this.s=[C(a,"keydown",this.Jc,this),C(a,"keypress",this.Jc,this)],this.c||(this.c=this.Sc.bind(this),qa.addEventListener("resize",this.c,!1))):(uf(this.a),void 0!==this.c&&(qa.removeEventListener("resize",this.c,!1),this.c=void 0));this.Sc()};l.dl=function(){this.render()};l.fl=function(){this.render()}; +l.el=function(){this.S&&(Xa(this.S),this.S=null);var a=this.aa();a&&(this.S=C(a,"propertychange",this.fl,this));this.render()};l.Lk=function(){this.render()};l.Mk=function(){this.render()};l.Kk=function(){this.N&&(this.N.forEach(Xa),this.N=null);var a=this.sc();a&&(this.N=[C(a,"propertychange",this.Mk,this),C(a,"change",this.Lk,this)]);this.render()};l.Po=function(){this.i&&qa.cancelAnimationFrame(this.i);this.Y()};l.render=function(){void 0===this.i&&(this.i=qa.requestAnimationFrame(this.Y))}; +l.Io=function(a){return this.o.remove(a)};l.Jo=function(a){return this.l.remove(a)};l.Lo=function(a){return this.sc().Oc().remove(a)};l.Mo=function(a){return this.j.remove(a)}; +l.Oo=function(a){var c,d,e,f=this.$a(),g=this.aa(),h=Wb(),k=null;if(void 0!==f&&0<f[0]&&0<f[1]&&g&&ge(g)){var k=ce(g,this.f?this.f.viewHints:void 0),m=this.sc().df(),n={};c=0;for(d=m.length;c<d;++c)n[w(m[c].layer)]=m[c];e=g.V();k={animate:!1,attributions:{},coordinateToPixelMatrix:this.Ra,extent:h,focus:this.T?this.T:e.center,index:this.pb++,layerStates:n,layerStatesArray:m,logos:Pa({},this.Je),pixelRatio:this.Ke,pixelToCoordinateMatrix:this.Le,postRenderFunctions:[],size:f,skippedFeatureUids:this.ze, +tileQueue:this.na,time:a,usedTiles:{},viewState:e,viewHints:k,wantedTiles:{}}}if(k){a=this.R;c=f=0;for(d=a.length;c<d;++c)g=a[c],g(this,k)&&(a[f++]=g);a.length=f;k.extent=uc(e.center,e.resolution,e.rotation,k.size,h)}this.f=k;this.M.xe(k);k&&(k.animate&&this.render(),Array.prototype.push.apply(this.ta,k.postRenderFunctions),0!==this.R.length||k.viewHints[0]||k.viewHints[1]||ic(k.extent,this.xa)||(this.b(new If("moveend",this,k)),Zb(k.extent,this.xa)));this.b(new If("postrender",this,k));Fg(this.Zk, +this)};l.ei=function(a){this.set("layergroup",a)};l.Sf=function(a){this.set("size",a)};l.$g=function(a){this.set("target",a)};l.ep=function(a){this.set("view",a)};l.ni=function(a){a=w(a).toString();this.ze[a]=!0;this.render()}; +l.Sc=function(){var a=this.tc();if(a){var c=lf(a),d=Se&&a.currentStyle,e;if(e=d)jf(c),e=!0;if(e&&"auto"!=d.width&&"auto"!=d.height&&!d.boxSizing)c=Df(a,d.width,"width","pixelWidth"),a=Df(a,d.height,"height","pixelHeight"),a=new hf(c,a);else{d=new hf(a.offsetWidth,a.offsetHeight);c=Ff(a,"padding");if(!Se||9<=Number(ef))e=yf(a,"borderLeftWidth"),f=yf(a,"borderRightWidth"),g=yf(a,"borderTopWidth"),a=yf(a,"borderBottomWidth"),a=new xf(parseFloat(g),parseFloat(f),parseFloat(a),parseFloat(e));else{e=Hf(a, +"borderLeft");var f=Hf(a,"borderRight"),g=Hf(a,"borderTop"),a=Hf(a,"borderBottom"),a=new xf(g,f,a,e)}a=new hf(d.width-a.left-c.left-c.right-a.right,d.height-a.top-c.top-c.bottom-a.bottom)}this.Sf([a.width,a.height])}else this.Sf(void 0)};l.ri=function(a){a=w(a).toString();delete this.ze[a];this.render()}; +function Nn(a){var c=null;void 0!==a.keyboardEventTarget&&(c="string"===typeof a.keyboardEventTarget?document.getElementById(a.keyboardEventTarget):a.keyboardEventTarget);var d={},e={};if(void 0===a.logo||"boolean"===typeof a.logo&&a.logo)e["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAHGAAABxgEXwfpGAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAhNQTFRF////AP//AICAgP//AFVVQECA////K1VVSbbbYL/fJ05idsTYJFtbbcjbJllmZszWWMTOIFhoHlNiZszTa9DdUcHNHlNlV8XRIVdiasrUHlZjIVZjaMnVH1RlIFRkH1RkH1ZlasvYasvXVsPQH1VkacnVa8vWIVZjIFRjVMPQa8rXIVVkXsXRsNveIFVkIFZlIVVj3eDeh6GmbMvXH1ZkIFRka8rWbMvXIFVkIFVjIFVkbMvWH1VjbMvWIFVlbcvWIFVla8vVIFVkbMvWbMvVH1VkbMvWIFVlbcvWIFVkbcvVbMvWjNPbIFVkU8LPwMzNIFVkbczWIFVkbsvWbMvXIFVkRnB8bcvW2+TkW8XRIFVkIlZlJVloJlpoKlxrLl9tMmJwOWd0Omh1RXF8TneCT3iDUHiDU8LPVMLPVcLPVcPQVsPPVsPQV8PQWMTQWsTQW8TQXMXSXsXRX4SNX8bSYMfTYcfTYsfTY8jUZcfSZsnUaIqTacrVasrVa8jTa8rWbI2VbMvWbcvWdJObdcvUdszUd8vVeJaee87Yfc3WgJyjhqGnitDYjaarldPZnrK2oNbborW5o9bbo9fbpLa6q9ndrL3ArtndscDDutzfu8fJwN7gwt7gxc/QyuHhy+HizeHi0NfX0+Pj19zb1+Tj2uXk29/e3uLg3+Lh3+bl4uXj4ufl4+fl5Ofl5ufl5ujm5+jmySDnBAAAAFp0Uk5TAAECAgMEBAYHCA0NDg4UGRogIiMmKSssLzU7PkJJT1JTVFliY2hrdHZ3foSFhYeJjY2QkpugqbG1tre5w8zQ09XY3uXn6+zx8vT09vf4+Pj5+fr6/P39/f3+gz7SsAAAAVVJREFUOMtjYKA7EBDnwCPLrObS1BRiLoJLnte6CQy8FLHLCzs2QUG4FjZ5GbcmBDDjxJBXDWxCBrb8aM4zbkIDzpLYnAcE9VXlJSWlZRU13koIeW57mGx5XjoMZEUqwxWYQaQbSzLSkYGfKFSe0QMsX5WbjgY0YS4MBplemI4BdGBW+DQ11eZiymfqQuXZIjqwyadPNoSZ4L+0FVM6e+oGI6g8a9iKNT3o8kVzNkzRg5lgl7p4wyRUL9Yt2jAxVh6mQCogae6GmflI8p0r13VFWTHBQ0rWPW7ahgWVcPm+9cuLoyy4kCJDzCm6d8PSFoh0zvQNC5OjDJhQopPPJqph1doJBUD5tnkbZiUEqaCnB3bTqLTFG1bPn71kw4b+GFdpLElKIzRxxgYgWNYc5SCENVHKeUaltHdXx0dZ8uBI1hJ2UUDgq82CM2MwKeibqAvSO7MCABq0wXEPiqWEAAAAAElFTkSuQmCC"]= +"http://openlayers.org/";else{var f=a.logo;"string"===typeof f?e[f]="":f instanceof HTMLElement?e[w(f).toString()]=f:ha(f)&&(e[f.src]=f.href)}f=a.layers instanceof Kj?a.layers:new Kj({layers:a.layers});d.layergroup=f;d.target=a.target;d.view=void 0!==a.view?a.view:new be;var f=yi,g;void 0!==a.renderer?Array.isArray(a.renderer)?g=a.renderer:"string"===typeof a.renderer&&(g=[a.renderer]):g=Mn;var h,k;h=0;for(k=g.length;h<k;++h){var m=g[h];if("canvas"==m){if($g){f=Gm;break}}else if("dom"==m){f=Om;break}else if("webgl"== +m&&Tg){f=Jn;break}}var n;void 0!==a.controls?n=Array.isArray(a.controls)?new we(a.controls.slice()):a.controls:n=wg();var p;void 0!==a.interactions?p=Array.isArray(a.interactions)?new we(a.interactions.slice()):a.interactions:p=Jj();a=void 0!==a.overlays?Array.isArray(a.overlays)?new we(a.overlays.slice()):a.overlays:new we;return{controls:n,interactions:p,keyboardEventTarget:c,logos:e,overlays:a,Qo:f,values:d}}Tj();function On(a){pb.call(this);this.j=a.id;this.o=void 0!==a.insertFirst?a.insertFirst:!0;this.s=void 0!==a.stopEvent?a.stopEvent:!0;this.f=document.createElement("DIV");this.f.className="ol-overlay-container";this.f.style.position="absolute";this.autoPan=void 0!==a.autoPan?a.autoPan:!1;this.i=void 0!==a.autoPanAnimation?a.autoPanAnimation:{};this.l=void 0!==a.autoPanMargin?a.autoPanMargin:20;this.a={Hd:"",$d:"",ye:"",Be:"",visible:!0};this.c=null;C(this,rb("element"),this.Fk,this);C(this,rb("map"), +this.Rk,this);C(this,rb("offset"),this.Vk,this);C(this,rb("position"),this.Xk,this);C(this,rb("positioning"),this.Yk,this);void 0!==a.element&&this.ai(a.element);this.gi(void 0!==a.offset?a.offset:[0,0]);this.ji(void 0!==a.positioning?a.positioning:"top-left");void 0!==a.position&&this.qf(a.position)}y(On,pb);l=On.prototype;l.be=function(){return this.get("element")};l.Wa=function(){return this.j};l.ce=function(){return this.get("map")};l.Fg=function(){return this.get("offset")};l.ah=function(){return this.get("position")}; +l.Gg=function(){return this.get("positioning")};l.Fk=function(){sf(this.f);var a=this.be();a&&this.f.appendChild(a)};l.Rk=function(){this.c&&(uf(this.f),Xa(this.c),this.c=null);var a=this.ce();a&&(this.c=C(a,"postrender",this.render,this),Pn(this),a=this.s?a.v:a.B,this.o?tf(a,this.f,0):a.appendChild(this.f))};l.render=function(){Pn(this)};l.Vk=function(){Pn(this)}; +l.Xk=function(){Pn(this);if(void 0!==this.get("position")&&this.autoPan){var a=this.ce();if(void 0!==a&&a.tc()){var c=Qn(a.tc(),a.$a()),d=this.be(),e=d.offsetWidth,f=d.currentStyle||qa.getComputedStyle(d),e=e+(parseInt(f.marginLeft,10)+parseInt(f.marginRight,10)),f=d.offsetHeight,g=d.currentStyle||qa.getComputedStyle(d),f=f+(parseInt(g.marginTop,10)+parseInt(g.marginBottom,10)),h=Qn(d,[e,f]),d=this.l;cc(c,h)||(e=h[0]-c[0],f=c[2]-h[2],g=h[1]-c[1],h=c[3]-h[3],c=[0,0],0>e?c[0]=e-d:0>f&&(c[0]=Math.abs(f)+ +d),0>g?c[1]=g-d:0>h&&(c[1]=Math.abs(h)+d),0===c[0]&&0===c[1])||(d=a.aa().bb(),e=a.Da(d),c=[e[0]+c[0],e[1]+c[1]],this.i&&(this.i.source=d,a.Va(ne(this.i))),a.aa().jb(a.Ma(c)))}}};l.Yk=function(){Pn(this)};l.ai=function(a){this.set("element",a)};l.setMap=function(a){this.set("map",a)};l.gi=function(a){this.set("offset",a)};l.qf=function(a){this.set("position",a)}; +function Qn(a,c){var d=lf(a),e=new gf(0,0),f;f=d?lf(d):document;var g;(g=!Se||9<=Number(ef))||(jf(f),g=!0);a!=(g?f.documentElement:f.body)&&(f=zf(a),g=jf(d).b,d=g.scrollingElement?g.scrollingElement:Ve?g.body||g.documentElement:g.documentElement,g=g.parentWindow||g.defaultView,d=Se&&cf("10")&&g.pageYOffset!=d.scrollTop?new gf(d.scrollLeft,d.scrollTop):new gf(g.pageXOffset||d.scrollLeft,g.pageYOffset||d.scrollTop),e.x=f.left+d.x,e.y=f.top+d.y);return[e.x,e.y,e.x+c[0],e.y+c[1]]} +l.ji=function(a){this.set("positioning",a)};function Rn(a,c){a.a.visible!==c&&(Cf(a.f,c),a.a.visible=c)} +function Pn(a){var c=a.ce(),d=a.ah();if(void 0!==c&&c.f&&void 0!==d){var d=c.Da(d),e=c.$a(),c=a.f.style,f=a.Fg(),g=a.Gg(),h=f[0],f=f[1];if("bottom-right"==g||"center-right"==g||"top-right"==g)""!==a.a.$d&&(a.a.$d=c.left=""),h=Math.round(e[0]-d[0]-h)+"px",a.a.ye!=h&&(a.a.ye=c.right=h);else{""!==a.a.ye&&(a.a.ye=c.right="");if("bottom-center"==g||"center-center"==g||"top-center"==g)h-=Af(a.f).width/2;h=Math.round(d[0]+h)+"px";a.a.$d!=h&&(a.a.$d=c.left=h)}if("bottom-left"==g||"bottom-center"==g||"bottom-right"== +g)""!==a.a.Be&&(a.a.Be=c.top=""),d=Math.round(e[1]-d[1]-f)+"px",a.a.Hd!=d&&(a.a.Hd=c.bottom=d);else{""!==a.a.Hd&&(a.a.Hd=c.bottom="");if("center-left"==g||"center-center"==g||"center-right"==g)f-=Af(a.f).height/2;d=Math.round(d[1]+f)+"px";a.a.Be!=d&&(a.a.Be=c.top=d)}Rn(a,!0)}else Rn(a,!1)};function Sn(a){a=a?a:{};this.l=void 0!==a.collapsed?a.collapsed:!0;this.o=void 0!==a.collapsible?a.collapsible:!0;this.o||(this.l=!1);var c=void 0!==a.className?a.className:"ol-overviewmap",d=void 0!==a.tipLabel?a.tipLabel:"Overview map",e=void 0!==a.collapseLabel?a.collapseLabel:"\u00ab";this.v="string"===typeof e?pf("SPAN",{},e):e;e=void 0!==a.label?a.label:"\u00bb";this.B="string"===typeof e?pf("SPAN",{},e):e;d=pf("BUTTON",{type:"button",title:d},this.o&&!this.l?this.v:this.B);C(d,"click",this.am, +this);e=document.createElement("DIV");e.className="ol-overviewmap-map";var f=this.f=new S({controls:new we,interactions:new we,target:e,view:a.view});a.layers&&a.layers.forEach(function(a){f.gg(a)},this);var g=document.createElement("DIV");g.className="ol-overviewmap-box";g.style.boxSizing="border-box";this.j=new On({position:[0,0],positioning:"bottom-left",element:g});this.f.hg(this.j);c=pf("DIV",c+" ol-unselectable ol-control"+(this.l&&this.o?" ol-collapsed":"")+(this.o?"":" ol-uncollapsible"), +e,d);Jf.call(this,{element:c,render:a.render?a.render:Tn,target:a.target})}y(Sn,Jf);l=Sn.prototype;l.setMap=function(a){var c=this.a;a!==c&&(c&&(c=c.aa())&&cb(c,rb("rotation"),this.Yd,this),Sn.ia.setMap.call(this,a),a&&(this.s.push(C(a,"propertychange",this.Sk,this)),0===this.f.Zg().Zb()&&this.f.ei(a.sc()),a=a.aa()))&&(C(a,rb("rotation"),this.Yd,this),ge(a)&&(this.f.Sc(),Un(this)))}; +l.Sk=function(a){"view"===a.key&&((a=a.oldValue)&&cb(a,rb("rotation"),this.Yd,this),a=this.a.aa(),C(a,rb("rotation"),this.Yd,this))};l.Yd=function(){this.f.aa().de(this.a.aa().Ka())};function Tn(){var a=this.a,c=this.f;if(a.f&&c.f){var d=a.$a(),a=a.aa().Fc(d),e=c.$a(),d=c.aa().Fc(e),f=c.Da(oc(a)),g=c.Da(mc(a)),c=Math.abs(f[0]-g[0]),f=Math.abs(f[1]-g[1]),g=e[0],e=e[1];c<.1*g||f<.1*e||c>.75*g||f>.75*e?Un(this):cc(d,a)||(a=this.f,d=this.a.aa(),a.aa().jb(d.bb()))}Vn(this)} +function Un(a){var c=a.a;a=a.f;var d=c.$a(),c=c.aa().Fc(d),d=a.$a();a=a.aa();yc(c,1/(.1*Math.pow(2,Math.log(7.5)/Math.LN2/2)));a.Ze(c,d)}function Vn(a){var c=a.a,d=a.f;if(c.f&&d.f){var e=c.$a(),f=c.aa(),g=d.aa();d.$a();var d=f.Ka(),c=a.j,h=a.j.be(),f=f.Fc(e),e=g.$(),g=lc(f),f=nc(f),k;if(a=a.a.aa().bb())k=[g[0]-a[0],g[1]-a[1]],Rb(k,d),Mb(k,a);c.qf(k);h&&(h.style.width=Math.abs((g[0]-f[0])/e)+"px",h.style.height=Math.abs((f[1]-g[1])/e)+"px")}}l.am=function(a){a.preventDefault();Wn(this)}; +function Wn(a){a.element.classList.toggle("ol-collapsed");a.l?vf(a.v,a.B):vf(a.B,a.v);a.l=!a.l;var c=a.f;a.l||c.f||(c.Sc(),Un(a),bb(c,"postrender",function(){Vn(this)},a))}l.$l=function(){return this.o};l.cm=function(a){this.o!==a&&(this.o=a,this.element.classList.toggle("ol-uncollapsible"),!a&&this.l&&Wn(this))};l.bm=function(a){this.o&&this.l!==a&&Wn(this)};l.Zl=function(){return this.l};l.kk=function(){return this.f};function Xn(a){a=a?a:{};var c=void 0!==a.className?a.className:"ol-scale-line";this.o=document.createElement("DIV");this.o.className=c+"-inner";this.f=document.createElement("DIV");this.f.className=c+" ol-unselectable";this.f.appendChild(this.o);this.v=null;this.j=void 0!==a.minWidth?a.minWidth:64;this.l=!1;this.M=void 0;this.B="";Jf.call(this,{element:this.f,render:a.render?a.render:Yn,target:a.target});C(this,rb("units"),this.R,this);this.N(a.units||"metric")}y(Xn,Jf);var Zn=[1,2,5]; +Xn.prototype.vb=function(){return this.get("units")};function Yn(a){(a=a.frameState)?this.v=a.viewState:this.v=null;$n(this)}Xn.prototype.R=function(){$n(this)};Xn.prototype.N=function(a){this.set("units",a)}; +function $n(a){var c=a.v;if(c){var d=c.projection,e=d.Vb(),c=d.getPointResolution(c.resolution,c.center)*e,e=a.j*c,d="",f=a.vb();"degrees"==f?(d=Ec.degrees,c/=d,e<d/60?(d="\u2033",c*=3600):e<d?(d="\u2032",c*=60):d="\u00b0"):"imperial"==f?.9144>e?(d="in",c/=.0254):1609.344>e?(d="ft",c/=.3048):(d="mi",c/=1609.344):"nautical"==f?(c/=1852,d="nm"):"metric"==f?1>e?(d="mm",c*=1E3):1E3>e?d="m":(d="km",c/=1E3):"us"==f&&(.9144>e?(d="in",c*=39.37):1609.344>e?(d="ft",c/=.30480061):(d="mi",c/=1609.3472));for(var f= +3*Math.floor(Math.log(a.j*c)/Math.log(10)),g;;){g=Zn[(f%3+3)%3]*Math.pow(10,Math.floor(f/3));e=Math.round(g/c);if(isNaN(e)){Cf(a.f,!1);a.l=!1;return}if(e>=a.j)break;++f}c=g+" "+d;a.B!=c&&(a.o.innerHTML=c,a.B=c);a.M!=e&&(a.o.style.width=e+"px",a.M=e);a.l||(Cf(a.f,!0),a.l=!0)}else a.l&&(Cf(a.f,!1),a.l=!1)};function ao(a){a=a?a:{};this.f=void 0;this.l=bo;this.v=[];this.M=this.j=0;this.T=null;this.ea=!1;this.Y=void 0!==a.duration?a.duration:200;var c=void 0!==a.className?a.className:"ol-zoomslider",d=pf("BUTTON",{type:"button","class":c+"-thumb ol-unselectable"}),c=pf("DIV",[c,"ol-unselectable","ol-control"],d);this.o=new Gh(c);C(this.o,qh,this.Ek,this);C(this.o,rh,this.Ig,this);C(this.o,sh,this.Jg,this);C(c,"click",this.Dk,this);C(d,"click",hb);Jf.call(this,{element:c,render:a.render?a.render:co})} +y(ao,Jf);ao.prototype.fa=function(){fb(this.o);ao.ia.fa.call(this)};var bo=0;l=ao.prototype;l.setMap=function(a){ao.ia.setMap.call(this,a);a&&a.render()}; +function co(a){if(a.frameState){if(!this.ea){var c=this.element,d=Af(c),e=c.firstElementChild,c=Ff(e,"margin"),f=new hf(e.offsetWidth,e.offsetHeight),e=f.width+c.right+c.left,c=f.height+c.top+c.bottom;this.T=[e,c];d.width>d.height?(this.l=1,this.M=d.width-e):(this.l=bo,this.j=d.height-c);this.ea=!0}a=a.frameState.viewState.resolution;a!==this.f&&(this.f=a,eo(this,a))}} +l.Dk=function(a){var c=this.a,d=c.aa(),e=d.$();c.Va(pe({resolution:e,duration:this.Y,easing:je}));a=fo(this,Da(1===this.l?(a.offsetX-this.T[0]/2)/this.M:(a.offsetY-this.T[1]/2)/this.j,0,1));d.Qb(d.constrainResolution(a))}; +l.Ek=function(a){if(!this.B&&a.b.target===this.element.firstElementChild&&(he(this.a.aa(),1),this.N=a.clientX,this.R=a.clientY,this.B=!0,0===this.v.length)){a=this.Ig;var c=this.Jg;this.v.push(C(document,"mousemove",a,this),C(document,"touchmove",a,this),C(document,rh,a,this),C(document,"mouseup",c,this),C(document,"touchend",c,this),C(document,sh,c,this))}}; +l.Ig=function(a){if(this.B){var c=this.element.firstElementChild;this.f=fo(this,Da(1===this.l?(a.clientX-this.N+parseInt(c.style.left,10))/this.M:(a.clientY-this.R+parseInt(c.style.top,10))/this.j,0,1));this.a.aa().Qb(this.f);eo(this,this.f);this.N=a.clientX;this.R=a.clientY}};l.Jg=function(){if(this.B){var a=this.a,c=a.aa();he(c,-1);a.Va(pe({resolution:this.f,duration:this.Y,easing:je}));a=c.constrainResolution(this.f);c.Qb(a);this.B=!1;this.R=this.N=void 0;this.v.forEach(Xa);this.v.length=0}}; +function eo(a,c){var d;d=1-fe(a.a.aa())(c);var e=a.element.firstElementChild;1==a.l?e.style.left=a.M*d+"px":e.style.top=a.j*d+"px"}function fo(a,c){return ee(a.a.aa())(1-c)};function go(a){a=a?a:{};this.f=a.extent?a.extent:null;var c=void 0!==a.className?a.className:"ol-zoom-extent",d=pf("BUTTON",{type:"button",title:void 0!==a.tipLabel?a.tipLabel:"Fit to extent"},void 0!==a.label?a.label:"E");C(d,"click",this.l,this);c=pf("DIV",c+" ol-unselectable ol-control",d);Jf.call(this,{element:c,target:a.target})}y(go,Jf);go.prototype.l=function(a){a.preventDefault();var c=this.a;a=c.aa();var d=this.f?this.f:a.i.O(),c=c.$a();a.Ze(d,c)};function ho(a){pb.call(this);a=a?a:{};this.a=null;C(this,rb("tracking"),this.El,this);this.mf(void 0!==a.tracking?a.tracking:!1)}y(ho,pb);l=ho.prototype;l.fa=function(){this.mf(!1);ho.ia.fa.call(this)}; +l.Xn=function(a){if(null!==a.alpha){var c=Ha(a.alpha);this.set("alpha",c);"boolean"===typeof a.absolute&&a.absolute?this.set("heading",c):fa(a.webkitCompassHeading)&&-1!=a.webkitCompassAccuracy&&this.set("heading",Ha(a.webkitCompassHeading))}null!==a.beta&&this.set("beta",Ha(a.beta));null!==a.gamma&&this.set("gamma",Ha(a.gamma));this.u()};l.Kj=function(){return this.get("alpha")};l.Nj=function(){return this.get("beta")};l.Uj=function(){return this.get("gamma")};l.Dl=function(){return this.get("heading")}; +l.Vg=function(){return this.get("tracking")};l.El=function(){if(ah){var a=this.Vg();a&&!this.a?this.a=C(qa,"deviceorientation",this.Xn,this):a||null===this.a||(Xa(this.a),this.a=null)}};l.mf=function(a){this.set("tracking",a)};function io(){this.defaultDataProjection=null}function jo(a,c,d){var e;d&&(e={dataProjection:d.dataProjection?d.dataProjection:a.Oa(c),featureProjection:d.featureProjection});return ko(a,e)}function ko(a,c){var d;c&&(d={featureProjection:c.featureProjection,dataProjection:c.dataProjection?c.dataProjection:a.defaultDataProjection,rightHanded:c.rightHanded},c.decimals&&(d.decimals=c.decimals));return d} +function lo(a,c,d){var e=d?Ic(d.featureProjection):null,f=d?Ic(d.dataProjection):null,g;e&&f&&!Zc(e,f)?a instanceof dd?g=(c?a.clone():a).hb(c?e:f,c?f:e):g=cd(c?a.slice():a,c?e:f,c?f:e):g=a;if(c&&d&&d.decimals){var h=Math.pow(10,d.decimals);a=function(a){for(var c=0,d=a.length;c<d;++c)a[c]=Math.round(a[c]*h)/h;return a};Array.isArray(g)?a(g):g.mc(a)}return g};function mo(){this.defaultDataProjection=null}y(mo,io);function no(a){return ha(a)?a:"string"===typeof a?(a=JSON.parse(a))?a:null:null}l=mo.prototype;l.X=function(){return"json"};l.Nb=function(a,c){return this.Pc(no(a),jo(this,a,c))};l.Ca=function(a,c){return this.Ff(no(a),jo(this,a,c))};l.Qc=function(a,c){return this.Mh(no(a),jo(this,a,c))};l.Oa=function(a){return this.Th(no(a))};l.yd=function(a,c){return JSON.stringify(this.Tc(a,c))};l.Sb=function(a,c){return JSON.stringify(this.Ee(a,c))}; +l.Uc=function(a,c){return JSON.stringify(this.Ge(a,c))};function oo(a,c,d,e,f,g){var h=NaN,k=NaN,m=(d-c)/e;if(0!==m)if(1==m)h=a[c],k=a[c+1];else if(2==m)h=(1-f)*a[c]+f*a[c+e],k=(1-f)*a[c+1]+f*a[c+e+1];else{var k=a[c],m=a[c+1],n=0,h=[0],p;for(p=c+e;p<d;p+=e){var q=a[p],r=a[p+1],n=n+Math.sqrt((q-k)*(q-k)+(r-m)*(r-m));h.push(n);k=q;m=r}d=f*n;m=0;n=h.length;for(p=!1;m<n;)f=m+(n-m>>1),k=+tb(h[f],d),0>k?m=f+1:(n=f,p=!k);f=p?m:~m;0>f?(d=(d-h[-f-2])/(h[-f-1]-h[-f-2]),c+=(-f-2)*e,h=La(a[c],a[c+e],d),k=La(a[c+1],a[c+e+1],d)):(h=a[c+f*e],k=a[c+f*e+1])}return g?(g[0]= +h,g[1]=k,g):[h,k]}function po(a,c,d,e,f,g){if(d==c)return null;if(f<a[c+e-1])return g?(d=a.slice(c,c+e),d[e-1]=f,d):null;if(a[d-1]<f)return g?(d=a.slice(d-e,d),d[e-1]=f,d):null;if(f==a[c+e-1])return a.slice(c,c+e);c/=e;for(d/=e;c<d;)g=c+d>>1,f<a[(g+1)*e-1]?d=g:c=g+1;d=a[c*e-1];if(f==d)return a.slice((c-1)*e,(c-1)*e+e);g=(f-d)/(a[(c+1)*e-1]-d);d=[];var h;for(h=0;h<e-1;++h)d.push(La(a[(c-1)*e+h],a[c*e+h],g));d.push(f);return d} +function qo(a,c,d,e,f,g){var h=0;if(g)return po(a,h,c[c.length-1],d,e,f);if(e<a[d-1])return f?(a=a.slice(0,d),a[d-1]=e,a):null;if(a[a.length-1]<e)return f?(a=a.slice(a.length-d),a[d-1]=e,a):null;f=0;for(g=c.length;f<g;++f){var k=c[f];if(h!=k){if(e<a[h+d-1])break;if(e<=a[k-1])return po(a,h,k,d,e,!1);h=k}}return null};function T(a,c){sd.call(this);this.i=null;this.M=this.N=this.j=-1;this.ma(a,c)}y(T,sd);l=T.prototype;l.rj=function(a){this.A?xb(this.A,a):this.A=a.slice();this.u()};l.clone=function(){var a=new T(null);a.ba(this.f,this.A.slice());return a};l.rb=function(a,c,d,e){if(e<$b(this.O(),a,c))return e;this.M!=this.g&&(this.N=Math.sqrt(zd(this.A,0,this.A.length,this.a,0)),this.M=this.g);return Bd(this.A,0,this.A.length,this.a,this.N,!1,a,c,d,e)}; +l.Hj=function(a,c){return Qd(this.A,0,this.A.length,this.a,a,c)};l.fm=function(a,c){return"XYM"!=this.f&&"XYZM"!=this.f?null:po(this.A,0,this.A.length,this.a,a,void 0!==c?c:!1)};l.Z=function(){return Gd(this.A,0,this.A.length,this.a)};l.wg=function(a,c){return oo(this.A,0,this.A.length,this.a,a,c)};l.gm=function(){var a=this.A,c=this.a,d=a[0],e=a[1],f=0,g;for(g=0+c;g<this.A.length;g+=c)var h=a[g],k=a[g+1],f=f+Math.sqrt((h-d)*(h-d)+(k-e)*(k-e)),d=h,e=k;return f}; +function xk(a){a.j!=a.g&&(a.i=a.wg(.5,a.i),a.j=a.g);return a.i}l.Ic=function(a){var c=[];c.length=Id(this.A,0,this.A.length,this.a,a,c,0);a=new T(null);a.ba("XY",c);return a};l.X=function(){return"LineString"};l.Ia=function(a){return Rd(this.A,0,this.A.length,this.a,a)};l.ma=function(a,c){a?(vd(this,c,a,1),this.A||(this.A=[]),this.A.length=Ed(this.A,0,a,this.a),this.u()):this.ba("XY",null)};l.ba=function(a,c){ud(this,a,c);this.u()};function U(a,c){sd.call(this);this.i=[];this.j=this.M=-1;this.ma(a,c)}y(U,sd);l=U.prototype;l.sj=function(a){this.A?xb(this.A,a.ga().slice()):this.A=a.ga().slice();this.i.push(this.A.length);this.u()};l.clone=function(){var a=new U(null);a.ba(this.f,this.A.slice(),this.i.slice());return a};l.rb=function(a,c,d,e){if(e<$b(this.O(),a,c))return e;this.j!=this.g&&(this.M=Math.sqrt(Ad(this.A,0,this.i,this.a,0)),this.j=this.g);return Cd(this.A,0,this.i,this.a,this.M,!1,a,c,d,e)}; +l.im=function(a,c,d){return"XYM"!=this.f&&"XYZM"!=this.f||0===this.A.length?null:qo(this.A,this.i,this.a,a,void 0!==c?c:!1,void 0!==d?d:!1)};l.Z=function(){return Hd(this.A,0,this.i,this.a)};l.zb=function(){return this.i};l.bk=function(a){if(0>a||this.i.length<=a)return null;var c=new T(null);c.ba(this.f,this.A.slice(0===a?0:this.i[a-1],this.i[a]));return c}; +l.gd=function(){var a=this.A,c=this.i,d=this.f,e=[],f=0,g,h;g=0;for(h=c.length;g<h;++g){var k=c[g],m=new T(null);m.ba(d,a.slice(f,k));e.push(m);f=k}return e};function yk(a){var c=[],d=a.A,e=0,f=a.i;a=a.a;var g,h;g=0;for(h=f.length;g<h;++g){var k=f[g],e=oo(d,e,k,a,.5);xb(c,e);e=k}return c}l.Ic=function(a){var c=[],d=[],e=this.A,f=this.i,g=this.a,h=0,k=0,m,n;m=0;for(n=f.length;m<n;++m){var p=f[m],k=Id(e,h,p,g,a,c,k);d.push(k);h=p}c.length=k;a=new U(null);a.ba("XY",c,d);return a};l.X=function(){return"MultiLineString"}; +l.Ia=function(a){a:{var c=this.A,d=this.i,e=this.a,f=0,g,h;g=0;for(h=d.length;g<h;++g){if(Rd(c,f,d[g],e,a)){a=!0;break a}f=d[g]}a=!1}return a};l.ma=function(a,c){if(a){vd(this,c,a,2);this.A||(this.A=[]);var d=Fd(this.A,0,a,this.a,this.i);this.A.length=0===d.length?0:d[d.length-1];this.u()}else this.ba("XY",null,this.i)};l.ba=function(a,c,d){ud(this,a,c);this.i=d;this.u()}; +function ro(a,c){var d=a.f,e=[],f=[],g,h;g=0;for(h=c.length;g<h;++g){var k=c[g];0===g&&(d=k.f);xb(e,k.ga());f.push(e.length)}a.ba(d,e,f)};function so(a,c){sd.call(this);this.ma(a,c)}y(so,sd);l=so.prototype;l.uj=function(a){this.A?xb(this.A,a.ga()):this.A=a.ga().slice();this.u()};l.clone=function(){var a=new so(null);a.ba(this.f,this.A.slice());return a};l.rb=function(a,c,d,e){if(e<$b(this.O(),a,c))return e;var f=this.A,g=this.a,h,k,m;h=0;for(k=f.length;h<k;h+=g)if(m=Ga(a,c,f[h],f[h+1]),m<e){e=m;for(m=0;m<g;++m)d[m]=f[h+m];d.length=g}return e};l.Z=function(){return Gd(this.A,0,this.A.length,this.a)}; +l.mk=function(a){var c=this.A?this.A.length/this.a:0;if(0>a||c<=a)return null;c=new D(null);c.ba(this.f,this.A.slice(a*this.a,(a+1)*this.a));return c};l.ee=function(){var a=this.A,c=this.f,d=this.a,e=[],f,g;f=0;for(g=a.length;f<g;f+=d){var h=new D(null);h.ba(c,a.slice(f,f+d));e.push(h)}return e};l.X=function(){return"MultiPoint"};l.Ia=function(a){var c=this.A,d=this.a,e,f,g,h;e=0;for(f=c.length;e<f;e+=d)if(g=c[e],h=c[e+1],bc(a,g,h))return!0;return!1}; +l.ma=function(a,c){a?(vd(this,c,a,1),this.A||(this.A=[]),this.A.length=Ed(this.A,0,a,this.a),this.u()):this.ba("XY",null)};l.ba=function(a,c){ud(this,a,c);this.u()};function to(a,c){sd.call(this);this.i=[];this.M=-1;this.N=null;this.T=this.R=this.S=-1;this.j=null;this.ma(a,c)}y(to,sd);l=to.prototype;l.vj=function(a){if(this.A){var c=this.A.length;xb(this.A,a.ga());a=a.zb().slice();var d,e;d=0;for(e=a.length;d<e;++d)a[d]+=c}else this.A=a.ga().slice(),a=a.zb().slice(),this.i.push();this.i.push(a);this.u()};l.clone=function(){for(var a=new to(null),c=this.i.length,d=Array(c),e=0;e<c;++e)d[e]=this.i[e].slice();uo(a,this.f,this.A.slice(),d);return a}; +l.rb=function(a,c,d,e){if(e<$b(this.O(),a,c))return e;if(this.R!=this.g){var f=this.i,g=0,h=0,k,m;k=0;for(m=f.length;k<m;++k)var n=f[k],h=Ad(this.A,g,n,this.a,h),g=n[n.length-1];this.S=Math.sqrt(h);this.R=this.g}f=zk(this);g=this.i;h=this.a;k=this.S;m=0;var n=[NaN,NaN],p,q;p=0;for(q=g.length;p<q;++p){var r=g[p];e=Cd(f,m,r,h,k,!0,a,c,d,e,n);m=r[r.length-1]}return e}; +l.wc=function(a,c){var d;a:{d=zk(this);var e=this.i,f=0;if(0!==e.length){var g,h;g=0;for(h=e.length;g<h;++g){var k=e[g];if(Od(d,f,k,this.a,a,c)){d=!0;break a}f=k[k.length-1]}}d=!1}return d};l.jm=function(){var a=zk(this),c=this.i,d=0,e=0,f,g;f=0;for(g=c.length;f<g;++f)var h=c[f],e=e+xd(a,d,h,this.a),d=h[h.length-1];return e}; +l.Z=function(a){var c;void 0!==a?(c=zk(this).slice(),Wd(c,this.i,this.a,a)):c=this.A;a=c;c=this.i;var d=this.a,e=0,f=[],g=0,h,k;h=0;for(k=c.length;h<k;++h){var m=c[h];f[g++]=Hd(a,e,m,d,f[g]);e=m[m.length-1]}f.length=g;return f}; +function Ak(a){if(a.M!=a.g){var c=a.A,d=a.i,e=a.a,f=0,g=[],h,k,m=Wb();h=0;for(k=d.length;h<k;++h){var n=d[h],m=gc(c,f,n[0],e);g.push((m[0]+m[2])/2,(m[1]+m[3])/2);f=n[n.length-1]}c=zk(a);d=a.i;e=a.a;f=0;h=[];k=0;for(m=d.length;k<m;++k)n=d[k],h=Pd(c,f,n,e,g,2*k,h),f=n[n.length-1];a.N=h;a.M=a.g}return a.N}l.Zj=function(){var a=new so(null);a.ba("XY",Ak(this).slice());return a}; +function zk(a){if(a.T!=a.g){var c=a.A,d;a:{d=a.i;var e,f;e=0;for(f=d.length;e<f;++e)if(!Ud(c,d[e],a.a,void 0)){d=!1;break a}d=!0}d?a.j=c:(a.j=c.slice(),a.j.length=Wd(a.j,a.i,a.a));a.T=a.g}return a.j}l.Ic=function(a){var c=[],d=[],e=this.A,f=this.i,g=this.a;a=Math.sqrt(a);var h=0,k=0,m,n;m=0;for(n=f.length;m<n;++m){var p=f[m],q=[],k=Jd(e,h,p,g,a,c,k,q);d.push(q);h=p[p.length-1]}c.length=k;e=new to(null);uo(e,"XY",c,d);return e}; +l.pk=function(a){if(0>a||this.i.length<=a)return null;var c;0===a?c=0:(c=this.i[a-1],c=c[c.length-1]);a=this.i[a].slice();var d=a[a.length-1];if(0!==c){var e,f;e=0;for(f=a.length;e<f;++e)a[e]-=c}e=new F(null);e.ba(this.f,this.A.slice(c,d),a);return e};l.Qd=function(){var a=this.f,c=this.A,d=this.i,e=[],f=0,g,h,k,m;g=0;for(h=d.length;g<h;++g){var n=d[g].slice(),p=n[n.length-1];if(0!==f)for(k=0,m=n.length;k<m;++k)n[k]-=f;k=new F(null);k.ba(a,c.slice(f,p),n);e.push(k);f=p}return e};l.X=function(){return"MultiPolygon"}; +l.Ia=function(a){a:{var c=zk(this),d=this.i,e=this.a,f=0,g,h;g=0;for(h=d.length;g<h;++g){var k=d[g];if(Sd(c,f,k,e,a)){a=!0;break a}f=k[k.length-1]}a=!1}return a};l.ma=function(a,c){if(a){vd(this,c,a,3);this.A||(this.A=[]);var d=this.A,e=this.a,f=this.i,g=0,f=f?f:[],h=0,k,m;k=0;for(m=a.length;k<m;++k)g=Fd(d,g,a[k],e,f[h]),f[h++]=g,g=g[g.length-1];f.length=h;0===f.length?this.A.length=0:(d=f[f.length-1],this.A.length=0===d.length?0:d[d.length-1]);this.u()}else uo(this,"XY",null,this.i)}; +function uo(a,c,d,e){ud(a,c,d);a.i=e;a.u()}function vo(a,c){var d=a.f,e=[],f=[],g,h,k;g=0;for(h=c.length;g<h;++g){var m=c[g];0===g&&(d=m.f);var n=e.length;k=m.zb();var p,q;p=0;for(q=k.length;p<q;++p)k[p]+=n;xb(e,m.ga());f.push(k)}uo(a,d,e,f)};function wo(a){a=a?a:{};this.defaultDataProjection=null;this.b=a.geometryName}y(wo,mo); +function xo(a,c){if(!a)return null;var d;if(fa(a.x)&&fa(a.y))d="Point";else if(a.points)d="MultiPoint";else if(a.paths)d=1===a.paths.length?"LineString":"MultiLineString";else if(a.rings){var e=a.rings,f=yo(a),g=[];d=[];var h,k;h=0;for(k=e.length;h<k;++h){var m=wb(e[h]);Td(m,0,m.length,f.length)?g.push([e[h]]):d.push(e[h])}for(;d.length;){e=d.shift();f=!1;for(h=g.length-1;0<=h;h--)if(cc((new Kd(g[h][0])).O(),(new Kd(e)).O())){g[h].push(e);f=!0;break}f||g.push([e.reverse()])}a=Pa({},a);1===g.length? +(d="Polygon",a.rings=g[0]):(d="MultiPolygon",a.rings=g)}return lo((0,zo[d])(a),!1,c)}function yo(a){var c="XY";!0===a.hasZ&&!0===a.hasM?c="XYZM":!0===a.hasZ?c="XYZ":!0===a.hasM&&(c="XYM");return c}function Ao(a){a=a.f;return{hasZ:"XYZ"===a||"XYZM"===a,hasM:"XYM"===a||"XYZM"===a}} +var zo={Point:function(a){return void 0!==a.m&&void 0!==a.z?new D([a.x,a.y,a.z,a.m],"XYZM"):void 0!==a.z?new D([a.x,a.y,a.z],"XYZ"):void 0!==a.m?new D([a.x,a.y,a.m],"XYM"):new D([a.x,a.y])},LineString:function(a){return new T(a.paths[0],yo(a))},Polygon:function(a){return new F(a.rings,yo(a))},MultiPoint:function(a){return new so(a.points,yo(a))},MultiLineString:function(a){return new U(a.paths,yo(a))},MultiPolygon:function(a){return new to(a.rings,yo(a))}},Bo={Point:function(a){var c=a.Z();a=a.f; +if("XYZ"===a)return{x:c[0],y:c[1],z:c[2]};if("XYM"===a)return{x:c[0],y:c[1],m:c[2]};if("XYZM"===a)return{x:c[0],y:c[1],z:c[2],m:c[3]};if("XY"===a)return{x:c[0],y:c[1]}},LineString:function(a){var c=Ao(a);return{hasZ:c.hasZ,hasM:c.hasM,paths:[a.Z()]}},Polygon:function(a){var c=Ao(a);return{hasZ:c.hasZ,hasM:c.hasM,rings:a.Z(!1)}},MultiPoint:function(a){var c=Ao(a);return{hasZ:c.hasZ,hasM:c.hasM,points:a.Z()}},MultiLineString:function(a){var c=Ao(a);return{hasZ:c.hasZ,hasM:c.hasM,paths:a.Z()}},MultiPolygon:function(a){var c= +Ao(a);a=a.Z(!1);for(var d=[],e=0;e<a.length;e++)for(var f=a[e].length-1;0<=f;f--)d.push(a[e][f]);return{hasZ:c.hasZ,hasM:c.hasM,rings:d}}};l=wo.prototype;l.Pc=function(a,c){var d=xo(a.geometry,c),e=new zl;this.b&&e.zc(this.b);e.Ta(d);c&&c.hf&&a.attributes[c.hf]&&e.hc(a.attributes[c.hf]);a.attributes&&e.C(a.attributes);return e}; +l.Ff=function(a,c){var d=c?c:{};if(a.features){var e=[],f=a.features,g,h;d.hf=a.objectIdFieldName;g=0;for(h=f.length;g<h;++g)e.push(this.Pc(f[g],d));return e}return[this.Pc(a,d)]};l.Mh=function(a,c){return xo(a,c)};l.Th=function(a){return a.spatialReference&&a.spatialReference.wkid?Ic("EPSG:"+a.spatialReference.wkid):null};function Co(a,c){return(0,Bo[a.X()])(lo(a,!0,c),c)}l.Ge=function(a,c){return Co(a,ko(this,c))}; +l.Tc=function(a,c){c=ko(this,c);var d={},e=a.W();e&&(d.geometry=Co(e,c));e=a.L();delete e[a.a];d.attributes=Sa(e)?{}:e;c&&c.featureProjection&&(d.spatialReference={wkid:Ic(c.featureProjection).eb.split(":").pop()});return d};l.Ee=function(a,c){c=ko(this,c);var d=[],e,f;e=0;for(f=a.length;e<f;++e)d.push(this.Tc(a[e],c));return{features:d}};function Do(a){dd.call(this);this.c=a?a:null;Eo(this)}y(Do,dd);function Fo(a){var c=[],d,e;d=0;for(e=a.length;d<e;++d)c.push(a[d].clone());return c}function Go(a){var c,d;if(a.c)for(c=0,d=a.c.length;c<d;++c)cb(a.c[c],"change",a.u,a)}function Eo(a){var c,d;if(a.c)for(c=0,d=a.c.length;c<d;++c)C(a.c[c],"change",a.u,a)}l=Do.prototype;l.clone=function(){var a=new Do(null);a.ci(this.c);return a}; +l.rb=function(a,c,d,e){if(e<$b(this.O(),a,c))return e;var f=this.c,g,h;g=0;for(h=f.length;g<h;++g)e=f[g].rb(a,c,d,e);return e};l.wc=function(a,c){var d=this.c,e,f;e=0;for(f=d.length;e<f;++e)if(d[e].wc(a,c))return!0;return!1};l.Jd=function(a){ec(Infinity,Infinity,-Infinity,-Infinity,a);for(var c=this.c,d=0,e=c.length;d<e;++d)jc(a,c[d].O());return a};l.bf=function(){return Fo(this.c)}; +l.hd=function(a){this.s!=this.g&&(Qa(this.l),this.o=0,this.s=this.g);if(0>a||0!==this.o&&a<this.o)return this;var c=a.toString();if(this.l.hasOwnProperty(c))return this.l[c];var d=[],e=this.c,f=!1,g,h;g=0;for(h=e.length;g<h;++g){var k=e[g],m=k.hd(a);d.push(m);m!==k&&(f=!0)}if(f)return a=new Do(null),Go(a),a.c=d,Eo(a),a.u(),this.l[c]=a;this.o=a;return this};l.X=function(){return"GeometryCollection"};l.Ia=function(a){var c=this.c,d,e;d=0;for(e=c.length;d<e;++d)if(c[d].Ia(a))return!0;return!1}; +l.Sa=function(){return 0===this.c.length};l.rotate=function(a,c){for(var d=this.c,e=0,f=d.length;e<f;++e)d[e].rotate(a,c);this.u()};l.ci=function(a){a=Fo(a);Go(this);this.c=a;Eo(this);this.u()};l.mc=function(a){var c=this.c,d,e;d=0;for(e=c.length;d<e;++d)c[d].mc(a);this.u()};l.Nc=function(a,c){var d=this.c,e,f;e=0;for(f=d.length;e<f;++e)d[e].Nc(a,c);this.u()};l.fa=function(){Go(this);Do.ia.fa.call(this)};function Ho(a){a=a?a:{};this.defaultDataProjection=null;this.defaultDataProjection=Ic(a.defaultDataProjection?a.defaultDataProjection:"EPSG:4326");this.b=a.geometryName}y(Ho,mo);function Io(a,c){return a?lo((0,Jo[a.type])(a),!1,c):null}function Ko(a,c){return(0,Lo[a.X()])(lo(a,!0,c),c)} +var Jo={Point:function(a){return new D(a.coordinates)},LineString:function(a){return new T(a.coordinates)},Polygon:function(a){return new F(a.coordinates)},MultiPoint:function(a){return new so(a.coordinates)},MultiLineString:function(a){return new U(a.coordinates)},MultiPolygon:function(a){return new to(a.coordinates)},GeometryCollection:function(a,c){var d=a.geometries.map(function(a){return Io(a,c)});return new Do(d)}},Lo={Point:function(a){return{type:"Point",coordinates:a.Z()}},LineString:function(a){return{type:"LineString", +coordinates:a.Z()}},Polygon:function(a,c){var d;c&&(d=c.rightHanded);return{type:"Polygon",coordinates:a.Z(d)}},MultiPoint:function(a){return{type:"MultiPoint",coordinates:a.Z()}},MultiLineString:function(a){return{type:"MultiLineString",coordinates:a.Z()}},MultiPolygon:function(a,c){var d;c&&(d=c.rightHanded);return{type:"MultiPolygon",coordinates:a.Z(d)}},GeometryCollection:function(a,c){return{type:"GeometryCollection",geometries:a.c.map(function(a){var e=Pa({},c);delete e.featureProjection;return Ko(a, +e)})}},Circle:function(){return{type:"GeometryCollection",geometries:[]}}};l=Ho.prototype;l.Pc=function(a,c){var d=Io(a.geometry,c),e=new zl;this.b&&e.zc(this.b);e.Ta(d);void 0!==a.id&&e.hc(a.id);a.properties&&e.C(a.properties);return e};l.Ff=function(a,c){if("Feature"==a.type)return[this.Pc(a,c)];if("FeatureCollection"==a.type){var d=[],e=a.features,f,g;f=0;for(g=e.length;f<g;++f)d.push(this.Pc(e[f],c));return d}return[]};l.Mh=function(a,c){return Io(a,c)}; +l.Th=function(a){return(a=a.crs)?"name"==a.type?Ic(a.properties.name):"EPSG"==a.type?Ic("EPSG:"+a.properties.code):null:this.defaultDataProjection};l.Tc=function(a,c){c=ko(this,c);var d={type:"Feature"},e=a.Wa();void 0!==e&&(d.id=e);(e=a.W())?d.geometry=Ko(e,c):d.geometry=null;e=a.L();delete e[a.a];Sa(e)?d.properties=null:d.properties=e;return d};l.Ee=function(a,c){c=ko(this,c);var d=[],e,f;e=0;for(f=a.length;e<f;++e)d.push(this.Tc(a[e],c));return{type:"FeatureCollection",features:d}}; +l.Ge=function(a,c){return Ko(a,ko(this,c))};function Mo(){this.f=new XMLSerializer;this.defaultDataProjection=null}y(Mo,io);l=Mo.prototype;l.X=function(){return"xml"};l.Nb=function(a,c){if(Gl(a))return No(this,a,c);if(Hl(a))return this.Kh(a,c);if("string"===typeof a){var d=Il(a);return No(this,d,c)}return null};function No(a,c,d){a=Oo(a,c,d);return 0<a.length?a[0]:null}l.Ca=function(a,c){if(Gl(a))return Oo(this,a,c);if(Hl(a))return this.gc(a,c);if("string"===typeof a){var d=Il(a);return Oo(this,d,c)}return[]}; +function Oo(a,c,d){var e=[];for(c=c.firstChild;c;c=c.nextSibling)1==c.nodeType&&xb(e,a.gc(c,d));return e}l.Qc=function(a,c){if(Gl(a))return this.v(a,c);if(Hl(a)){var d=this.te(a,[jo(this,a,c?c:{})]);return d?d:null}return"string"===typeof a?(d=Il(a),this.v(d,c)):null};l.Oa=function(a){return Gl(a)?this.Lf(a):Hl(a)?this.we(a):"string"===typeof a?(a=Il(a),this.Lf(a)):null};l.Lf=function(){return this.defaultDataProjection};l.we=function(){return this.defaultDataProjection}; +l.yd=function(a,c){var d=this.B(a,c);return this.f.serializeToString(d)};l.Sb=function(a,c){var d=this.a(a,c);return this.f.serializeToString(d)};l.Uc=function(a,c){var d=this.s(a,c);return this.f.serializeToString(d)};function Po(a){a=a?a:{};this.featureType=a.featureType;this.featureNS=a.featureNS;this.srsName=a.srsName;this.schemaLocation="";this.b={};this.b["http://www.opengis.net/gml"]={featureMember:Ll(Po.prototype.qd),featureMembers:Ll(Po.prototype.qd)};Mo.call(this)}y(Po,Mo);var Qo=/^[\s\xa0]*$/;l=Po.prototype; +l.qd=function(a,c){var d=a.localName,e=null;if("FeatureCollection"==d)"http://www.opengis.net/wfs"===a.namespaceURI?e=P([],this.b,a,c,this):e=P(null,this.b,a,c,this);else if("featureMembers"==d||"featureMember"==d){var f=c[0],g=f.featureType,h=f.featureNS,k,m;if(!g&&a.childNodes){g=[];h={};k=0;for(m=a.childNodes.length;k<m;++k){var n=a.childNodes[k];if(1===n.nodeType){var p=n.nodeName.split(":").pop();if(-1===g.indexOf(p)){var q="",r=0,n=n.namespaceURI,u;for(u in h){if(h[u]===n){q=u;break}++r}q|| +(q="p"+r,h[q]=n);g.push(q+":"+p)}}}"featureMember"!=d&&(f.featureType=g,f.featureNS=h)}"string"===typeof h&&(k=h,h={},h.p0=k);var f={},g=Array.isArray(g)?g:[g],v;for(v in h){p={};k=0;for(m=g.length;k<m;++k)(-1===g[k].indexOf(":")?"p0":g[k].split(":")[0])===v&&(p[g[k].split(":").pop()]="featureMembers"==d?Kl(this.Ef,this):Ll(this.Ef,this));f[h[v]]=p}"featureMember"==d?e=P(void 0,f,a,c):e=P([],f,a,c)}null===e&&(e=[]);return e}; +l.te=function(a,c){var d=c[0];d.srsName=a.firstElementChild.getAttribute("srsName");var e=P(null,this.Yf,a,c,this);if(e)return lo(e,!1,d)}; +l.Ef=function(a,c){var d,e;(e=a.getAttribute("fid"))||(e=a.getAttributeNS("http://www.opengis.net/gml","id")||"");var f={},g;for(d=a.firstElementChild;d;d=d.nextElementSibling){var h=d.localName;if(0===d.childNodes.length||1===d.childNodes.length&&(3===d.firstChild.nodeType||4===d.firstChild.nodeType)){var k=El(d,!1);Qo.test(k)&&(k=void 0);f[h]=k}else"boundedBy"!==h&&(g=h),f[h]=this.te(d,c)}d=new zl(f);g&&d.zc(g);e&&d.hc(e);return d}; +l.Sh=function(a,c){var d=this.se(a,c);if(d){var e=new D(null);e.ba("XYZ",d);return e}};l.Qh=function(a,c){var d=P([],this.Pi,a,c,this);if(d)return new so(d)};l.Ph=function(a,c){var d=P([],this.Oi,a,c,this);if(d){var e=new U(null);ro(e,d);return e}};l.Rh=function(a,c){var d=P([],this.Qi,a,c,this);if(d){var e=new to(null);vo(e,d);return e}};l.Hh=function(a,c){Sl(this.Ti,a,c,this)};l.Pg=function(a,c){Sl(this.Mi,a,c,this)};l.Ih=function(a,c){Sl(this.Ui,a,c,this)}; +l.ue=function(a,c){var d=this.se(a,c);if(d){var e=new T(null);e.ba("XYZ",d);return e}};l.to=function(a,c){var d=P(null,this.Ad,a,c,this);if(d)return d};l.Oh=function(a,c){var d=this.se(a,c);if(d){var e=new Kd(null);Ld(e,"XYZ",d);return e}};l.ve=function(a,c){var d=P([null],this.Ie,a,c,this);if(d&&d[0]){var e=new F(null),f=d[0],g=[f.length],h,k;h=1;for(k=d.length;h<k;++h)xb(f,d[h]),g.push(f.length);e.ba("XYZ",f,g);return e}};l.se=function(a,c){return P(null,this.Ad,a,c,this)}; +l.Pi={"http://www.opengis.net/gml":{pointMember:Kl(Po.prototype.Hh),pointMembers:Kl(Po.prototype.Hh)}};l.Oi={"http://www.opengis.net/gml":{lineStringMember:Kl(Po.prototype.Pg),lineStringMembers:Kl(Po.prototype.Pg)}};l.Qi={"http://www.opengis.net/gml":{polygonMember:Kl(Po.prototype.Ih),polygonMembers:Kl(Po.prototype.Ih)}};l.Ti={"http://www.opengis.net/gml":{Point:Kl(Po.prototype.se)}};l.Mi={"http://www.opengis.net/gml":{LineString:Kl(Po.prototype.ue)}};l.Ui={"http://www.opengis.net/gml":{Polygon:Kl(Po.prototype.ve)}}; +l.Bd={"http://www.opengis.net/gml":{LinearRing:Ll(Po.prototype.to)}};l.gc=function(a,c){var d={featureType:this.featureType,featureNS:this.featureNS};c&&Pa(d,jo(this,a,c));return this.qd(a,[d])||[]};l.we=function(a){return Ic(this.srsName?this.srsName:a.firstElementChild.getAttribute("srsName"))};function Ro(a){a=El(a,!1);return So(a)}function So(a){if(a=/^\s*(true|1)|(false|0)\s*$/.exec(a))return void 0!==a[1]||!1} +function To(a){a=El(a,!1);if(a=/^\s*(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(Z|(?:([+\-])(\d{2})(?::(\d{2}))?))\s*$/.exec(a)){var c=Date.UTC(parseInt(a[1],10),parseInt(a[2],10)-1,parseInt(a[3],10),parseInt(a[4],10),parseInt(a[5],10),parseInt(a[6],10))/1E3;if("Z"!=a[7]){var d="-"==a[8]?-1:1,c=c+60*d*parseInt(a[9],10);void 0!==a[10]&&(c+=3600*d*parseInt(a[10],10))}return c}}function Uo(a){a=El(a,!1);return Vo(a)} +function Vo(a){if(a=/^\s*([+\-]?\d*\.?\d+(?:e[+\-]?\d+)?)\s*$/i.exec(a))return parseFloat(a[1])}function Wo(a){a=El(a,!1);return Xo(a)}function Xo(a){if(a=/^\s*(\d+)\s*$/.exec(a))return parseInt(a[1],10)}function V(a){return El(a,!1).trim()}function Yo(a,c){Zo(a,c?"1":"0")}function $o(a,c){a.appendChild(Cl.createTextNode(c.toPrecision()))}function ap(a,c){a.appendChild(Cl.createTextNode(c.toString()))}function Zo(a,c){a.appendChild(Cl.createTextNode(c))};function bp(a){a=a?a:{};Po.call(this,a);this.b["http://www.opengis.net/gml"].featureMember=Kl(Po.prototype.qd);this.schemaLocation=a.schemaLocation?a.schemaLocation:"http://www.opengis.net/gml http://schemas.opengis.net/gml/2.1.2/feature.xsd"}y(bp,Po);l=bp.prototype; +l.Lh=function(a,c){var d=El(a,!1).replace(/^\s*|\s*$/g,""),e=c[0].srsName,f=a.parentNode.getAttribute("srsDimension"),g="enu";e&&(e=Ic(e))&&(g=e.b);d=d.split(/[\s,]+/);e=2;a.getAttribute("srsDimension")?e=Xo(a.getAttribute("srsDimension")):a.getAttribute("dimension")?e=Xo(a.getAttribute("dimension")):f&&(e=Xo(f));for(var h,k,m=[],n=0,p=d.length;n<p;n+=e)f=parseFloat(d[n]),h=parseFloat(d[n+1]),k=3===e?parseFloat(d[n+2]):0,"en"===g.substr(0,2)?m.push(f,h,k):m.push(h,f,k);return m}; +l.qo=function(a,c){var d=P([null],this.Ii,a,c,this);return ec(d[1][0],d[1][1],d[1][3],d[1][4])};l.il=function(a,c){var d=P(void 0,this.Bd,a,c,this);d&&c[c.length-1].push(d)};l.Yn=function(a,c){var d=P(void 0,this.Bd,a,c,this);d&&(c[c.length-1][0]=d)};l.Ad={"http://www.opengis.net/gml":{coordinates:Ll(bp.prototype.Lh)}};l.Ie={"http://www.opengis.net/gml":{innerBoundaryIs:bp.prototype.il,outerBoundaryIs:bp.prototype.Yn}};l.Ii={"http://www.opengis.net/gml":{coordinates:Kl(bp.prototype.Lh)}}; +l.Yf={"http://www.opengis.net/gml":{Point:Ll(Po.prototype.Sh),MultiPoint:Ll(Po.prototype.Qh),LineString:Ll(Po.prototype.ue),MultiLineString:Ll(Po.prototype.Ph),LinearRing:Ll(Po.prototype.Oh),Polygon:Ll(Po.prototype.ve),MultiPolygon:Ll(Po.prototype.Rh),Box:Ll(bp.prototype.qo)}};function cp(a){a=a?a:{};Po.call(this,a);this.j=void 0!==a.surface?a.surface:!1;this.i=void 0!==a.curve?a.curve:!1;this.l=void 0!==a.multiCurve?a.multiCurve:!0;this.o=void 0!==a.multiSurface?a.multiSurface:!0;this.schemaLocation=a.schemaLocation?a.schemaLocation:"http://www.opengis.net/gml http://schemas.opengis.net/gml/3.1.1/profiles/gmlsfProfile/1.0.0/gmlsf.xsd"}y(cp,Po);l=cp.prototype;l.xo=function(a,c){var d=P([],this.Ni,a,c,this);if(d){var e=new U(null);ro(e,d);return e}}; +l.yo=function(a,c){var d=P([],this.Ri,a,c,this);if(d){var e=new to(null);vo(e,d);return e}};l.rg=function(a,c){Sl(this.Ji,a,c,this)};l.pi=function(a,c){Sl(this.Yi,a,c,this)};l.Bo=function(a,c){return P([null],this.Si,a,c,this)};l.Do=function(a,c){return P([null],this.Xi,a,c,this)};l.Co=function(a,c){return P([null],this.Ie,a,c,this)};l.wo=function(a,c){return P([null],this.Ad,a,c,this)};l.kl=function(a,c){var d=P(void 0,this.Bd,a,c,this);d&&c[c.length-1].push(d)}; +l.Dj=function(a,c){var d=P(void 0,this.Bd,a,c,this);d&&(c[c.length-1][0]=d)};l.Uh=function(a,c){var d=P([null],this.Zi,a,c,this);if(d&&d[0]){var e=new F(null),f=d[0],g=[f.length],h,k;h=1;for(k=d.length;h<k;++h)xb(f,d[h]),g.push(f.length);e.ba("XYZ",f,g);return e}};l.Jh=function(a,c){var d=P([null],this.Ki,a,c,this);if(d){var e=new T(null);e.ba("XYZ",d);return e}};l.so=function(a,c){var d=P([null],this.Li,a,c,this);return ec(d[1][0],d[1][1],d[2][0],d[2][1])}; +l.uo=function(a,c){for(var d=El(a,!1),e=/^\s*([+\-]?\d*\.?\d+(?:[eE][+\-]?\d+)?)\s*/,f=[],g;g=e.exec(d);)f.push(parseFloat(g[1])),d=d.substr(g[0].length);if(""===d){d=c[0].srsName;e="enu";d&&(e=Ic(d).b);if("neu"===e)for(d=0,e=f.length;d<e;d+=3)g=f[d],f[d]=f[d+1],f[d+1]=g;d=f.length;2==d&&f.push(0);return 0===d?void 0:f}}; +l.If=function(a,c){var d=El(a,!1).replace(/^\s*|\s*$/g,""),e=c[0].srsName,f=a.parentNode.getAttribute("srsDimension"),g="enu";e&&(g=Ic(e).b);d=d.split(/\s+/);e=2;a.getAttribute("srsDimension")?e=Xo(a.getAttribute("srsDimension")):a.getAttribute("dimension")?e=Xo(a.getAttribute("dimension")):f&&(e=Xo(f));for(var h,k,m=[],n=0,p=d.length;n<p;n+=e)f=parseFloat(d[n]),h=parseFloat(d[n+1]),k=3===e?parseFloat(d[n+2]):0,"en"===g.substr(0,2)?m.push(f,h,k):m.push(h,f,k);return m}; +l.Ad={"http://www.opengis.net/gml":{pos:Ll(cp.prototype.uo),posList:Ll(cp.prototype.If)}};l.Ie={"http://www.opengis.net/gml":{interior:cp.prototype.kl,exterior:cp.prototype.Dj}}; +l.Yf={"http://www.opengis.net/gml":{Point:Ll(Po.prototype.Sh),MultiPoint:Ll(Po.prototype.Qh),LineString:Ll(Po.prototype.ue),MultiLineString:Ll(Po.prototype.Ph),LinearRing:Ll(Po.prototype.Oh),Polygon:Ll(Po.prototype.ve),MultiPolygon:Ll(Po.prototype.Rh),Surface:Ll(cp.prototype.Uh),MultiSurface:Ll(cp.prototype.yo),Curve:Ll(cp.prototype.Jh),MultiCurve:Ll(cp.prototype.xo),Envelope:Ll(cp.prototype.so)}};l.Ni={"http://www.opengis.net/gml":{curveMember:Kl(cp.prototype.rg),curveMembers:Kl(cp.prototype.rg)}}; +l.Ri={"http://www.opengis.net/gml":{surfaceMember:Kl(cp.prototype.pi),surfaceMembers:Kl(cp.prototype.pi)}};l.Ji={"http://www.opengis.net/gml":{LineString:Kl(Po.prototype.ue),Curve:Kl(cp.prototype.Jh)}};l.Yi={"http://www.opengis.net/gml":{Polygon:Kl(Po.prototype.ve),Surface:Kl(cp.prototype.Uh)}};l.Zi={"http://www.opengis.net/gml":{patches:Ll(cp.prototype.Bo)}};l.Ki={"http://www.opengis.net/gml":{segments:Ll(cp.prototype.Do)}};l.Li={"http://www.opengis.net/gml":{lowerCorner:Kl(cp.prototype.If),upperCorner:Kl(cp.prototype.If)}}; +l.Si={"http://www.opengis.net/gml":{PolygonPatch:Ll(cp.prototype.Co)}};l.Xi={"http://www.opengis.net/gml":{LineStringSegment:Ll(cp.prototype.wo)}};function dp(a,c,d){d=d[d.length-1].srsName;c=c.Z();for(var e=c.length,f=Array(e),g,h=0;h<e;++h){g=c[h];var k=h,m="enu";d&&(m=Ic(d).b);f[k]="en"===m.substr(0,2)?g[0]+" "+g[1]:g[1]+" "+g[0]}Zo(a,f.join(" "))} +l.Ei=function(a,c,d){var e=d[d.length-1].srsName;e&&a.setAttribute("srsName",e);e=Dl(a.namespaceURI,"pos");a.appendChild(e);d=d[d.length-1].srsName;a="enu";d&&(a=Ic(d).b);c=c.Z();Zo(e,"en"===a.substr(0,2)?c[0]+" "+c[1]:c[1]+" "+c[0])};var ep={"http://www.opengis.net/gml":{lowerCorner:M(Zo),upperCorner:M(Zo)}};l=cp.prototype;l.rp=function(a,c,d){var e=d[d.length-1].srsName;e&&a.setAttribute("srsName",e);Tl({node:a},ep,Ql,[c[0]+" "+c[1],c[2]+" "+c[3]],d,["lowerCorner","upperCorner"],this)}; +l.Bi=function(a,c,d){var e=d[d.length-1].srsName;e&&a.setAttribute("srsName",e);e=Dl(a.namespaceURI,"posList");a.appendChild(e);dp(e,c,d)};l.Wi=function(a,c){var d=c[c.length-1],e=d.node,f=d.exteriorWritten;void 0===f&&(d.exteriorWritten=!0);return Dl(e.namespaceURI,void 0!==f?"interior":"exterior")}; +l.He=function(a,c,d){var e=d[d.length-1].srsName;"PolygonPatch"!==a.nodeName&&e&&a.setAttribute("srsName",e);"Polygon"===a.nodeName||"PolygonPatch"===a.nodeName?(c=c.Pd(),Tl({node:a,srsName:e},fp,this.Wi,c,d,void 0,this)):"Surface"===a.nodeName&&(e=Dl(a.namespaceURI,"patches"),a.appendChild(e),a=Dl(e.namespaceURI,"PolygonPatch"),e.appendChild(a),this.He(a,c,d))}; +l.Ce=function(a,c,d){var e=d[d.length-1].srsName;"LineStringSegment"!==a.nodeName&&e&&a.setAttribute("srsName",e);"LineString"===a.nodeName||"LineStringSegment"===a.nodeName?(e=Dl(a.namespaceURI,"posList"),a.appendChild(e),dp(e,c,d)):"Curve"===a.nodeName&&(e=Dl(a.namespaceURI,"segments"),a.appendChild(e),a=Dl(e.namespaceURI,"LineStringSegment"),e.appendChild(a),this.Ce(a,c,d))}; +l.Di=function(a,c,d){var e=d[d.length-1],f=e.srsName,e=e.surface;f&&a.setAttribute("srsName",f);c=c.Qd();Tl({node:a,srsName:f,surface:e},gp,this.c,c,d,void 0,this)};l.sp=function(a,c,d){var e=d[d.length-1].srsName;e&&a.setAttribute("srsName",e);c=c.ee();Tl({node:a,srsName:e},hp,Ol("pointMember"),c,d,void 0,this)};l.Ci=function(a,c,d){var e=d[d.length-1],f=e.srsName,e=e.curve;f&&a.setAttribute("srsName",f);c=c.gd();Tl({node:a,srsName:f,curve:e},ip,this.c,c,d,void 0,this)}; +l.Fi=function(a,c,d){var e=Dl(a.namespaceURI,"LinearRing");a.appendChild(e);this.Bi(e,c,d)};l.Gi=function(a,c,d){var e=this.g(c,d);e&&(a.appendChild(e),this.He(e,c,d))};l.tp=function(a,c,d){var e=Dl(a.namespaceURI,"Point");a.appendChild(e);this.Ei(e,c,d)};l.Ai=function(a,c,d){var e=this.g(c,d);e&&(a.appendChild(e),this.Ce(e,c,d))}; +l.Fe=function(a,c,d){var e=d[d.length-1],f=Pa({},e);f.node=a;var g;Array.isArray(c)?e.dataProjection?g=cd(c,e.featureProjection,e.dataProjection):g=c:g=lo(c,!0,e);Tl(f,jp,this.g,[g],d,void 0,this)}; +l.wi=function(a,c,d){var e=c.Wa();e&&a.setAttribute("fid",e);var e=d[d.length-1],f=e.featureNS,g=c.a;e.yc||(e.yc={},e.yc[f]={});var h=c.L();c=[];var k=[],m;for(m in h){var n=h[m];null!==n&&(c.push(m),k.push(n),m==g||n instanceof dd?m in e.yc[f]||(e.yc[f][m]=M(this.Fe,this)):m in e.yc[f]||(e.yc[f][m]=M(Zo)))}m=Pa({},e);m.node=a;Tl(m,e.yc,Ol(void 0,f),k,d,c)}; +var gp={"http://www.opengis.net/gml":{surfaceMember:M(cp.prototype.Gi),polygonMember:M(cp.prototype.Gi)}},hp={"http://www.opengis.net/gml":{pointMember:M(cp.prototype.tp)}},ip={"http://www.opengis.net/gml":{lineStringMember:M(cp.prototype.Ai),curveMember:M(cp.prototype.Ai)}},fp={"http://www.opengis.net/gml":{exterior:M(cp.prototype.Fi),interior:M(cp.prototype.Fi)}},jp={"http://www.opengis.net/gml":{Curve:M(cp.prototype.Ce),MultiCurve:M(cp.prototype.Ci),Point:M(cp.prototype.Ei),MultiPoint:M(cp.prototype.sp), +LineString:M(cp.prototype.Ce),MultiLineString:M(cp.prototype.Ci),LinearRing:M(cp.prototype.Bi),Polygon:M(cp.prototype.He),MultiPolygon:M(cp.prototype.Di),Surface:M(cp.prototype.He),MultiSurface:M(cp.prototype.Di),Envelope:M(cp.prototype.rp)}},kp={MultiLineString:"lineStringMember",MultiCurve:"curveMember",MultiPolygon:"polygonMember",MultiSurface:"surfaceMember"};cp.prototype.c=function(a,c){return Dl("http://www.opengis.net/gml",kp[c[c.length-1].node.nodeName])}; +cp.prototype.g=function(a,c){var d=c[c.length-1],e=d.multiSurface,f=d.surface,g=d.curve,d=d.multiCurve,h;Array.isArray(a)?h="Envelope":(h=a.X(),"MultiPolygon"===h&&!0===e?h="MultiSurface":"Polygon"===h&&!0===f?h="Surface":"LineString"===h&&!0===g?h="Curve":"MultiLineString"===h&&!0===d&&(h="MultiCurve"));return Dl("http://www.opengis.net/gml",h)}; +cp.prototype.s=function(a,c){c=ko(this,c);var d=Dl("http://www.opengis.net/gml","geom"),e={node:d,srsName:this.srsName,curve:this.i,surface:this.j,multiSurface:this.o,multiCurve:this.l};c&&Pa(e,c);this.Fe(d,a,[e]);return d}; +cp.prototype.a=function(a,c){c=ko(this,c);var d=Dl("http://www.opengis.net/gml","featureMembers");d.setAttributeNS("http://www.w3.org/2001/XMLSchema-instance","xsi:schemaLocation",this.schemaLocation);var e={srsName:this.srsName,curve:this.i,surface:this.j,multiSurface:this.o,multiCurve:this.l,featureNS:this.featureNS,featureType:this.featureType};c&&Pa(e,c);var e=[e],f=e[e.length-1],g=f.featureType,h=f.featureNS,k={};k[h]={};k[h][g]=M(this.wi,this);f=Pa({},f);f.node=d;Tl(f,k,Ol(g,h),a,e);return d};function lp(a){a=a?a:{};Mo.call(this);this.defaultDataProjection=Ic("EPSG:4326");this.b=a.readExtensions}y(lp,Mo);var mp=[null,"http://www.topografix.com/GPX/1/0","http://www.topografix.com/GPX/1/1"];function np(a,c,d){a.push(parseFloat(c.getAttribute("lon")),parseFloat(c.getAttribute("lat")));"ele"in d?(a.push(d.ele),delete d.ele):a.push(0);"time"in d?(a.push(d.time),delete d.time):a.push(0);return a}function op(a,c){var d=c[c.length-1],e=a.getAttribute("href");null!==e&&(d.link=e);Sl(pp,a,c)} +function qp(a,c){c[c.length-1].extensionsNode_=a}function rp(a,c){var d=c[0],e=P({flatCoordinates:[]},sp,a,c);if(e){var f=e.flatCoordinates;delete e.flatCoordinates;var g=new T(null);g.ba("XYZM",f);lo(g,!1,d);d=new zl(g);d.C(e);return d}}function tp(a,c){var d=c[0],e=P({flatCoordinates:[],ends:[]},up,a,c);if(e){var f=e.flatCoordinates;delete e.flatCoordinates;var g=e.ends;delete e.ends;var h=new U(null);h.ba("XYZM",f,g);lo(h,!1,d);d=new zl(h);d.C(e);return d}} +function vp(a,c){var d=c[0],e=P({},wp,a,c);if(e){var f=np([],a,e),f=new D(f,"XYZM");lo(f,!1,d);d=new zl(f);d.C(e);return d}} +var xp={rte:rp,trk:tp,wpt:vp},yp=N(mp,{rte:Kl(rp),trk:Kl(tp),wpt:Kl(vp)}),pp=N(mp,{text:K(V,"linkText"),type:K(V,"linkType")}),sp=N(mp,{name:K(V),cmt:K(V),desc:K(V),src:K(V),link:op,number:K(Wo),extensions:qp,type:K(V),rtept:function(a,c){var d=P({},zp,a,c);d&&np(c[c.length-1].flatCoordinates,a,d)}}),zp=N(mp,{ele:K(Uo),time:K(To)}),up=N(mp,{name:K(V),cmt:K(V),desc:K(V),src:K(V),link:op,number:K(Wo),type:K(V),extensions:qp,trkseg:function(a,c){var d=c[c.length-1];Sl(Ap,a,c);d.ends.push(d.flatCoordinates.length)}}), +Ap=N(mp,{trkpt:function(a,c){var d=P({},Bp,a,c);d&&np(c[c.length-1].flatCoordinates,a,d)}}),Bp=N(mp,{ele:K(Uo),time:K(To)}),wp=N(mp,{ele:K(Uo),time:K(To),magvar:K(Uo),geoidheight:K(Uo),name:K(V),cmt:K(V),desc:K(V),src:K(V),link:op,sym:K(V),type:K(V),fix:K(V),sat:K(Wo),hdop:K(Uo),vdop:K(Uo),pdop:K(Uo),ageofdgpsdata:K(Uo),dgpsid:K(Wo),extensions:qp}); +function Cp(a,c){c||(c=[]);for(var d=0,e=c.length;d<e;++d){var f=c[d];if(a.b){var g=f.get("extensionsNode_")||null;a.b(f,g)}f.set("extensionsNode_",void 0)}}lp.prototype.Kh=function(a,c){if(!ub(mp,a.namespaceURI))return null;var d=xp[a.localName];if(!d)return null;d=d(a,[jo(this,a,c)]);if(!d)return null;Cp(this,[d]);return d};lp.prototype.gc=function(a,c){if(!ub(mp,a.namespaceURI))return[];if("gpx"==a.localName){var d=P([],yp,a,[jo(this,a,c)]);if(d)return Cp(this,d),d}return[]}; +function Dp(a,c,d){a.setAttribute("href",c);c=d[d.length-1].properties;Tl({node:a},Ep,Ql,[c.linkText,c.linkType],d,Fp)}function Gp(a,c,d){var e=d[d.length-1],f=e.node.namespaceURI,g=e.properties;a.setAttributeNS(null,"lat",c[1]);a.setAttributeNS(null,"lon",c[0]);switch(e.geometryLayout){case "XYZM":0!==c[3]&&(g.time=c[3]);case "XYZ":0!==c[2]&&(g.ele=c[2]);break;case "XYM":0!==c[2]&&(g.time=c[2])}c=Hp[f];e=Rl(g,c);Tl({node:a,properties:g},Ip,Ql,e,d,c)} +var Fp=["text","type"],Ep=N(mp,{text:M(Zo),type:M(Zo)}),Jp=N(mp,"name cmt desc src link number type rtept".split(" ")),Kp=N(mp,{name:M(Zo),cmt:M(Zo),desc:M(Zo),src:M(Zo),link:M(Dp),number:M(ap),type:M(Zo),rtept:Nl(M(Gp))}),Lp=N(mp,"name cmt desc src link number type trkseg".split(" ")),Op=N(mp,{name:M(Zo),cmt:M(Zo),desc:M(Zo),src:M(Zo),link:M(Dp),number:M(ap),type:M(Zo),trkseg:Nl(M(function(a,c,d){Tl({node:a,geometryLayout:c.f,properties:{}},Mp,Np,c.Z(),d)}))}),Np=Ol("trkpt"),Mp=N(mp,{trkpt:M(Gp)}), +Hp=N(mp,"ele time magvar geoidheight name cmt desc src link sym type fix sat hdop vdop pdop ageofdgpsdata dgpsid".split(" ")),Ip=N(mp,{ele:M($o),time:M(function(a,c){var d=new Date(1E3*c);a.appendChild(Cl.createTextNode(d.getUTCFullYear()+"-"+Kb(d.getUTCMonth()+1)+"-"+Kb(d.getUTCDate())+"T"+Kb(d.getUTCHours())+":"+Kb(d.getUTCMinutes())+":"+Kb(d.getUTCSeconds())+"Z"))}),magvar:M($o),geoidheight:M($o),name:M(Zo),cmt:M(Zo),desc:M(Zo),src:M(Zo),link:M(Dp),sym:M(Zo),type:M(Zo),fix:M(Zo),sat:M(ap),hdop:M($o), +vdop:M($o),pdop:M($o),ageofdgpsdata:M($o),dgpsid:M(ap)}),Pp={Point:"wpt",LineString:"rte",MultiLineString:"trk"};function Qp(a,c){var d=a.W();if(d&&(d=Pp[d.X()]))return Dl(c[c.length-1].node.namespaceURI,d)} +var Rp=N(mp,{rte:M(function(a,c,d){var e=d[0],f=c.L();a={node:a,properties:f};if(c=c.W())c=lo(c,!0,e),a.geometryLayout=c.f,f.rtept=c.Z();e=Jp[d[d.length-1].node.namespaceURI];f=Rl(f,e);Tl(a,Kp,Ql,f,d,e)}),trk:M(function(a,c,d){var e=d[0],f=c.L();a={node:a,properties:f};if(c=c.W())c=lo(c,!0,e),f.trkseg=c.gd();e=Lp[d[d.length-1].node.namespaceURI];f=Rl(f,e);Tl(a,Op,Ql,f,d,e)}),wpt:M(function(a,c,d){var e=d[0],f=d[d.length-1];f.properties=c.L();if(c=c.W())c=lo(c,!0,e),f.geometryLayout=c.f,Gp(a,c.Z(), +d)})});lp.prototype.a=function(a,c){c=ko(this,c);var d=Dl("http://www.topografix.com/GPX/1/1","gpx");Tl({node:d},Rp,Qp,a,[c]);return d};function Sp(){this.defaultDataProjection=null}y(Sp,io);function Tp(a){return"string"===typeof a?a:""}l=Sp.prototype;l.X=function(){return"text"};l.Nb=function(a,c){return this.pd(Tp(a),ko(this,c))};l.Ca=function(a,c){return this.Gf(Tp(a),ko(this,c))};l.Qc=function(a,c){return this.rd(Tp(a),ko(this,c))};l.Oa=function(a){Tp(a);return this.defaultDataProjection};l.yd=function(a,c){return this.De(a,ko(this,c))};l.Sb=function(a,c){return this.xi(a,ko(this,c))}; +l.Uc=function(a,c){return this.zd(a,ko(this,c))};function Up(a){a=a?a:{};this.defaultDataProjection=null;this.defaultDataProjection=Ic("EPSG:4326");this.b=a.altitudeMode?a.altitudeMode:"none"}y(Up,Sp);var Vp=/^B(\d{2})(\d{2})(\d{2})(\d{2})(\d{5})([NS])(\d{3})(\d{5})([EW])([AV])(\d{5})(\d{5})/,Wp=/^H.([A-Z]{3}).*?:(.*)/,Xp=/^HFDTE(\d{2})(\d{2})(\d{2})/,Yp=/\r\n|\r|\n/; +Up.prototype.pd=function(a,c){var d=this.b,e=a.split(Yp),f={},g=[],h=2E3,k=0,m=1,n,p;n=0;for(p=e.length;n<p;++n){var q=e[n],r;if("B"==q.charAt(0)){if(r=Vp.exec(q)){var q=parseInt(r[1],10),u=parseInt(r[2],10),v=parseInt(r[3],10),x=parseInt(r[4],10)+parseInt(r[5],10)/6E4;"S"==r[6]&&(x=-x);var z=parseInt(r[7],10)+parseInt(r[8],10)/6E4;"W"==r[9]&&(z=-z);g.push(z,x);"none"!=d&&g.push("gps"==d?parseInt(r[11],10):"barometric"==d?parseInt(r[12],10):0);g.push(Date.UTC(h,k,m,q,u,v)/1E3)}}else"H"==q.charAt(0)&& +((r=Xp.exec(q))?(m=parseInt(r[1],10),k=parseInt(r[2],10)-1,h=2E3+parseInt(r[3],10)):(r=Wp.exec(q))&&(f[r[1]]=r[2].trim()))}if(0===g.length)return null;e=new T(null);e.ba("none"==d?"XYM":"XYZM",g);d=new zl(lo(e,!1,c));d.C(f);return d};Up.prototype.Gf=function(a,c){var d=this.pd(a,c);return d?[d]:[]};function Zp(a,c){this.a={};this.b=[];this.g=0;var d=arguments.length;if(1<d){if(d%2)throw Error("Uneven number of arguments");for(var e=0;e<d;e+=2)this.set(arguments[e],arguments[e+1])}else if(a){var f;if(a instanceof Zp)f=a.K(),e=a.uc();else{var d=[],g=0;for(f in a)d[g++]=f;f=d;d=[];g=0;for(e in a)d[g++]=a[e];e=d}for(d=0;d<f.length;d++)this.set(f[d],e[d])}}l=Zp.prototype;l.rc=function(){return this.g};l.uc=function(){$p(this);for(var a=[],c=0;c<this.b.length;c++)a.push(this.a[this.b[c]]);return a}; +l.K=function(){$p(this);return this.b.concat()};l.Sa=function(){return 0==this.g};l.clear=function(){this.a={};this.g=this.b.length=0};l.remove=function(a){return aq(this.a,a)?(delete this.a[a],this.g--,this.b.length>2*this.g&&$p(this),!0):!1};function $p(a){if(a.g!=a.b.length){for(var c=0,d=0;c<a.b.length;){var e=a.b[c];aq(a.a,e)&&(a.b[d++]=e);c++}a.b.length=d}if(a.g!=a.b.length){for(var f={},d=c=0;c<a.b.length;)e=a.b[c],aq(f,e)||(a.b[d++]=e,f[e]=1),c++;a.b.length=d}} +l.get=function(a,c){return aq(this.a,a)?this.a[a]:c};l.set=function(a,c){aq(this.a,a)||(this.g++,this.b.push(a));this.a[a]=c};l.forEach=function(a,c){for(var d=this.K(),e=0;e<d.length;e++){var f=d[e],g=this.get(f);a.call(c,g,f,this)}};l.clone=function(){return new Zp(this)};function aq(a,c){return Object.prototype.hasOwnProperty.call(a,c)};var bq=/^(?:([^:/?#.]+):)?(?:\/\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\?([^#]*))?(?:#(.*))?$/;function cq(a,c){if(a)for(var d=a.split("&"),e=0;e<d.length;e++){var f=d[e].indexOf("="),g=null,h=null;0<=f?(g=d[e].substring(0,f),h=d[e].substring(f+1)):g=d[e];c(g,h?decodeURIComponent(h.replace(/\+/g," ")):"")}} +function dq(a){if(a[1]){var c=a[0],d=c.indexOf("#");0<=d&&(a.push(c.substr(d)),a[0]=c=c.substr(0,d));d=c.indexOf("?");0>d?a[1]="?":d==c.length-1&&(a[1]=void 0)}return a.join("")}function eq(a,c,d){if("array"==ca(c))for(var e=0;e<c.length;e++)eq(a,String(c[e]),d);else null!=c&&d.push("&",a,""===c?"":"=",encodeURIComponent(String(c)))}function fq(a,c){for(var d in c)eq(d,c[d],a);return a};function gq(a,c){this.a=this.l=this.g="";this.o=null;this.f=this.b="";this.c=!1;var d;a instanceof gq?(this.c=void 0!==c?c:a.c,hq(this,a.g),this.l=a.l,this.a=a.a,iq(this,a.o),this.b=a.b,jq(this,a.i.clone()),this.f=a.f):a&&(d=String(a).match(bq))?(this.c=!!c,hq(this,d[1]||"",!0),this.l=kq(d[2]||""),this.a=kq(d[3]||"",!0),iq(this,d[4]),this.b=kq(d[5]||"",!0),jq(this,d[6]||"",!0),this.f=kq(d[7]||"")):(this.c=!!c,this.i=new lq(null,0,this.c))} +gq.prototype.toString=function(){var a=[],c=this.g;c&&a.push(mq(c,nq,!0),":");var d=this.a;if(d||"file"==c)a.push("//"),(c=this.l)&&a.push(mq(c,nq,!0),"@"),a.push(encodeURIComponent(String(d)).replace(/%25([0-9a-fA-F]{2})/g,"%$1")),d=this.o,null!=d&&a.push(":",String(d));if(d=this.b)this.a&&"/"!=d.charAt(0)&&a.push("/"),a.push(mq(d,"/"==d.charAt(0)?oq:pq,!0));(d=this.i.toString())&&a.push("?",d);(d=this.f)&&a.push("#",mq(d,qq));return a.join("")};gq.prototype.clone=function(){return new gq(this)}; +function hq(a,c,d){a.g=d?kq(c,!0):c;a.g&&(a.g=a.g.replace(/:$/,""))}function iq(a,c){if(c){c=Number(c);if(isNaN(c)||0>c)throw Error("Bad port number "+c);a.o=c}else a.o=null}function jq(a,c,d){c instanceof lq?(a.i=c,rq(a.i,a.c)):(d||(c=mq(c,sq)),a.i=new lq(c,0,a.c))}function tq(a){return a instanceof gq?a.clone():new gq(a,void 0)} +function uq(a,c){a instanceof gq||(a=tq(a));c instanceof gq||(c=tq(c));var d=a,e=c,f=d.clone(),g=!!e.g;g?hq(f,e.g):g=!!e.l;g?f.l=e.l:g=!!e.a;g?f.a=e.a:g=null!=e.o;var h=e.b;if(g)iq(f,e.o);else if(g=!!e.b)if("/"!=h.charAt(0)&&(d.a&&!d.b?h="/"+h:(d=f.b.lastIndexOf("/"),-1!=d&&(h=f.b.substr(0,d+1)+h))),d=h,".."==d||"."==d)h="";else if(-1!=d.indexOf("./")||-1!=d.indexOf("/.")){for(var h=0==d.lastIndexOf("/",0),d=d.split("/"),k=[],m=0;m<d.length;){var n=d[m++];"."==n?h&&m==d.length&&k.push(""):".."==n? +((1<k.length||1==k.length&&""!=k[0])&&k.pop(),h&&m==d.length&&k.push("")):(k.push(n),h=!0)}h=k.join("/")}else h=d;g?f.b=h:g=""!==e.i.toString();g?jq(f,kq(e.i.toString())):g=!!e.f;g&&(f.f=e.f);return f}function kq(a,c){return a?c?decodeURI(a.replace(/%25/g,"%2525")):decodeURIComponent(a):""}function mq(a,c,d){return ea(a)?(a=encodeURI(a).replace(c,vq),d&&(a=a.replace(/%25([0-9a-fA-F]{2})/g,"%$1")),a):null}function vq(a){a=a.charCodeAt(0);return"%"+(a>>4&15).toString(16)+(a&15).toString(16)} +var nq=/[#\/\?@]/g,pq=/[\#\?:]/g,oq=/[\#\?]/g,sq=/[\#\?@]/g,qq=/#/g;function lq(a,c,d){this.a=this.b=null;this.g=a||null;this.f=!!d}function wq(a){a.b||(a.b=new Zp,a.a=0,a.g&&cq(a.g,function(c,d){a.add(decodeURIComponent(c.replace(/\+/g," ")),d)}))}l=lq.prototype;l.rc=function(){wq(this);return this.a};l.add=function(a,c){wq(this);this.g=null;a=xq(this,a);var d=this.b.get(a);d||this.b.set(a,d=[]);d.push(c);this.a=this.a+1;return this}; +l.remove=function(a){wq(this);a=xq(this,a);return aq(this.b.a,a)?(this.g=null,this.a=this.a-this.b.get(a).length,this.b.remove(a)):!1};l.clear=function(){this.b=this.g=null;this.a=0};l.Sa=function(){wq(this);return 0==this.a};function yq(a,c){wq(a);c=xq(a,c);return aq(a.b.a,c)}l.K=function(){wq(this);for(var a=this.b.uc(),c=this.b.K(),d=[],e=0;e<c.length;e++)for(var f=a[e],g=0;g<f.length;g++)d.push(c[e]);return d}; +l.uc=function(a){wq(this);var c=[];if(ea(a))yq(this,a)&&(c=ze(c,this.b.get(xq(this,a))));else{a=this.b.uc();for(var d=0;d<a.length;d++)c=ze(c,a[d])}return c};l.set=function(a,c){wq(this);this.g=null;a=xq(this,a);yq(this,a)&&(this.a=this.a-this.b.get(a).length);this.b.set(a,[c]);this.a=this.a+1;return this};l.get=function(a,c){var d=a?this.uc(a):[];return 0<d.length?String(d[0]):c}; +l.toString=function(){if(this.g)return this.g;if(!this.b)return"";for(var a=[],c=this.b.K(),d=0;d<c.length;d++)for(var e=c[d],f=encodeURIComponent(String(e)),e=this.uc(e),g=0;g<e.length;g++){var h=f;""!==e[g]&&(h+="="+encodeURIComponent(String(e[g])));a.push(h)}return this.g=a.join("&")};l.clone=function(){var a=new lq;a.g=this.g;this.b&&(a.b=this.b.clone(),a.a=this.a);return a};function xq(a,c){var d=String(c);a.f&&(d=d.toLowerCase());return d} +function rq(a,c){c&&!a.f&&(wq(a),a.g=null,a.b.forEach(function(a,c){var f=c.toLowerCase();c!=f&&(this.remove(c),this.remove(f),0<a.length&&(this.g=null,this.b.set(xq(this,f),Ae(a)),this.a=this.a+a.length))},a));a.f=c};function zq(a){a=a||{};this.g=a.font;this.i=a.rotation;this.a=a.scale;this.s=a.text;this.o=a.textAlign;this.j=a.textBaseline;this.b=void 0!==a.fill?a.fill:new ak({color:"#333"});this.l=void 0!==a.stroke?a.stroke:null;this.f=void 0!==a.offsetX?a.offsetX:0;this.c=void 0!==a.offsetY?a.offsetY:0}l=zq.prototype;l.Tj=function(){return this.g};l.gk=function(){return this.f};l.hk=function(){return this.c};l.On=function(){return this.b};l.Pn=function(){return this.i};l.Qn=function(){return this.a};l.Rn=function(){return this.l}; +l.Ea=function(){return this.s};l.uk=function(){return this.o};l.vk=function(){return this.j};l.Wo=function(a){this.g=a};l.hi=function(a){this.f=a};l.ii=function(a){this.c=a};l.Vo=function(a){this.b=a};l.Sn=function(a){this.i=a};l.Tn=function(a){this.a=a};l.bp=function(a){this.l=a};l.ki=function(a){this.s=a};l.li=function(a){this.o=a};l.cp=function(a){this.j=a};function Aq(a){a=a?a:{};Mo.call(this);this.defaultDataProjection=Ic("EPSG:4326");this.g=a.defaultStyle?a.defaultStyle:Bq;this.c=void 0!==a.extractStyles?a.extractStyles:!0;this.l=void 0!==a.writeStyles?a.writeStyles:!0;this.b={};this.i=void 0!==a.showPointNames?a.showPointNames:!0}y(Aq,Mo); +var Cq=["http://www.google.com/kml/ext/2.2"],Dq=[null,"http://earth.google.com/kml/2.0","http://earth.google.com/kml/2.1","http://earth.google.com/kml/2.2","http://www.opengis.net/kml/2.2"],Eq=[255,255,255,1],Fq=new ak({color:Eq}),Gq=[20,2],Hq=[64,64],Iq=new ui({anchor:Gq,anchorOrigin:"bottom-left",anchorXUnits:"pixels",anchorYUnits:"pixels",crossOrigin:"anonymous",rotation:0,scale:.5,size:Hq,src:"https://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png"}),Jq=new gk({color:Eq,width:1}),Kq=new zq({font:"bold 16px Helvetica", +fill:Fq,stroke:new gk({color:[51,51,51,1],width:2}),scale:.8}),Bq=[new jk({fill:Fq,image:Iq,text:Kq,stroke:Jq,zIndex:0})],Lq={fraction:"fraction",pixels:"pixels"};function Mq(a,c){var d=null,e=[0,0],f="start";a.a&&(d=a.a.fd())&&2==d.length&&(e[0]=a.a.i*d[0]/2,e[1]=-a.a.i*d[1]/2,f="left");if(Sa(a.Ea()))d=new zq({text:c,offsetX:e[0],offsetY:e[1],textAlign:f});else{var d=a.Ea(),g={},h;for(h in d)g[h]=d[h];d=g;d.ki(c);d.li(f);d.hi(e[0]);d.ii(e[1])}return new jk({text:d})} +function Nq(a,c,d,e,f){return function(){var g=f,h="";g&&this.W()&&(g="Point"===this.W().X());g&&(h=this.get("name"),g=g&&h);if(a)return g?(g=Mq(a[0],h),a.concat(g)):a;if(c){var k=Oq(c,d,e);return g?(g=Mq(k[0],h),k.concat(g)):k}return g?(g=Mq(d[0],h),d.concat(g)):d}}function Oq(a,c,d){return Array.isArray(a)?a:"string"===typeof a?(!(a in d)&&"#"+a in d&&(a="#"+a),Oq(d[a],c,d)):c} +function Pq(a){a=El(a,!1);if(a=/^\s*#?\s*([0-9A-Fa-f]{8})\s*$/.exec(a))return a=a[1],[parseInt(a.substr(6,2),16),parseInt(a.substr(4,2),16),parseInt(a.substr(2,2),16),parseInt(a.substr(0,2),16)/255]}function Qq(a){a=El(a,!1);for(var c=[],d=/^\s*([+\-]?\d*\.?\d+(?:e[+\-]?\d+)?)\s*,\s*([+\-]?\d*\.?\d+(?:e[+\-]?\d+)?)(?:\s*,\s*([+\-]?\d*\.?\d+(?:e[+\-]?\d+)?))?\s*/i,e;e=d.exec(a);)c.push(parseFloat(e[1]),parseFloat(e[2]),e[3]?parseFloat(e[3]):0),a=a.substr(e[0].length);return""!==a?void 0:c} +function Rq(a){var c=El(a,!1);return a.baseURI?uq(a.baseURI,c.trim()).toString():c.trim()}function Sq(a){a=Uo(a);if(void 0!==a)return Math.sqrt(a)}function Tq(a,c){return P(null,Uq,a,c)}function Vq(a,c){var d=P({A:[],ui:[]},Wq,a,c);if(d){var e=d.A,d=d.ui,f,g;f=0;for(g=Math.min(e.length,d.length);f<g;++f)e[4*f+3]=d[f];d=new T(null);d.ba("XYZM",e);return d}}function Xq(a,c){var d=P({},Yq,a,c),e=P(null,Zq,a,c);if(e){var f=new T(null);f.ba("XYZ",e);f.C(d);return f}} +function $q(a,c){var d=P({},Yq,a,c),e=P(null,Zq,a,c);if(e){var f=new F(null);f.ba("XYZ",e,[e.length]);f.C(d);return f}} +function ar(a,c){var d=P([],br,a,c);if(!d)return null;if(0===d.length)return new Do(d);var e=!0,f=d[0].X(),g,h,k;h=1;for(k=d.length;h<k;++h)if(g=d[h],g.X()!=f){e=!1;break}if(e){if("Point"==f){g=d[0];e=g.f;f=g.ga();h=1;for(k=d.length;h<k;++h)g=d[h],xb(f,g.ga());g=new so(null);g.ba(e,f);cr(g,d);return g}return"LineString"==f?(g=new U(null),ro(g,d),cr(g,d),g):"Polygon"==f?(g=new to(null),vo(g,d),cr(g,d),g):"GeometryCollection"==f?new Do(d):null}return new Do(d)} +function dr(a,c){var d=P({},Yq,a,c),e=P(null,Zq,a,c);if(e){var f=new D(null);f.ba("XYZ",e);f.C(d);return f}}function er(a,c){var d=P({},Yq,a,c),e=P([null],fr,a,c);if(e&&e[0]){var f=new F(null),g=e[0],h=[g.length],k,m;k=1;for(m=e.length;k<m;++k)xb(g,e[k]),h.push(g.length);f.ba("XYZ",g,h);f.C(d);return f}} +function gr(a,c){var d=P({},hr,a,c);if(!d)return null;var e="fillStyle"in d?d.fillStyle:Fq,f=d.fill;void 0===f||f||(e=null);var f="imageStyle"in d?d.imageStyle:Iq,g="textStyle"in d?d.textStyle:Kq,h="strokeStyle"in d?d.strokeStyle:Jq,d=d.outline;void 0===d||d||(h=null);return[new jk({fill:e,image:f,stroke:h,text:g,zIndex:void 0})]} +function cr(a,c){var d=c.length,e=Array(c.length),f=Array(c.length),g,h,k,m;k=m=!1;for(h=0;h<d;++h)g=c[h],e[h]=g.get("extrude"),f[h]=g.get("altitudeMode"),k=k||void 0!==e[h],m=m||f[h];k&&a.set("extrude",e);m&&a.set("altitudeMode",f)}function ir(a,c){Sl(jr,a,c)} +var kr=N(Dq,{value:Ll(V)}),jr=N(Dq,{Data:function(a,c){var d=a.getAttribute("name");if(null!==d){var e=P(void 0,kr,a,c);e&&(c[c.length-1][d]=e)}},SchemaData:function(a,c){Sl(lr,a,c)}}),Yq=N(Dq,{extrude:K(Ro),altitudeMode:K(V)}),Uq=N(Dq,{coordinates:Ll(Qq)}),fr=N(Dq,{innerBoundaryIs:function(a,c){var d=P(void 0,mr,a,c);d&&c[c.length-1].push(d)},outerBoundaryIs:function(a,c){var d=P(void 0,nr,a,c);d&&(c[c.length-1][0]=d)}}),Wq=N(Dq,{when:function(a,c){var d=c[c.length-1].ui,e=El(a,!1);if(e=/^\s*(\d{4})($|-(\d{2})($|-(\d{2})($|T(\d{2}):(\d{2}):(\d{2})(Z|(?:([+\-])(\d{2})(?::(\d{2}))?)))))\s*$/.exec(e)){var f= +Date.UTC(parseInt(e[1],10),e[3]?parseInt(e[3],10)-1:0,e[5]?parseInt(e[5],10):1,e[7]?parseInt(e[7],10):0,e[8]?parseInt(e[8],10):0,e[9]?parseInt(e[9],10):0);if(e[10]&&"Z"!=e[10]){var g="-"==e[11]?-1:1,f=f+60*g*parseInt(e[12],10);e[13]&&(f+=3600*g*parseInt(e[13],10))}d.push(f)}else d.push(0)}},N(Cq,{coord:function(a,c){var d=c[c.length-1].A,e=El(a,!1);(e=/^\s*([+\-]?\d+(?:\.\d*)?(?:e[+\-]?\d*)?)\s+([+\-]?\d+(?:\.\d*)?(?:e[+\-]?\d*)?)\s+([+\-]?\d+(?:\.\d*)?(?:e[+\-]?\d*)?)\s*$/i.exec(e))?d.push(parseFloat(e[1]), +parseFloat(e[2]),parseFloat(e[3]),0):d.push(0,0,0,0)}})),Zq=N(Dq,{coordinates:Ll(Qq)}),or=N(Dq,{href:K(Rq)},N(Cq,{x:K(Uo),y:K(Uo),w:K(Uo),h:K(Uo)})),pr=N(Dq,{Icon:K(function(a,c){var d=P({},or,a,c);return d?d:null}),heading:K(Uo),hotSpot:K(function(a){var c=a.getAttribute("xunits"),d=a.getAttribute("yunits");return{x:parseFloat(a.getAttribute("x")),Wf:Lq[c],y:parseFloat(a.getAttribute("y")),Xf:Lq[d]}}),scale:K(Sq)}),mr=N(Dq,{LinearRing:Ll(Tq)}),qr=N(Dq,{color:K(Pq),scale:K(Sq)}),rr=N(Dq,{color:K(Pq), +width:K(Uo)}),br=N(Dq,{LineString:Kl(Xq),LinearRing:Kl($q),MultiGeometry:Kl(ar),Point:Kl(dr),Polygon:Kl(er)}),sr=N(Cq,{Track:Kl(Vq)}),ur=N(Dq,{ExtendedData:ir,Link:function(a,c){Sl(tr,a,c)},address:K(V),description:K(V),name:K(V),open:K(Ro),phoneNumber:K(V),visibility:K(Ro)}),tr=N(Dq,{href:K(Rq)}),nr=N(Dq,{LinearRing:Ll(Tq)}),vr=N(Dq,{Style:K(gr),key:K(V),styleUrl:K(function(a){var c=El(a,!1).trim();return a.baseURI?uq(a.baseURI,c).toString():c})}),xr=N(Dq,{ExtendedData:ir,MultiGeometry:K(ar,"geometry"), +LineString:K(Xq,"geometry"),LinearRing:K($q,"geometry"),Point:K(dr,"geometry"),Polygon:K(er,"geometry"),Style:K(gr),StyleMap:function(a,c){var d=P(void 0,wr,a,c);if(d){var e=c[c.length-1];Array.isArray(d)?e.Style=d:"string"===typeof d&&(e.styleUrl=d)}},address:K(V),description:K(V),name:K(V),open:K(Ro),phoneNumber:K(V),styleUrl:K(Rq),visibility:K(Ro)},N(Cq,{MultiTrack:K(function(a,c){var d=P([],sr,a,c);if(d){var e=new U(null);ro(e,d);return e}},"geometry"),Track:K(Vq,"geometry")})),yr=N(Dq,{color:K(Pq), +fill:K(Ro),outline:K(Ro)}),lr=N(Dq,{SimpleData:function(a,c){var d=a.getAttribute("name");if(null!==d){var e=V(a);c[c.length-1][d]=e}}}),hr=N(Dq,{IconStyle:function(a,c){var d=P({},pr,a,c);if(d){var e=c[c.length-1],f="Icon"in d?d.Icon:{},g;g=(g=f.href)?g:"https://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png";var h,k,m,n=d.hotSpot;n?(h=[n.x,n.y],k=n.Wf,m=n.Xf):"https://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png"===g?(h=Gq,m=k="pixels"):/^http:\/\/maps\.(?:google|gstatic)\.com\//.test(g)&& +(h=[.5,0],m=k="fraction");var p,n=f.x,q=f.y;void 0!==n&&void 0!==q&&(p=[n,q]);var r,n=f.w,f=f.h;void 0!==n&&void 0!==f&&(r=[n,f]);var u,f=d.heading;void 0!==f&&(u=Ha(f));d=d.scale;"https://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png"==g&&(r=Hq,void 0===d&&(d=.5));h=new ui({anchor:h,anchorOrigin:"bottom-left",anchorXUnits:k,anchorYUnits:m,crossOrigin:"anonymous",offset:p,offsetOrigin:"bottom-left",rotation:u,scale:d,size:r,src:g});e.imageStyle=h}},LabelStyle:function(a,c){var d=P({},qr,a, +c);d&&(c[c.length-1].textStyle=new zq({fill:new ak({color:"color"in d?d.color:Eq}),scale:d.scale}))},LineStyle:function(a,c){var d=P({},rr,a,c);d&&(c[c.length-1].strokeStyle=new gk({color:"color"in d?d.color:Eq,width:"width"in d?d.width:1}))},PolyStyle:function(a,c){var d=P({},yr,a,c);if(d){var e=c[c.length-1];e.fillStyle=new ak({color:"color"in d?d.color:Eq});var f=d.fill;void 0!==f&&(e.fill=f);d=d.outline;void 0!==d&&(e.outline=d)}}}),wr=N(Dq,{Pair:function(a,c){var d=P({},vr,a,c);if(d){var e=d.key; +e&&"normal"==e&&((e=d.styleUrl)&&(c[c.length-1]=e),(d=d.Style)&&(c[c.length-1]=d))}}});l=Aq.prototype;l.Cf=function(a,c){var d=N(Dq,{Document:Jl(this.Cf,this),Folder:Jl(this.Cf,this),Placemark:Kl(this.Kf,this),Style:this.Fo.bind(this),StyleMap:this.Eo.bind(this)});if(d=P([],d,a,c,this))return d}; +l.Kf=function(a,c){var d=P({geometry:null},xr,a,c);if(d){var e=new zl,f=a.getAttribute("id");null!==f&&e.hc(f);var f=c[0],g=d.geometry;g&&lo(g,!1,f);e.Ta(g);delete d.geometry;this.c&&e.nf(Nq(d.Style,d.styleUrl,this.g,this.b,this.i));delete d.Style;e.C(d);return e}};l.Fo=function(a,c){var d=a.getAttribute("id");if(null!==d){var e=gr(a,c);e&&(d=a.baseURI?uq(a.baseURI,"#"+d).toString():"#"+d,this.b[d]=e)}}; +l.Eo=function(a,c){var d=a.getAttribute("id");if(null!==d){var e=P(void 0,wr,a,c);e&&(d=a.baseURI?uq(a.baseURI,"#"+d).toString():"#"+d,this.b[d]=e)}};l.Kh=function(a,c){if(!ub(Dq,a.namespaceURI))return null;var d=this.Kf(a,[jo(this,a,c)]);return d?d:null}; +l.gc=function(a,c){if(!ub(Dq,a.namespaceURI))return[];var d;d=a.localName;if("Document"==d||"Folder"==d)return(d=this.Cf(a,[jo(this,a,c)]))?d:[];if("Placemark"==d)return(d=this.Kf(a,[jo(this,a,c)]))?[d]:[];if("kml"==d){d=[];var e;for(e=a.firstElementChild;e;e=e.nextElementSibling){var f=this.gc(e,c);f&&xb(d,f)}return d}return[]};l.zo=function(a){if(Gl(a))return zr(this,a);if(Hl(a))return Ar(this,a);if("string"===typeof a)return a=Il(a),zr(this,a)}; +function zr(a,c){var d;for(d=c.firstChild;d;d=d.nextSibling)if(1==d.nodeType){var e=Ar(a,d);if(e)return e}}function Ar(a,c){var d;for(d=c.firstElementChild;d;d=d.nextElementSibling)if(ub(Dq,d.namespaceURI)&&"name"==d.localName)return V(d);for(d=c.firstElementChild;d;d=d.nextElementSibling){var e=d.localName;if(ub(Dq,d.namespaceURI)&&("Document"==e||"Folder"==e||"Placemark"==e||"kml"==e)&&(e=Ar(a,d)))return e}} +l.Ao=function(a){var c=[];Gl(a)?xb(c,Br(this,a)):Hl(a)?xb(c,Cr(this,a)):"string"===typeof a&&(a=Il(a),xb(c,Br(this,a)));return c};function Br(a,c){var d,e=[];for(d=c.firstChild;d;d=d.nextSibling)1==d.nodeType&&xb(e,Cr(a,d));return e} +function Cr(a,c){var d,e=[];for(d=c.firstElementChild;d;d=d.nextElementSibling)if(ub(Dq,d.namespaceURI)&&"NetworkLink"==d.localName){var f=P({},ur,d,[]);e.push(f)}for(d=c.firstElementChild;d;d=d.nextElementSibling)f=d.localName,!ub(Dq,d.namespaceURI)||"Document"!=f&&"Folder"!=f&&"kml"!=f||xb(e,Cr(a,d));return e}function Dr(a,c){var d=Fe(c),d=[255*(4==d.length?d[3]:1),d[2],d[1],d[0]],e;for(e=0;4>e;++e){var f=parseInt(d[e],10).toString(16);d[e]=1==f.length?"0"+f:f}Zo(a,d.join(""))} +function Er(a,c,d){a={node:a};var e=c.X(),f,g;"GeometryCollection"==e?(f=c.bf(),g=Fr):"MultiPoint"==e?(f=c.ee(),g=Gr):"MultiLineString"==e?(f=c.gd(),g=Hr):"MultiPolygon"==e&&(f=c.Qd(),g=Ir);Tl(a,Jr,g,f,d)}function Kr(a,c,d){Tl({node:a},Lr,Mr,[c],d)} +function Nr(a,c,d){var e={node:a};c.Wa()&&a.setAttribute("id",c.Wa());a=c.L();var f=c.$b();f&&(f=f.call(c,0))&&(f=Array.isArray(f)?f[0]:f,this.l&&(a.Style=f),(f=f.Ea())&&(a.name=f.Ea()));f=Or[d[d.length-1].node.namespaceURI];a=Rl(a,f);Tl(e,Pr,Ql,a,d,f);a=d[0];(c=c.W())&&(c=lo(c,!0,a));Tl(e,Pr,Fr,[c],d)}function Qr(a,c,d){var e=c.ga();a={node:a};a.layout=c.f;a.stride=c.ua();Tl(a,Rr,Sr,[e],d)}function Tr(a,c,d){c=c.Pd();var e=c.shift();a={node:a};Tl(a,Ur,Vr,c,d);Tl(a,Ur,Wr,[e],d)} +function Xr(a,c){$o(a,Math.round(c*c*1E6)/1E6)} +var Yr=N(Dq,["Document","Placemark"]),as=N(Dq,{Document:M(function(a,c,d){Tl({node:a},Zr,$r,c,d,void 0,this)}),Placemark:M(Nr)}),Zr=N(Dq,{Placemark:M(Nr)}),bs={Point:"Point",LineString:"LineString",LinearRing:"LinearRing",Polygon:"Polygon",MultiPoint:"MultiGeometry",MultiLineString:"MultiGeometry",MultiPolygon:"MultiGeometry",GeometryCollection:"MultiGeometry"},cs=N(Dq,["href"],N(Cq,["x","y","w","h"])),ds=N(Dq,{href:M(Zo)},N(Cq,{x:M($o),y:M($o),w:M($o),h:M($o)})),es=N(Dq,["scale","heading","Icon", +"hotSpot"]),gs=N(Dq,{Icon:M(function(a,c,d){a={node:a};var e=cs[d[d.length-1].node.namespaceURI],f=Rl(c,e);Tl(a,ds,Ql,f,d,e);e=cs[Cq[0]];f=Rl(c,e);Tl(a,ds,fs,f,d,e)}),heading:M($o),hotSpot:M(function(a,c){a.setAttribute("x",c.x);a.setAttribute("y",c.y);a.setAttribute("xunits",c.Wf);a.setAttribute("yunits",c.Xf)}),scale:M(Xr)}),hs=N(Dq,["color","scale"]),is=N(Dq,{color:M(Dr),scale:M(Xr)}),js=N(Dq,["color","width"]),ks=N(Dq,{color:M(Dr),width:M($o)}),Lr=N(Dq,{LinearRing:M(Qr)}),Jr=N(Dq,{LineString:M(Qr), +Point:M(Qr),Polygon:M(Tr),GeometryCollection:M(Er)}),Or=N(Dq,"name open visibility address phoneNumber description styleUrl Style".split(" ")),Pr=N(Dq,{MultiGeometry:M(Er),LineString:M(Qr),LinearRing:M(Qr),Point:M(Qr),Polygon:M(Tr),Style:M(function(a,c,d){a={node:a};var e={},f=c.c,g=c.f,h=c.a;c=c.Ea();h instanceof ui&&(e.IconStyle=h);c&&(e.LabelStyle=c);g&&(e.LineStyle=g);f&&(e.PolyStyle=f);c=ls[d[d.length-1].node.namespaceURI];e=Rl(e,c);Tl(a,ms,Ql,e,d,c)}),address:M(Zo),description:M(Zo),name:M(Zo), +open:M(Yo),phoneNumber:M(Zo),styleUrl:M(Zo),visibility:M(Yo)}),Rr=N(Dq,{coordinates:M(function(a,c,d){d=d[d.length-1];var e=d.layout;d=d.stride;var f;"XY"==e||"XYM"==e?f=2:("XYZ"==e||"XYZM"==e)&&(f=3);var g,h=c.length,k="";if(0<h){k+=c[0];for(e=1;e<f;++e)k+=","+c[e];for(g=d;g<h;g+=d)for(k+=" "+c[g],e=1;e<f;++e)k+=","+c[g+e]}Zo(a,k)})}),Ur=N(Dq,{outerBoundaryIs:M(Kr),innerBoundaryIs:M(Kr)}),ns=N(Dq,{color:M(Dr)}),ls=N(Dq,["IconStyle","LabelStyle","LineStyle","PolyStyle"]),ms=N(Dq,{IconStyle:M(function(a, +c,d){a={node:a};var e={},f=c.Bb(),g=c.fd(),h={href:c.b.j};if(f){h.w=f[0];h.h=f[1];var k=c.Tb(),m=c.Fa();m&&g&&0!==m[0]&&m[1]!==f[1]&&(h.x=m[0],h.y=g[1]-(m[1]+f[1]));k&&0!==k[0]&&k[1]!==f[1]&&(e.hotSpot={x:k[0],Wf:"pixels",y:f[1]-k[1],Xf:"pixels"})}e.Icon=h;f=c.i;1!==f&&(e.scale=f);c=c.j;0!==c&&(e.heading=c);c=es[d[d.length-1].node.namespaceURI];e=Rl(e,c);Tl(a,gs,Ql,e,d,c)}),LabelStyle:M(function(a,c,d){a={node:a};var e={},f=c.b;f&&(e.color=f.b);(c=c.a)&&1!==c&&(e.scale=c);c=hs[d[d.length-1].node.namespaceURI]; +e=Rl(e,c);Tl(a,is,Ql,e,d,c)}),LineStyle:M(function(a,c,d){a={node:a};var e=js[d[d.length-1].node.namespaceURI];c=Rl({color:c.b,width:c.a},e);Tl(a,ks,Ql,c,d,e)}),PolyStyle:M(function(a,c,d){Tl({node:a},ns,os,[c.b],d)})});function fs(a,c,d){return Dl(Cq[0],"gx:"+d)}function $r(a,c){return Dl(c[c.length-1].node.namespaceURI,"Placemark")}function Fr(a,c){if(a)return Dl(c[c.length-1].node.namespaceURI,bs[a.X()])} +var os=Ol("color"),Sr=Ol("coordinates"),Vr=Ol("innerBoundaryIs"),Gr=Ol("Point"),Hr=Ol("LineString"),Mr=Ol("LinearRing"),Ir=Ol("Polygon"),Wr=Ol("outerBoundaryIs"); +Aq.prototype.a=function(a,c){c=ko(this,c);var d=Dl(Dq[4],"kml");d.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:gx",Cq[0]);d.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance");d.setAttributeNS("http://www.w3.org/2001/XMLSchema-instance","xsi:schemaLocation","http://www.opengis.net/kml/2.2 https://developers.google.com/kml/schema/kml22gx.xsd");var e={node:d},f={};1<a.length?f.Document=a:1==a.length&&(f.Placemark=a[0]);var g=Yr[d.namespaceURI], +f=Rl(f,g);Tl(e,as,Ql,f,[c],g,this);return d};(function(){var a={},c={ha:a};(function(d){if("object"===typeof a&&"undefined"!==typeof c)c.ha=d();else{var e;"undefined"!==typeof window?e=window:"undefined"!==typeof global?e=global:"undefined"!==typeof self?e=self:e=this;e.Mp=d()}})(function(){return function e(a,c,h){function k(n,q){if(!c[n]){if(!a[n]){var r="function"==typeof require&&require;if(!q&&r)return r(n,!0);if(m)return m(n,!0);r=Error("Cannot find module '"+n+"'");throw r.code="MODULE_NOT_FOUND",r;}r=c[n]={ha:{}};a[n][0].call(r.ha,function(c){var e= +a[n][1][c];return k(e?e:c)},r,r.ha,e,a,c,h)}return c[n].ha}for(var m="function"==typeof require&&require,n=0;n<h.length;n++)k(h[n]);return k}({1:[function(a,c,g){g.read=function(a,c,e,f,g){var q;q=8*g-f-1;var r=(1<<q)-1,u=r>>1,v=-7;g=e?g-1:0;var x=e?-1:1,z=a[c+g];g+=x;e=z&(1<<-v)-1;z>>=-v;for(v+=q;0<v;e=256*e+a[c+g],g+=x,v-=8);q=e&(1<<-v)-1;e>>=-v;for(v+=f;0<v;q=256*q+a[c+g],g+=x,v-=8);if(0===e)e=1-u;else{if(e===r)return q?NaN:Infinity*(z?-1:1);q+=Math.pow(2,f);e=e-u}return(z?-1:1)*q*Math.pow(2,e- +f)};g.write=function(a,c,e,f,g,q){var r,u=8*q-g-1,v=(1<<u)-1,x=v>>1,z=23===g?Math.pow(2,-24)-Math.pow(2,-77):0;q=f?0:q-1;var E=f?1:-1,B=0>c||0===c&&0>1/c?1:0;c=Math.abs(c);isNaN(c)||Infinity===c?(c=isNaN(c)?1:0,f=v):(f=Math.floor(Math.log(c)/Math.LN2),1>c*(r=Math.pow(2,-f))&&(f--,r*=2),c=1<=f+x?c+z/r:c+z*Math.pow(2,1-x),2<=c*r&&(f++,r/=2),f+x>=v?(c=0,f=v):1<=f+x?(c=(c*r-1)*Math.pow(2,g),f+=x):(c=c*Math.pow(2,x-1)*Math.pow(2,g),f=0));for(;8<=g;a[e+q]=c&255,q+=E,c/=256,g-=8);f=f<<g|c;for(u+=g;0<u;a[e+ +q]=f&255,q+=E,f/=256,u-=8);a[e+q-E]|=128*B}},{}],2:[function(a,c){function g(a){var c;a&&a.length&&(c=a,a=c.length);a=new Uint8Array(a||0);c&&a.set(c);a.Vh=m.Vh;a.Vf=m.Vf;a.Nh=m.Nh;a.zi=m.zi;a.Jf=m.Jf;a.yi=m.yi;a.Df=m.Df;a.vi=m.vi;a.toString=m.toString;a.write=m.write;a.slice=m.slice;a.pg=m.pg;a.ij=!0;return a}function h(a){for(var c=a.length,e=[],f=0,g,h;f<c;f++){g=a.charCodeAt(f);if(55295<g&&57344>g)if(h)if(56320>g){e.push(239,191,189);h=g;continue}else g=h-55296<<10|g-56320|65536,h=null;else{56319< +g||f+1===c?e.push(239,191,189):h=g;continue}else h&&(e.push(239,191,189),h=null);128>g?e.push(g):2048>g?e.push(g>>6|192,g&63|128):65536>g?e.push(g>>12|224,g>>6&63|128,g&63|128):e.push(g>>18|240,g>>12&63|128,g>>6&63|128,g&63|128)}return e}c.ha=g;var k=a("ieee754"),m,n,p;m={Vh:function(a){return(this[a]|this[a+1]<<8|this[a+2]<<16)+16777216*this[a+3]},Vf:function(a,c){this[c]=a;this[c+1]=a>>>8;this[c+2]=a>>>16;this[c+3]=a>>>24},Nh:function(a){return(this[a]|this[a+1]<<8|this[a+2]<<16)+(this[a+3]<<24)}, +Jf:function(a){return k.read(this,a,!0,23,4)},Df:function(a){return k.read(this,a,!0,52,8)},yi:function(a,c){return k.write(this,a,c,!0,23,4)},vi:function(a,c){return k.write(this,a,c,!0,52,8)},toString:function(a,c,e){var f=a="";e=Math.min(this.length,e||this.length);for(c=c||0;c<e;c++){var g=this[c];127>=g?(a+=decodeURIComponent(f)+String.fromCharCode(g),f=""):f+="%"+g.toString(16)}return a+=decodeURIComponent(f)},write:function(a,c){for(var e=a===n?p:h(a),f=0;f<e.length;f++)this[c+f]=e[f]},slice:function(a, +c){return this.subarray(a,c)},pg:function(a,c){c=c||0;for(var e=0;e<this.length;e++)a[c+e]=this[e]}};m.zi=m.Vf;g.byteLength=function(a){n=a;p=h(a);return p.length};g.isBuffer=function(a){return!(!a||!a.ij)}},{ieee754:1}],3:[function(a,c){(function(g){function h(a){this.Eb=k.isBuffer(a)?a:new k(a||0);this.ca=0;this.length=this.Eb.length}c.ha=h;var k=g.up||a("./buffer");h.f=0;h.g=1;h.b=2;h.a=5;var m=Math.pow(2,63);h.prototype={Hf:function(a,c,e){for(e=e||this.length;this.ca<e;){var f=this.Aa(),g=this.ca; +a(f>>3,c,this);this.ca===g&&this.ip(f)}return c},vo:function(){var a=this.Eb.Jf(this.ca);this.ca+=4;return a},ro:function(){var a=this.Eb.Df(this.ca);this.ca+=8;return a},Aa:function(){var a=this.Eb,c,e,f,g,h;c=a[this.ca++];if(128>c)return c;c=c&127;f=a[this.ca++];if(128>f)return c|f<<7;f=(f&127)<<7;g=a[this.ca++];if(128>g)return c|f|g<<14;g=(g&127)<<14;h=a[this.ca++];if(128>h)return c|f|g|h<<21;e=a[this.ca++];c=(c|f|g|(h&127)<<21)+268435456*(e&127);if(128>e)return c;e=a[this.ca++];c+=34359738368* +(e&127);if(128>e)return c;e=a[this.ca++];c+=4398046511104*(e&127);if(128>e)return c;e=a[this.ca++];c+=562949953421312*(e&127);if(128>e)return c;e=a[this.ca++];c+=72057594037927936*(e&127);if(128>e)return c;e=a[this.ca++];if(128>e)return c+0x7fffffffffffffff*(e&127);throw Error("Expected varint not more than 10 bytes");},Go:function(){var a=this.ca,c=this.Aa();if(c<m)return c;for(var e=this.ca-2;255===this.Eb[e];)e--;e<a&&(e=a);for(var f=c=0;f<e-a+1;f++)var g=~this.Eb[a+f]&127,c=c+(4>f?g<<7*f:g*Math.pow(2, +7*f));return-c-1},sd:function(){var a=this.Aa();return 1===a%2?(a+1)/-2:a/2},po:function(){return!!this.Aa()},Mf:function(){var a=this.Aa()+this.ca,c=this.Eb.toString("utf8",this.ca,a);this.ca=a;return c},ip:function(a){a=a&7;if(a===h.f)for(;127<this.Eb[this.ca++];);else if(a===h.b)this.ca=this.Aa()+this.ca;else if(a===h.a)this.ca+=4;else if(a===h.g)this.ca+=8;else throw Error("Unimplemented type: "+a);}}}).call(this,"undefined"!==typeof global?global:"undefined"!==typeof self?self:"undefined"!== +typeof window?window:{})},{"./buffer":2}]},{},[3])(3)});Zl=c.ha})();(function(){var a={},c={ha:a};(function(d){if("object"===typeof a&&"undefined"!==typeof c)c.ha=d();else{var e;"undefined"!==typeof window?e=window:"undefined"!==typeof global?e=global:"undefined"!==typeof self?e=self:e=this;e.Op=d()}})(function(){return function e(a,c,h){function k(n,q){if(!c[n]){if(!a[n]){var r="function"==typeof require&&require;if(!q&&r)return r(n,!0);if(m)return m(n,!0);r=Error("Cannot find module '"+n+"'");throw r.code="MODULE_NOT_FOUND",r;}r=c[n]={ha:{}};a[n][0].call(r.ha,function(c){var e= +a[n][1][c];return k(e?e:c)},r,r.ha,e,a,c,h)}return c[n].ha}for(var m="function"==typeof require&&require,n=0;n<h.length;n++)k(h[n]);return k}({1:[function(a,c){function g(a,c){this.x=a;this.y=c}c.ha=g;g.prototype={clone:function(){return new g(this.x,this.y)},add:function(a){return this.clone().aj(a)},rotate:function(a){return this.clone().lj(a)},round:function(){return this.clone().mj()},angle:function(){return Math.atan2(this.y,this.x)},aj:function(a){this.x+=a.x;this.y+=a.y;return this},lj:function(a){var c= +Math.cos(a);a=Math.sin(a);var e=a*this.x+c*this.y;this.x=c*this.x-a*this.y;this.y=e;return this},mj:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this}};g.b=function(a){return a instanceof g?a:Array.isArray(a)?new g(a[0],a[1]):a}},{}],2:[function(a,c){c.ha.$i=a("./lib/vectortile.js");c.ha.Hp=a("./lib/vectortilefeature.js");c.ha.Ip=a("./lib/vectortilelayer.js")},{"./lib/vectortile.js":3,"./lib/vectortilefeature.js":4,"./lib/vectortilelayer.js":5}],3:[function(a,c){function g(a, +c,e){3===a&&(a=new h(e,e.Aa()+e.ca),a.length&&(c[a.name]=a))}var h=a("./vectortilelayer");c.ha=function(a,c){this.layers=a.Hf(g,{},c)}},{"./vectortilelayer":5}],4:[function(a,c){function g(a,c,e,f,g){this.properties={};this.extent=e;this.type=0;this.lc=a;this.Me=-1;this.Dd=f;this.Fd=g;a.Hf(h,this,c)}function h(a,c,e){if(1==a)c.Kp=e.Aa();else if(2==a)for(a=e.Aa()+e.ca;e.ca<a;){var f=c.Dd[e.Aa()],g=c.Fd[e.Aa()];c.properties[f]=g}else 3==a?c.type=e.Aa():4==a&&(c.Me=e.ca)}var k=a("point-geometry");c.ha= +g;g.b=["Unknown","Point","LineString","Polygon"];g.prototype.Qg=function(){var a=this.lc;a.ca=this.Me;for(var c=a.Aa()+a.ca,e=1,f=0,g=0,h=0,v=[],x;a.ca<c;)if(f||(f=a.Aa(),e=f&7,f=f>>3),f--,1===e||2===e)g+=a.sd(),h+=a.sd(),1===e&&(x&&v.push(x),x=[]),x.push(new k(g,h));else if(7===e)x&&x.push(x[0].clone());else throw Error("unknown command "+e);x&&v.push(x);return v};g.prototype.bbox=function(){var a=this.lc;a.ca=this.Me;for(var c=a.Aa()+a.ca,e=1,f=0,g=0,h=0,k=Infinity,x=-Infinity,z=Infinity,E=-Infinity;a.ca< +c;)if(f||(f=a.Aa(),e=f&7,f=f>>3),f--,1===e||2===e)g+=a.sd(),h+=a.sd(),g<k&&(k=g),g>x&&(x=g),h<z&&(z=h),h>E&&(E=h);else if(7!==e)throw Error("unknown command "+e);return[k,z,x,E]}},{"point-geometry":1}],5:[function(a,c){function g(a,c){this.version=1;this.name=null;this.extent=4096;this.length=0;this.lc=a;this.Dd=[];this.Fd=[];this.Cd=[];a.Hf(h,this,c);this.length=this.Cd.length}function h(a,c,e){15===a?c.version=e.Aa():1===a?c.name=e.Mf():5===a?c.extent=e.Aa():2===a?c.Cd.push(e.ca):3===a?c.Dd.push(e.Mf()): +4===a&&c.Fd.push(k(e))}function k(a){for(var c=null,e=a.Aa()+a.ca;a.ca<e;)c=a.Aa()>>3,c=1===c?a.Mf():2===c?a.vo():3===c?a.ro():4===c?a.Go():5===c?a.Aa():6===c?a.sd():7===c?a.po():null;return c}var m=a("./vectortilefeature.js");c.ha=g;g.prototype.feature=function(a){if(0>a||a>=this.Cd.length)throw Error("feature index out of bounds");this.lc.ca=this.Cd[a];a=this.lc.Aa()+this.lc.ca;return new m(this.lc,a,this.extent,this.Dd,this.Fd)}},{"./vectortilefeature.js":4}]},{},[2])(2)});$l=c.ha})();function ps(a){this.defaultDataProjection=null;a=a?a:{};this.defaultDataProjection=new Fc({code:"",units:"tile-pixels"});this.b=a.featureClass?a.featureClass:Zk;this.g=a.geometryName?a.geometryName:"geometry";this.a=a.layerName?a.layerName:"layer";this.f=a.layers?a.layers:null}y(ps,io);ps.prototype.X=function(){return"arraybuffer"}; +ps.prototype.Ca=function(a,c){var d=this.f,e=new Zl(a),e=new $l.$i(e),f=[],g=this.b,h,k,m;for(m in e.layers)if(!d||-1!=d.indexOf(m)){h=e.layers[m];for(var n=0,p=h.length;n<p;++n){if(g===Zk){var q=h.feature(n);k=m;var r=q.Qg(),u=[],v=[];qs(r,v,u);var x=q.type,z=void 0;1===x?z=1===r.length?"Point":"MultiPoint":2===x?z=1===r.length?"LineString":"MultiLineString":3===x&&(z="Polygon");q=q.properties;q[this.a]=k;k=new this.b(z,v,u,q)}else{q=h.feature(n);z=m;v=c;k=new this.b;u=q.properties;u[this.a]=z;z= +q.type;if(0===z)z=null;else{q=q.Qg();r=[];x=[];qs(q,x,r);var E=void 0;1===z?E=1===q.length?new D(null):new so(null):2===z?1===q.length?E=new T(null):E=new U(null):3===z&&(E=new F(null));E.ba("XY",x,r);z=E}(v=lo(z,!1,ko(this,v)))&&(u[this.g]=v);k.C(u);k.zc(this.g)}f.push(k)}}return f};ps.prototype.Oa=function(){return this.defaultDataProjection};ps.prototype.c=function(a){this.f=a}; +function qs(a,c,d){for(var e=0,f=0,g=a.length;f<g;++f){var h=a[f],k,m;k=0;for(m=h.length;k<m;++k){var n=h[k];c.push(n.x,n.y)}e+=2*k;d.push(e)}};function rs(a,c){return new ss(a,c)}function ts(a,c,d){return new us(a,c,d)}function vs(a){pb.call(this);this.Ae=a}y(vs,pb);function ws(a){vs.call(this,a)}y(ws,vs);function xs(a,c,d){vs.call(this,a);this.a=c;this.f=d}y(xs,ws);function ss(a,c){xs.call(this,"And",a,c)}y(ss,xs);function ys(a,c){xs.call(this,"Or",a,c)}y(ys,xs);function zs(a){vs.call(this,"Not");this.condition=a}y(zs,ws);function us(a,c,d){vs.call(this,"BBOX");this.geometryName=a;this.extent=c;this.srsName=d}y(us,vs); +function As(a,c){vs.call(this,a);this.a=c}y(As,vs);function Bs(a,c,d,e){As.call(this,a,c);this.c=d;this.f=e}y(Bs,As);function Cs(a,c,d){Bs.call(this,"PropertyIsEqualTo",a,c,d)}y(Cs,Bs);function Ds(a,c,d){Bs.call(this,"PropertyIsNotEqualTo",a,c,d)}y(Ds,Bs);function Es(a,c){Bs.call(this,"PropertyIsLessThan",a,c)}y(Es,Bs);function Fs(a,c){Bs.call(this,"PropertyIsLessThanOrEqualTo",a,c)}y(Fs,Bs);function Gs(a,c){Bs.call(this,"PropertyIsGreaterThan",a,c)}y(Gs,Bs); +function Hs(a,c){Bs.call(this,"PropertyIsGreaterThanOrEqualTo",a,c)}y(Hs,Bs);function Is(a){As.call(this,"PropertyIsNull",a)}y(Is,As);function Js(a,c,d){As.call(this,"PropertyIsBetween",a);this.f=c;this.c=d}y(Js,As);function Ks(a,c,d,e,f,g){As.call(this,"PropertyIsLike",a);this.i=c;this.o=void 0!==d?d:"*";this.l=void 0!==e?e:".";this.c=void 0!==f?f:"!";this.f=g}y(Ks,As);function Ls(){Mo.call(this);this.defaultDataProjection=Ic("EPSG:4326")}y(Ls,Mo);function Ms(a,c){c[c.length-1].xd[a.getAttribute("k")]=a.getAttribute("v")} +var Ns=[null],Os=N(Ns,{nd:function(a,c){c[c.length-1].Mc.push(a.getAttribute("ref"))},tag:Ms}),Qs=N(Ns,{node:function(a,c){var d=c[0],e=c[c.length-1],f=a.getAttribute("id"),g=[parseFloat(a.getAttribute("lon")),parseFloat(a.getAttribute("lat"))];e.Ug[f]=g;var h=P({xd:{}},Ps,a,c);Sa(h.xd)||(g=new D(g),lo(g,!1,d),d=new zl(g),d.hc(f),d.C(h.xd),e.features.push(d))},way:function(a,c){for(var d=c[0],e=a.getAttribute("id"),f=P({Mc:[],xd:{}},Os,a,c),g=c[c.length-1],h=[],k=0,m=f.Mc.length;k<m;k++)xb(h,g.Ug[f.Mc[k]]); +f.Mc[0]==f.Mc[f.Mc.length-1]?(k=new F(null),k.ba("XY",h,[h.length])):(k=new T(null),k.ba("XY",h));lo(k,!1,d);d=new zl(k);d.hc(e);d.C(f.xd);g.features.push(d)}}),Ps=N(Ns,{tag:Ms});Ls.prototype.gc=function(a,c){var d=jo(this,a,c);return"osm"==a.localName&&(d=P({Ug:{},features:[]},Qs,a,[d]),d.features)?d.features:[]};function Rs(a){return a.getAttributeNS("http://www.w3.org/1999/xlink","href")};function Ss(){}Ss.prototype.read=function(a){return Gl(a)?this.a(a):Hl(a)?this.b(a):"string"===typeof a?(a=Il(a),this.a(a)):null};function Ts(){}y(Ts,Ss);Ts.prototype.a=function(a){for(a=a.firstChild;a;a=a.nextSibling)if(1==a.nodeType)return this.b(a);return null};Ts.prototype.b=function(a){return(a=P({},Us,a,[]))?a:null}; +var Vs=[null,"http://www.opengis.net/ows/1.1"],Us=N(Vs,{ServiceIdentification:K(function(a,c){return P({},Ws,a,c)}),ServiceProvider:K(function(a,c){return P({},Xs,a,c)}),OperationsMetadata:K(function(a,c){return P({},Ys,a,c)})}),Zs=N(Vs,{DeliveryPoint:K(V),City:K(V),AdministrativeArea:K(V),PostalCode:K(V),Country:K(V),ElectronicMailAddress:K(V)}),$s=N(Vs,{Value:Ml(function(a){return V(a)})}),at=N(Vs,{AllowedValues:K(function(a,c){return P({},$s,a,c)})}),ct=N(Vs,{Phone:K(function(a,c){return P({}, +bt,a,c)}),Address:K(function(a,c){return P({},Zs,a,c)})}),et=N(Vs,{HTTP:K(function(a,c){return P({},dt,a,c)})}),dt=N(Vs,{Get:Ml(function(a,c){var d=Rs(a);return d?P({href:d},ft,a,c):void 0}),Post:void 0}),gt=N(Vs,{DCP:K(function(a,c){return P({},et,a,c)})}),Ys=N(Vs,{Operation:function(a,c){var d=a.getAttribute("name"),e=P({},gt,a,c);e&&(c[c.length-1][d]=e)}}),bt=N(Vs,{Voice:K(V),Facsimile:K(V)}),ft=N(Vs,{Constraint:Ml(function(a,c){var d=a.getAttribute("name");return d?P({name:d},at,a,c):void 0})}), +ht=N(Vs,{IndividualName:K(V),PositionName:K(V),ContactInfo:K(function(a,c){return P({},ct,a,c)})}),Ws=N(Vs,{Title:K(V),ServiceTypeVersion:K(V),ServiceType:K(V)}),Xs=N(Vs,{ProviderName:K(V),ProviderSite:K(Rs),ServiceContact:K(function(a,c){return P({},ht,a,c)})});function it(a,c,d,e){var f;void 0!==e?f=e:f=[];for(var g=e=0;g<c;){var h=a[g++];f[e++]=a[g++];f[e++]=h;for(h=2;h<d;++h)f[e++]=a[g++]}f.length=e};function jt(a){a=a?a:{};this.defaultDataProjection=null;this.defaultDataProjection=Ic("EPSG:4326");this.b=a.factor?a.factor:1E5;this.a=a.geometryLayout?a.geometryLayout:"XY"}y(jt,Sp);function kt(a,c,d){var e,f=Array(c);for(e=0;e<c;++e)f[e]=0;var g,h;g=0;for(h=a.length;g<h;)for(e=0;e<c;++e,++g){var k=a[g],m=k-f[e];f[e]=k;a[g]=m}return lt(a,d?d:1E5)} +function mt(a,c,d){var e,f=Array(c);for(e=0;e<c;++e)f[e]=0;a=nt(a,d?d:1E5);var g;d=0;for(g=a.length;d<g;)for(e=0;e<c;++e,++d)f[e]+=a[d],a[d]=f[e];return a}function lt(a,c){var d=c?c:1E5,e,f;e=0;for(f=a.length;e<f;++e)a[e]=Math.round(a[e]*d);d=0;for(e=a.length;d<e;++d)f=a[d],a[d]=0>f?~(f<<1):f<<1;d="";e=0;for(f=a.length;e<f;++e){for(var g=a[e],h=void 0,k="";32<=g;)h=(32|g&31)+63,k+=String.fromCharCode(h),g>>=5;k+=String.fromCharCode(g+63);d+=k}return d} +function nt(a,c){var d=c?c:1E5,e=[],f=0,g=0,h,k;h=0;for(k=a.length;h<k;++h){var m=a.charCodeAt(h)-63,f=f|(m&31)<<g;32>m?(e.push(f),g=f=0):g+=5}f=0;for(g=e.length;f<g;++f)h=e[f],e[f]=h&1?~(h>>1):h>>1;f=0;for(g=e.length;f<g;++f)e[f]/=d;return e}l=jt.prototype;l.pd=function(a,c){var d=this.rd(a,c);return new zl(d)};l.Gf=function(a,c){return[this.pd(a,c)]};l.rd=function(a,c){var d=td(this.a),e=mt(a,d,this.b);it(e,e.length,d,e);d=Gd(e,0,e.length,d);return lo(new T(d,this.a),!1,ko(this,c))}; +l.De=function(a,c){var d=a.W();return d?this.zd(d,c):""};l.xi=function(a,c){return this.De(a[0],c)};l.zd=function(a,c){a=lo(a,!0,ko(this,c));var d=a.ga(),e=a.ua();it(d,d.length,e,d);return kt(d,e,this.b)};function ot(a){a=a?a:{};this.defaultDataProjection=null;this.defaultDataProjection=Ic(a.defaultDataProjection?a.defaultDataProjection:"EPSG:4326")}y(ot,mo);function pt(a,c){var d=[],e,f,g,h;g=0;for(h=a.length;g<h;++g)e=a[g],0<g&&d.pop(),0<=e?f=c[e]:f=c[~e].slice().reverse(),d.push.apply(d,f);e=0;for(f=d.length;e<f;++e)d[e]=d[e].slice();return d}function rt(a,c,d,e,f){a=a.geometries;var g=[],h,k;h=0;for(k=a.length;h<k;++h)g[h]=st(a[h],c,d,e,f);return g} +function st(a,c,d,e,f){var g=a.type,h=tt[g];c="Point"===g||"MultiPoint"===g?h(a,d,e):h(a,c);d=new zl;d.Ta(lo(c,!1,f));void 0!==a.id&&d.hc(a.id);a.properties&&d.C(a.properties);return d} +ot.prototype.Ff=function(a,c){if("Topology"==a.type){var d,e=null,f=null;a.transform&&(d=a.transform,e=d.scale,f=d.translate);var g=a.arcs;if(d){d=e;var h=f,k,m;k=0;for(m=g.length;k<m;++k)for(var n=g[k],p=d,q=h,r=0,u=0,v=void 0,x=void 0,z=void 0,x=0,z=n.length;x<z;++x)v=n[x],r+=v[0],u+=v[1],v[0]=r,v[1]=u,ut(v,p,q)}d=[];h=Ra(a.objects);k=0;for(m=h.length;k<m;++k)"GeometryCollection"===h[k].type?(n=h[k],d.push.apply(d,rt(n,g,e,f,c))):(n=h[k],d.push(st(n,g,e,f,c)));return d}return[]}; +function ut(a,c,d){a[0]=a[0]*c[0]+d[0];a[1]=a[1]*c[1]+d[1]}ot.prototype.Oa=function(){return this.defaultDataProjection}; +var tt={Point:function(a,c,d){a=a.coordinates;c&&d&&ut(a,c,d);return new D(a)},LineString:function(a,c){var d=pt(a.arcs,c);return new T(d)},Polygon:function(a,c){var d=[],e,f;e=0;for(f=a.arcs.length;e<f;++e)d[e]=pt(a.arcs[e],c);return new F(d)},MultiPoint:function(a,c,d){a=a.coordinates;var e,f;if(c&&d)for(e=0,f=a.length;e<f;++e)ut(a[e],c,d);return new so(a)},MultiLineString:function(a,c){var d=[],e,f;e=0;for(f=a.arcs.length;e<f;++e)d[e]=pt(a.arcs[e],c);return new U(d)},MultiPolygon:function(a,c){var d= +[],e,f,g,h,k,m;k=0;for(m=a.arcs.length;k<m;++k){e=a.arcs[k];f=[];g=0;for(h=e.length;g<h;++g)f[g]=pt(e[g],c);d[k]=f}return new to(d)}};function vt(a){a=a?a:{};this.i=a.featureType;this.g=a.featureNS;this.b=a.gmlFormat?a.gmlFormat:new cp;this.c=a.schemaLocation?a.schemaLocation:"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd";Mo.call(this)}y(vt,Mo);vt.prototype.gc=function(a,c){var d={featureType:this.i,featureNS:this.g};Pa(d,jo(this,a,c?c:{}));d=[d];this.b.b["http://www.opengis.net/gml"].featureMember=Kl(Po.prototype.qd);(d=P([],this.b.b,a,d,this.b))||(d=[]);return d}; +vt.prototype.o=function(a){if(Gl(a))return wt(a);if(Hl(a))return P({},xt,a,[]);if("string"===typeof a)return a=Il(a),wt(a)};vt.prototype.l=function(a){if(Gl(a))return yt(this,a);if(Hl(a))return zt(this,a);if("string"===typeof a)return a=Il(a),yt(this,a)};function yt(a,c){for(var d=c.firstChild;d;d=d.nextSibling)if(1==d.nodeType)return zt(a,d)}var At={"http://www.opengis.net/gml":{boundedBy:K(Po.prototype.te,"bounds")}}; +function zt(a,c){var d={},e=Xo(c.getAttribute("numberOfFeatures"));d.numberOfFeatures=e;return P(d,At,c,[],a.b)} +var Bt={"http://www.opengis.net/wfs":{totalInserted:K(Wo),totalUpdated:K(Wo),totalDeleted:K(Wo)}},Ct={"http://www.opengis.net/ogc":{FeatureId:Kl(function(a){return a.getAttribute("fid")})}},Dt={"http://www.opengis.net/wfs":{Feature:function(a,c){Sl(Ct,a,c)}}},xt={"http://www.opengis.net/wfs":{TransactionSummary:K(function(a,c){return P({},Bt,a,c)},"transactionSummary"),InsertResults:K(function(a,c){return P([],Dt,a,c)},"insertIds")}}; +function wt(a){for(a=a.firstChild;a;a=a.nextSibling)if(1==a.nodeType)return P({},xt,a,[])}var Et={"http://www.opengis.net/wfs":{PropertyName:M(Zo)}};function Ft(a,c){var d=Dl("http://www.opengis.net/ogc","Filter"),e=Dl("http://www.opengis.net/ogc","FeatureId");d.appendChild(e);e.setAttribute("fid",c);a.appendChild(d)} +var Gt={"http://www.opengis.net/wfs":{Insert:M(function(a,c,d){var e=d[d.length-1],e=Dl(e.featureNS,e.featureType);a.appendChild(e);cp.prototype.wi(e,c,d)}),Update:M(function(a,c,d){var e=d[d.length-1],f=e.featureType,g=e.featurePrefix,g=g?g:"feature",h=e.featureNS;a.setAttribute("typeName",g+":"+f);a.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:"+g,h);f=c.Wa();if(void 0!==f){for(var g=c.K(),h=[],k=0,m=g.length;k<m;k++){var n=c.get(g[k]);void 0!==n&&h.push({name:g[k],value:n})}Tl({node:a, +srsName:e.srsName},Gt,Ol("Property"),h,d);Ft(a,f)}}),Delete:M(function(a,c,d){var e=d[d.length-1];d=e.featureType;var f=e.featurePrefix,f=f?f:"feature",e=e.featureNS;a.setAttribute("typeName",f+":"+d);a.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:"+f,e);c=c.Wa();void 0!==c&&Ft(a,c)}),Property:M(function(a,c,d){var e=Dl("http://www.opengis.net/wfs","Name");a.appendChild(e);Zo(e,c.name);void 0!==c.value&&null!==c.value&&(e=Dl("http://www.opengis.net/wfs","Value"),a.appendChild(e),c.value instanceof +dd?cp.prototype.Fe(e,c.value,d):Zo(e,c.value))}),Native:M(function(a,c){c.qp&&a.setAttribute("vendorId",c.qp);void 0!==c.So&&a.setAttribute("safeToIgnore",c.So);void 0!==c.value&&Zo(a,c.value)})}};function Ht(a,c,d){a={node:a};var e=c.a;Tl(a,It,Ol(e.Ae),[e],d);c=c.f;Tl(a,It,Ol(c.Ae),[c],d)}function Jt(a,c){void 0!==c.f&&a.setAttribute("matchCase",c.f.toString());Kt(a,c.a);Lt("Literal",a,""+c.c)}function Lt(a,c,d){a=Dl("http://www.opengis.net/ogc",a);Zo(a,d);c.appendChild(a)} +function Kt(a,c){Lt("PropertyName",a,c)} +var It={"http://www.opengis.net/wfs":{Query:M(function(a,c,d){var e=d[d.length-1],f=e.featurePrefix,g=e.featureNS,h=e.propertyNames,k=e.srsName;a.setAttribute("typeName",(f?f+":":"")+c);k&&a.setAttribute("srsName",k);g&&a.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:"+f,g);c=Pa({},e);c.node=a;Tl(c,Et,Ol("PropertyName"),h,d);if(e=e.filter)h=Dl("http://www.opengis.net/ogc","Filter"),a.appendChild(h),Tl({node:h},It,Ol(e.Ae),[e],d)})},"http://www.opengis.net/ogc":{And:M(Ht),Or:M(Ht),Not:M(function(a, +c,d){c=c.condition;Tl({node:a},It,Ol(c.Ae),[c],d)}),BBOX:M(function(a,c,d){d[d.length-1].srsName=c.srsName;Kt(a,c.geometryName);cp.prototype.Fe(a,c.extent,d)}),PropertyIsEqualTo:M(Jt),PropertyIsNotEqualTo:M(Jt),PropertyIsLessThan:M(Jt),PropertyIsLessThanOrEqualTo:M(Jt),PropertyIsGreaterThan:M(Jt),PropertyIsGreaterThanOrEqualTo:M(Jt),PropertyIsNull:M(function(a,c){Kt(a,c.a)}),PropertyIsBetween:M(function(a,c){Kt(a,c.a);Lt("LowerBoundary",a,""+c.f);Lt("UpperBoundary",a,""+c.c)}),PropertyIsLike:M(function(a, +c){a.setAttribute("wildCard",c.o);a.setAttribute("singleChar",c.l);a.setAttribute("escapeChar",c.c);void 0!==c.f&&a.setAttribute("matchCase",c.f.toString());Kt(a,c.a);Lt("Literal",a,""+c.i)})}}; +vt.prototype.j=function(a){var c=Dl("http://www.opengis.net/wfs","GetFeature");c.setAttribute("service","WFS");c.setAttribute("version","1.1.0");var d;if(a&&(a.handle&&c.setAttribute("handle",a.handle),a.outputFormat&&c.setAttribute("outputFormat",a.outputFormat),void 0!==a.maxFeatures&&c.setAttribute("maxFeatures",a.maxFeatures),a.resultType&&c.setAttribute("resultType",a.resultType),void 0!==a.startIndex&&c.setAttribute("startIndex",a.startIndex),void 0!==a.count&&c.setAttribute("count",a.count), +d=a.filter,a.bbox)){var e=ts(a.geometryName,a.bbox,a.srsName);d?d=rs(d,e):d=e}c.setAttributeNS("http://www.w3.org/2001/XMLSchema-instance","xsi:schemaLocation",this.c);e=a.featureTypes;a=[{node:c,srsName:a.srsName,featureNS:a.featureNS?a.featureNS:this.g,featurePrefix:a.featurePrefix,geometryName:a.geometryName,filter:d,propertyNames:a.propertyNames?a.propertyNames:[]}];d=Pa({},a[a.length-1]);d.node=c;Tl(d,It,Ol("Query"),e,a);return c}; +vt.prototype.U=function(a,c,d,e){var f=[],g=Dl("http://www.opengis.net/wfs","Transaction");g.setAttribute("service","WFS");g.setAttribute("version","1.1.0");var h,k;e&&(h=e.gmlOptions?e.gmlOptions:{},e.handle&&g.setAttribute("handle",e.handle));g.setAttributeNS("http://www.w3.org/2001/XMLSchema-instance","xsi:schemaLocation",this.c);a&&(k={node:g,featureNS:e.featureNS,featureType:e.featureType,featurePrefix:e.featurePrefix},Pa(k,h),Tl(k,Gt,Ol("Insert"),a,f));c&&(k={node:g,featureNS:e.featureNS,featureType:e.featureType, +featurePrefix:e.featurePrefix},Pa(k,h),Tl(k,Gt,Ol("Update"),c,f));d&&Tl({node:g,featureNS:e.featureNS,featureType:e.featureType,featurePrefix:e.featurePrefix},Gt,Ol("Delete"),d,f);e.nativeElements&&Tl({node:g,featureNS:e.featureNS,featureType:e.featureType,featurePrefix:e.featurePrefix},Gt,Ol("Native"),e.nativeElements,f);return g};vt.prototype.Lf=function(a){for(a=a.firstChild;a;a=a.nextSibling)if(1==a.nodeType)return this.we(a);return null}; +vt.prototype.we=function(a){if(a.firstElementChild&&a.firstElementChild.firstElementChild)for(a=a.firstElementChild.firstElementChild,a=a.firstElementChild;a;a=a.nextElementSibling)if(0!==a.childNodes.length&&(1!==a.childNodes.length||3!==a.firstChild.nodeType)){var c=[{}];this.b.te(a,c);return Ic(c.pop().srsName)}return null};function Mt(a){a=a?a:{};this.defaultDataProjection=null;this.b=void 0!==a.splitCollection?a.splitCollection:!1}y(Mt,Sp);function Nt(a){a=a.Z();return 0===a.length?"":a[0]+" "+a[1]}function Ot(a){a=a.Z();for(var c=[],d=0,e=a.length;d<e;++d)c.push(a[d][0]+" "+a[d][1]);return c.join(",")}function Pt(a){var c=[];a=a.Pd();for(var d=0,e=a.length;d<e;++d)c.push("("+Ot(a[d])+")");return c.join(",")}function Qt(a){var c=a.X();a=(0,Rt[c])(a);c=c.toUpperCase();return 0===a.length?c+" EMPTY":c+"("+a+")"} +var Rt={Point:Nt,LineString:Ot,Polygon:Pt,MultiPoint:function(a){var c=[];a=a.ee();for(var d=0,e=a.length;d<e;++d)c.push("("+Nt(a[d])+")");return c.join(",")},MultiLineString:function(a){var c=[];a=a.gd();for(var d=0,e=a.length;d<e;++d)c.push("("+Ot(a[d])+")");return c.join(",")},MultiPolygon:function(a){var c=[];a=a.Qd();for(var d=0,e=a.length;d<e;++d)c.push("("+Pt(a[d])+")");return c.join(",")},GeometryCollection:function(a){var c=[];a=a.bf();for(var d=0,e=a.length;d<e;++d)c.push(Qt(a[d]));return c.join(",")}}; +l=Mt.prototype;l.pd=function(a,c){var d=this.rd(a,c);if(d){var e=new zl;e.Ta(d);return e}return null};l.Gf=function(a,c){var d=[],e=this.rd(a,c);this.b&&"GeometryCollection"==e.X()?d=e.c:d=[e];for(var f=[],g=0,h=d.length;g<h;++g)e=new zl,e.Ta(d[g]),f.push(e);return f};l.rd=function(a,c){var d;d=new St(new Tt(a));d.b=Ut(d.a);return(d=Vt(d))?lo(d,!1,c):null};l.De=function(a,c){var d=a.W();return d?this.zd(d,c):""}; +l.xi=function(a,c){if(1==a.length)return this.De(a[0],c);for(var d=[],e=0,f=a.length;e<f;++e)d.push(a[e].W());d=new Do(d);return this.zd(d,c)};l.zd=function(a,c){return Qt(lo(a,!0,c))};function Tt(a){this.a=a;this.b=-1} +function Ut(a){var c=a.a.charAt(++a.b),d={position:a.b,value:c};if("("==c)d.type=2;else if(","==c)d.type=5;else if(")"==c)d.type=3;else if("0"<=c&&"9">=c||"."==c||"-"==c){d.type=4;var e,c=a.b,f=!1,g=!1;do{if("."==e)f=!0;else if("e"==e||"E"==e)g=!0;e=a.a.charAt(++a.b)}while("0"<=e&&"9">=e||"."==e&&(void 0===f||!f)||!g&&("e"==e||"E"==e)||g&&("-"==e||"+"==e));a=parseFloat(a.a.substring(c,a.b--));d.value=a}else if("a"<=c&&"z">=c||"A"<=c&&"Z">=c){d.type=1;c=a.b;do e=a.a.charAt(++a.b);while("a"<=e&&"z">= +e||"A"<=e&&"Z">=e);a=a.a.substring(c,a.b--).toUpperCase();d.value=a}else{if(" "==c||"\t"==c||"\r"==c||"\n"==c)return Ut(a);if(""===c)d.type=6;else throw Error("Unexpected character: "+c);}return d}function St(a){this.a=a}l=St.prototype;l.match=function(a){if(a=this.b.type==a)this.b=Ut(this.a);return a}; +function Vt(a){var c=a.b;if(a.match(1)){var d=c.value;if("GEOMETRYCOLLECTION"==d){a:{if(a.match(2)){c=[];do c.push(Vt(a));while(a.match(5));if(a.match(3)){a=c;break a}}else if(Wt(a)){a=[];break a}throw Error(Xt(a));}return new Do(a)}var e=Yt[d],c=Zt[d];if(!e||!c)throw Error("Invalid geometry type: "+d);a=e.call(a);return new c(a)}throw Error(Xt(a));}l.Af=function(){if(this.match(2)){var a=$t(this);if(this.match(3))return a}else if(Wt(this))return null;throw Error(Xt(this));}; +l.zf=function(){if(this.match(2)){var a=au(this);if(this.match(3))return a}else if(Wt(this))return[];throw Error(Xt(this));};l.Bf=function(){if(this.match(2)){var a=bu(this);if(this.match(3))return a}else if(Wt(this))return[];throw Error(Xt(this));};l.ao=function(){if(this.match(2)){var a;if(2==this.b.type)for(a=[this.Af()];this.match(5);)a.push(this.Af());else a=au(this);if(this.match(3))return a}else if(Wt(this))return[];throw Error(Xt(this));}; +l.$n=function(){if(this.match(2)){var a=bu(this);if(this.match(3))return a}else if(Wt(this))return[];throw Error(Xt(this));};l.bo=function(){if(this.match(2)){for(var a=[this.Bf()];this.match(5);)a.push(this.Bf());if(this.match(3))return a}else if(Wt(this))return[];throw Error(Xt(this));};function $t(a){for(var c=[],d=0;2>d;++d){var e=a.b;if(a.match(4))c.push(e.value);else break}if(2==c.length)return c;throw Error(Xt(a));}function au(a){for(var c=[$t(a)];a.match(5);)c.push($t(a));return c} +function bu(a){for(var c=[a.zf()];a.match(5);)c.push(a.zf());return c}function Wt(a){var c=1==a.b.type&&"EMPTY"==a.b.value;c&&(a.b=Ut(a.a));return c}function Xt(a){return"Unexpected `"+a.b.value+"` at position "+a.b.position+" in `"+a.a.a+"`"}var Zt={POINT:D,LINESTRING:T,POLYGON:F,MULTIPOINT:so,MULTILINESTRING:U,MULTIPOLYGON:to},Yt={POINT:St.prototype.Af,LINESTRING:St.prototype.zf,POLYGON:St.prototype.Bf,MULTIPOINT:St.prototype.ao,MULTILINESTRING:St.prototype.$n,MULTIPOLYGON:St.prototype.bo};function cu(){this.version=void 0}y(cu,Ss);cu.prototype.a=function(a){for(a=a.firstChild;a;a=a.nextSibling)if(1==a.nodeType)return this.b(a);return null};cu.prototype.b=function(a){this.version=a.getAttribute("version").trim();return(a=P({version:this.version},du,a,[]))?a:null};function eu(a,c){return P({},fu,a,c)}function gu(a,c){return P({},hu,a,c)}function iu(a,c){var d=eu(a,c);if(d){var e=[Xo(a.getAttribute("width")),Xo(a.getAttribute("height"))];d.size=e;return d}} +function ju(a,c){return P([],ku,a,c)} +var lu=[null,"http://www.opengis.net/wms"],du=N(lu,{Service:K(function(a,c){return P({},mu,a,c)}),Capability:K(function(a,c){return P({},nu,a,c)})}),nu=N(lu,{Request:K(function(a,c){return P({},ou,a,c)}),Exception:K(function(a,c){return P([],pu,a,c)}),Layer:K(function(a,c){return P({},qu,a,c)})}),mu=N(lu,{Name:K(V),Title:K(V),Abstract:K(V),KeywordList:K(ju),OnlineResource:K(Rs),ContactInformation:K(function(a,c){return P({},ru,a,c)}),Fees:K(V),AccessConstraints:K(V),LayerLimit:K(Wo),MaxWidth:K(Wo), +MaxHeight:K(Wo)}),ru=N(lu,{ContactPersonPrimary:K(function(a,c){return P({},su,a,c)}),ContactPosition:K(V),ContactAddress:K(function(a,c){return P({},tu,a,c)}),ContactVoiceTelephone:K(V),ContactFacsimileTelephone:K(V),ContactElectronicMailAddress:K(V)}),su=N(lu,{ContactPerson:K(V),ContactOrganization:K(V)}),tu=N(lu,{AddressType:K(V),Address:K(V),City:K(V),StateOrProvince:K(V),PostCode:K(V),Country:K(V)}),pu=N(lu,{Format:Kl(V)}),qu=N(lu,{Name:K(V),Title:K(V),Abstract:K(V),KeywordList:K(ju),CRS:Ml(V), +EX_GeographicBoundingBox:K(function(a,c){var d=P({},uu,a,c);if(d){var e=d.westBoundLongitude,f=d.southBoundLatitude,g=d.eastBoundLongitude,d=d.northBoundLatitude;return void 0===e||void 0===f||void 0===g||void 0===d?void 0:[e,f,g,d]}}),BoundingBox:Ml(function(a){var c=[Vo(a.getAttribute("minx")),Vo(a.getAttribute("miny")),Vo(a.getAttribute("maxx")),Vo(a.getAttribute("maxy"))],d=[Vo(a.getAttribute("resx")),Vo(a.getAttribute("resy"))];return{crs:a.getAttribute("CRS"),extent:c,res:d}}),Dimension:Ml(function(a){return{name:a.getAttribute("name"), +units:a.getAttribute("units"),unitSymbol:a.getAttribute("unitSymbol"),"default":a.getAttribute("default"),multipleValues:So(a.getAttribute("multipleValues")),nearestValue:So(a.getAttribute("nearestValue")),current:So(a.getAttribute("current")),values:V(a)}}),Attribution:K(function(a,c){return P({},vu,a,c)}),AuthorityURL:Ml(function(a,c){var d=eu(a,c);if(d)return d.name=a.getAttribute("name"),d}),Identifier:Ml(V),MetadataURL:Ml(function(a,c){var d=eu(a,c);if(d)return d.type=a.getAttribute("type"), +d}),DataURL:Ml(eu),FeatureListURL:Ml(eu),Style:Ml(function(a,c){return P({},wu,a,c)}),MinScaleDenominator:K(Uo),MaxScaleDenominator:K(Uo),Layer:Ml(function(a,c){var d=c[c.length-1],e=P({},qu,a,c);if(e){var f=So(a.getAttribute("queryable"));void 0===f&&(f=d.queryable);e.queryable=void 0!==f?f:!1;f=Xo(a.getAttribute("cascaded"));void 0===f&&(f=d.cascaded);e.cascaded=f;f=So(a.getAttribute("opaque"));void 0===f&&(f=d.opaque);e.opaque=void 0!==f?f:!1;f=So(a.getAttribute("noSubsets"));void 0===f&&(f=d.noSubsets); +e.noSubsets=void 0!==f?f:!1;(f=Vo(a.getAttribute("fixedWidth")))||(f=d.fixedWidth);e.fixedWidth=f;(f=Vo(a.getAttribute("fixedHeight")))||(f=d.fixedHeight);e.fixedHeight=f;["Style","CRS","AuthorityURL"].forEach(function(a){a in d&&(e[a]=(e[a]||[]).concat(d[a]))});"EX_GeographicBoundingBox BoundingBox Dimension Attribution MinScaleDenominator MaxScaleDenominator".split(" ").forEach(function(a){a in e||(e[a]=d[a])});return e}})}),vu=N(lu,{Title:K(V),OnlineResource:K(Rs),LogoURL:K(iu)}),uu=N(lu,{westBoundLongitude:K(Uo), +eastBoundLongitude:K(Uo),southBoundLatitude:K(Uo),northBoundLatitude:K(Uo)}),ou=N(lu,{GetCapabilities:K(gu),GetMap:K(gu),GetFeatureInfo:K(gu)}),hu=N(lu,{Format:Ml(V),DCPType:Ml(function(a,c){return P({},xu,a,c)})}),xu=N(lu,{HTTP:K(function(a,c){return P({},yu,a,c)})}),yu=N(lu,{Get:K(eu),Post:K(eu)}),wu=N(lu,{Name:K(V),Title:K(V),Abstract:K(V),LegendURL:Ml(iu),StyleSheetURL:K(eu),StyleURL:K(eu)}),fu=N(lu,{Format:K(V),OnlineResource:K(Rs)}),ku=N(lu,{Keyword:Kl(V)});function zu(a){a=a?a:{};this.g="http://mapserver.gis.umn.edu/mapserver";this.b=new bp;this.c=a.layers?a.layers:null;Mo.call(this)}y(zu,Mo); +zu.prototype.gc=function(a,c){var d={};c&&Pa(d,jo(this,a,c));var e=[d];a.setAttribute("namespaceURI",this.g);var f=a.localName,d=[];if(0!==a.childNodes.length){if("msGMLOutput"==f)for(var g=0,h=a.childNodes.length;g<h;g++){var k=a.childNodes[g];if(1===k.nodeType){var m=e[0],n=k.localName.replace("_layer","");if(!this.c||ub(this.c,n)){n+="_feature";m.featureType=n;m.featureNS=this.g;var p={};p[n]=Kl(this.b.Ef,this.b);m=N([m.featureNS,null],p);k.setAttribute("namespaceURI",this.g);(k=P([],m,k,e,this.b))&& +xb(d,k)}}}"FeatureCollection"==f&&(e=P([],this.b.b,a,[{}],this.b))&&(d=e)}return d};function Au(){this.g=new Ts}y(Au,Ss);Au.prototype.a=function(a){for(a=a.firstChild;a;a=a.nextSibling)if(1==a.nodeType)return this.b(a);return null};Au.prototype.b=function(a){var c=a.getAttribute("version").trim(),d=this.g.b(a);if(!d)return null;d.version=c;return(d=P(d,Bu,a,[]))?d:null};function Cu(a){var c=V(a).split(" ");if(c&&2==c.length)return a=+c[0],c=+c[1],isNaN(a)||isNaN(c)?void 0:[a,c]} +var Du=[null,"http://www.opengis.net/wmts/1.0"],Eu=[null,"http://www.opengis.net/ows/1.1"],Bu=N(Du,{Contents:K(function(a,c){return P({},Fu,a,c)})}),Fu=N(Du,{Layer:Ml(function(a,c){return P({},Gu,a,c)}),TileMatrixSet:Ml(function(a,c){return P({},Hu,a,c)})}),Gu=N(Du,{Style:Ml(function(a,c){var d=P({},Iu,a,c);if(d){var e="true"===a.getAttribute("isDefault");d.isDefault=e;return d}}),Format:Ml(V),TileMatrixSetLink:Ml(function(a,c){return P({},Ju,a,c)}),Dimension:Ml(function(a,c){return P({},Ku,a,c)}), +ResourceURL:Ml(function(a){var c=a.getAttribute("format"),d=a.getAttribute("template");a=a.getAttribute("resourceType");var e={};c&&(e.format=c);d&&(e.template=d);a&&(e.resourceType=a);return e})},N(Eu,{Title:K(V),Abstract:K(V),WGS84BoundingBox:K(function(a,c){var d=P([],Lu,a,c);return 2!=d.length?void 0:Vb(d)}),Identifier:K(V)})),Iu=N(Du,{LegendURL:Ml(function(a){var c={};c.format=a.getAttribute("format");c.href=Rs(a);return c})},N(Eu,{Title:K(V),Identifier:K(V)})),Ju=N(Du,{TileMatrixSet:K(V)}), +Ku=N(Du,{Default:K(V),Value:Ml(V)},N(Eu,{Identifier:K(V)})),Lu=N(Eu,{LowerCorner:Kl(Cu),UpperCorner:Kl(Cu)}),Hu=N(Du,{WellKnownScaleSet:K(V),TileMatrix:Ml(function(a,c){return P({},Mu,a,c)})},N(Eu,{SupportedCRS:K(V),Identifier:K(V)})),Mu=N(Du,{TopLeftCorner:K(Cu),ScaleDenominator:K(Uo),TileWidth:K(Wo),TileHeight:K(Wo),MatrixWidth:K(Wo),MatrixHeight:K(Wo)},N(Eu,{Identifier:K(V)}));function Nu(a){pb.call(this);a=a||{};this.a=null;this.c=ad;this.f=void 0;C(this,rb("projection"),this.Jl,this);C(this,rb("tracking"),this.Kl,this);void 0!==a.projection&&this.Yg(Ic(a.projection));void 0!==a.trackingOptions&&this.mi(a.trackingOptions);this.ae(void 0!==a.tracking?a.tracking:!1)}y(Nu,pb);l=Nu.prototype;l.fa=function(){this.ae(!1);Nu.ia.fa.call(this)};l.Jl=function(){var a=this.Wg();a&&(this.c=Lc(Ic("EPSG:4326"),a),this.a&&this.set("position",this.c(this.a)))}; +l.Kl=function(){if(bh){var a=this.Xg();a&&void 0===this.f?this.f=qa.navigator.geolocation.watchPosition(this.ko.bind(this),this.lo.bind(this),this.Hg()):a||void 0===this.f||(qa.navigator.geolocation.clearWatch(this.f),this.f=void 0)}}; +l.ko=function(a){a=a.coords;this.set("accuracy",a.accuracy);this.set("altitude",null===a.altitude?void 0:a.altitude);this.set("altitudeAccuracy",null===a.altitudeAccuracy?void 0:a.altitudeAccuracy);this.set("heading",null===a.heading?void 0:Ha(a.heading));this.a?(this.a[0]=a.longitude,this.a[1]=a.latitude):this.a=[a.longitude,a.latitude];var c=this.c(this.a);this.set("position",c);this.set("speed",null===a.speed?void 0:a.speed);a=Yd(Pj,this.a,a.accuracy);a.mc(this.c);this.set("accuracyGeometry",a); +this.u()};l.lo=function(a){a.type="error";this.ae(!1);this.b(a)};l.Ij=function(){return this.get("accuracy")};l.Jj=function(){return this.get("accuracyGeometry")||null};l.Lj=function(){return this.get("altitude")};l.Mj=function(){return this.get("altitudeAccuracy")};l.Hl=function(){return this.get("heading")};l.Il=function(){return this.get("position")};l.Wg=function(){return this.get("projection")};l.sk=function(){return this.get("speed")};l.Xg=function(){return this.get("tracking")};l.Hg=function(){return this.get("trackingOptions")}; +l.Yg=function(a){this.set("projection",a)};l.ae=function(a){this.set("tracking",a)};l.mi=function(a){this.set("trackingOptions",a)};function Ou(a,c,d){sd.call(this);this.Rf(a,c?c:0,d)}y(Ou,sd);l=Ou.prototype;l.clone=function(){var a=new Ou(null),c=this.A.slice();ud(a,this.f,c);a.u();return a};l.rb=function(a,c,d,e){var f=this.A;a-=f[0];var g=c-f[1];c=a*a+g*g;if(c<e){if(0===c)for(e=0;e<this.a;++e)d[e]=f[e];else for(e=this.sf()/Math.sqrt(c),d[0]=f[0]+e*a,d[1]=f[1]+e*g,e=2;e<this.a;++e)d[e]=f[e];d.length=this.a;return c}return e};l.wc=function(a,c){var d=this.A,e=a-d[0],d=c-d[1];return e*e+d*d<=Pu(this)}; +l.ld=function(){return this.A.slice(0,this.a)};l.Jd=function(a){var c=this.A,d=c[this.a]-c[0];return ec(c[0]-d,c[1]-d,c[0]+d,c[1]+d,a)};l.sf=function(){return Math.sqrt(Pu(this))};function Pu(a){var c=a.A[a.a]-a.A[0];a=a.A[a.a+1]-a.A[1];return c*c+a*a}l.X=function(){return"Circle"};l.Ia=function(a){var c=this.O();return wc(a,c)?(c=this.ld(),a[0]<=c[0]&&a[2]>=c[0]||a[1]<=c[1]&&a[3]>=c[1]?!0:kc(a,this.og,this)):!1}; +l.dm=function(a){var c=this.a,d=this.A[c]-this.A[0],e=a.slice();e[c]=e[0]+d;for(d=1;d<c;++d)e[c+d]=a[d];ud(this,this.f,e);this.u()};l.Rf=function(a,c,d){if(a){vd(this,d,a,0);this.A||(this.A=[]);d=this.A;a=Dd(d,a);d[a++]=d[0]+c;var e;c=1;for(e=this.a;c<e;++c)d[a++]=d[c];d.length=a}else ud(this,"XY",null);this.u()};l.em=function(a){this.A[this.a]=this.A[0]+a;this.u()};function Qu(a,c,d){for(var e=[],f=a(0),g=a(1),h=c(f),k=c(g),m=[g,f],n=[k,h],p=[1,0],q={},r=1E5,u,v,x,z,E;0<--r&&0<p.length;)x=p.pop(),f=m.pop(),h=n.pop(),g=x.toString(),g in q||(e.push(h[0],h[1]),q[g]=!0),z=p.pop(),g=m.pop(),k=n.pop(),E=(x+z)/2,u=a(E),v=c(u),Fa(v[0],v[1],h[0],h[1],k[0],k[1])<d?(e.push(k[0],k[1]),g=z.toString(),q[g]=!0):(p.push(z,E,E,x),n.push(k,v,v,h),m.push(g,u,u,f));return e}function Ru(a,c,d,e,f){var g=Ic("EPSG:4326");return Qu(function(e){return[a,c+(d-c)*e]},$c(g,e),f)} +function Su(a,c,d,e,f){var g=Ic("EPSG:4326");return Qu(function(e){return[c+(d-c)*e,a]},$c(g,e),f)};function Tu(a){a=a||{};this.c=this.o=null;this.g=this.i=Infinity;this.f=this.l=-Infinity;this.B=this.U=Infinity;this.N=this.M=-Infinity;this.ya=void 0!==a.targetSize?a.targetSize:100;this.R=void 0!==a.maxLines?a.maxLines:100;this.b=[];this.a=[];this.va=void 0!==a.strokeStyle?a.strokeStyle:Uu;this.v=this.j=void 0;this.s=null;this.setMap(void 0!==a.map?a.map:null)}var Uu=new gk({color:"rgba(0,0,0,0.2)"}),Vu=[90,45,30,20,10,5,2,1,.5,.2,.1,.05,.01,.005,.002,.001]; +function Wu(a,c,d,e,f,g,h){var k=h;c=Ru(c,d,e,a.c,f);k=void 0!==a.b[k]?a.b[k]:new T(null);k.ba("XY",c);wc(k.O(),g)&&(a.b[h++]=k);return h}function Xu(a,c,d,e,f){var g=f;c=Su(c,a.f,a.g,a.c,d);g=void 0!==a.a[g]?a.a[g]:new T(null);g.ba("XY",c);wc(g.O(),e)&&(a.a[f++]=g);return f}l=Tu.prototype;l.Ll=function(){return this.o};l.ek=function(){return this.b};l.lk=function(){return this.a}; +l.Mg=function(a){var c=a.vectorContext,d=a.frameState,e=d.extent;a=d.viewState;var f=a.center,g=a.projection,h=a.resolution;a=d.pixelRatio;a=h*h/(4*a*a);if(!this.c||!Zc(this.c,g)){var k=Ic("EPSG:4326"),m=g.O(),n=g.i,p=cd(n,k,g),q=n[2],r=n[1],u=n[0],v=p[3],x=p[2],z=p[1],p=p[0];this.i=n[3];this.g=q;this.l=r;this.f=u;this.U=v;this.B=x;this.M=z;this.N=p;this.j=$c(k,g);this.v=$c(g,k);this.s=this.v(tc(m));this.c=g}k=0;g.a&&(g=g.O(),k=rc(g),d=d.focus[0],d<g[0]||d>g[2])&&(k*=Math.ceil((g[0]-d)/k),e=[e[0]+ +k,e[1],e[2]+k,e[3]]);d=this.s[0];g=this.s[1];k=-1;n=Math.pow(this.ya*h,2);q=[];r=[];h=0;for(m=Vu.length;h<m;++h){u=Vu[h]/2;q[0]=d-u;q[1]=g-u;r[0]=d+u;r[1]=g+u;this.j(q,q);this.j(r,r);u=Math.pow(r[0]-q[0],2)+Math.pow(r[1]-q[1],2);if(u<=n)break;k=Vu[h]}h=k;if(-1==h)this.b.length=this.a.length=0;else{d=this.v(f);f=d[0];d=d[1];g=this.R;k=[Math.max(e[0],this.N),Math.max(e[1],this.M),Math.min(e[2],this.B),Math.min(e[3],this.U)];k=cd(k,this.c,"EPSG:4326");n=k[3];r=k[1];f=Math.floor(f/h)*h;q=Da(f,this.f, +this.g);m=Wu(this,q,r,n,a,e,0);for(k=0;q!=this.f&&k++<g;)q=Math.max(q-h,this.f),m=Wu(this,q,r,n,a,e,m);q=Da(f,this.f,this.g);for(k=0;q!=this.g&&k++<g;)q=Math.min(q+h,this.g),m=Wu(this,q,r,n,a,e,m);this.b.length=m;d=Math.floor(d/h)*h;f=Da(d,this.l,this.i);m=Xu(this,f,a,e,0);for(k=0;f!=this.l&&k++<g;)f=Math.max(f-h,this.l),m=Xu(this,f,a,e,m);f=Da(d,this.l,this.i);for(k=0;f!=this.i&&k++<g;)f=Math.min(f+h,this.i),m=Xu(this,f,a,e,m);this.a.length=m}c.Ob(null,this.va);a=0;for(f=this.b.length;a<f;++a)h= +this.b[a],c.cd(h,null);a=0;for(f=this.a.length;a<f;++a)h=this.a[a],c.cd(h,null)};l.setMap=function(a){this.o&&(this.o.G("postcompose",this.Mg,this),this.o.render());a&&(a.D("postcompose",this.Mg,this),a.render());this.o=a};function Yu(a,c,d,e,f,g,h){fi.call(this,a,c,d,0,e);this.j=f;this.g=new Image;null!==g&&(this.g.crossOrigin=g);this.i={};this.c=null;this.state=0;this.o=h}y(Yu,fi);Yu.prototype.a=function(a){if(void 0!==a){var c;a=w(a);if(a in this.i)return this.i[a];Sa(this.i)?c=this.g:c=this.g.cloneNode(!1);return this.i[a]=c}return this.g};Yu.prototype.s=function(){this.state=3;this.c.forEach(Xa);this.c=null;gi(this)}; +Yu.prototype.v=function(){void 0===this.resolution&&(this.resolution=sc(this.extent)/this.g.height);this.state=2;this.c.forEach(Xa);this.c=null;gi(this)};Yu.prototype.load=function(){0==this.state&&(this.state=1,gi(this),this.c=[bb(this.g,"error",this.s,this),bb(this.g,"load",this.v,this)],this.o(this,this.j))};function Zu(a,c,d,e,f){Qf.call(this,a,c);this.s=d;this.g=new Image;null!==e&&(this.g.crossOrigin=e);this.c={};this.j=null;this.v=f}y(Zu,Qf);l=Zu.prototype;l.fa=function(){1==this.state&&$u(this);this.a&&fb(this.a);this.state=5;Rf(this);Zu.ia.fa.call(this)};l.ab=function(a){if(void 0!==a){var c=w(a);if(c in this.c)return this.c[c];a=Sa(this.c)?this.g:this.g.cloneNode(!1);return this.c[c]=a}return this.g};l.gb=function(){return this.s};l.Ml=function(){this.state=3;$u(this);Rf(this)}; +l.Nl=function(){this.state=this.g.naturalWidth&&this.g.naturalHeight?2:4;$u(this);Rf(this)};l.load=function(){0==this.state&&(this.state=1,Rf(this),this.j=[bb(this.g,"error",this.Ml,this),bb(this.g,"load",this.Nl,this)],this.v(this,this.s))};function $u(a){a.j.forEach(Xa);a.j=null};function av(a){a=a?a:{};Mi.call(this,{handleEvent:Ac});this.c=a.formatConstructors?a.formatConstructors:[];this.j=a.projection?Ic(a.projection):null;this.a=null;this.target=a.target?a.target:null}y(av,Mi);function bv(a){a=a.dataTransfer.files;var c,d,e;c=0;for(d=a.length;c<d;++c){e=a.item(c);var f=new FileReader;f.addEventListener("load",this.o.bind(this,e));f.readAsText(e)}}function cv(a){a.stopPropagation();a.preventDefault();a.dataTransfer.dropEffect="copy"} +av.prototype.o=function(a,c){var d=c.target.result,e=this.v,f=this.j;f||(f=e.aa().i);var e=this.c,g=[],h,k;h=0;for(k=e.length;h<k;++h){var m=new e[h];var n={featureProjection:f};try{g=m.Ca(d,n)}catch(p){g=null}if(g&&0<g.length)break}this.b(new dv(ev,this,a,g,f))};av.prototype.setMap=function(a){this.a&&(this.a.forEach(Xa),this.a=null);av.ia.setMap.call(this,a);a&&(a=this.target?this.target:a.a,this.a=[C(a,"drop",bv,this),C(a,"dragenter",cv,this),C(a,"dragover",cv,this),C(a,"drop",cv,this)])}; +var ev="addfeatures";function dv(a,c,d,e,f){gb.call(this,a,c);this.features=e;this.file=d;this.projection=f}y(dv,gb);function fv(a){a=a?a:{};aj.call(this,{handleDownEvent:gv,handleDragEvent:hv,handleUpEvent:iv});this.s=a.condition?a.condition:Xi;this.a=this.c=void 0;this.j=0;this.B=void 0!==a.duration?a.duration:400}y(fv,aj); +function hv(a){if(Zi(a)){var c=a.map,d=c.$a(),e=a.pixel;a=e[0]-d[0]/2;e=d[1]/2-e[1];d=Math.atan2(e,a);a=Math.sqrt(a*a+e*e);e=c.aa();c.render();if(void 0!==this.c){var f=d-this.c;Ni(c,e,e.Ka()-f)}this.c=d;void 0!==this.a&&(d=this.a*(e.$()/a),Pi(c,e,d));void 0!==this.a&&(this.j=this.a/a);this.a=a}} +function iv(a){if(!Zi(a))return!0;a=a.map;var c=a.aa();he(c,-1);var d=this.j-1,e=c.Ka(),e=c.constrainRotation(e,0);Ni(a,c,e,void 0,void 0);var e=c.$(),f=this.B,e=c.constrainResolution(e,0,d);Pi(a,c,e,void 0,f);this.j=0;return!1}function gv(a){return Zi(a)&&this.s(a)?(he(a.map.aa(),1),this.a=this.c=void 0,!0):!1};function jv(a,c){gb.call(this,a);this.feature=c}y(jv,gb); +function kv(a){aj.call(this,{handleDownEvent:lv,handleEvent:mv,handleUpEvent:nv});this.wa=null;this.S=!1;this.Cc=a.source?a.source:null;this.pb=a.features?a.features:null;this.yj=a.snapTolerance?a.snapTolerance:12;this.Y=a.type;this.c=ov(this.Y);this.Ra=a.minPoints?a.minPoints:this.c===pv?3:2;this.xa=a.maxPoints?a.maxPoints:Infinity;this.Je=a.finishCondition?a.finishCondition:Ac;var c=a.geometryFunction;if(!c)if("Circle"===this.Y)c=function(a,c){var d=c?c:new Ou([NaN,NaN]);d.Rf(a[0],Math.sqrt(Sb(a[0], +a[1])));return d};else{var d,c=this.c;c===qv?d=D:c===rv?d=T:c===pv&&(d=F);c=function(a,c){var g=c;g?g.ma(a):g=new d(a);return g}}this.N=c;this.T=this.B=this.a=this.R=this.j=this.s=null;this.Bj=a.clickTolerance?a.clickTolerance*a.clickTolerance:36;this.na=new H({source:new Q({useSpatialIndex:!1,wrapX:a.wrapX?a.wrapX:!1}),style:a.style?a.style:sv()});this.Db=a.geometryName;this.xj=a.condition?a.condition:Wi;this.ta=a.freehandCondition?a.freehandCondition:Xi;C(this,rb("active"),this.ti,this)}y(kv,aj); +function sv(){var a=ok();return function(c){return a[c.W().X()]}}l=kv.prototype;l.setMap=function(a){kv.ia.setMap.call(this,a);this.ti()};function mv(a){this.c!==rv&&this.c!==pv||!this.ta(a)||(this.S=!0);var c=!this.S;this.S&&a.type===Yh?(tv(this,a),c=!1):a.type===Xh?c=uv(this,a):a.type===Rh&&(c=!1);return bj.call(this,a)&&c}function lv(a){return this.xj(a)?(this.wa=a.pixel,!0):this.S?(this.wa=a.pixel,this.s||vv(this,a),!0):!1} +function nv(a){this.S=!1;var c=this.wa,d=a.pixel,e=c[0]-d[0],c=c[1]-d[1],d=!0;e*e+c*c<=this.Bj&&(uv(this,a),this.s?this.c===wv?this.dd():xv(this,a)?this.Je(a)&&this.dd():tv(this,a):(vv(this,a),this.c===qv&&this.dd()),d=!1);return d} +function uv(a,c){if(a.s){var d=c.coordinate,e=a.j.W(),f;a.c===qv?f=a.a:a.c===pv?(f=a.a[0],f=f[f.length-1],xv(a,c)&&(d=a.s.slice())):(f=a.a,f=f[f.length-1]);f[0]=d[0];f[1]=d[1];a.N(a.a,e);a.R&&a.R.W().ma(d);e instanceof F&&a.c!==pv?(a.B||(a.B=new zl(new T(null))),e=e.Cg(0),d=a.B.W(),d.ba(e.f,e.ga())):a.T&&(d=a.B.W(),d.ma(a.T));yv(a)}else d=c.coordinate.slice(),a.R?a.R.W().ma(d):(a.R=new zl(new D(d)),yv(a));return!0} +function xv(a,c){var d=!1;if(a.j){var e=!1,f=[a.s];a.c===rv?e=a.a.length>a.Ra:a.c===pv&&(e=a.a[0].length>a.Ra,f=[a.a[0][0],a.a[0][a.a[0].length-2]]);if(e)for(var e=c.map,g=0,h=f.length;g<h;g++){var k=f[g],m=e.Da(k),n=c.pixel,d=n[0]-m[0],m=n[1]-m[1],n=a.S&&a.ta(c)?1:a.yj;if(d=Math.sqrt(d*d+m*m)<=n){a.s=k;break}}}return d} +function vv(a,c){var d=c.coordinate;a.s=d;a.c===qv?a.a=d.slice():a.c===pv?(a.a=[[d.slice(),d.slice()]],a.T=a.a[0]):(a.a=[d.slice(),d.slice()],a.c===wv&&(a.T=a.a));a.T&&(a.B=new zl(new T(a.T)));d=a.N(a.a);a.j=new zl;a.Db&&a.j.zc(a.Db);a.j.Ta(d);yv(a);a.b(new jv("drawstart",a.j))} +function tv(a,c){var d=c.coordinate,e=a.j.W(),f,g;if(a.c===rv)a.s=d.slice(),g=a.a,g.push(d.slice()),f=g.length>a.xa,a.N(g,e);else if(a.c===pv){g=a.a[0];g.push(d.slice());if(f=g.length>a.xa)a.s=g[0];a.N(a.a,e)}yv(a);f&&a.dd()}l.Ko=function(){var a=this.j.W(),c,d;this.c===rv?(c=this.a,c.splice(-2,1),this.N(c,a)):this.c===pv&&(c=this.a[0],c.splice(-2,1),d=this.B.W(),d.ma(c),this.N(this.a,a));0===c.length&&(this.s=null);yv(this)}; +l.dd=function(){var a=zv(this),c=this.a,d=a.W();this.c===rv?(c.pop(),this.N(c,d)):this.c===pv&&(c[0].pop(),c[0].push(c[0][0]),this.N(c,d));"MultiPoint"===this.Y?a.Ta(new so([c])):"MultiLineString"===this.Y?a.Ta(new U([c])):"MultiPolygon"===this.Y&&a.Ta(new to([c]));this.b(new jv("drawend",a));this.pb&&this.pb.push(a);this.Cc&&this.Cc.qb(a)};function zv(a){a.s=null;var c=a.j;c&&(a.j=null,a.R=null,a.B=null,a.na.da().clear(!0));return c} +l.lm=function(a){var c=a.W();this.j=a;this.a=c.Z();a=this.a[this.a.length-1];this.s=a.slice();this.a.push(a.slice());yv(this);this.b(new jv("drawstart",this.j))};l.Bc=Bc;function yv(a){var c=[];a.j&&c.push(a.j);a.B&&c.push(a.B);a.R&&c.push(a.R);a=a.na.da();a.clear(!0);a.Ec(c)}l.ti=function(){var a=this.v,c=this.f();a&&c||zv(this);this.na.setMap(c?a:null)}; +function ov(a){var c;"Point"===a||"MultiPoint"===a?c=qv:"LineString"===a||"MultiLineString"===a?c=rv:"Polygon"===a||"MultiPolygon"===a?c=pv:"Circle"===a&&(c=wv);return c}var qv="Point",rv="LineString",pv="Polygon",wv="Circle";function Av(a,c,d){gb.call(this,a);this.features=c;this.mapBrowserPointerEvent=d}y(Av,gb); +function Bv(a){aj.call(this,{handleDownEvent:Cv,handleDragEvent:Dv,handleEvent:Ev,handleUpEvent:Fv});this.Db=a.condition?a.condition:$i;this.Ra=function(a){return Wi(a)&&Vi(a)};this.pb=a.deleteCondition?a.deleteCondition:this.Ra;this.xa=this.c=null;this.na=[0,0];this.N=this.T=!1;this.a=new bm;this.R=void 0!==a.pixelTolerance?a.pixelTolerance:10;this.s=this.ta=!1;this.j=[];this.S=new H({source:new Q({useSpatialIndex:!1,wrapX:!!a.wrapX}),style:a.style?a.style:Gv(),updateWhileAnimating:!0,updateWhileInteracting:!0}); +this.wa={Point:this.sm,LineString:this.fh,LinearRing:this.fh,Polygon:this.tm,MultiPoint:this.qm,MultiLineString:this.pm,MultiPolygon:this.rm,GeometryCollection:this.om};this.B=a.features;this.B.forEach(this.tf,this);C(this.B,"add",this.mm,this);C(this.B,"remove",this.nm,this);this.Y=null}y(Bv,aj);l=Bv.prototype;l.tf=function(a){var c=a.W();c.X()in this.wa&&this.wa[c.X()].call(this,a,c);(c=this.v)&&Hv(this,this.na,c);C(a,"change",this.eh,this)}; +function Iv(a,c){a.N||(a.N=!0,a.b(new Av("modifystart",a.B,c)))}function Jv(a,c){Kv(a,c);a.c&&0===a.B.Zb()&&(a.S.da().kb(a.c),a.c=null);cb(c,"change",a.eh,a)}function Kv(a,c){var d=a.a,e=[];d.forEach(function(a){c===a.feature&&e.push(a)});for(var f=e.length-1;0<=f;--f)d.remove(e[f])}l.setMap=function(a){this.S.setMap(a);Bv.ia.setMap.call(this,a)};l.mm=function(a){this.tf(a.element)};l.eh=function(a){this.s||(a=a.target,Jv(this,a),this.tf(a))};l.nm=function(a){Jv(this,a.element)}; +l.sm=function(a,c){var d=c.Z(),d={feature:a,geometry:c,la:[d,d]};this.a.za(c.O(),d)};l.qm=function(a,c){var d=c.Z(),e,f,g;f=0;for(g=d.length;f<g;++f)e=d[f],e={feature:a,geometry:c,depth:[f],index:f,la:[e,e]},this.a.za(c.O(),e)};l.fh=function(a,c){var d=c.Z(),e,f,g,h;e=0;for(f=d.length-1;e<f;++e)g=d.slice(e,e+2),h={feature:a,geometry:c,index:e,la:g},this.a.za(Vb(g),h)}; +l.pm=function(a,c){var d=c.Z(),e,f,g,h,k,m,n;h=0;for(k=d.length;h<k;++h)for(e=d[h],f=0,g=e.length-1;f<g;++f)m=e.slice(f,f+2),n={feature:a,geometry:c,depth:[h],index:f,la:m},this.a.za(Vb(m),n)};l.tm=function(a,c){var d=c.Z(),e,f,g,h,k,m,n;h=0;for(k=d.length;h<k;++h)for(e=d[h],f=0,g=e.length-1;f<g;++f)m=e.slice(f,f+2),n={feature:a,geometry:c,depth:[h],index:f,la:m},this.a.za(Vb(m),n)}; +l.rm=function(a,c){var d=c.Z(),e,f,g,h,k,m,n,p,q,r;m=0;for(n=d.length;m<n;++m)for(p=d[m],h=0,k=p.length;h<k;++h)for(e=p[h],f=0,g=e.length-1;f<g;++f)q=e.slice(f,f+2),r={feature:a,geometry:c,depth:[h,m],index:f,la:q},this.a.za(Vb(q),r)};l.om=function(a,c){var d,e=c.c;for(d=0;d<e.length;++d)this.wa[e[d].X()].call(this,a,e[d])};function Lv(a,c){var d=a.c;d?d.W().ma(c):(d=new zl(new D(c)),a.c=d,a.S.da().qb(d))}function Mv(a,c){return a.index-c.index} +function Cv(a){if(!this.Db(a))return!1;Hv(this,a.pixel,a.map);this.j.length=0;this.N=!1;var c=this.c;if(c){var d=[],c=c.W().Z(),e=Vb([c]),e=em(this.a,e),f={};e.sort(Mv);for(var g=0,h=e.length;g<h;++g){var k=e[g],m=k.la,n=w(k.feature),p=k.depth;p&&(n+="-"+p.join("-"));f[n]||(f[n]=Array(2));if(Qb(m[0],c)&&!f[n][0])this.j.push([k,0]),f[n][0]=k;else if(Qb(m[1],c)&&!f[n][1]){if("LineString"!==k.geometry.X()&&"MultiLineString"!==k.geometry.X()||!f[n][0]||0!==f[n][0].index)this.j.push([k,1]),f[n][1]=k}else w(m)in +this.xa&&!f[n][0]&&!f[n][1]&&d.push([k,c])}d.length&&Iv(this,a);for(a=d.length-1;0<=a;--a)this.jl.apply(this,d[a])}return!!this.c} +function Dv(a){this.T=!1;Iv(this,a);a=a.coordinate;for(var c=0,d=this.j.length;c<d;++c){for(var e=this.j[c],f=e[0],g=f.depth,h=f.geometry,k=h.Z(),m=f.la,e=e[1];a.length<h.ua();)a.push(0);switch(h.X()){case "Point":k=a;m[0]=m[1]=a;break;case "MultiPoint":k[f.index]=a;m[0]=m[1]=a;break;case "LineString":k[f.index+e]=a;m[e]=a;break;case "MultiLineString":k[g[0]][f.index+e]=a;m[e]=a;break;case "Polygon":k[g[0]][f.index+e]=a;m[e]=a;break;case "MultiPolygon":k[g[1]][g[0]][f.index+e]=a,m[e]=a}f=h;this.s= +!0;f.ma(k);this.s=!1}Lv(this,a)}function Fv(a){for(var c,d=this.j.length-1;0<=d;--d)c=this.j[d][0],cm(this.a,Vb(c.la),c);this.N&&(this.b(new Av("modifyend",this.B,a)),this.N=!1);return!1}function Ev(a){if(!(a instanceof Nh))return!0;this.Y=a;var c;ce(a.map.aa())[1]||a.type!=Xh||this.M||(this.na=a.pixel,Hv(this,a.pixel,a.map));this.c&&this.pb(a)&&(a.type==Sh&&this.T?c=!0:(this.c.W(),c=this.Wh()));a.type==Sh&&(this.T=!1);return bj.call(this,a)&&!c} +function Hv(a,c,d){function e(a,c){return Tb(f,a.la)-Tb(f,c.la)}var f=d.Ma(c),g=d.Ma([c[0]-a.R,c[1]+a.R]),h=d.Ma([c[0]+a.R,c[1]-a.R]),g=Vb([g,h]),g=em(a.a,g);if(0<g.length){g.sort(e);var h=g[0].la,k=Nb(f,h),m=d.Da(k);if(Math.sqrt(Sb(c,m))<=a.R){c=d.Da(h[0]);d=d.Da(h[1]);c=Sb(m,c);d=Sb(m,d);a.ta=Math.sqrt(Math.min(c,d))<=a.R;a.ta&&(k=c>d?h[1]:h[0]);Lv(a,k);d={};d[w(h)]=!0;c=1;for(m=g.length;c<m;++c)if(k=g[c].la,Qb(h[0],k[0])&&Qb(h[1],k[1])||Qb(h[0],k[1])&&Qb(h[1],k[0]))d[w(k)]=!0;else break;a.xa=d; +return}}a.c&&(a.S.da().kb(a.c),a.c=null)} +l.jl=function(a,c){for(var d=a.la,e=a.feature,f=a.geometry,g=a.depth,h=a.index,k;c.length<f.ua();)c.push(0);switch(f.X()){case "MultiLineString":k=f.Z();k[g[0]].splice(h+1,0,c);break;case "Polygon":k=f.Z();k[g[0]].splice(h+1,0,c);break;case "MultiPolygon":k=f.Z();k[g[1]][g[0]].splice(h+1,0,c);break;case "LineString":k=f.Z();k.splice(h+1,0,c);break;default:return}this.s=!0;f.ma(k);this.s=!1;k=this.a;k.remove(a);Nv(this,f,h,g,1);var m={la:[d[0],c],feature:e,geometry:f,depth:g,index:h};k.za(Vb(m.la), +m);this.j.push([m,1]);d={la:[c,d[1]],feature:e,geometry:f,depth:g,index:h+1};k.za(Vb(d.la),d);this.j.push([d,0]);this.T=!0}; +l.Wh=function(){var a=!1;if(this.Y&&this.Y.type!=Yh){var c=this.Y;Iv(this,c);var d=this.j,a={},e,f,g,h,k,m,n,p,q;for(h=d.length-1;0<=h;--h)g=d[h],n=g[0],p=w(n.feature),n.depth&&(p+="-"+n.depth.join("-")),p in a||(a[p]={}),0===g[1]?(a[p].right=n,a[p].index=n.index):1==g[1]&&(a[p].left=n,a[p].index=n.index+1);for(p in a){m=a[p].right;h=a[p].left;g=a[p].index;k=g-1;n=void 0!==h?h:m;0>k&&(k=0);d=n.geometry;e=f=d.Z();q=!1;switch(d.X()){case "MultiLineString":2<f[n.depth[0]].length&&(f[n.depth[0]].splice(g, +1),q=!0);break;case "LineString":2<f.length&&(f.splice(g,1),q=!0);break;case "MultiPolygon":e=e[n.depth[1]];case "Polygon":e=e[n.depth[0]],4<e.length&&(g==e.length-1&&(g=0),e.splice(g,1),q=!0,0===g&&(e.pop(),e.push(e[0]),k=e.length-1))}q&&(e=d,this.s=!0,e.ma(f),this.s=!1,f=[],void 0!==h&&(this.a.remove(h),f.push(h.la[0])),void 0!==m&&(this.a.remove(m),f.push(m.la[1])),void 0!==h&&void 0!==m&&(h={depth:n.depth,feature:n.feature,geometry:n.geometry,index:k,la:f},this.a.za(Vb(h.la),h)),Nv(this,d,g,n.depth, +-1),this.c&&(this.S.da().kb(this.c),this.c=null))}a=!0;this.b(new Av("modifyend",this.B,c));this.N=!1}return a};function Nv(a,c,d,e,f){gm(a.a,c.O(),function(a){a.geometry===c&&(void 0===e||void 0===a.depth||Ab(a.depth,e))&&a.index>d&&(a.index+=f)})}function Gv(){var a=ok();return function(){return a.Point}};function Ov(a,c,d,e){gb.call(this,a);this.selected=c;this.deselected=d;this.mapBrowserEvent=e}y(Ov,gb); +function Pv(a){Mi.call(this,{handleEvent:Qv});var c=a?a:{};this.M=c.condition?c.condition:Vi;this.B=c.addCondition?c.addCondition:Bc;this.N=c.removeCondition?c.removeCondition:Bc;this.R=c.toggleCondition?c.toggleCondition:Xi;this.j=c.multi?c.multi:!1;this.o=c.filter?c.filter:Ac;this.c=new H({source:new Q({useSpatialIndex:!1,features:c.features,wrapX:c.wrapX}),style:c.style?c.style:Rv(),updateWhileAnimating:!0,updateWhileInteracting:!0});if(c.layers)if(ga(c.layers))a=function(a){return c.layers(a)}; +else{var d=c.layers;a=function(a){return ub(d,a)}}else a=Ac;this.s=a;this.a={};a=this.c.da().c;C(a,"add",this.um,this);C(a,"remove",this.xm,this)}y(Pv,Mi);l=Pv.prototype;l.vm=function(){return this.c.da().c};l.wm=function(a){a=w(a);return this.a[a]}; +function Qv(a){if(!this.M(a))return!0;var c=this.B(a),d=this.N(a),e=this.R(a),f=!c&&!d&&!e,g=a.map,h=this.c.da().c,k=[],m=[],n=!1;if(f)Qa(this.a),g.ed(a.pixel,function(a,c){if(this.o(a,c)){m.push(a);var d=w(a);this.a[d]=c;return!this.j}},this,this.s),0<m.length&&1==h.Zb()&&h.item(0)==m[0]||(n=!0,0!==h.Zb()&&(k=Array.prototype.concat(h.a),h.clear()),h.lf(m));else{g.ed(a.pixel,function(a,f){if(this.o(a,f)){if(!c&&!e||ub(h.a,a))(d||e)&&ub(h.a,a)&&(k.push(a),g=w(a),delete this.a[g]);else{m.push(a);var g= +w(a);this.a[g]=f}return!this.j}},this,this.s);for(f=k.length-1;0<=f;--f)h.remove(k[f]);h.lf(m);if(0<m.length||0<k.length)n=!0}n&&this.b(new Ov("select",m,k,a));return Ui(a)}l.setMap=function(a){var c=this.v,d=this.c.da().c;c&&d.forEach(c.ri,c);Pv.ia.setMap.call(this,a);this.c.setMap(a);a&&d.forEach(a.ni,a)};function Rv(){var a=ok();xb(a.Polygon,a.LineString);xb(a.GeometryCollection,a.LineString);return function(c){return a[c.W().X()]}}l.um=function(a){a=a.element;var c=this.v;c&&c.ni(a)}; +l.xm=function(a){a=a.element;var c=this.v;c&&c.ri(a)};function Sv(a){aj.call(this,{handleEvent:Tv,handleDownEvent:Ac,handleUpEvent:Uv});a=a?a:{};this.s=a.source?a.source:null;this.na=void 0!==a.vertex?a.vertex:!0;this.T=void 0!==a.edge?a.edge:!0;this.j=a.features?a.features:null;this.ta=[];this.N={};this.R={};this.Y={};this.B={};this.S=null;this.c=void 0!==a.pixelTolerance?a.pixelTolerance:10;this.xa=Vv.bind(this);this.a=new bm;this.wa={Point:this.Dm,LineString:this.ih,LinearRing:this.ih,Polygon:this.Em,MultiPoint:this.Bm,MultiLineString:this.Am,MultiPolygon:this.Cm, +GeometryCollection:this.zm}}y(Sv,aj);l=Sv.prototype;l.qb=function(a,c){var d=void 0!==c?c:!0,e=w(a),f=a.W();if(f){var g=this.wa[f.X()];g&&(this.Y[e]=f.O(Wb()),g.call(this,a,f),d&&(this.R[e]=C(f,"change",this.Gk.bind(this,a),this)))}d&&(this.N[e]=C(a,rb(a.a),this.ym,this))};l.Fj=function(a){this.qb(a)};l.Gj=function(a){this.kb(a)};l.gh=function(a){var c;a instanceof lm?c=a.feature:a instanceof ve&&(c=a.element);this.qb(c)}; +l.hh=function(a){var c;a instanceof lm?c=a.feature:a instanceof ve&&(c=a.element);this.kb(c)};l.ym=function(a){a=a.target;this.kb(a,!0);this.qb(a,!0)};l.Gk=function(a){if(this.M){var c=w(a);c in this.B||(this.B[c]=a)}else this.si(a)};l.kb=function(a,c){var d=void 0!==c?c:!0,e=w(a),f=this.Y[e];if(f){var g=this.a,h=[];gm(g,f,function(c){a===c.feature&&h.push(c)});for(f=h.length-1;0<=f;--f)g.remove(h[f]);d&&(nb(this.R[e]),delete this.R[e])}d&&(nb(this.N[e]),delete this.N[e])}; +l.setMap=function(a){var c=this.v,d=this.ta,e;this.j?e=this.j:this.s&&(e=this.s.je());c&&(d.forEach(nb),d.length=0,e.forEach(this.Gj,this));Sv.ia.setMap.call(this,a);a&&(this.j?d.push(C(this.j,"add",this.gh,this),C(this.j,"remove",this.hh,this)):this.s&&d.push(C(this.s,"addfeature",this.gh,this),C(this.s,"removefeature",this.hh,this)),e.forEach(this.Fj,this))};l.Bc=Bc;l.si=function(a){this.kb(a,!1);this.qb(a,!1)}; +l.zm=function(a,c){var d,e=c.c;for(d=0;d<e.length;++d)this.wa[e[d].X()].call(this,a,e[d])};l.ih=function(a,c){var d=c.Z(),e,f,g,h;e=0;for(f=d.length-1;e<f;++e)g=d.slice(e,e+2),h={feature:a,la:g},this.a.za(Vb(g),h)};l.Am=function(a,c){var d=c.Z(),e,f,g,h,k,m,n;h=0;for(k=d.length;h<k;++h)for(e=d[h],f=0,g=e.length-1;f<g;++f)m=e.slice(f,f+2),n={feature:a,la:m},this.a.za(Vb(m),n)};l.Bm=function(a,c){var d=c.Z(),e,f,g;f=0;for(g=d.length;f<g;++f)e=d[f],e={feature:a,la:[e,e]},this.a.za(c.O(),e)}; +l.Cm=function(a,c){var d=c.Z(),e,f,g,h,k,m,n,p,q,r;m=0;for(n=d.length;m<n;++m)for(p=d[m],h=0,k=p.length;h<k;++h)for(e=p[h],f=0,g=e.length-1;f<g;++f)q=e.slice(f,f+2),r={feature:a,la:q},this.a.za(Vb(q),r)};l.Dm=function(a,c){var d=c.Z(),d={feature:a,la:[d,d]};this.a.za(c.O(),d)};l.Em=function(a,c){var d=c.Z(),e,f,g,h,k,m,n;h=0;for(k=d.length;h<k;++h)for(e=d[h],f=0,g=e.length-1;f<g;++f)m=e.slice(f,f+2),n={feature:a,la:m},this.a.za(Vb(m),n)}; +function Tv(a){var c,d;d=a.pixel;var e=a.coordinate;c=a.map;var f=c.Ma([d[0]-this.c,d[1]+this.c]),g=c.Ma([d[0]+this.c,d[1]-this.c]),f=Vb([f,g]),h=em(this.a,f),k=!1,f=!1,m=null,g=null;if(0<h.length){this.S=e;h.sort(this.xa);h=h[0].la;if(this.na&&!this.T){if(e=c.Da(h[0]),k=c.Da(h[1]),e=Sb(d,e),d=Sb(d,k),k=Math.sqrt(Math.min(e,d)),k=k<=this.c)f=!0,m=e>d?h[1]:h[0],g=c.Da(m)}else this.T&&(m=Nb(e,h),g=c.Da(m),Math.sqrt(Sb(d,g))<=this.c&&(f=!0,this.na&&(e=c.Da(h[0]),k=c.Da(h[1]),e=Sb(g,e),d=Sb(g,k),k=Math.sqrt(Math.min(e, +d)),k=k<=this.c)))&&(m=e>d?h[1]:h[0],g=c.Da(m));f&&(g=[Math.round(g[0]),Math.round(g[1])])}c=m;d=g;f&&(a.coordinate=c.slice(0,2),a.pixel=d);return bj.call(this,a)}function Uv(){var a=Ra(this.B);a.length&&(a.forEach(this.si,this),this.B={});return!1}function Vv(a,c){return Tb(this.S,a.la)-Tb(this.S,c.la)};function Wv(a,c,d){gb.call(this,a);this.features=c;this.coordinate=d}y(Wv,gb);function Xv(a){aj.call(this,{handleDownEvent:Yv,handleDragEvent:Zv,handleMoveEvent:$v,handleUpEvent:aw});this.s=void 0;this.a=null;this.c=void 0!==a.features?a.features:null;var c;if(a.layers)if(ga(a.layers))c=function(c){return a.layers(c)};else{var d=a.layers;c=function(a){return ub(d,a)}}else c=Ac;this.B=c;this.j=null}y(Xv,aj); +function Yv(a){this.j=bw(this,a.pixel,a.map);return!this.a&&this.j?(this.a=a.coordinate,$v.call(this,a),this.b(new Wv("translatestart",this.c,a.coordinate)),!0):!1}function aw(a){return this.a?(this.a=null,$v.call(this,a),this.b(new Wv("translateend",this.c,a.coordinate)),!0):!1} +function Zv(a){if(this.a){a=a.coordinate;var c=a[0]-this.a[0],d=a[1]-this.a[1];if(this.c)this.c.forEach(function(a){var e=a.W();e.Nc(c,d);a.Ta(e)});else if(this.j){var e=this.j.W();e.Nc(c,d);this.j.Ta(e)}this.a=a;this.b(new Wv("translating",this.c,a))}} +function $v(a){var c=a.map.tc();if(a=a.map.ed(a.pixel,function(a){return a})){var d=!1;this.c&&ub(this.c.a,a)&&(d=!0);this.s=c.style.cursor;c.style.cursor=this.a?"-webkit-grabbing":d?"-webkit-grab":"pointer";c.style.cursor=this.a?d?"grab":"pointer":"grabbing"}else c.style.cursor=void 0!==this.s?this.s:"",this.s=void 0}function bw(a,c,d){var e=null;c=d.ed(c,function(a){return a},a,a.B);a.c&&ub(a.c.a,c)&&(e=c);return e};function W(a){a=a?a:{};var c=Pa({},a);delete c.gradient;delete c.radius;delete c.blur;delete c.shadow;delete c.weight;H.call(this,c);this.f=null;this.ea=void 0!==a.shadow?a.shadow:250;this.Y=void 0;this.c=null;C(this,rb("gradient"),this.Hk,this);this.di(a.gradient?a.gradient:cw);this.Zh(void 0!==a.blur?a.blur:15);this.lh(void 0!==a.radius?a.radius:8);C(this,rb("blur"),this.gf,this);C(this,rb("radius"),this.gf,this);this.gf();var d=a.weight?a.weight:"weight",e;"string"===typeof d?e=function(a){return a.get(d)}: +e=d;this.l(function(a){a=e(a);a=void 0!==a?Da(a,0,1):1;var c=255*a|0,d=this.c[c];d||(d=[new jk({image:new ui({opacity:a,src:this.Y})})],this.c[c]=d);return d}.bind(this));this.set("renderOrder",null);C(this,"render",this.$k,this)}y(W,H);var cw=["#00f","#0ff","#0f0","#ff0","#f00"];l=W.prototype;l.ug=function(){return this.get("blur")};l.Bg=function(){return this.get("gradient")};l.kh=function(){return this.get("radius")}; +l.Hk=function(){for(var a=this.Bg(),c=Mg(1,256),d=c.createLinearGradient(0,0,1,256),e=1/(a.length-1),f=0,g=a.length;f<g;++f)d.addColorStop(f*e,a[f]);c.fillStyle=d;c.fillRect(0,0,1,256);this.f=c.getImageData(0,0,1,256).data};l.gf=function(){var a=this.kh(),c=this.ug(),d=a+c+1,e=2*d,e=Mg(e,e);e.shadowOffsetX=e.shadowOffsetY=this.ea;e.shadowBlur=c;e.shadowColor="#000";e.beginPath();c=d-this.ea;e.arc(c,c,a,0,2*Math.PI,!0);e.fill();this.Y=e.canvas.toDataURL();this.c=Array(256);this.u()}; +l.$k=function(a){a=a.context;var c=a.canvas,c=a.getImageData(0,0,c.width,c.height),d=c.data,e,f,g;e=0;for(f=d.length;e<f;e+=4)if(g=4*d[e+3])d[e]=this.f[g],d[e+1]=this.f[g+1],d[e+2]=this.f[g+2];a.putImageData(c,0,0)};l.Zh=function(a){this.set("blur",a)};l.di=function(a){this.set("gradient",a)};l.lh=function(a){this.set("radius",a)};function dw(a,c,d,e){function f(){delete qa[h];g.parentNode.removeChild(g)}var g=qa.document.createElement("script"),h="olc_"+w(c);g.async=!0;g.src=a+(-1==a.indexOf("?")?"?":"&")+(e||"callback")+"="+h;var k=qa.setTimeout(function(){f();d&&d()},1E4);qa[h]=function(a){qa.clearTimeout(k);f();c(a)};qa.document.getElementsByTagName("head")[0].appendChild(g)};function ew(a,c,d,e,f,g,h,k,m,n,p){Qf.call(this,f,0);this.R=void 0!==p?p:!1;this.N=h;this.M=k;this.l=null;this.c={};this.j=c;this.v=e;this.U=g?g:f;this.g=[];this.Rc=null;this.s=0;g=e.Ba(this.U);k=this.v.O();f=this.j.O();g=k?vc(g,k):g;if(0===pc(g))this.state=4;else if((k=a.O())&&(f?f=vc(f,k):f=k),e=e.$(this.U[0]),e=jl(a,d,tc(g),e),!isFinite(e)||0>=e)this.state=4;else if(this.B=new ml(a,d,g,f,e*(void 0!==n?n:.5)),0===this.B.f.length)this.state=4;else if(this.s=gg(c,e),d=pl(this.B),f&&(a.a?(d[1]=Da(d[1], +f[1],f[3]),d[3]=Da(d[3],f[1],f[3])):d=vc(d,f)),pc(d))if(a=bg(c,d,this.s),100>(a.a-a.b+1)*(a.f-a.g+1)){for(c=a.b;c<=a.a;c++)for(d=a.g;d<=a.f;d++)(n=m(this.s,c,d,h))&&this.g.push(n);0===this.g.length&&(this.state=4)}else this.state=3;else this.state=4}y(ew,Qf);ew.prototype.fa=function(){1==this.state&&(this.Rc.forEach(Xa),this.Rc=null);ew.ia.fa.call(this)}; +ew.prototype.ab=function(a){if(void 0!==a){var c=w(a);if(c in this.c)return this.c[c];a=Sa(this.c)?this.l:this.l.cloneNode(!1);return this.c[c]=a}return this.l}; +ew.prototype.ud=function(){var a=[];this.g.forEach(function(c){c&&2==c.V()&&a.push({extent:this.j.Ba(c.ja),image:c.ab()})},this);this.g.length=0;if(0===a.length)this.state=3;else{var c=this.U[0],d=this.v.Ha(c),e=fa(d)?d:d[0],d=fa(d)?d:d[1],c=this.v.$(c),f=this.j.$(this.s),g=this.v.Ba(this.U);this.l=ll(e,d,this.N,f,this.j.O(),c,g,this.B,a,this.M,this.R);this.state=2}Rf(this)}; +ew.prototype.load=function(){if(0==this.state){this.state=1;Rf(this);var a=0;this.Rc=[];this.g.forEach(function(c){var d=c.V();if(0==d||1==d){a++;var e;e=C(c,"change",function(){var d=c.V();if(2==d||3==d||4==d)Xa(e),a--,0===a&&(this.Rc.forEach(Xa),this.Rc=null,this.ud())},this);this.Rc.push(e)}},this);this.g.forEach(function(a){0==a.V()&&a.load()});0===a&&qa.setTimeout(this.ud.bind(this),0)}};function X(a){zm.call(this,{attributions:a.attributions,cacheSize:a.cacheSize,extent:a.extent,logo:a.logo,opaque:a.opaque,projection:a.projection,state:a.state,tileGrid:a.tileGrid,tileLoadFunction:a.tileLoadFunction?a.tileLoadFunction:fw,tilePixelRatio:a.tilePixelRatio,tileUrlFunction:a.tileUrlFunction,url:a.url,urls:a.urls,wrapX:a.wrapX});this.crossOrigin=void 0!==a.crossOrigin?a.crossOrigin:null;this.tileClass=void 0!==a.tileClass?a.tileClass:Zu;this.i={};this.s={};this.na=a.reprojectionErrorThreshold; +this.M=!1}y(X,zm);l=X.prototype;l.vh=function(){if(Pf(this.a))return!0;for(var a in this.i)if(Pf(this.i[a]))return!0;return!1};l.Gc=function(a,c){var d=this.jd(a);this.a.Gc(this.a==d?c:{});for(var e in this.i){var f=this.i[e];f.Gc(f==d?c:{})}};l.Od=function(a){return this.f&&a&&!Zc(this.f,a)?0:this.cf()};l.cf=function(){return 0};l.ef=function(a){return this.f&&a&&!Zc(this.f,a)?!1:X.ia.ef.call(this,a)}; +l.fb=function(a){var c=this.f;return!this.tileGrid||c&&!Zc(c,a)?(c=w(a).toString(),c in this.s||(this.s[c]=hg(a)),this.s[c]):this.tileGrid};l.jd=function(a){var c=this.f;if(!c||Zc(c,a))return this.a;a=w(a).toString();a in this.i||(this.i[a]=new Of);return this.i[a]};function gw(a,c,d,e,f,g,h){c=[c,d,e];f=(d=og(a,c,g))?a.tileUrlFunction(d,f,g):void 0;f=new a.tileClass(c,void 0!==f?0:4,void 0!==f?f:"",a.crossOrigin,a.tileLoadFunction);f.key=h;C(f,"change",a.wh,a);return f} +l.Wb=function(a,c,d,e,f){if(this.f&&f&&!Zc(this.f,f)){var g=this.jd(f);c=[a,c,d];a=this.Ab.apply(this,c);if(Lf(g,a))return g.get(a);var h=this.f;d=this.fb(h);var k=this.fb(f),m=og(this,c,f);e=new ew(h,d,f,k,c,m,this.Xb(e),this.cf(),function(a,c,d,e){return hw(this,a,c,d,e,h)}.bind(this),this.na,this.M);g.set(a,e);return e}return hw(this,a,c,d,e,f)}; +function hw(a,c,d,e,f,g){var h=null,k=a.Ab(c,d,e),m=a.Yb;if(Lf(a.a,k)){if(h=a.a.get(k),h.key!=m){var n=h;h.a&&h.a.key==m?(h=h.a,2==n.V()&&(h.a=n)):(h=gw(a,c,d,e,f,g,m),2==n.V()?h.a=n:n.a&&2==n.a.V()&&(h.a=n.a,n.a=null));h.a&&(h.a.a=null);a.a.replace(k,h)}}else h=gw(a,c,d,e,f,g,m),a.a.set(k,h);return h}l.lb=function(a){if(this.M!=a){this.M=a;for(var c in this.i)this.i[c].clear();this.u()}};l.mb=function(a,c){var d=Ic(a);d&&(d=w(d).toString(),d in this.s||(this.s[d]=c))}; +function fw(a,c){a.ab().src=c};function iw(a){X.call(this,{cacheSize:a.cacheSize,crossOrigin:"anonymous",opaque:!0,projection:Ic("EPSG:3857"),reprojectionErrorThreshold:a.reprojectionErrorThreshold,state:"loading",tileLoadFunction:a.tileLoadFunction,wrapX:void 0!==a.wrapX?a.wrapX:!0});this.j=void 0!==a.culture?a.culture:"en-us";this.c=void 0!==a.maxZoom?a.maxZoom:-1;dw("https://dev.virtualearth.net/REST/v1/Imagery/Metadata/"+a.imagerySet+"?uriScheme=https&include=ImageryProviders&key="+a.key,this.v.bind(this),void 0,"jsonp")} +y(iw,X);var jw=new ue({html:'<a class="ol-attribution-bing-tos" href="http://www.microsoft.com/maps/product/terms.html">Terms of Use</a>'}); +iw.prototype.v=function(a){if(200!=a.statusCode||"OK"!=a.statusDescription||"ValidCredentials"!=a.authenticationResultCode||1!=a.resourceSets.length||1!=a.resourceSets[0].resources.length)Xf(this,"error");else{var c=a.brandLogoUri;-1==c.indexOf("https")&&(c=c.replace("http","https"));var d=a.resourceSets[0].resources[0],e=-1==this.c?d.zoomMax:this.c;a=ig(this.f);var f=kg({extent:a,minZoom:d.zoomMin,maxZoom:e,tileSize:d.imageWidth==d.imageHeight?d.imageWidth:[d.imageWidth,d.imageHeight]});this.tileGrid= +f;var g=this.j;this.tileUrlFunction=wm(d.imageUrlSubdomains.map(function(a){var c=[0,0,0],e=d.imageUrl.replace("{subdomain}",a).replace("{culture}",g);return function(a){if(a)return Mf(a[0],a[1],-a[2]-1,c),e.replace("{quadkey}",Nf(c))}}));if(d.imageryProviders){var h=Lc(Ic("EPSG:4326"),this.f);a=d.imageryProviders.map(function(a){var c=a.attribution,d={};a.coverageAreas.forEach(function(a){var c=a.zoomMin,g=Math.min(a.zoomMax,e);a=a.bbox;a=zc([a[1],a[0],a[3],a[2]],h);var k,m;for(k=c;k<=g;++k)m=k.toString(), +c=bg(f,a,k),m in d?d[m].push(c):d[m]=[c]});return new ue({html:c,tileRanges:d})});a.push(jw);this.ka(a)}this.R=c;Xf(this,"ready")}};function kw(a){a=a||{};var c=void 0!==a.projection?a.projection:"EPSG:3857",d=void 0!==a.tileGrid?a.tileGrid:kg({extent:ig(c),maxZoom:a.maxZoom,minZoom:a.minZoom,tileSize:a.tileSize});X.call(this,{attributions:a.attributions,cacheSize:a.cacheSize,crossOrigin:a.crossOrigin,logo:a.logo,opaque:a.opaque,projection:c,reprojectionErrorThreshold:a.reprojectionErrorThreshold,tileGrid:d,tileLoadFunction:a.tileLoadFunction,tilePixelRatio:a.tilePixelRatio,tileUrlFunction:a.tileUrlFunction,url:a.url,urls:a.urls, +wrapX:void 0!==a.wrapX?a.wrapX:!0})}y(kw,X);function lw(a){this.v=a.account;this.B=a.map||"";this.c=a.config||{};this.j={};kw.call(this,{attributions:a.attributions,cacheSize:a.cacheSize,crossOrigin:a.crossOrigin,logo:a.logo,maxZoom:void 0!==a.maxZoom?a.maxZoom:18,minZoom:a.minZoom,projection:a.projection,state:"loading",wrapX:a.wrapX});mw(this)}y(lw,kw);l=lw.prototype;l.Pj=function(){return this.c};l.op=function(a){Pa(this.c,a);mw(this)};l.Uo=function(a){this.c=a||{};mw(this)}; +function mw(a){var c=JSON.stringify(a.c);if(a.j[c])nw(a,a.j[c]);else{var d="https://"+a.v+".cartodb.com/api/v1/map";a.B&&(d+="/named/"+a.B);var e=new XMLHttpRequest;e.addEventListener("load",a.Jk.bind(a,c));e.addEventListener("error",a.Ik.bind(a));e.open("POST",d);e.setRequestHeader("Content-type","application/json");e.send(JSON.stringify(a.c))}} +l.Jk=function(a,c){var d=c.target;if(200<=d.status&&300>d.status){var e;try{e=JSON.parse(d.responseText)}catch(f){Xf(this,"error");return}nw(this,e);this.j[a]=e;Xf(this,"ready")}else Xf(this,"error")};l.Ik=function(){Xf(this,"error")};function nw(a,c){a.Na("https://"+c.cdn_url.https+"/"+a.v+"/api/v1/map/"+c.layergroupid+"/{z}/{x}/{y}.png")};function Y(a){Q.call(this,{attributions:a.attributions,extent:a.extent,logo:a.logo,projection:a.projection,wrapX:a.wrapX});this.M=void 0;this.ta=void 0!==a.distance?a.distance:20;this.B=[];this.ea=a.geometryFunction||function(a){return a.W()};this.v=a.source;this.v.D("change",Y.prototype.Ra,this)}y(Y,Q);Y.prototype.xa=function(){return this.v};Y.prototype.Kc=function(a,c,d){this.v.Kc(a,c,d);c!==this.M&&(this.clear(),this.M=c,ow(this),this.Ec(this.B))}; +Y.prototype.Ra=function(){this.clear();ow(this);this.Ec(this.B);this.u()};function ow(a){if(void 0!==a.M){a.B.length=0;for(var c=Wb(),d=a.ta*a.M,e=a.v.je(),f={},g=0,h=e.length;g<h;g++){var k=e[g];w(k).toString()in f||!(k=a.ea(k))||(k=k.Z(),fc(k,c),Yb(c,d,c),k=a.v.af(c),k=k.filter(function(a){a=w(a).toString();return a in f?!1:f[a]=!0}),a.B.push(pw(a,k)))}}} +function pw(a,c){for(var d=[0,0],e=c.length-1;0<=e;--e){var f=a.ea(c[e]);f?Mb(d,f.Z()):c.splice(e,1)}e=1/c.length;d[0]*=e;d[1]*=e;d=new zl(new D(d));d.set("features",c);return d};function qw(a){a=a||{};rl.call(this,{attributions:a.attributions,logo:a.logo,projection:a.projection,resolutions:a.resolutions});this.Y=void 0!==a.crossOrigin?a.crossOrigin:null;this.i=a.url;this.j=void 0!==a.imageLoadFunction?a.imageLoadFunction:xl;this.v=a.params||{};this.c=null;this.s=[0,0];this.T=0;this.S=void 0!==a.ratio?a.ratio:1.5}y(qw,rl);l=qw.prototype;l.Mm=function(){return this.v}; +l.Hc=function(a,c,d,e){if(void 0===this.i)return null;c=sl(this,c);var f=this.c;if(f&&this.T==this.g&&f.$()==c&&f.f==d&&cc(f.O(),a))return f;f={F:"image",FORMAT:"PNG32",TRANSPARENT:!0};Pa(f,this.v);a=a.slice();var g=(a[0]+a[2])/2,h=(a[1]+a[3])/2;if(1!=this.S){var k=this.S*rc(a)/2,m=this.S*sc(a)/2;a[0]=g-k;a[1]=h-m;a[2]=g+k;a[3]=h+m}var k=c/d,m=Math.ceil(rc(a)/k),n=Math.ceil(sc(a)/k);a[0]=g-k*m/2;a[2]=g+k*m/2;a[1]=h-k*n/2;a[3]=h+k*n/2;this.s[0]=m;this.s[1]=n;g=a;h=this.s;e=e.eb.split(":").pop();f.SIZE= +h[0]+","+h[1];f.BBOX=g.join(",");f.BBOXSR=e;f.IMAGESR=e;f.DPI=90*d;e=this.i.replace(/MapServer\/?$/,"MapServer/export").replace(/ImageServer\/?$/,"ImageServer/exportImage");f=dq(fq([e],f));this.c=new Yu(a,c,d,this.l,f,this.Y,this.j);this.T=this.g;C(this.c,"change",this.o,this);return this.c};l.Lm=function(){return this.j};l.Nm=function(){return this.i};l.Om=function(a){this.c=null;this.j=a;this.u()};l.Pm=function(a){a!=this.i&&(this.i=a,this.c=null,this.u())}; +l.Qm=function(a){Pa(this.v,a);this.c=null;this.u()};function rw(a){rl.call(this,{projection:a.projection,resolutions:a.resolutions});this.Y=void 0!==a.crossOrigin?a.crossOrigin:null;this.s=void 0!==a.displayDpi?a.displayDpi:96;this.j=a.params||{};this.T=a.url;this.c=void 0!==a.imageLoadFunction?a.imageLoadFunction:xl;this.ea=void 0!==a.hidpi?a.hidpi:!0;this.ta=void 0!==a.metersPerUnit?a.metersPerUnit:1;this.v=void 0!==a.ratio?a.ratio:1;this.xa=void 0!==a.useOverlay?a.useOverlay:!1;this.i=null;this.S=0}y(rw,rl);l=rw.prototype;l.Sm=function(){return this.j}; +l.Hc=function(a,c,d){c=sl(this,c);d=this.ea?d:1;var e=this.i;if(e&&this.S==this.g&&e.$()==c&&e.f==d&&cc(e.O(),a))return e;1!=this.v&&(a=a.slice(),yc(a,this.v));var f=[rc(a)/c*d,sc(a)/c*d];if(void 0!==this.T){var e=this.T,g=tc(a),h=this.ta,k=rc(a),m=sc(a),n=f[0],p=f[1],q=.0254/this.s,f={OPERATION:this.xa?"GETDYNAMICMAPOVERLAYIMAGE":"GETMAPIMAGE",VERSION:"2.0.0",LOCALE:"en",CLIENTAGENT:"ol.source.ImageMapGuide source",CLIP:"1",SETDISPLAYDPI:this.s,SETDISPLAYWIDTH:Math.round(f[0]),SETDISPLAYHEIGHT:Math.round(f[1]), +SETVIEWSCALE:p*k>n*m?k*h/(n*q):m*h/(p*q),SETVIEWCENTERX:g[0],SETVIEWCENTERY:g[1]};Pa(f,this.j);e=dq(fq([e],f));e=new Yu(a,c,d,this.l,e,this.Y,this.c);C(e,"change",this.o,this)}else e=null;this.i=e;this.S=this.g;return e};l.Rm=function(){return this.c};l.Um=function(a){Pa(this.j,a);this.u()};l.Tm=function(a){this.i=null;this.c=a;this.u()};function sw(a){var c=a.imageExtent,d=void 0!==a.crossOrigin?a.crossOrigin:null,e=void 0!==a.imageLoadFunction?a.imageLoadFunction:xl;rl.call(this,{attributions:a.attributions,logo:a.logo,projection:Ic(a.projection)});this.c=new Yu(c,void 0,1,this.l,a.url,d,e);this.i=a.imageSize?a.imageSize:null;C(this.c,"change",this.o,this)}y(sw,rl);sw.prototype.Hc=function(a){return wc(a,this.c.O())?this.c:null}; +sw.prototype.o=function(a){if(2==this.c.V()){var c=this.c.O(),d=this.c.a(),e,f;this.i?(e=this.i[0],f=this.i[1]):(e=d.width,f=d.height);c=Math.ceil(rc(c)/(sc(c)/f));if(c!=e){var c=Mg(c,f),g=c.canvas;c.drawImage(d,0,0,e,f,0,0,g.width,g.height);this.c.g=g}}sw.ia.o.call(this,a)};function tw(a){a=a||{};rl.call(this,{attributions:a.attributions,logo:a.logo,projection:a.projection,resolutions:a.resolutions});this.ta=void 0!==a.crossOrigin?a.crossOrigin:null;this.j=a.url;this.S=void 0!==a.imageLoadFunction?a.imageLoadFunction:xl;this.i=a.params||{};this.v=!0;uw(this);this.ea=a.serverType;this.xa=void 0!==a.hidpi?a.hidpi:!0;this.c=null;this.T=[0,0];this.Y=0;this.s=void 0!==a.ratio?a.ratio:1.5}y(tw,rl);var vw=[101,101];l=tw.prototype; +l.$m=function(a,c,d,e){if(void 0!==this.j){var f=uc(a,c,0,vw),g={SERVICE:"WMS",VERSION:"1.3.0",REQUEST:"GetFeatureInfo",FORMAT:"image/png",TRANSPARENT:!0,QUERY_LAYERS:this.i.LAYERS};Pa(g,this.i,e);e=Math.floor((f[3]-a[1])/c);g[this.v?"I":"X"]=Math.floor((a[0]-f[0])/c);g[this.v?"J":"Y"]=e;return ww(this,f,vw,1,Ic(d),g)}};l.bn=function(){return this.i}; +l.Hc=function(a,c,d,e){if(void 0===this.j)return null;c=sl(this,c);1==d||this.xa&&void 0!==this.ea||(d=1);a=a.slice();var f=(a[0]+a[2])/2,g=(a[1]+a[3])/2,h=c/d,k=rc(a)/h,h=sc(a)/h,m=this.c;if(m&&this.Y==this.g&&m.$()==c&&m.f==d&&cc(m.O(),a))return m;if(1!=this.s){var m=this.s*rc(a)/2,n=this.s*sc(a)/2;a[0]=f-m;a[1]=g-n;a[2]=f+m;a[3]=g+n}f={SERVICE:"WMS",VERSION:"1.3.0",REQUEST:"GetMap",FORMAT:"image/png",TRANSPARENT:!0};Pa(f,this.i);this.T[0]=Math.ceil(k*this.s);this.T[1]=Math.ceil(h*this.s);e=ww(this, +a,this.T,d,e,f);this.c=new Yu(a,c,d,this.l,e,this.ta,this.S);this.Y=this.g;C(this.c,"change",this.o,this);return this.c};l.an=function(){return this.S}; +function ww(a,c,d,e,f,g){g[a.v?"CRS":"SRS"]=f.eb;"STYLES"in a.i||(g.STYLES="");if(1!=e)switch(a.ea){case "geoserver":e=90*e+.5|0;g.FORMAT_OPTIONS="FORMAT_OPTIONS"in g?g.FORMAT_OPTIONS+(";dpi:"+e):"dpi:"+e;break;case "mapserver":g.MAP_RESOLUTION=90*e;break;case "carmentaserver":case "qgis":g.DPI=90*e}g.WIDTH=d[0];g.HEIGHT=d[1];d=f.b;var h;a.v&&"ne"==d.substr(0,2)?h=[c[1],c[0],c[3],c[2]]:h=c;g.BBOX=h.join(",");return dq(fq([a.j],g))}l.cn=function(){return this.j}; +l.dn=function(a){this.c=null;this.S=a;this.u()};l.en=function(a){a!=this.j&&(this.j=a,this.c=null,this.u())};l.fn=function(a){Pa(this.i,a);uw(this);this.c=null;this.u()};function uw(a){a.v=0<=Lb(a.i.VERSION||"1.3.0")};function xw(a){a=a||{};var c;void 0!==a.attributions?c=a.attributions:c=[yw];kw.call(this,{attributions:c,cacheSize:a.cacheSize,crossOrigin:void 0!==a.crossOrigin?a.crossOrigin:"anonymous",opaque:void 0!==a.opaque?a.opaque:!0,maxZoom:void 0!==a.maxZoom?a.maxZoom:19,reprojectionErrorThreshold:a.reprojectionErrorThreshold,tileLoadFunction:a.tileLoadFunction,url:void 0!==a.url?a.url:"https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png",wrapX:a.wrapX})}y(xw,kw);var yw=new ue({html:'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors.'});function zw(a){a=a||{};var c=Aw[a.layer];this.c=a.layer;kw.call(this,{attributions:c.attributions,cacheSize:a.cacheSize,crossOrigin:"anonymous",logo:"https://developer.mapquest.com/content/osm/mq_logo.png",maxZoom:c.maxZoom,reprojectionErrorThreshold:a.reprojectionErrorThreshold,opaque:c.opaque,tileLoadFunction:a.tileLoadFunction,url:void 0!==a.url?a.url:"https://otile{1-4}-s.mqcdn.com/tiles/1.0.0/"+this.c+"/{z}/{x}/{y}.jpg"})}y(zw,kw); +var Bw=new ue({html:'Tiles Courtesy of <a href="http://www.mapquest.com/">MapQuest</a>'}),Aw={osm:{maxZoom:19,opaque:!0,attributions:[Bw,yw]},sat:{maxZoom:18,opaque:!0,attributions:[Bw,new ue({html:"Portions Courtesy NASA/JPL-Caltech and U.S. Depart. of Agriculture, Farm Service Agency"})]},hyb:{maxZoom:18,opaque:!1,attributions:[Bw,yw]}};zw.prototype.j=function(){return this.c};(function(){var a={},c={ha:a};(function(d){if("object"===typeof a&&"undefined"!==typeof c)c.ha=d();else{var e;"undefined"!==typeof window?e=window:"undefined"!==typeof global?e=global:"undefined"!==typeof self?e=self:e=this;e.Np=d()}})(function(){return function e(a,c,h){function k(n,q){if(!c[n]){if(!a[n]){var r="function"==typeof require&&require;if(!q&&r)return r(n,!0);if(m)return m(n,!0);r=Error("Cannot find module '"+n+"'");throw r.code="MODULE_NOT_FOUND",r;}r=c[n]={ha:{}};a[n][0].call(r.ha,function(c){var e= +a[n][1][c];return k(e?e:c)},r,r.ha,e,a,c,h)}return c[n].ha}for(var m="function"==typeof require&&require,n=0;n<h.length;n++)k(h[n]);return k}({1:[function(a,c,g){a=a("./processor");g.Vi=a},{"./processor":2}],2:[function(a,c){function g(a){var c=!0;try{new ImageData(10,10)}catch(e){c=!1}return function(e){var f=e.buffers,g=e.meta,h=e.width,k=e.height,m=f.length,n=f[0].byteLength;if(e.imageOps){n=Array(m);for(e=0;e<m;++e){var A=n,G=e,O;O=new Uint8ClampedArray(f[e]);var L=h,R=k;O=c?new ImageData(O,L, +R):{data:O,width:L,height:R};A[G]=O}h=a(n,g).data}else{h=new Uint8ClampedArray(n);k=Array(m);A=Array(m);for(e=0;e<m;++e)k[e]=new Uint8ClampedArray(f[e]),A[e]=[0,0,0,0];for(f=0;f<n;f+=4){for(e=0;e<m;++e)G=k[e],A[e][0]=G[f],A[e][1]=G[f+1],A[e][2]=G[f+2],A[e][3]=G[f+3];e=a(A,g);h[f]=e[0];h[f+1]=e[1];h[f+2]=e[2];h[f+3]=e[3]}}return h.buffer}}function h(a,c){var e=Object.keys(a.lib||{}).map(function(c){return"var "+c+" = "+a.lib[c].toString()+";"}).concat(["var __minion__ = ("+g.toString()+")(",a.operation.toString(), +");",'self.addEventListener("message", function(event) {'," var buffer = __minion__(event.data);"," self.postMessage({buffer: buffer, meta: event.data.meta}, [buffer]);","});"]),e=URL.createObjectURL(new Blob(e,{type:"text/javascript"})),e=new Worker(e);e.addEventListener("message",c);return e}function k(a,c){var e=g(a.operation);return{postMessage:function(a){setTimeout(function(){c({data:{buffer:e(a),meta:a.meta}})},0)}}}function m(a){this.Ne=!!a.hl;var c;0===a.threads?c=0:this.Ne?c=1:c=a.threads|| +1;var e=[];if(c)for(var f=0;f<c;++f)e[f]=h(a,this.eg.bind(this,f));else e[0]=k(a,this.eg.bind(this,0));this.Gd=e;this.Vc=[];this.jj=a.oo||Infinity;this.Ed=0;this.Dc={};this.Oe=null}var n=a("./util").Bl;m.prototype.mo=function(a,c,e){this.gj({vc:a,Sg:c,mg:e});this.bg()};m.prototype.gj=function(a){for(this.Vc.push(a);this.Vc.length>this.jj;)this.Vc.shift().mg(null,null)};m.prototype.bg=function(){if(0===this.Ed&&0<this.Vc.length){var a=this.Oe=this.Vc.shift(),c=a.vc[0].width,e=a.vc[0].height,f=a.vc.map(function(a){return a.data.buffer}), +g=this.Gd.length;this.Ed=g;if(1===g)this.Gd[0].postMessage({buffers:f,meta:a.Sg,imageOps:this.Ne,width:c,height:e},f);else for(var h=4*Math.ceil(a.vc[0].data.length/4/g),k=0;k<g;++k){for(var m=k*h,n=[],A=0,G=f.length;A<G;++A)n.push(f[k].slice(m,m+h));this.Gd[k].postMessage({buffers:n,meta:a.Sg,imageOps:this.Ne,width:c,height:e},n)}}};m.prototype.eg=function(a,c){this.Jp||(this.Dc[a]=c.data,--this.Ed,0===this.Ed&&this.kj())};m.prototype.kj=function(){var a=this.Oe,c=this.Gd.length,e,f;if(1===c)e=new Uint8ClampedArray(this.Dc[0].buffer), +f=this.Dc[0].meta;else{var g=a.vc[0].data.length;e=new Uint8ClampedArray(g);f=Array(g);for(var g=4*Math.ceil(g/4/c),h=0;h<c;++h){var k=h*g;e.set(new Uint8ClampedArray(this.Dc[h].buffer),k);f[h]=this.Dc[h].meta}}this.Oe=null;this.Dc={};a.mg(null,n(e,a.vc[0].width,a.vc[0].height),f);this.bg()};c.ha=m},{"./util":3}],3:[function(a,c,g){var h=!0;try{new ImageData(10,10)}catch(m){h=!1}var k=document.createElement("canvas").getContext("2d");g.Bl=function(a,c,e){if(h)return new ImageData(a,c,e);c=k.createImageData(c, +e);c.data.set(a);return c}},{}]},{},[1])(1)});am=c.ha})();function Cw(a){this.S=null;this.xa=void 0!==a.operationType?a.operationType:"pixel";this.Ra=void 0!==a.threads?a.threads:1;this.c=Dw(a.sources);for(var c=0,d=this.c.length;c<d;++c)C(this.c[c],"change",this.u,this);this.i=Mg();this.ea=new Ii(function(){return 1},this.u.bind(this));for(var c=Ew(this.c),d={},e=0,f=c.length;e<f;++e)d[w(c[e].layer)]=c[e];this.j=this.s=null;this.Y={animate:!1,attributions:{},coordinateToPixelMatrix:hd(),extent:null,focus:null,index:0,layerStates:d,layerStatesArray:c,logos:{}, +pixelRatio:1,pixelToCoordinateMatrix:hd(),postRenderFunctions:[],size:[0,0],skippedFeatureUids:{},tileQueue:this.ea,time:Date.now(),usedTiles:{},viewState:{rotation:0},viewHints:[],wantedTiles:{}};rl.call(this,{});void 0!==a.operation&&this.v(a.operation,a.lib)}y(Cw,rl);Cw.prototype.v=function(a,c){this.S=new am.Vi({operation:a,hl:"image"===this.xa,oo:1,lib:c,threads:this.Ra});this.u()};function Fw(a,c,d){var e=a.s;return!e||a.g!==e.Ro||d!==e.resolution||!ic(c,e.extent)} +Cw.prototype.B=function(a,c,d,e){d=!0;for(var f,g=0,h=this.c.length;g<h;++g)if(f=this.c[g].a.da(),"ready"!==f.V()){d=!1;break}if(!d)return null;a=a.slice();if(!Fw(this,a,c))return this.j;d=this.i.canvas;f=Math.round(rc(a)/c);g=Math.round(sc(a)/c);if(f!==d.width||g!==d.height)d.width=f,d.height=g;f=Pa({},this.Y);f.viewState=Pa({},f.viewState);var g=tc(a),h=Math.round(rc(a)/c),k=Math.round(sc(a)/c);f.extent=a;f.focus=tc(a);f.size[0]=h;f.size[1]=k;h=f.viewState;h.center=g;h.projection=e;h.resolution= +c;this.j=e=new dl(a,c,1,this.l,d,this.T.bind(this,f));this.s={extent:a,resolution:c,Ro:this.g};return e}; +Cw.prototype.T=function(a,c){for(var d=this.c.length,e=Array(d),f=0;f<d;++f){var g;g=this.c[f];var h=a,k=a.layerStatesArray[f];if(g.l(h,k)){var m=h.size[0],n=h.size[1];if(Gw){var p=Gw.canvas;p.width!==m||p.height!==n?Gw=Mg(m,n):Gw.clearRect(0,0,m,n)}else Gw=Mg(m,n);g.i(h,k,Gw);g=Gw.getImageData(0,0,m,n)}else g=null;if(g)e[f]=g;else return}d={};this.b(new Hw(Iw,a,d));this.S.mo(e,d,this.ta.bind(this,a,c));Ji(a.tileQueue,16,16)}; +Cw.prototype.ta=function(a,c,d,e,f){d?c(d):e&&(this.b(new Hw(Jw,a,f)),Fw(this,a.extent,a.viewState.resolution/a.pixelRatio)||this.i.putImageData(e,0,0),c(null))};var Gw=null;function Ew(a){return a.map(function(a){return ai(a.a)})}function Dw(a){for(var c=a.length,d=Array(c),e=0;e<c;++e){var f=e,g=a[e],h=null;g instanceof lg?(g=new Vj({source:g}),h=new rm(g)):g instanceof rl&&(g=new Uj({source:g}),h=new qm(g));d[f]=h}return d} +function Hw(a,c,d){gb.call(this,a);this.extent=c.extent;this.resolution=c.viewState.resolution/c.pixelRatio;this.data=d}y(Hw,gb);var Iw="beforeoperations",Jw="afteroperations";var Kw={terrain:{sb:"jpg",opaque:!0},"terrain-background":{sb:"jpg",opaque:!0},"terrain-labels":{sb:"png",opaque:!1},"terrain-lines":{sb:"png",opaque:!1},"toner-background":{sb:"png",opaque:!0},toner:{sb:"png",opaque:!0},"toner-hybrid":{sb:"png",opaque:!1},"toner-labels":{sb:"png",opaque:!1},"toner-lines":{sb:"png",opaque:!1},"toner-lite":{sb:"png",opaque:!0},watercolor:{sb:"jpg",opaque:!0}},Lw={terrain:{minZoom:4,maxZoom:18},toner:{minZoom:0,maxZoom:20},watercolor:{minZoom:1,maxZoom:16}}; +function Mw(a){var c=a.layer.indexOf("-"),c=-1==c?a.layer:a.layer.slice(0,c),c=Lw[c],d=Kw[a.layer];kw.call(this,{attributions:Nw,cacheSize:a.cacheSize,crossOrigin:"anonymous",maxZoom:c.maxZoom,minZoom:c.minZoom,opaque:d.opaque,reprojectionErrorThreshold:a.reprojectionErrorThreshold,tileLoadFunction:a.tileLoadFunction,url:void 0!==a.url?a.url:"https://stamen-tiles-{a-d}.a.ssl.fastly.net/"+a.layer+"/{z}/{x}/{y}."+d.sb})}y(Mw,kw); +var Nw=[new ue({html:'Map tiles by <a href="http://stamen.com/">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0/">CC BY 3.0</a>.'}),yw];function Ow(a){a=a||{};X.call(this,{attributions:a.attributions,cacheSize:a.cacheSize,crossOrigin:a.crossOrigin,logo:a.logo,projection:a.projection,reprojectionErrorThreshold:a.reprojectionErrorThreshold,tileGrid:a.tileGrid,tileLoadFunction:a.tileLoadFunction,url:a.url,urls:a.urls,wrapX:void 0!==a.wrapX?a.wrapX:!0});this.c=a.params||{};this.j=Wb()}y(Ow,X);Ow.prototype.v=function(){return this.c};Ow.prototype.Xb=function(a){return a}; +Ow.prototype.qc=function(a,c,d){var e=this.tileGrid;e||(e=this.fb(d));if(!(e.b.length<=a[0])){var f=e.Ba(a,this.j),g=Uf(e.Ha(a[0]),this.o);1!=c&&(g=Tf(g,c,this.o));e={F:"image",FORMAT:"PNG32",TRANSPARENT:!0};Pa(e,this.c);var h=this.urls;h?(d=d.eb.split(":").pop(),e.SIZE=g[0]+","+g[1],e.BBOX=f.join(","),e.BBOXSR=d,e.IMAGESR=d,e.DPI=Math.round(e.DPI?e.DPI*c:90*c),a=(1==h.length?h[0]:h[Ja((a[1]<<a[0])+a[2],h.length)]).replace(/MapServer\/?$/,"MapServer/export").replace(/ImageServer\/?$/,"ImageServer/exportImage"), +a=dq(fq([a],e))):a=void 0;return a}};Ow.prototype.B=function(a){Pa(this.c,a);this.u()};function Pw(a,c,d){Qf.call(this,a,2);this.l=c;this.c=d;this.g={}}y(Pw,Qf);Pw.prototype.ab=function(a){a=void 0!==a?w(a):-1;if(a in this.g)return this.g[a];var c=this.l,d=Mg(c[0],c[1]);d.strokeStyle="black";d.strokeRect(.5,.5,c[0]+.5,c[1]+.5);d.fillStyle="black";d.textAlign="center";d.textBaseline="middle";d.font="24px sans-serif";d.fillText(this.c,c[0]/2,c[1]/2);return this.g[a]=d.canvas}; +function Qw(a){lg.call(this,{opaque:!1,projection:a.projection,tileGrid:a.tileGrid,wrapX:void 0!==a.wrapX?a.wrapX:!0})}y(Qw,lg);Qw.prototype.Wb=function(a,c,d){var e=this.Ab(a,c,d);if(Lf(this.a,e))return this.a.get(e);var f=Uf(this.tileGrid.Ha(a));a=[a,c,d];c=(c=og(this,a))?og(this,c).toString():"";f=new Pw(a,f,c);this.a.set(e,f);return f};function Rw(a){this.c=null;X.call(this,{attributions:a.attributions,cacheSize:a.cacheSize,crossOrigin:a.crossOrigin,projection:Ic("EPSG:3857"),reprojectionErrorThreshold:a.reprojectionErrorThreshold,state:"loading",tileLoadFunction:a.tileLoadFunction,wrapX:void 0!==a.wrapX?a.wrapX:!0});if(a.jsonp)dw(a.url,this.th.bind(this),this.he.bind(this));else{var c=new XMLHttpRequest;c.addEventListener("load",this.hn.bind(this));c.addEventListener("error",this.gn.bind(this));c.open("GET",a.url);c.send()}} +y(Rw,X);l=Rw.prototype;l.hn=function(a){a=a.target;if(200<=a.status&&300>a.status){var c;try{c=JSON.parse(a.responseText)}catch(d){this.he();return}this.th(c)}else this.he()};l.gn=function(){this.he()};l.wk=function(){return this.c}; +l.th=function(a){var c=Ic("EPSG:4326"),d=this.f,e;void 0!==a.bounds&&(e=zc(a.bounds,Lc(c,d)));var f=a.minzoom||0,g=a.maxzoom||22;this.tileGrid=d=kg({extent:ig(d),maxZoom:g,minZoom:f});this.tileUrlFunction=vm(a.tiles,d);if(void 0!==a.attribution&&!this.l){c=void 0!==e?e:c.O();e={};for(var h;f<=g;++f)h=f.toString(),e[h]=[bg(d,c,f)];this.ka([new ue({html:a.attribution,tileRanges:e})])}this.c=a;Xf(this,"ready")};l.he=function(){Xf(this,"error")};function Sw(a){lg.call(this,{projection:Ic("EPSG:3857"),state:"loading"});this.s=void 0!==a.preemptive?a.preemptive:!0;this.j=xm;this.i=void 0;this.c=a.jsonp||!1;if(a.url)if(this.c)dw(a.url,this.xf.bind(this),this.ie.bind(this));else{var c=new XMLHttpRequest;c.addEventListener("load",this.mn.bind(this));c.addEventListener("error",this.ln.bind(this));c.open("GET",a.url);c.send()}else a.tileJSON&&this.xf(a.tileJSON)}y(Sw,lg);l=Sw.prototype; +l.mn=function(a){a=a.target;if(200<=a.status&&300>a.status){var c;try{c=JSON.parse(a.responseText)}catch(d){this.ie();return}this.xf(c)}else this.ie()};l.ln=function(){this.ie()};l.tk=function(){return this.i};l.Ej=function(a,c,d,e,f){this.tileGrid?(c=this.tileGrid.Td(a,c),Tw(this.Wb(c[0],c[1],c[2],1,this.f),a,d,e,f)):!0===f?Fg(function(){d.call(e,null)}):d.call(e,null)};l.ie=function(){Xf(this,"error")}; +l.xf=function(a){var c=Ic("EPSG:4326"),d=this.f,e;void 0!==a.bounds&&(e=zc(a.bounds,Lc(c,d)));var f=a.minzoom||0,g=a.maxzoom||22;this.tileGrid=d=kg({extent:ig(d),maxZoom:g,minZoom:f});this.i=a.template;var h=a.grids;if(h){this.j=vm(h,d);if(void 0!==a.attribution){c=void 0!==e?e:c.O();for(e={};f<=g;++f)h=f.toString(),e[h]=[bg(d,c,f)];this.ka([new ue({html:a.attribution,tileRanges:e})])}Xf(this,"ready")}else Xf(this,"error")}; +l.Wb=function(a,c,d,e,f){var g=this.Ab(a,c,d);if(Lf(this.a,g))return this.a.get(g);a=[a,c,d];c=og(this,a,f);e=this.j(c,e,f);e=new Uw(a,void 0!==e?0:4,void 0!==e?e:"",this.tileGrid.Ba(a),this.s,this.c);this.a.set(g,e);return e};l.Uf=function(a,c,d){a=this.Ab(a,c,d);Lf(this.a,a)&&this.a.get(a)};function Uw(a,c,d,e,f,g){Qf.call(this,a,c);this.s=d;this.g=e;this.U=f;this.c=this.j=this.l=null;this.v=g}y(Uw,Qf);l=Uw.prototype;l.ab=function(){return null}; +l.getData=function(a){if(!this.l||!this.j)return null;var c=this.l[Math.floor((1-(a[1]-this.g[1])/(this.g[3]-this.g[1]))*this.l.length)];if("string"!==typeof c)return null;c=c.charCodeAt(Math.floor((a[0]-this.g[0])/(this.g[2]-this.g[0])*c.length));93<=c&&c--;35<=c&&c--;c-=32;a=null;c in this.j&&(c=this.j[c],this.c&&c in this.c?a=this.c[c]:a=c);return a}; +function Tw(a,c,d,e,f){0==a.state&&!0===f?(bb(a,"change",function(){d.call(e,this.getData(c))},a),Vw(a)):!0===f?Fg(function(){d.call(e,this.getData(c))},a):d.call(e,a.getData(c))}l.gb=function(){return this.s};l.Vd=function(){this.state=3;Rf(this)};l.uh=function(a){this.l=a.grid;this.j=a.keys;this.c=a.data;this.state=4;Rf(this)}; +function Vw(a){if(0==a.state)if(a.state=1,a.v)dw(a.s,a.uh.bind(a),a.Vd.bind(a));else{var c=new XMLHttpRequest;c.addEventListener("load",a.kn.bind(a));c.addEventListener("error",a.jn.bind(a));c.open("GET",a.s);c.send()}}l.kn=function(a){a=a.target;if(200<=a.status&&300>a.status){var c;try{c=JSON.parse(a.responseText)}catch(d){this.Vd();return}this.uh(c)}else this.Vd()};l.jn=function(){this.Vd()};l.load=function(){this.U&&Vw(this)};function Ww(a){a=a||{};var c=a.params||{};X.call(this,{attributions:a.attributions,cacheSize:a.cacheSize,crossOrigin:a.crossOrigin,logo:a.logo,opaque:!("TRANSPARENT"in c?c.TRANSPARENT:1),projection:a.projection,reprojectionErrorThreshold:a.reprojectionErrorThreshold,tileGrid:a.tileGrid,tileLoadFunction:a.tileLoadFunction,url:a.url,urls:a.urls,wrapX:void 0!==a.wrapX?a.wrapX:!0});this.v=void 0!==a.gutter?a.gutter:0;this.c=c;this.j=!0;this.B=a.serverType;this.T=void 0!==a.hidpi?a.hidpi:!0;this.S=""; +Xw(this);this.Y=Wb();Yw(this);ng(this,Zw(this))}y(Ww,X);l=Ww.prototype; +l.nn=function(a,c,d,e){d=Ic(d);var f=this.tileGrid;f||(f=this.fb(d));c=f.Td(a,c);if(!(f.b.length<=c[0])){var g=f.$(c[0]),h=f.Ba(c,this.Y),f=Uf(f.Ha(c[0]),this.o),k=this.v;0!==k&&(f=Sf(f,k,this.o),h=Yb(h,g*k,h));k={SERVICE:"WMS",VERSION:"1.3.0",REQUEST:"GetFeatureInfo",FORMAT:"image/png",TRANSPARENT:!0,QUERY_LAYERS:this.c.LAYERS};Pa(k,this.c,e);e=Math.floor((h[3]-a[1])/g);k[this.j?"I":"X"]=Math.floor((a[0]-h[0])/g);k[this.j?"J":"Y"]=e;return $w(this,c,f,h,1,d,k)}};l.cf=function(){return this.v}; +l.Ab=function(a,c,d){return this.S+Ww.ia.Ab.call(this,a,c,d)};l.pn=function(){return this.c}; +function $w(a,c,d,e,f,g,h){var k=a.urls;if(k){h.WIDTH=d[0];h.HEIGHT=d[1];h[a.j?"CRS":"SRS"]=g.eb;"STYLES"in a.c||(h.STYLES="");if(1!=f)switch(a.B){case "geoserver":d=90*f+.5|0;h.FORMAT_OPTIONS="FORMAT_OPTIONS"in h?h.FORMAT_OPTIONS+(";dpi:"+d):"dpi:"+d;break;case "mapserver":h.MAP_RESOLUTION=90*f;break;case "carmentaserver":case "qgis":h.DPI=90*f}g=g.b;a.j&&"ne"==g.substr(0,2)&&(a=e[0],e[0]=e[1],e[1]=a,a=e[2],e[2]=e[3],e[3]=a);h.BBOX=e.join(",");return dq(fq([1==k.length?k[0]:k[Ja((c[1]<<c[0])+c[2], +k.length)]],h))}}l.Xb=function(a){return this.T&&void 0!==this.B?a:1};function Xw(a){var c=0,d=[];if(a.urls){var e,f;e=0;for(f=a.urls.length;e<f;++e)d[c++]=a.urls[e]}a.S=d.join("#")}function Zw(a){var c=0,d=[],e;for(e in a.c)d[c++]=e+"-"+a.c[e];return d.join("/")} +l.qc=function(a,c,d){var e=this.tileGrid;e||(e=this.fb(d));if(!(e.b.length<=a[0])){1==c||this.T&&void 0!==this.B||(c=1);var f=e.$(a[0]),g=e.Ba(a,this.Y),e=Uf(e.Ha(a[0]),this.o),h=this.v;0!==h&&(e=Sf(e,h,this.o),g=Yb(g,f*h,g));1!=c&&(e=Tf(e,c,this.o));f={SERVICE:"WMS",VERSION:"1.3.0",REQUEST:"GetMap",FORMAT:"image/png",TRANSPARENT:!0};Pa(f,this.c);return $w(this,a,e,g,c,d,f)}};l.qn=function(a){Pa(this.c,a);Xw(this);Yw(this);ng(this,Zw(this))};function Yw(a){a.j=0<=Lb(a.c.VERSION||"1.3.0")};function ax(a){this.l=a.matrixIds;Yf.call(this,{extent:a.extent,origin:a.origin,origins:a.origins,resolutions:a.resolutions,tileSize:a.tileSize,tileSizes:a.tileSizes,sizes:a.sizes})}y(ax,Yf);ax.prototype.j=function(){return this.l}; +function bx(a,c){var d=[],e=[],f=[],g=[],h=[],k;k=Ic(a.SupportedCRS.replace(/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/,"$1:$3"));var m=k.Vb(),n="ne"==k.b.substr(0,2);a.TileMatrix.sort(function(a,c){return c.ScaleDenominator-a.ScaleDenominator});a.TileMatrix.forEach(function(a){e.push(a.Identifier);var c=2.8E-4*a.ScaleDenominator/m,k=a.TileWidth,u=a.TileHeight;n?f.push([a.TopLeftCorner[1],a.TopLeftCorner[0]]):f.push(a.TopLeftCorner);d.push(c);g.push(k==u?k:[k,u]);h.push([a.MatrixWidth,-a.MatrixHeight])}); +return new ax({extent:c,origins:f,resolutions:d,matrixIds:e,tileSizes:g,sizes:h})};function Z(a){function c(a){a="KVP"==e?dq(fq([a],g)):a.replace(/\{(\w+?)\}/g,function(a,c){return c.toLowerCase()in g?g[c.toLowerCase()]:a});return function(c){if(c){var d={TileMatrix:f.l[c[0]],TileCol:c[1],TileRow:-c[2]-1};Pa(d,h);c=a;return c="KVP"==e?dq(fq([c],d)):c.replace(/\{(\w+?)\}/g,function(a,c){return d[c]})}}}this.T=void 0!==a.version?a.version:"1.0.0";this.v=void 0!==a.format?a.format:"image/jpeg";this.c=void 0!==a.dimensions?a.dimensions:{};this.B=a.layer;this.j=a.matrixSet;this.S=a.style; +var d=a.urls;void 0===d&&void 0!==a.url&&(d=ym(a.url));var e=this.Y=void 0!==a.requestEncoding?a.requestEncoding:"KVP",f=a.tileGrid,g={layer:this.B,style:this.S,tilematrixset:this.j};"KVP"==e&&Pa(g,{Service:"WMTS",Request:"GetTile",Version:this.T,Format:this.v});var h=this.c,k=d&&0<d.length?wm(d.map(c)):xm;X.call(this,{attributions:a.attributions,cacheSize:a.cacheSize,crossOrigin:a.crossOrigin,logo:a.logo,projection:a.projection,reprojectionErrorThreshold:a.reprojectionErrorThreshold,tileClass:a.tileClass, +tileGrid:f,tileLoadFunction:a.tileLoadFunction,tilePixelRatio:a.tilePixelRatio,tileUrlFunction:k,urls:d,wrapX:void 0!==a.wrapX?a.wrapX:!1});ng(this,cx(this))}y(Z,X);l=Z.prototype;l.Rj=function(){return this.c};l.rn=function(){return this.v};l.sn=function(){return this.B};l.dk=function(){return this.j};l.rk=function(){return this.Y};l.tn=function(){return this.S};l.yk=function(){return this.T};function cx(a){var c=0,d=[],e;for(e in a.c)d[c++]=e+"-"+a.c[e];return d.join("/")} +l.pp=function(a){Pa(this.c,a);ng(this,cx(this))};function dx(a){a=a||{};var c=a.size,d=c[0],e=c[1],f=[],g=256;switch(void 0!==a.tierSizeCalculation?a.tierSizeCalculation:"default"){case "default":for(;d>g||e>g;)f.push([Math.ceil(d/g),Math.ceil(e/g)]),g+=g;break;case "truncated":for(;d>g||e>g;)f.push([Math.ceil(d/g),Math.ceil(e/g)]),d>>=1,e>>=1}f.push([1,1]);f.reverse();for(var g=[1],h=[0],e=1,d=f.length;e<d;e++)g.push(1<<e),h.push(f[e-1][0]*f[e-1][1]+h[e-1]);g.reverse();var c=[0,-c[1],c[0],0],c=new Yf({extent:c,origin:oc(c),resolutions:g}),k=a.url; +X.call(this,{attributions:a.attributions,cacheSize:a.cacheSize,crossOrigin:a.crossOrigin,logo:a.logo,reprojectionErrorThreshold:a.reprojectionErrorThreshold,tileClass:ex,tileGrid:c,tileUrlFunction:function(a){if(a){var c=a[0],d=a[1];a=-a[2]-1;return k+"TileGroup"+((d+a*f[c][0]+h[c])/256|0)+"/"+c+"-"+d+"-"+a+".jpg"}}})}y(dx,X);function ex(a,c,d,e,f){Zu.call(this,a,c,d,e,f);this.l={}}y(ex,Zu); +ex.prototype.ab=function(a){var c=void 0!==a?w(a).toString():"";if(c in this.l)return this.l[c];a=ex.ia.ab.call(this,a);if(2==this.state){if(256==a.width&&256==a.height)return this.l[c]=a;var d=Mg(256,256);d.drawImage(a,0,0);return this.l[c]=d.canvas}return a};function fx(a){a=a||{};this.a=void 0!==a.initialSize?a.initialSize:256;this.g=void 0!==a.maxSize?a.maxSize:void 0!==na?na:2048;this.b=void 0!==a.space?a.space:1;this.c=[new gx(this.a,this.b)];this.f=this.a;this.i=[new gx(this.f,this.b)]}fx.prototype.add=function(a,c,d,e,f,g){if(c+this.b>this.g||d+this.b>this.g)return null;e=hx(this,!1,a,c,d,e,g);if(!e)return null;a=hx(this,!0,a,c,d,void 0!==f?f:pa,g);return{offsetX:e.offsetX,offsetY:e.offsetY,image:e.image,Ng:a.image}}; +function hx(a,c,d,e,f,g,h){var k=c?a.i:a.c,m,n,p;n=0;for(p=k.length;n<p;++n){m=k[n];if(m=m.add(d,e,f,g,h))return m;m||n!==p-1||(c?(m=Math.min(2*a.f,a.g),a.f=m):(m=Math.min(2*a.a,a.g),a.a=m),m=new gx(m,a.b),k.push(m),++p)}}function gx(a,c){this.b=c;this.a=[{x:0,y:0,width:a,height:a}];this.f={};this.g=Mg(a,a);this.c=this.g.canvas}gx.prototype.get=function(a){return this.f[a]||null}; +gx.prototype.add=function(a,c,d,e,f){var g,h,k;h=0;for(k=this.a.length;h<k;++h)if(g=this.a[h],g.width>=c+this.b&&g.height>=d+this.b)return k={offsetX:g.x+this.b,offsetY:g.y+this.b,image:this.c},this.f[a]=k,e.call(f,this.g,g.x+this.b,g.y+this.b),a=h,c=c+this.b,d=d+this.b,f=e=void 0,g.width-c>g.height-d?(e={x:g.x+c,y:g.y,width:g.width-c,height:g.height},f={x:g.x,y:g.y+d,width:c,height:g.height-d},ix(this,a,e,f)):(e={x:g.x+c,y:g.y,width:g.width-c,height:d},f={x:g.x,y:g.y+d,width:g.width,height:g.height- +d},ix(this,a,e,f)),k;return null};function ix(a,c,d,e){c=[c,1];0<d.width&&0<d.height&&c.push(d);0<e.width&&0<e.height&&c.push(e);a.a.splice.apply(a.a,c)};function jx(a){this.B=this.s=this.f=null;this.o=void 0!==a.fill?a.fill:null;this.va=[0,0];this.b=a.points;this.g=void 0!==a.radius?a.radius:a.radius1;this.c=void 0!==a.radius2?a.radius2:this.g;this.l=void 0!==a.angle?a.angle:0;this.a=void 0!==a.stroke?a.stroke:null;this.R=this.ya=this.N=null;var c=a.atlasManager,d="",e="",f=0,g=null,h,k=0;this.a&&(h=He(this.a.b),k=this.a.a,void 0===k&&(k=1),g=this.a.g,Zg||(g=null),e=this.a.c,void 0===e&&(e="round"),d=this.a.f,void 0===d&&(d="round"),f=this.a.i,void 0=== +f&&(f=10));var m=2*(this.g+k)+1,d={strokeStyle:h,wd:k,size:m,lineCap:d,lineDash:g,lineJoin:e,miterLimit:f};if(void 0===c){var n=Mg(m,m);this.s=n.canvas;c=m=this.s.width;this.Dh(d,n,0,0);this.o?this.B=this.s:(n=Mg(d.size,d.size),this.B=n.canvas,this.Ch(d,n,0,0))}else m=Math.round(m),(e=!this.o)&&(n=this.Ch.bind(this,d)),f=this.a?hk(this.a):"-",g=this.o?bk(this.o):"-",this.f&&f==this.f[1]&&g==this.f[2]&&this.g==this.f[3]&&this.c==this.f[4]&&this.l==this.f[5]&&this.b==this.f[6]||(this.f=["r"+f+g+(void 0!== +this.g?this.g.toString():"-")+(void 0!==this.c?this.c.toString():"-")+(void 0!==this.l?this.l.toString():"-")+(void 0!==this.b?this.b.toString():"-"),f,g,this.g,this.c,this.l,this.b]),n=c.add(this.f[0],m,m,this.Dh.bind(this,d),n),this.s=n.image,this.va=[n.offsetX,n.offsetY],c=n.image.width,this.B=e?n.Ng:this.s;this.N=[m/2,m/2];this.ya=[m,m];this.R=[c,c];ti.call(this,{opacity:1,rotateWithView:void 0!==a.rotateWithView?a.rotateWithView:!1,rotation:void 0!==a.rotation?a.rotation:0,scale:1,snapToPixel:void 0!== +a.snapToPixel?a.snapToPixel:!0})}y(jx,ti);l=jx.prototype;l.Tb=function(){return this.N};l.zn=function(){return this.l};l.An=function(){return this.o};l.ke=function(){return this.B};l.ec=function(){return this.s};l.fd=function(){return this.R};l.od=function(){return 2};l.Fa=function(){return this.va};l.Bn=function(){return this.b};l.Cn=function(){return this.g};l.qk=function(){return this.c};l.Bb=function(){return this.ya};l.Dn=function(){return this.a};l.kf=pa;l.load=pa;l.Tf=pa; +l.Dh=function(a,c,d,e){var f;c.setTransform(1,0,0,1,0,0);c.translate(d,e);c.beginPath();this.c!==this.g&&(this.b*=2);for(d=0;d<=this.b;d++)e=2*d*Math.PI/this.b-Math.PI/2+this.l,f=0===d%2?this.g:this.c,c.lineTo(a.size/2+f*Math.cos(e),a.size/2+f*Math.sin(e));this.o&&(c.fillStyle=Je(this.o.b),c.fill());this.a&&(c.strokeStyle=a.strokeStyle,c.lineWidth=a.wd,a.lineDash&&c.setLineDash(a.lineDash),c.lineCap=a.lineCap,c.lineJoin=a.lineJoin,c.miterLimit=a.miterLimit,c.stroke());c.closePath()}; +l.Ch=function(a,c,d,e){c.setTransform(1,0,0,1,0,0);c.translate(d,e);c.beginPath();this.c!==this.g&&(this.b*=2);var f;for(d=0;d<=this.b;d++)f=2*d*Math.PI/this.b-Math.PI/2+this.l,e=0===d%2?this.g:this.c,c.lineTo(a.size/2+e*Math.cos(f),a.size/2+e*Math.sin(f));c.fillStyle=Wj;c.fill();this.a&&(c.strokeStyle=a.strokeStyle,c.lineWidth=a.wd,a.lineDash&&c.setLineDash(a.lineDash),c.stroke());c.closePath()};t("ol.animation.bounce",function(a){var c=a.resolution,d=a.start?a.start:Date.now(),e=void 0!==a.duration?a.duration:1E3,f=a.easing?a.easing:me;return function(a,h){if(h.time<d)return h.animate=!0,h.viewHints[0]+=1,!0;if(h.time<d+e){var k=f((h.time-d)/e),m=c-h.viewState.resolution;h.animate=!0;h.viewState.resolution+=k*m;h.viewHints[0]+=1;return!0}return!1}},OPENLAYERS);t("ol.animation.pan",ne,OPENLAYERS);t("ol.animation.rotate",oe,OPENLAYERS);t("ol.animation.zoom",pe,OPENLAYERS); +t("ol.Attribution",ue,OPENLAYERS);ue.prototype.getHTML=ue.prototype.g;ve.prototype.element=ve.prototype.element;t("ol.Collection",we,OPENLAYERS);we.prototype.clear=we.prototype.clear;we.prototype.extend=we.prototype.lf;we.prototype.forEach=we.prototype.forEach;we.prototype.getArray=we.prototype.Cl;we.prototype.item=we.prototype.item;we.prototype.getLength=we.prototype.Zb;we.prototype.insertAt=we.prototype.Zd;we.prototype.pop=we.prototype.pop;we.prototype.push=we.prototype.push; +we.prototype.remove=we.prototype.remove;we.prototype.removeAt=we.prototype.Nf;we.prototype.setAt=we.prototype.To;t("ol.colorlike.asColorLike",Je,OPENLAYERS);t("ol.coordinate.add",Mb,OPENLAYERS);t("ol.coordinate.createStringXY",function(a){return function(c){return Ub(c,a)}},OPENLAYERS);t("ol.coordinate.format",Pb,OPENLAYERS);t("ol.coordinate.rotate",Rb,OPENLAYERS);t("ol.coordinate.toStringHDMS",function(a,c){return a?Ob(a[1],"NS",c)+" "+Ob(a[0],"EW",c):""},OPENLAYERS); +t("ol.coordinate.toStringXY",Ub,OPENLAYERS);t("ol.DeviceOrientation",ho,OPENLAYERS);ho.prototype.getAlpha=ho.prototype.Kj;ho.prototype.getBeta=ho.prototype.Nj;ho.prototype.getGamma=ho.prototype.Uj;ho.prototype.getHeading=ho.prototype.Dl;ho.prototype.getTracking=ho.prototype.Vg;ho.prototype.setTracking=ho.prototype.mf;t("ol.easing.easeIn",ie,OPENLAYERS);t("ol.easing.easeOut",je,OPENLAYERS);t("ol.easing.inAndOut",ke,OPENLAYERS);t("ol.easing.linear",le,OPENLAYERS);t("ol.easing.upAndDown",me,OPENLAYERS); +t("ol.extent.boundingExtent",Vb,OPENLAYERS);t("ol.extent.buffer",Yb,OPENLAYERS);t("ol.extent.containsCoordinate",ac,OPENLAYERS);t("ol.extent.containsExtent",cc,OPENLAYERS);t("ol.extent.containsXY",bc,OPENLAYERS);t("ol.extent.createEmpty",Wb,OPENLAYERS);t("ol.extent.equals",ic,OPENLAYERS);t("ol.extent.extend",jc,OPENLAYERS);t("ol.extent.getBottomLeft",lc,OPENLAYERS);t("ol.extent.getBottomRight",mc,OPENLAYERS);t("ol.extent.getCenter",tc,OPENLAYERS);t("ol.extent.getHeight",sc,OPENLAYERS); +t("ol.extent.getIntersection",vc,OPENLAYERS);t("ol.extent.getSize",function(a){return[a[2]-a[0],a[3]-a[1]]},OPENLAYERS);t("ol.extent.getTopLeft",oc,OPENLAYERS);t("ol.extent.getTopRight",nc,OPENLAYERS);t("ol.extent.getWidth",rc,OPENLAYERS);t("ol.extent.intersects",wc,OPENLAYERS);t("ol.extent.isEmpty",qc,OPENLAYERS);t("ol.extent.applyTransform",zc,OPENLAYERS);t("ol.Feature",zl,OPENLAYERS);zl.prototype.clone=zl.prototype.clone;zl.prototype.getGeometry=zl.prototype.W;zl.prototype.getId=zl.prototype.Wa; +zl.prototype.getGeometryName=zl.prototype.Wj;zl.prototype.getStyle=zl.prototype.Fl;zl.prototype.getStyleFunction=zl.prototype.$b;zl.prototype.setGeometry=zl.prototype.Ta;zl.prototype.setStyle=zl.prototype.nf;zl.prototype.setId=zl.prototype.hc;zl.prototype.setGeometryName=zl.prototype.zc;t("ol.featureloader.tile",Vl,OPENLAYERS);t("ol.featureloader.xhr",Wl,OPENLAYERS);t("ol.Geolocation",Nu,OPENLAYERS);Nu.prototype.getAccuracy=Nu.prototype.Ij;Nu.prototype.getAccuracyGeometry=Nu.prototype.Jj; +Nu.prototype.getAltitude=Nu.prototype.Lj;Nu.prototype.getAltitudeAccuracy=Nu.prototype.Mj;Nu.prototype.getHeading=Nu.prototype.Hl;Nu.prototype.getPosition=Nu.prototype.Il;Nu.prototype.getProjection=Nu.prototype.Wg;Nu.prototype.getSpeed=Nu.prototype.sk;Nu.prototype.getTracking=Nu.prototype.Xg;Nu.prototype.getTrackingOptions=Nu.prototype.Hg;Nu.prototype.setProjection=Nu.prototype.Yg;Nu.prototype.setTracking=Nu.prototype.ae;Nu.prototype.setTrackingOptions=Nu.prototype.mi;t("ol.Graticule",Tu,OPENLAYERS); +Tu.prototype.getMap=Tu.prototype.Ll;Tu.prototype.getMeridians=Tu.prototype.ek;Tu.prototype.getParallels=Tu.prototype.lk;Tu.prototype.setMap=Tu.prototype.setMap;t("ol.has.DEVICE_PIXEL_RATIO",Yg,OPENLAYERS);t("ol.has.CANVAS",$g,OPENLAYERS);t("ol.has.DEVICE_ORIENTATION",ah,OPENLAYERS);t("ol.has.GEOLOCATION",bh,OPENLAYERS);t("ol.has.TOUCH",ch,OPENLAYERS);t("ol.has.WEBGL",Tg,OPENLAYERS);Yu.prototype.getImage=Yu.prototype.a;Zu.prototype.getImage=Zu.prototype.ab;t("ol.Kinetic",Ki,OPENLAYERS); +t("ol.loadingstrategy.all",Xl,OPENLAYERS);t("ol.loadingstrategy.bbox",function(a){return[a]},OPENLAYERS);t("ol.loadingstrategy.tile",function(a){return function(c,d){var e=gg(a,d),f=bg(a,c,e),g=[],e=[e,0,0];for(e[1]=f.b;e[1]<=f.a;++e[1])for(e[2]=f.g;e[2]<=f.f;++e[2])g.push(a.Ba(e));return g}},OPENLAYERS);t("ol.Map",S,OPENLAYERS);S.prototype.addControl=S.prototype.pj;S.prototype.addInteraction=S.prototype.qj;S.prototype.addLayer=S.prototype.gg;S.prototype.addOverlay=S.prototype.hg; +S.prototype.beforeRender=S.prototype.Va;S.prototype.forEachFeatureAtPixel=S.prototype.ed;S.prototype.forEachLayerAtPixel=S.prototype.Pl;S.prototype.hasFeatureAtPixel=S.prototype.gl;S.prototype.getEventCoordinate=S.prototype.Sj;S.prototype.getEventPixel=S.prototype.Nd;S.prototype.getTarget=S.prototype.pf;S.prototype.getTargetElement=S.prototype.tc;S.prototype.getCoordinateFromPixel=S.prototype.Ma;S.prototype.getControls=S.prototype.Qj;S.prototype.getOverlays=S.prototype.jk; +S.prototype.getOverlayById=S.prototype.ik;S.prototype.getInteractions=S.prototype.Xj;S.prototype.getLayerGroup=S.prototype.sc;S.prototype.getLayers=S.prototype.Zg;S.prototype.getPixelFromCoordinate=S.prototype.Da;S.prototype.getSize=S.prototype.$a;S.prototype.getView=S.prototype.aa;S.prototype.getViewport=S.prototype.zk;S.prototype.renderSync=S.prototype.Po;S.prototype.render=S.prototype.render;S.prototype.removeControl=S.prototype.Io;S.prototype.removeInteraction=S.prototype.Jo; +S.prototype.removeLayer=S.prototype.Lo;S.prototype.removeOverlay=S.prototype.Mo;S.prototype.setLayerGroup=S.prototype.ei;S.prototype.setSize=S.prototype.Sf;S.prototype.setTarget=S.prototype.$g;S.prototype.setView=S.prototype.ep;S.prototype.updateSize=S.prototype.Sc;Mh.prototype.originalEvent=Mh.prototype.originalEvent;Mh.prototype.pixel=Mh.prototype.pixel;Mh.prototype.coordinate=Mh.prototype.coordinate;Mh.prototype.dragging=Mh.prototype.dragging;If.prototype.map=If.prototype.map; +If.prototype.frameState=If.prototype.frameState;ob.prototype.key=ob.prototype.key;ob.prototype.oldValue=ob.prototype.oldValue;t("ol.Object",pb,OPENLAYERS);pb.prototype.get=pb.prototype.get;pb.prototype.getKeys=pb.prototype.K;pb.prototype.getProperties=pb.prototype.L;pb.prototype.set=pb.prototype.set;pb.prototype.setProperties=pb.prototype.C;pb.prototype.unset=pb.prototype.P;t("ol.Observable",mb,OPENLAYERS);t("ol.Observable.unByKey",nb,OPENLAYERS);mb.prototype.changed=mb.prototype.u; +mb.prototype.dispatchEvent=mb.prototype.b;mb.prototype.getRevision=mb.prototype.H;mb.prototype.on=mb.prototype.D;mb.prototype.once=mb.prototype.I;mb.prototype.un=mb.prototype.G;mb.prototype.unByKey=mb.prototype.J;t("ol.inherits",y,OPENLAYERS);t("ol.Overlay",On,OPENLAYERS);On.prototype.getElement=On.prototype.be;On.prototype.getId=On.prototype.Wa;On.prototype.getMap=On.prototype.ce;On.prototype.getOffset=On.prototype.Fg;On.prototype.getPosition=On.prototype.ah;On.prototype.getPositioning=On.prototype.Gg; +On.prototype.setElement=On.prototype.ai;On.prototype.setMap=On.prototype.setMap;On.prototype.setOffset=On.prototype.gi;On.prototype.setPosition=On.prototype.qf;On.prototype.setPositioning=On.prototype.ji;t("ol.render.toContext",function(a,c){var d=a.canvas,e=c?c:{},f=e.pixelRatio||Yg;if(e=e.size)d.width=e[0]*f,d.height=e[1]*f,d.style.width=e[0]+"px",d.style.height=e[1]+"px";d=[0,0,d.width,d.height];e=hi(hd(),0,0,f,f,0,0,0);return new qk(a,f,d,e,0)},OPENLAYERS);t("ol.size.toSize",Uf,OPENLAYERS); +Qf.prototype.getTileCoord=Qf.prototype.i;Bl.prototype.getFormat=Bl.prototype.Ql;Bl.prototype.setFeatures=Bl.prototype.bi;Bl.prototype.setProjection=Bl.prototype.rf;Bl.prototype.setLoader=Bl.prototype.fi;t("ol.View",be,OPENLAYERS);be.prototype.constrainCenter=be.prototype.Kd;be.prototype.constrainResolution=be.prototype.constrainResolution;be.prototype.constrainRotation=be.prototype.constrainRotation;be.prototype.getCenter=be.prototype.bb;be.prototype.calculateExtent=be.prototype.Fc; +be.prototype.getProjection=be.prototype.Rl;be.prototype.getResolution=be.prototype.$;be.prototype.getResolutions=be.prototype.Sl;be.prototype.getRotation=be.prototype.Ka;be.prototype.getZoom=be.prototype.Bk;be.prototype.fit=be.prototype.Ze;be.prototype.centerOn=be.prototype.Aj;be.prototype.rotate=be.prototype.rotate;be.prototype.setCenter=be.prototype.jb;be.prototype.setResolution=be.prototype.Qb;be.prototype.setRotation=be.prototype.de;be.prototype.setZoom=be.prototype.hp; +t("ol.xml.getAllTextContent",El,OPENLAYERS);t("ol.xml.parse",Il,OPENLAYERS);Xm.prototype.getGL=Xm.prototype.Un;Xm.prototype.useProgram=Xm.prototype.re;t("ol.tilegrid.TileGrid",Yf,OPENLAYERS);Yf.prototype.getMaxZoom=Yf.prototype.Dg;Yf.prototype.getMinZoom=Yf.prototype.Eg;Yf.prototype.getOrigin=Yf.prototype.Fa;Yf.prototype.getResolution=Yf.prototype.$;Yf.prototype.getResolutions=Yf.prototype.Fh;Yf.prototype.getTileCoordExtent=Yf.prototype.Ba;Yf.prototype.getTileCoordForCoordAndResolution=Yf.prototype.Td; +Yf.prototype.getTileCoordForCoordAndZ=Yf.prototype.kd;Yf.prototype.getTileSize=Yf.prototype.Ha;t("ol.tilegrid.createXYZ",kg,OPENLAYERS);t("ol.tilegrid.WMTS",ax,OPENLAYERS);ax.prototype.getMatrixIds=ax.prototype.j;t("ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet",bx,OPENLAYERS);t("ol.style.AtlasManager",fx,OPENLAYERS);t("ol.style.Circle",ik,OPENLAYERS);ik.prototype.getFill=ik.prototype.vn;ik.prototype.getImage=ik.prototype.ec;ik.prototype.getRadius=ik.prototype.wn;ik.prototype.getStroke=ik.prototype.xn; +t("ol.style.Fill",ak,OPENLAYERS);ak.prototype.getColor=ak.prototype.g;ak.prototype.setColor=ak.prototype.f;t("ol.style.Icon",ui,OPENLAYERS);ui.prototype.getAnchor=ui.prototype.Tb;ui.prototype.getImage=ui.prototype.ec;ui.prototype.getOrigin=ui.prototype.Fa;ui.prototype.getSrc=ui.prototype.yn;ui.prototype.getSize=ui.prototype.Bb;ui.prototype.load=ui.prototype.load;t("ol.style.Image",ti,OPENLAYERS);ti.prototype.getOpacity=ti.prototype.le;ti.prototype.getRotateWithView=ti.prototype.Rd; +ti.prototype.getRotation=ti.prototype.me;ti.prototype.getScale=ti.prototype.ne;ti.prototype.getSnapToPixel=ti.prototype.Sd;ti.prototype.setOpacity=ti.prototype.oe;ti.prototype.setRotation=ti.prototype.pe;ti.prototype.setScale=ti.prototype.qe;t("ol.style.RegularShape",jx,OPENLAYERS);jx.prototype.getAnchor=jx.prototype.Tb;jx.prototype.getAngle=jx.prototype.zn;jx.prototype.getFill=jx.prototype.An;jx.prototype.getImage=jx.prototype.ec;jx.prototype.getOrigin=jx.prototype.Fa;jx.prototype.getPoints=jx.prototype.Bn; +jx.prototype.getRadius=jx.prototype.Cn;jx.prototype.getRadius2=jx.prototype.qk;jx.prototype.getSize=jx.prototype.Bb;jx.prototype.getStroke=jx.prototype.Dn;t("ol.style.Stroke",gk,OPENLAYERS);gk.prototype.getColor=gk.prototype.En;gk.prototype.getLineCap=gk.prototype.$j;gk.prototype.getLineDash=gk.prototype.Fn;gk.prototype.getLineJoin=gk.prototype.ak;gk.prototype.getMiterLimit=gk.prototype.fk;gk.prototype.getWidth=gk.prototype.Gn;gk.prototype.setColor=gk.prototype.Hn;gk.prototype.setLineCap=gk.prototype.Zo; +gk.prototype.setLineDash=gk.prototype.In;gk.prototype.setLineJoin=gk.prototype.$o;gk.prototype.setMiterLimit=gk.prototype.ap;gk.prototype.setWidth=gk.prototype.fp;t("ol.style.Style",jk,OPENLAYERS);jk.prototype.getGeometry=jk.prototype.W;jk.prototype.getGeometryFunction=jk.prototype.Vj;jk.prototype.getFill=jk.prototype.Jn;jk.prototype.getImage=jk.prototype.Kn;jk.prototype.getStroke=jk.prototype.Ln;jk.prototype.getText=jk.prototype.Ea;jk.prototype.getZIndex=jk.prototype.Mn; +jk.prototype.setGeometry=jk.prototype.Eh;jk.prototype.setZIndex=jk.prototype.Nn;t("ol.style.Text",zq,OPENLAYERS);zq.prototype.getFont=zq.prototype.Tj;zq.prototype.getOffsetX=zq.prototype.gk;zq.prototype.getOffsetY=zq.prototype.hk;zq.prototype.getFill=zq.prototype.On;zq.prototype.getRotation=zq.prototype.Pn;zq.prototype.getScale=zq.prototype.Qn;zq.prototype.getStroke=zq.prototype.Rn;zq.prototype.getText=zq.prototype.Ea;zq.prototype.getTextAlign=zq.prototype.uk;zq.prototype.getTextBaseline=zq.prototype.vk; +zq.prototype.setFont=zq.prototype.Wo;zq.prototype.setOffsetX=zq.prototype.hi;zq.prototype.setOffsetY=zq.prototype.ii;zq.prototype.setFill=zq.prototype.Vo;zq.prototype.setRotation=zq.prototype.Sn;zq.prototype.setScale=zq.prototype.Tn;zq.prototype.setStroke=zq.prototype.bp;zq.prototype.setText=zq.prototype.ki;zq.prototype.setTextAlign=zq.prototype.li;zq.prototype.setTextBaseline=zq.prototype.cp;t("ol.Sphere",Cc,OPENLAYERS);Cc.prototype.geodesicArea=Cc.prototype.a;Cc.prototype.haversineDistance=Cc.prototype.b; +t("ol.source.BingMaps",iw,OPENLAYERS);t("ol.source.BingMaps.TOS_ATTRIBUTION",jw,OPENLAYERS);t("ol.source.CartoDB",lw,OPENLAYERS);lw.prototype.getConfig=lw.prototype.Pj;lw.prototype.updateConfig=lw.prototype.op;lw.prototype.setConfig=lw.prototype.Uo;t("ol.source.Cluster",Y,OPENLAYERS);Y.prototype.getSource=Y.prototype.xa;t("ol.source.ImageArcGISRest",qw,OPENLAYERS);qw.prototype.getParams=qw.prototype.Mm;qw.prototype.getImageLoadFunction=qw.prototype.Lm;qw.prototype.getUrl=qw.prototype.Nm; +qw.prototype.setImageLoadFunction=qw.prototype.Om;qw.prototype.setUrl=qw.prototype.Pm;qw.prototype.updateParams=qw.prototype.Qm;t("ol.source.ImageCanvas",yl,OPENLAYERS);t("ol.source.ImageMapGuide",rw,OPENLAYERS);rw.prototype.getParams=rw.prototype.Sm;rw.prototype.getImageLoadFunction=rw.prototype.Rm;rw.prototype.updateParams=rw.prototype.Um;rw.prototype.setImageLoadFunction=rw.prototype.Tm;t("ol.source.Image",rl,OPENLAYERS);tl.prototype.image=tl.prototype.image;t("ol.source.ImageStatic",sw,OPENLAYERS); +t("ol.source.ImageVector",om,OPENLAYERS);om.prototype.getSource=om.prototype.Vm;om.prototype.getStyle=om.prototype.Wm;om.prototype.getStyleFunction=om.prototype.Xm;om.prototype.setStyle=om.prototype.sh;t("ol.source.ImageWMS",tw,OPENLAYERS);tw.prototype.getGetFeatureInfoUrl=tw.prototype.$m;tw.prototype.getParams=tw.prototype.bn;tw.prototype.getImageLoadFunction=tw.prototype.an;tw.prototype.getUrl=tw.prototype.cn;tw.prototype.setImageLoadFunction=tw.prototype.dn;tw.prototype.setUrl=tw.prototype.en; +tw.prototype.updateParams=tw.prototype.fn;t("ol.source.MapQuest",zw,OPENLAYERS);zw.prototype.getLayer=zw.prototype.j;t("ol.source.OSM",xw,OPENLAYERS);t("ol.source.OSM.ATTRIBUTION",yw,OPENLAYERS);t("ol.source.Raster",Cw,OPENLAYERS);Cw.prototype.setOperation=Cw.prototype.v;Hw.prototype.extent=Hw.prototype.extent;Hw.prototype.resolution=Hw.prototype.resolution;Hw.prototype.data=Hw.prototype.data;t("ol.source.Source",Vf,OPENLAYERS);Vf.prototype.getAttributions=Vf.prototype.ra;Vf.prototype.getLogo=Vf.prototype.qa; +Vf.prototype.getProjection=Vf.prototype.sa;Vf.prototype.getState=Vf.prototype.V;Vf.prototype.refresh=Vf.prototype.pa;Vf.prototype.setAttributions=Vf.prototype.ka;t("ol.source.Stamen",Mw,OPENLAYERS);t("ol.source.TileArcGISRest",Ow,OPENLAYERS);Ow.prototype.getParams=Ow.prototype.v;Ow.prototype.updateParams=Ow.prototype.B;t("ol.source.TileDebug",Qw,OPENLAYERS);t("ol.source.TileImage",X,OPENLAYERS);X.prototype.setRenderReprojectionEdges=X.prototype.lb;X.prototype.setTileGridForProjection=X.prototype.mb; +t("ol.source.TileJSON",Rw,OPENLAYERS);Rw.prototype.getTileJSON=Rw.prototype.wk;t("ol.source.Tile",lg,OPENLAYERS);lg.prototype.getTileGrid=lg.prototype.Ga;pg.prototype.tile=pg.prototype.tile;t("ol.source.TileUTFGrid",Sw,OPENLAYERS);Sw.prototype.getTemplate=Sw.prototype.tk;Sw.prototype.forDataAtCoordinateAndResolution=Sw.prototype.Ej;t("ol.source.TileWMS",Ww,OPENLAYERS);Ww.prototype.getGetFeatureInfoUrl=Ww.prototype.nn;Ww.prototype.getParams=Ww.prototype.pn;Ww.prototype.updateParams=Ww.prototype.qn; +zm.prototype.getTileLoadFunction=zm.prototype.Xa;zm.prototype.getTileUrlFunction=zm.prototype.Ya;zm.prototype.getUrls=zm.prototype.Za;zm.prototype.setTileLoadFunction=zm.prototype.cb;zm.prototype.setTileUrlFunction=zm.prototype.La;zm.prototype.setUrl=zm.prototype.Na;zm.prototype.setUrls=zm.prototype.Ua;t("ol.source.Vector",Q,OPENLAYERS);Q.prototype.addFeature=Q.prototype.qb;Q.prototype.addFeatures=Q.prototype.Ec;Q.prototype.clear=Q.prototype.clear;Q.prototype.forEachFeature=Q.prototype.sg; +Q.prototype.forEachFeatureInExtent=Q.prototype.tb;Q.prototype.forEachFeatureIntersectingExtent=Q.prototype.tg;Q.prototype.getFeaturesCollection=Q.prototype.Ag;Q.prototype.getFeatures=Q.prototype.je;Q.prototype.getFeaturesAtCoordinate=Q.prototype.zg;Q.prototype.getFeaturesInExtent=Q.prototype.af;Q.prototype.getClosestFeatureToCoordinate=Q.prototype.vg;Q.prototype.getExtent=Q.prototype.O;Q.prototype.getFeatureById=Q.prototype.yg;Q.prototype.getFormat=Q.prototype.xh;Q.prototype.getUrl=Q.prototype.yh; +Q.prototype.removeFeature=Q.prototype.kb;lm.prototype.feature=lm.prototype.feature;t("ol.source.VectorTile",Am,OPENLAYERS);t("ol.source.WMTS",Z,OPENLAYERS);Z.prototype.getDimensions=Z.prototype.Rj;Z.prototype.getFormat=Z.prototype.rn;Z.prototype.getLayer=Z.prototype.sn;Z.prototype.getMatrixSet=Z.prototype.dk;Z.prototype.getRequestEncoding=Z.prototype.rk;Z.prototype.getStyle=Z.prototype.tn;Z.prototype.getVersion=Z.prototype.yk;Z.prototype.updateDimensions=Z.prototype.pp; +t("ol.source.WMTS.optionsFromCapabilities",function(a,c){var d=zb(a.Contents.Layer,function(a){return a.Identifier==c.layer}),e=a.Contents.TileMatrixSet,f,g;f=1<d.TileMatrixSetLink.length?"projection"in c?Db(d.TileMatrixSetLink,function(a){return zb(e,function(c){return c.Identifier==a.TileMatrixSet}).SupportedCRS.replace(/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/,"$1:$3")==c.projection}):Db(d.TileMatrixSetLink,function(a){return a.TileMatrixSet==c.matrixSet}):0;0>f&&(f=0);g=d.TileMatrixSetLink[f].TileMatrixSet; +var h=d.Format[0];"format"in c&&(h=c.format);f=Db(d.Style,function(a){return"style"in c?a.Title==c.style:a.isDefault});0>f&&(f=0);f=d.Style[f].Identifier;var k={};"Dimension"in d&&d.Dimension.forEach(function(a){var c=a.Identifier,d=a.Default;void 0===d&&(d=a.Value[0]);k[c]=d});var m=zb(a.Contents.TileMatrixSet,function(a){return a.Identifier==g}),n;n="projection"in c?Ic(c.projection):Ic(m.SupportedCRS.replace(/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/,"$1:$3"));var p=d.WGS84BoundingBox,q,r;void 0!==p&& +(r=Ic("EPSG:4326").O(),r=p[0]==r[0]&&p[2]==r[2],q=cd(p,"EPSG:4326",n),(p=n.O())&&(cc(p,q)||(q=void 0)));var m=bx(m,q),u=[];q=c.requestEncoding;q=void 0!==q?q:"";if(a.hasOwnProperty("OperationsMetadata")&&a.OperationsMetadata.hasOwnProperty("GetTile")&&0!==q.indexOf("REST"))for(var d=a.OperationsMetadata.GetTile.DCP.HTTP.Get,p=0,v=d.length;p<v;++p){var x=zb(d[p].Constraint,function(a){return"GetEncoding"==a.name}).AllowedValues.Value;0<x.length&&ub(x,"KVP")&&(q="KVP",u.push(d[p].href))}else q="REST", +d.ResourceURL.forEach(function(a){"tile"==a.resourceType&&(h=a.format,u.push(a.template))});return{urls:u,layer:c.layer,matrixSet:g,format:h,projection:n,requestEncoding:q,tileGrid:m,style:f,dimensions:k,wrapX:r}},OPENLAYERS);t("ol.source.XYZ",kw,OPENLAYERS);t("ol.source.Zoomify",dx,OPENLAYERS);ci.prototype.vectorContext=ci.prototype.vectorContext;ci.prototype.frameState=ci.prototype.frameState;ci.prototype.context=ci.prototype.context;ci.prototype.glContext=ci.prototype.glContext; +Zk.prototype.get=Zk.prototype.get;Zk.prototype.getExtent=Zk.prototype.O;Zk.prototype.getGeometry=Zk.prototype.W;Zk.prototype.getProperties=Zk.prototype.Hm;Zk.prototype.getType=Zk.prototype.X;t("ol.render.VectorContext",bi,OPENLAYERS);tn.prototype.setStyle=tn.prototype.md;tn.prototype.drawGeometry=tn.prototype.nc;tn.prototype.drawFeature=tn.prototype.Ue;qk.prototype.drawCircle=qk.prototype.Md;qk.prototype.setStyle=qk.prototype.md;qk.prototype.drawGeometry=qk.prototype.nc;qk.prototype.drawFeature=qk.prototype.Ue; +t("ol.proj.common.add",Tj,OPENLAYERS);t("ol.proj.METERS_PER_UNIT",Ec,OPENLAYERS);t("ol.proj.Projection",Fc,OPENLAYERS);Fc.prototype.getCode=Fc.prototype.Oj;Fc.prototype.getExtent=Fc.prototype.O;Fc.prototype.getUnits=Fc.prototype.vb;Fc.prototype.getMetersPerUnit=Fc.prototype.Vb;Fc.prototype.getWorldExtent=Fc.prototype.Ak;Fc.prototype.isGlobal=Fc.prototype.ll;Fc.prototype.setGlobal=Fc.prototype.Yo;Fc.prototype.setExtent=Fc.prototype.Gm;Fc.prototype.setWorldExtent=Fc.prototype.gp; +Fc.prototype.setGetPointResolution=Fc.prototype.Xo;Fc.prototype.getPointResolution=Fc.prototype.getPointResolution;t("ol.proj.setProj4",function(a){Hc=a},OPENLAYERS);t("ol.proj.addEquivalentProjections",Jc,OPENLAYERS);t("ol.proj.addProjection",Wc,OPENLAYERS);t("ol.proj.addCoordinateTransforms",Kc,OPENLAYERS);t("ol.proj.fromLonLat",function(a,c){return bd(a,"EPSG:4326",void 0!==c?c:"EPSG:3857")},OPENLAYERS);t("ol.proj.toLonLat",function(a,c){return bd(a,void 0!==c?c:"EPSG:3857","EPSG:4326")},OPENLAYERS); +t("ol.proj.get",Ic,OPENLAYERS);t("ol.proj.equivalent",Zc,OPENLAYERS);t("ol.proj.getTransform",$c,OPENLAYERS);t("ol.proj.transform",bd,OPENLAYERS);t("ol.proj.transformExtent",cd,OPENLAYERS);t("ol.layer.Heatmap",W,OPENLAYERS);W.prototype.getBlur=W.prototype.ug;W.prototype.getGradient=W.prototype.Bg;W.prototype.getRadius=W.prototype.kh;W.prototype.setBlur=W.prototype.Zh;W.prototype.setGradient=W.prototype.di;W.prototype.setRadius=W.prototype.lh;t("ol.layer.Image",Uj,OPENLAYERS); +Uj.prototype.getSource=Uj.prototype.da;t("ol.layer.Layer",di,OPENLAYERS);di.prototype.getSource=di.prototype.da;di.prototype.setMap=di.prototype.setMap;di.prototype.setSource=di.prototype.Ac;t("ol.layer.Base",$h,OPENLAYERS);$h.prototype.getExtent=$h.prototype.O;$h.prototype.getMaxResolution=$h.prototype.Ib;$h.prototype.getMinResolution=$h.prototype.Jb;$h.prototype.getOpacity=$h.prototype.Lb;$h.prototype.getVisible=$h.prototype.wb;$h.prototype.getZIndex=$h.prototype.Mb;$h.prototype.setExtent=$h.prototype.ac; +$h.prototype.setMaxResolution=$h.prototype.ic;$h.prototype.setMinResolution=$h.prototype.jc;$h.prototype.setOpacity=$h.prototype.bc;$h.prototype.setVisible=$h.prototype.cc;$h.prototype.setZIndex=$h.prototype.dc;t("ol.layer.Group",Kj,OPENLAYERS);Kj.prototype.getLayers=Kj.prototype.Oc;Kj.prototype.setLayers=Kj.prototype.jh;t("ol.layer.Tile",Vj,OPENLAYERS);Vj.prototype.getPreload=Vj.prototype.f;Vj.prototype.getSource=Vj.prototype.da;Vj.prototype.setPreload=Vj.prototype.l; +Vj.prototype.getUseInterimTilesOnError=Vj.prototype.c;Vj.prototype.setUseInterimTilesOnError=Vj.prototype.B;t("ol.layer.Vector",H,OPENLAYERS);H.prototype.getSource=H.prototype.da;H.prototype.getStyle=H.prototype.M;H.prototype.getStyleFunction=H.prototype.N;H.prototype.setStyle=H.prototype.l;t("ol.layer.VectorTile",I,OPENLAYERS);I.prototype.getPreload=I.prototype.f;I.prototype.getUseInterimTilesOnError=I.prototype.c;I.prototype.setPreload=I.prototype.Y;I.prototype.setUseInterimTilesOnError=I.prototype.ea; +t("ol.interaction.DoubleClickZoom",Qi,OPENLAYERS);t("ol.interaction.DoubleClickZoom.handleEvent",Ri,OPENLAYERS);t("ol.interaction.DragAndDrop",av,OPENLAYERS);t("ol.interaction.DragAndDrop.handleEvent",Ac,OPENLAYERS);dv.prototype.features=dv.prototype.features;dv.prototype.file=dv.prototype.file;dv.prototype.projection=dv.prototype.projection;oj.prototype.coordinate=oj.prototype.coordinate;oj.prototype.mapBrowserEvent=oj.prototype.mapBrowserEvent;t("ol.interaction.DragBox",pj,OPENLAYERS); +pj.prototype.getGeometry=pj.prototype.W;t("ol.interaction.DragPan",dj,OPENLAYERS);t("ol.interaction.DragRotateAndZoom",fv,OPENLAYERS);t("ol.interaction.DragRotate",hj,OPENLAYERS);t("ol.interaction.DragZoom",uj,OPENLAYERS);jv.prototype.feature=jv.prototype.feature;t("ol.interaction.Draw",kv,OPENLAYERS);t("ol.interaction.Draw.handleEvent",mv,OPENLAYERS);kv.prototype.removeLastPoint=kv.prototype.Ko;kv.prototype.finishDrawing=kv.prototype.dd;kv.prototype.extend=kv.prototype.lm; +t("ol.interaction.Draw.createRegularPolygon",function(a,c){return function(d,e){var f=d[0],g=d[1],h=Math.sqrt(Sb(f,g)),k=e?e:$d(new Ou(f),a);ae(k,f,h,c?c:Math.atan((g[1]-f[1])/(g[0]-f[0])));return k}},OPENLAYERS);t("ol.interaction.Interaction",Mi,OPENLAYERS);Mi.prototype.getActive=Mi.prototype.f;Mi.prototype.getMap=Mi.prototype.l;Mi.prototype.setActive=Mi.prototype.i;t("ol.interaction.defaults",Jj,OPENLAYERS);t("ol.interaction.KeyboardPan",vj,OPENLAYERS); +t("ol.interaction.KeyboardPan.handleEvent",wj,OPENLAYERS);t("ol.interaction.KeyboardZoom",xj,OPENLAYERS);t("ol.interaction.KeyboardZoom.handleEvent",yj,OPENLAYERS);Av.prototype.features=Av.prototype.features;Av.prototype.mapBrowserPointerEvent=Av.prototype.mapBrowserPointerEvent;t("ol.interaction.Modify",Bv,OPENLAYERS);t("ol.interaction.Modify.handleEvent",Ev,OPENLAYERS);Bv.prototype.removePoint=Bv.prototype.Wh;t("ol.interaction.MouseWheelZoom",zj,OPENLAYERS); +t("ol.interaction.MouseWheelZoom.handleEvent",Aj,OPENLAYERS);zj.prototype.setMouseAnchor=zj.prototype.N;t("ol.interaction.PinchRotate",Bj,OPENLAYERS);t("ol.interaction.PinchZoom",Fj,OPENLAYERS);t("ol.interaction.Pointer",aj,OPENLAYERS);t("ol.interaction.Pointer.handleEvent",bj,OPENLAYERS);Ov.prototype.selected=Ov.prototype.selected;Ov.prototype.deselected=Ov.prototype.deselected;Ov.prototype.mapBrowserEvent=Ov.prototype.mapBrowserEvent;t("ol.interaction.Select",Pv,OPENLAYERS); +Pv.prototype.getFeatures=Pv.prototype.vm;Pv.prototype.getLayer=Pv.prototype.wm;t("ol.interaction.Select.handleEvent",Qv,OPENLAYERS);Pv.prototype.setMap=Pv.prototype.setMap;t("ol.interaction.Snap",Sv,OPENLAYERS);Sv.prototype.addFeature=Sv.prototype.qb;Sv.prototype.removeFeature=Sv.prototype.kb;Wv.prototype.features=Wv.prototype.features;Wv.prototype.coordinate=Wv.prototype.coordinate;t("ol.interaction.Translate",Xv,OPENLAYERS);t("ol.geom.Circle",Ou,OPENLAYERS);Ou.prototype.clone=Ou.prototype.clone; +Ou.prototype.getCenter=Ou.prototype.ld;Ou.prototype.getRadius=Ou.prototype.sf;Ou.prototype.getType=Ou.prototype.X;Ou.prototype.intersectsExtent=Ou.prototype.Ia;Ou.prototype.setCenter=Ou.prototype.dm;Ou.prototype.setCenterAndRadius=Ou.prototype.Rf;Ou.prototype.setRadius=Ou.prototype.em;Ou.prototype.transform=Ou.prototype.hb;t("ol.geom.Geometry",dd,OPENLAYERS);dd.prototype.getClosestPoint=dd.prototype.ub;dd.prototype.getExtent=dd.prototype.O;dd.prototype.rotate=dd.prototype.rotate; +dd.prototype.simplify=dd.prototype.yb;dd.prototype.transform=dd.prototype.hb;t("ol.geom.GeometryCollection",Do,OPENLAYERS);Do.prototype.clone=Do.prototype.clone;Do.prototype.getGeometries=Do.prototype.bf;Do.prototype.getType=Do.prototype.X;Do.prototype.intersectsExtent=Do.prototype.Ia;Do.prototype.setGeometries=Do.prototype.ci;Do.prototype.applyTransform=Do.prototype.mc;Do.prototype.translate=Do.prototype.Nc;t("ol.geom.LinearRing",Kd,OPENLAYERS);Kd.prototype.clone=Kd.prototype.clone; +Kd.prototype.getArea=Kd.prototype.hm;Kd.prototype.getCoordinates=Kd.prototype.Z;Kd.prototype.getType=Kd.prototype.X;Kd.prototype.setCoordinates=Kd.prototype.ma;t("ol.geom.LineString",T,OPENLAYERS);T.prototype.appendCoordinate=T.prototype.rj;T.prototype.clone=T.prototype.clone;T.prototype.forEachSegment=T.prototype.Hj;T.prototype.getCoordinateAtM=T.prototype.fm;T.prototype.getCoordinates=T.prototype.Z;T.prototype.getCoordinateAt=T.prototype.wg;T.prototype.getLength=T.prototype.gm; +T.prototype.getType=T.prototype.X;T.prototype.intersectsExtent=T.prototype.Ia;T.prototype.setCoordinates=T.prototype.ma;t("ol.geom.MultiLineString",U,OPENLAYERS);U.prototype.appendLineString=U.prototype.sj;U.prototype.clone=U.prototype.clone;U.prototype.getCoordinateAtM=U.prototype.im;U.prototype.getCoordinates=U.prototype.Z;U.prototype.getLineString=U.prototype.bk;U.prototype.getLineStrings=U.prototype.gd;U.prototype.getType=U.prototype.X;U.prototype.intersectsExtent=U.prototype.Ia; +U.prototype.setCoordinates=U.prototype.ma;t("ol.geom.MultiPoint",so,OPENLAYERS);so.prototype.appendPoint=so.prototype.uj;so.prototype.clone=so.prototype.clone;so.prototype.getCoordinates=so.prototype.Z;so.prototype.getPoint=so.prototype.mk;so.prototype.getPoints=so.prototype.ee;so.prototype.getType=so.prototype.X;so.prototype.intersectsExtent=so.prototype.Ia;so.prototype.setCoordinates=so.prototype.ma;t("ol.geom.MultiPolygon",to,OPENLAYERS);to.prototype.appendPolygon=to.prototype.vj; +to.prototype.clone=to.prototype.clone;to.prototype.getArea=to.prototype.jm;to.prototype.getCoordinates=to.prototype.Z;to.prototype.getInteriorPoints=to.prototype.Zj;to.prototype.getPolygon=to.prototype.pk;to.prototype.getPolygons=to.prototype.Qd;to.prototype.getType=to.prototype.X;to.prototype.intersectsExtent=to.prototype.Ia;to.prototype.setCoordinates=to.prototype.ma;t("ol.geom.Point",D,OPENLAYERS);D.prototype.clone=D.prototype.clone;D.prototype.getCoordinates=D.prototype.Z; +D.prototype.getType=D.prototype.X;D.prototype.intersectsExtent=D.prototype.Ia;D.prototype.setCoordinates=D.prototype.ma;t("ol.geom.Polygon",F,OPENLAYERS);F.prototype.appendLinearRing=F.prototype.tj;F.prototype.clone=F.prototype.clone;F.prototype.getArea=F.prototype.km;F.prototype.getCoordinates=F.prototype.Z;F.prototype.getInteriorPoint=F.prototype.Yj;F.prototype.getLinearRingCount=F.prototype.ck;F.prototype.getLinearRing=F.prototype.Cg;F.prototype.getLinearRings=F.prototype.Pd; +F.prototype.getType=F.prototype.X;F.prototype.intersectsExtent=F.prototype.Ia;F.prototype.setCoordinates=F.prototype.ma;t("ol.geom.Polygon.circular",Yd,OPENLAYERS);t("ol.geom.Polygon.fromExtent",Zd,OPENLAYERS);t("ol.geom.Polygon.fromCircle",$d,OPENLAYERS);t("ol.geom.SimpleGeometry",sd,OPENLAYERS);sd.prototype.getFirstCoordinate=sd.prototype.Fb;sd.prototype.getLastCoordinate=sd.prototype.Gb;sd.prototype.getLayout=sd.prototype.Hb;sd.prototype.applyTransform=sd.prototype.mc;sd.prototype.translate=sd.prototype.Nc; +t("ol.format.EsriJSON",wo,OPENLAYERS);wo.prototype.readFeature=wo.prototype.Nb;wo.prototype.readFeatures=wo.prototype.Ca;wo.prototype.readGeometry=wo.prototype.Qc;wo.prototype.readProjection=wo.prototype.Oa;wo.prototype.writeGeometry=wo.prototype.Uc;wo.prototype.writeGeometryObject=wo.prototype.Ge;wo.prototype.writeFeature=wo.prototype.yd;wo.prototype.writeFeatureObject=wo.prototype.Tc;wo.prototype.writeFeatures=wo.prototype.Sb;wo.prototype.writeFeaturesObject=wo.prototype.Ee; +t("ol.format.Feature",io,OPENLAYERS);t("ol.format.GeoJSON",Ho,OPENLAYERS);Ho.prototype.readFeature=Ho.prototype.Nb;Ho.prototype.readFeatures=Ho.prototype.Ca;Ho.prototype.readGeometry=Ho.prototype.Qc;Ho.prototype.readProjection=Ho.prototype.Oa;Ho.prototype.writeFeature=Ho.prototype.yd;Ho.prototype.writeFeatureObject=Ho.prototype.Tc;Ho.prototype.writeFeatures=Ho.prototype.Sb;Ho.prototype.writeFeaturesObject=Ho.prototype.Ee;Ho.prototype.writeGeometry=Ho.prototype.Uc; +Ho.prototype.writeGeometryObject=Ho.prototype.Ge;t("ol.format.GPX",lp,OPENLAYERS);lp.prototype.readFeature=lp.prototype.Nb;lp.prototype.readFeatures=lp.prototype.Ca;lp.prototype.readProjection=lp.prototype.Oa;lp.prototype.writeFeatures=lp.prototype.Sb;lp.prototype.writeFeaturesNode=lp.prototype.a;t("ol.format.IGC",Up,OPENLAYERS);Up.prototype.readFeature=Up.prototype.Nb;Up.prototype.readFeatures=Up.prototype.Ca;Up.prototype.readProjection=Up.prototype.Oa;t("ol.format.KML",Aq,OPENLAYERS); +Aq.prototype.readFeature=Aq.prototype.Nb;Aq.prototype.readFeatures=Aq.prototype.Ca;Aq.prototype.readName=Aq.prototype.zo;Aq.prototype.readNetworkLinks=Aq.prototype.Ao;Aq.prototype.readProjection=Aq.prototype.Oa;Aq.prototype.writeFeatures=Aq.prototype.Sb;Aq.prototype.writeFeaturesNode=Aq.prototype.a;t("ol.format.MVT",ps,OPENLAYERS);ps.prototype.readFeatures=ps.prototype.Ca;ps.prototype.readProjection=ps.prototype.Oa;ps.prototype.setLayers=ps.prototype.c;t("ol.format.OSMXML",Ls,OPENLAYERS); +Ls.prototype.readFeatures=Ls.prototype.Ca;Ls.prototype.readProjection=Ls.prototype.Oa;t("ol.format.Polyline",jt,OPENLAYERS);t("ol.format.Polyline.encodeDeltas",kt,OPENLAYERS);t("ol.format.Polyline.decodeDeltas",mt,OPENLAYERS);t("ol.format.Polyline.encodeFloats",lt,OPENLAYERS);t("ol.format.Polyline.decodeFloats",nt,OPENLAYERS);jt.prototype.readFeature=jt.prototype.Nb;jt.prototype.readFeatures=jt.prototype.Ca;jt.prototype.readGeometry=jt.prototype.Qc;jt.prototype.readProjection=jt.prototype.Oa; +jt.prototype.writeGeometry=jt.prototype.Uc;t("ol.format.TopoJSON",ot,OPENLAYERS);ot.prototype.readFeatures=ot.prototype.Ca;ot.prototype.readProjection=ot.prototype.Oa;t("ol.format.WFS",vt,OPENLAYERS);vt.prototype.readFeatures=vt.prototype.Ca;vt.prototype.readTransactionResponse=vt.prototype.o;vt.prototype.readFeatureCollectionMetadata=vt.prototype.l;vt.prototype.writeGetFeature=vt.prototype.j;vt.prototype.writeTransaction=vt.prototype.U;vt.prototype.readProjection=vt.prototype.Oa; +t("ol.format.WKT",Mt,OPENLAYERS);Mt.prototype.readFeature=Mt.prototype.Nb;Mt.prototype.readFeatures=Mt.prototype.Ca;Mt.prototype.readGeometry=Mt.prototype.Qc;Mt.prototype.writeFeature=Mt.prototype.yd;Mt.prototype.writeFeatures=Mt.prototype.Sb;Mt.prototype.writeGeometry=Mt.prototype.Uc;t("ol.format.WMSCapabilities",cu,OPENLAYERS);cu.prototype.read=cu.prototype.read;t("ol.format.WMSGetFeatureInfo",zu,OPENLAYERS);zu.prototype.readFeatures=zu.prototype.Ca;t("ol.format.WMTSCapabilities",Au,OPENLAYERS); +Au.prototype.read=Au.prototype.read;t("ol.format.ogc.filter.and",rs,OPENLAYERS);t("ol.format.ogc.filter.or",function(a,c){return new ys(a,c)},OPENLAYERS);t("ol.format.ogc.filter.not",function(a){return new zs(a)},OPENLAYERS);t("ol.format.ogc.filter.bbox",ts,OPENLAYERS);t("ol.format.ogc.filter.equalTo",function(a,c,d){return new Cs(a,c,d)},OPENLAYERS);t("ol.format.ogc.filter.notEqualTo",function(a,c,d){return new Ds(a,c,d)},OPENLAYERS); +t("ol.format.ogc.filter.lessThan",function(a,c){return new Es(a,c)},OPENLAYERS);t("ol.format.ogc.filter.lessThanOrEqualTo",function(a,c){return new Fs(a,c)},OPENLAYERS);t("ol.format.ogc.filter.greaterThan",function(a,c){return new Gs(a,c)},OPENLAYERS);t("ol.format.ogc.filter.greaterThanOrEqualTo",function(a,c){return new Hs(a,c)},OPENLAYERS);t("ol.format.ogc.filter.isNull",function(a){return new Is(a)},OPENLAYERS);t("ol.format.ogc.filter.between",function(a,c,d){return new Js(a,c,d)},OPENLAYERS); +t("ol.format.ogc.filter.like",function(a,c,d,e,f,g){return new Ks(a,c,d,e,f,g)},OPENLAYERS);t("ol.format.ogc.filter.Filter",vs,OPENLAYERS);t("ol.format.ogc.filter.And",ss,OPENLAYERS);t("ol.format.ogc.filter.Or",ys,OPENLAYERS);t("ol.format.ogc.filter.Not",zs,OPENLAYERS);t("ol.format.ogc.filter.Bbox",us,OPENLAYERS);t("ol.format.ogc.filter.Comparison",As,OPENLAYERS);t("ol.format.ogc.filter.ComparisonBinary",Bs,OPENLAYERS);t("ol.format.ogc.filter.EqualTo",Cs,OPENLAYERS); +t("ol.format.ogc.filter.NotEqualTo",Ds,OPENLAYERS);t("ol.format.ogc.filter.LessThan",Es,OPENLAYERS);t("ol.format.ogc.filter.LessThanOrEqualTo",Fs,OPENLAYERS);t("ol.format.ogc.filter.GreaterThan",Gs,OPENLAYERS);t("ol.format.ogc.filter.GreaterThanOrEqualTo",Hs,OPENLAYERS);t("ol.format.ogc.filter.IsNull",Is,OPENLAYERS);t("ol.format.ogc.filter.IsBetween",Js,OPENLAYERS);t("ol.format.ogc.filter.IsLike",Ks,OPENLAYERS);t("ol.format.GML2",bp,OPENLAYERS);t("ol.format.GML3",cp,OPENLAYERS); +cp.prototype.writeGeometryNode=cp.prototype.s;cp.prototype.writeFeatures=cp.prototype.Sb;cp.prototype.writeFeaturesNode=cp.prototype.a;t("ol.format.GML",cp,OPENLAYERS);cp.prototype.writeFeatures=cp.prototype.Sb;cp.prototype.writeFeaturesNode=cp.prototype.a;Po.prototype.readFeatures=Po.prototype.Ca;t("ol.events.condition.altKeyOnly",function(a){a=a.originalEvent;return a.altKey&&!(a.metaKey||a.ctrlKey)&&!a.shiftKey},OPENLAYERS);t("ol.events.condition.altShiftKeysOnly",Si,OPENLAYERS); +t("ol.events.condition.always",Ac,OPENLAYERS);t("ol.events.condition.click",function(a){return a.type==Qh},OPENLAYERS);t("ol.events.condition.never",Bc,OPENLAYERS);t("ol.events.condition.pointerMove",Ui,OPENLAYERS);t("ol.events.condition.singleClick",Vi,OPENLAYERS);t("ol.events.condition.doubleClick",function(a){return a.type==Rh},OPENLAYERS);t("ol.events.condition.noModifierKeys",Wi,OPENLAYERS); +t("ol.events.condition.platformModifierKeyOnly",function(a){a=a.originalEvent;return!a.altKey&&(Xg?a.metaKey:a.ctrlKey)&&!a.shiftKey},OPENLAYERS);t("ol.events.condition.shiftKeyOnly",Xi,OPENLAYERS);t("ol.events.condition.targetNotEditable",Yi,OPENLAYERS);t("ol.events.condition.mouseOnly",Zi,OPENLAYERS);t("ol.events.condition.primaryAction",$i,OPENLAYERS);gb.prototype.type=gb.prototype.type;gb.prototype.target=gb.prototype.target;gb.prototype.preventDefault=gb.prototype.preventDefault; +gb.prototype.stopPropagation=gb.prototype.stopPropagation;t("ol.control.Attribution",qg,OPENLAYERS);t("ol.control.Attribution.render",rg,OPENLAYERS);qg.prototype.getCollapsible=qg.prototype.Ul;qg.prototype.setCollapsible=qg.prototype.Xl;qg.prototype.setCollapsed=qg.prototype.Wl;qg.prototype.getCollapsed=qg.prototype.Tl;t("ol.control.Control",Jf,OPENLAYERS);Jf.prototype.getMap=Jf.prototype.i;Jf.prototype.setMap=Jf.prototype.setMap;Jf.prototype.setTarget=Jf.prototype.c;t("ol.control.defaults",wg,OPENLAYERS); +t("ol.control.FullScreen",Bg,OPENLAYERS);t("ol.control.MousePosition",Cg,OPENLAYERS);t("ol.control.MousePosition.render",Dg,OPENLAYERS);Cg.prototype.getCoordinateFormat=Cg.prototype.xg;Cg.prototype.getProjection=Cg.prototype.bh;Cg.prototype.setCoordinateFormat=Cg.prototype.$h;Cg.prototype.setProjection=Cg.prototype.dh;t("ol.control.OverviewMap",Sn,OPENLAYERS);t("ol.control.OverviewMap.render",Tn,OPENLAYERS);Sn.prototype.getCollapsible=Sn.prototype.$l;Sn.prototype.setCollapsible=Sn.prototype.cm; +Sn.prototype.setCollapsed=Sn.prototype.bm;Sn.prototype.getCollapsed=Sn.prototype.Zl;Sn.prototype.getOverviewMap=Sn.prototype.kk;t("ol.control.Rotate",tg,OPENLAYERS);t("ol.control.Rotate.render",ug,OPENLAYERS);t("ol.control.ScaleLine",Xn,OPENLAYERS);Xn.prototype.getUnits=Xn.prototype.vb;t("ol.control.ScaleLine.render",Yn,OPENLAYERS);Xn.prototype.setUnits=Xn.prototype.N;t("ol.control.Zoom",vg,OPENLAYERS);t("ol.control.ZoomSlider",ao,OPENLAYERS);t("ol.control.ZoomSlider.render",co,OPENLAYERS); +t("ol.control.ZoomToExtent",go,OPENLAYERS);t("ol.color.asArray",Fe,OPENLAYERS);t("ol.color.asString",He,OPENLAYERS);ve.prototype.type=ve.prototype.type;ve.prototype.target=ve.prototype.target;ve.prototype.preventDefault=ve.prototype.preventDefault;ve.prototype.stopPropagation=ve.prototype.stopPropagation;pb.prototype.changed=pb.prototype.u;pb.prototype.dispatchEvent=pb.prototype.b;pb.prototype.getRevision=pb.prototype.H;pb.prototype.on=pb.prototype.D;pb.prototype.once=pb.prototype.I; +pb.prototype.un=pb.prototype.G;pb.prototype.unByKey=pb.prototype.J;we.prototype.get=we.prototype.get;we.prototype.getKeys=we.prototype.K;we.prototype.getProperties=we.prototype.L;we.prototype.set=we.prototype.set;we.prototype.setProperties=we.prototype.C;we.prototype.unset=we.prototype.P;we.prototype.changed=we.prototype.u;we.prototype.dispatchEvent=we.prototype.b;we.prototype.getRevision=we.prototype.H;we.prototype.on=we.prototype.D;we.prototype.once=we.prototype.I;we.prototype.un=we.prototype.G; +we.prototype.unByKey=we.prototype.J;ho.prototype.get=ho.prototype.get;ho.prototype.getKeys=ho.prototype.K;ho.prototype.getProperties=ho.prototype.L;ho.prototype.set=ho.prototype.set;ho.prototype.setProperties=ho.prototype.C;ho.prototype.unset=ho.prototype.P;ho.prototype.changed=ho.prototype.u;ho.prototype.dispatchEvent=ho.prototype.b;ho.prototype.getRevision=ho.prototype.H;ho.prototype.on=ho.prototype.D;ho.prototype.once=ho.prototype.I;ho.prototype.un=ho.prototype.G;ho.prototype.unByKey=ho.prototype.J; +zl.prototype.get=zl.prototype.get;zl.prototype.getKeys=zl.prototype.K;zl.prototype.getProperties=zl.prototype.L;zl.prototype.set=zl.prototype.set;zl.prototype.setProperties=zl.prototype.C;zl.prototype.unset=zl.prototype.P;zl.prototype.changed=zl.prototype.u;zl.prototype.dispatchEvent=zl.prototype.b;zl.prototype.getRevision=zl.prototype.H;zl.prototype.on=zl.prototype.D;zl.prototype.once=zl.prototype.I;zl.prototype.un=zl.prototype.G;zl.prototype.unByKey=zl.prototype.J;Nu.prototype.get=Nu.prototype.get; +Nu.prototype.getKeys=Nu.prototype.K;Nu.prototype.getProperties=Nu.prototype.L;Nu.prototype.set=Nu.prototype.set;Nu.prototype.setProperties=Nu.prototype.C;Nu.prototype.unset=Nu.prototype.P;Nu.prototype.changed=Nu.prototype.u;Nu.prototype.dispatchEvent=Nu.prototype.b;Nu.prototype.getRevision=Nu.prototype.H;Nu.prototype.on=Nu.prototype.D;Nu.prototype.once=Nu.prototype.I;Nu.prototype.un=Nu.prototype.G;Nu.prototype.unByKey=Nu.prototype.J;Zu.prototype.getTileCoord=Zu.prototype.i;S.prototype.get=S.prototype.get; +S.prototype.getKeys=S.prototype.K;S.prototype.getProperties=S.prototype.L;S.prototype.set=S.prototype.set;S.prototype.setProperties=S.prototype.C;S.prototype.unset=S.prototype.P;S.prototype.changed=S.prototype.u;S.prototype.dispatchEvent=S.prototype.b;S.prototype.getRevision=S.prototype.H;S.prototype.on=S.prototype.D;S.prototype.once=S.prototype.I;S.prototype.un=S.prototype.G;S.prototype.unByKey=S.prototype.J;If.prototype.type=If.prototype.type;If.prototype.target=If.prototype.target; +If.prototype.preventDefault=If.prototype.preventDefault;If.prototype.stopPropagation=If.prototype.stopPropagation;Mh.prototype.map=Mh.prototype.map;Mh.prototype.frameState=Mh.prototype.frameState;Mh.prototype.type=Mh.prototype.type;Mh.prototype.target=Mh.prototype.target;Mh.prototype.preventDefault=Mh.prototype.preventDefault;Mh.prototype.stopPropagation=Mh.prototype.stopPropagation;Nh.prototype.originalEvent=Nh.prototype.originalEvent;Nh.prototype.pixel=Nh.prototype.pixel; +Nh.prototype.coordinate=Nh.prototype.coordinate;Nh.prototype.dragging=Nh.prototype.dragging;Nh.prototype.preventDefault=Nh.prototype.preventDefault;Nh.prototype.stopPropagation=Nh.prototype.stopPropagation;Nh.prototype.map=Nh.prototype.map;Nh.prototype.frameState=Nh.prototype.frameState;Nh.prototype.type=Nh.prototype.type;Nh.prototype.target=Nh.prototype.target;ob.prototype.type=ob.prototype.type;ob.prototype.target=ob.prototype.target;ob.prototype.preventDefault=ob.prototype.preventDefault; +ob.prototype.stopPropagation=ob.prototype.stopPropagation;On.prototype.get=On.prototype.get;On.prototype.getKeys=On.prototype.K;On.prototype.getProperties=On.prototype.L;On.prototype.set=On.prototype.set;On.prototype.setProperties=On.prototype.C;On.prototype.unset=On.prototype.P;On.prototype.changed=On.prototype.u;On.prototype.dispatchEvent=On.prototype.b;On.prototype.getRevision=On.prototype.H;On.prototype.on=On.prototype.D;On.prototype.once=On.prototype.I;On.prototype.un=On.prototype.G; +On.prototype.unByKey=On.prototype.J;Bl.prototype.getTileCoord=Bl.prototype.i;be.prototype.get=be.prototype.get;be.prototype.getKeys=be.prototype.K;be.prototype.getProperties=be.prototype.L;be.prototype.set=be.prototype.set;be.prototype.setProperties=be.prototype.C;be.prototype.unset=be.prototype.P;be.prototype.changed=be.prototype.u;be.prototype.dispatchEvent=be.prototype.b;be.prototype.getRevision=be.prototype.H;be.prototype.on=be.prototype.D;be.prototype.once=be.prototype.I;be.prototype.un=be.prototype.G; +be.prototype.unByKey=be.prototype.J;ax.prototype.getMaxZoom=ax.prototype.Dg;ax.prototype.getMinZoom=ax.prototype.Eg;ax.prototype.getOrigin=ax.prototype.Fa;ax.prototype.getResolution=ax.prototype.$;ax.prototype.getResolutions=ax.prototype.Fh;ax.prototype.getTileCoordExtent=ax.prototype.Ba;ax.prototype.getTileCoordForCoordAndResolution=ax.prototype.Td;ax.prototype.getTileCoordForCoordAndZ=ax.prototype.kd;ax.prototype.getTileSize=ax.prototype.Ha;ik.prototype.getOpacity=ik.prototype.le; +ik.prototype.getRotateWithView=ik.prototype.Rd;ik.prototype.getRotation=ik.prototype.me;ik.prototype.getScale=ik.prototype.ne;ik.prototype.getSnapToPixel=ik.prototype.Sd;ik.prototype.setOpacity=ik.prototype.oe;ik.prototype.setRotation=ik.prototype.pe;ik.prototype.setScale=ik.prototype.qe;ui.prototype.getOpacity=ui.prototype.le;ui.prototype.getRotateWithView=ui.prototype.Rd;ui.prototype.getRotation=ui.prototype.me;ui.prototype.getScale=ui.prototype.ne;ui.prototype.getSnapToPixel=ui.prototype.Sd; +ui.prototype.setOpacity=ui.prototype.oe;ui.prototype.setRotation=ui.prototype.pe;ui.prototype.setScale=ui.prototype.qe;jx.prototype.getOpacity=jx.prototype.le;jx.prototype.getRotateWithView=jx.prototype.Rd;jx.prototype.getRotation=jx.prototype.me;jx.prototype.getScale=jx.prototype.ne;jx.prototype.getSnapToPixel=jx.prototype.Sd;jx.prototype.setOpacity=jx.prototype.oe;jx.prototype.setRotation=jx.prototype.pe;jx.prototype.setScale=jx.prototype.qe;Vf.prototype.get=Vf.prototype.get; +Vf.prototype.getKeys=Vf.prototype.K;Vf.prototype.getProperties=Vf.prototype.L;Vf.prototype.set=Vf.prototype.set;Vf.prototype.setProperties=Vf.prototype.C;Vf.prototype.unset=Vf.prototype.P;Vf.prototype.changed=Vf.prototype.u;Vf.prototype.dispatchEvent=Vf.prototype.b;Vf.prototype.getRevision=Vf.prototype.H;Vf.prototype.on=Vf.prototype.D;Vf.prototype.once=Vf.prototype.I;Vf.prototype.un=Vf.prototype.G;Vf.prototype.unByKey=Vf.prototype.J;lg.prototype.getAttributions=lg.prototype.ra; +lg.prototype.getLogo=lg.prototype.qa;lg.prototype.getProjection=lg.prototype.sa;lg.prototype.getState=lg.prototype.V;lg.prototype.refresh=lg.prototype.pa;lg.prototype.setAttributions=lg.prototype.ka;lg.prototype.get=lg.prototype.get;lg.prototype.getKeys=lg.prototype.K;lg.prototype.getProperties=lg.prototype.L;lg.prototype.set=lg.prototype.set;lg.prototype.setProperties=lg.prototype.C;lg.prototype.unset=lg.prototype.P;lg.prototype.changed=lg.prototype.u;lg.prototype.dispatchEvent=lg.prototype.b; +lg.prototype.getRevision=lg.prototype.H;lg.prototype.on=lg.prototype.D;lg.prototype.once=lg.prototype.I;lg.prototype.un=lg.prototype.G;lg.prototype.unByKey=lg.prototype.J;zm.prototype.getTileGrid=zm.prototype.Ga;zm.prototype.refresh=zm.prototype.pa;zm.prototype.getAttributions=zm.prototype.ra;zm.prototype.getLogo=zm.prototype.qa;zm.prototype.getProjection=zm.prototype.sa;zm.prototype.getState=zm.prototype.V;zm.prototype.setAttributions=zm.prototype.ka;zm.prototype.get=zm.prototype.get; +zm.prototype.getKeys=zm.prototype.K;zm.prototype.getProperties=zm.prototype.L;zm.prototype.set=zm.prototype.set;zm.prototype.setProperties=zm.prototype.C;zm.prototype.unset=zm.prototype.P;zm.prototype.changed=zm.prototype.u;zm.prototype.dispatchEvent=zm.prototype.b;zm.prototype.getRevision=zm.prototype.H;zm.prototype.on=zm.prototype.D;zm.prototype.once=zm.prototype.I;zm.prototype.un=zm.prototype.G;zm.prototype.unByKey=zm.prototype.J;X.prototype.getTileLoadFunction=X.prototype.Xa; +X.prototype.getTileUrlFunction=X.prototype.Ya;X.prototype.getUrls=X.prototype.Za;X.prototype.setTileLoadFunction=X.prototype.cb;X.prototype.setTileUrlFunction=X.prototype.La;X.prototype.setUrl=X.prototype.Na;X.prototype.setUrls=X.prototype.Ua;X.prototype.getTileGrid=X.prototype.Ga;X.prototype.refresh=X.prototype.pa;X.prototype.getAttributions=X.prototype.ra;X.prototype.getLogo=X.prototype.qa;X.prototype.getProjection=X.prototype.sa;X.prototype.getState=X.prototype.V;X.prototype.setAttributions=X.prototype.ka; +X.prototype.get=X.prototype.get;X.prototype.getKeys=X.prototype.K;X.prototype.getProperties=X.prototype.L;X.prototype.set=X.prototype.set;X.prototype.setProperties=X.prototype.C;X.prototype.unset=X.prototype.P;X.prototype.changed=X.prototype.u;X.prototype.dispatchEvent=X.prototype.b;X.prototype.getRevision=X.prototype.H;X.prototype.on=X.prototype.D;X.prototype.once=X.prototype.I;X.prototype.un=X.prototype.G;X.prototype.unByKey=X.prototype.J;iw.prototype.setRenderReprojectionEdges=iw.prototype.lb; +iw.prototype.setTileGridForProjection=iw.prototype.mb;iw.prototype.getTileLoadFunction=iw.prototype.Xa;iw.prototype.getTileUrlFunction=iw.prototype.Ya;iw.prototype.getUrls=iw.prototype.Za;iw.prototype.setTileLoadFunction=iw.prototype.cb;iw.prototype.setTileUrlFunction=iw.prototype.La;iw.prototype.setUrl=iw.prototype.Na;iw.prototype.setUrls=iw.prototype.Ua;iw.prototype.getTileGrid=iw.prototype.Ga;iw.prototype.refresh=iw.prototype.pa;iw.prototype.getAttributions=iw.prototype.ra; +iw.prototype.getLogo=iw.prototype.qa;iw.prototype.getProjection=iw.prototype.sa;iw.prototype.getState=iw.prototype.V;iw.prototype.setAttributions=iw.prototype.ka;iw.prototype.get=iw.prototype.get;iw.prototype.getKeys=iw.prototype.K;iw.prototype.getProperties=iw.prototype.L;iw.prototype.set=iw.prototype.set;iw.prototype.setProperties=iw.prototype.C;iw.prototype.unset=iw.prototype.P;iw.prototype.changed=iw.prototype.u;iw.prototype.dispatchEvent=iw.prototype.b;iw.prototype.getRevision=iw.prototype.H; +iw.prototype.on=iw.prototype.D;iw.prototype.once=iw.prototype.I;iw.prototype.un=iw.prototype.G;iw.prototype.unByKey=iw.prototype.J;kw.prototype.setRenderReprojectionEdges=kw.prototype.lb;kw.prototype.setTileGridForProjection=kw.prototype.mb;kw.prototype.getTileLoadFunction=kw.prototype.Xa;kw.prototype.getTileUrlFunction=kw.prototype.Ya;kw.prototype.getUrls=kw.prototype.Za;kw.prototype.setTileLoadFunction=kw.prototype.cb;kw.prototype.setTileUrlFunction=kw.prototype.La;kw.prototype.setUrl=kw.prototype.Na; +kw.prototype.setUrls=kw.prototype.Ua;kw.prototype.getTileGrid=kw.prototype.Ga;kw.prototype.refresh=kw.prototype.pa;kw.prototype.getAttributions=kw.prototype.ra;kw.prototype.getLogo=kw.prototype.qa;kw.prototype.getProjection=kw.prototype.sa;kw.prototype.getState=kw.prototype.V;kw.prototype.setAttributions=kw.prototype.ka;kw.prototype.get=kw.prototype.get;kw.prototype.getKeys=kw.prototype.K;kw.prototype.getProperties=kw.prototype.L;kw.prototype.set=kw.prototype.set;kw.prototype.setProperties=kw.prototype.C; +kw.prototype.unset=kw.prototype.P;kw.prototype.changed=kw.prototype.u;kw.prototype.dispatchEvent=kw.prototype.b;kw.prototype.getRevision=kw.prototype.H;kw.prototype.on=kw.prototype.D;kw.prototype.once=kw.prototype.I;kw.prototype.un=kw.prototype.G;kw.prototype.unByKey=kw.prototype.J;lw.prototype.setRenderReprojectionEdges=lw.prototype.lb;lw.prototype.setTileGridForProjection=lw.prototype.mb;lw.prototype.getTileLoadFunction=lw.prototype.Xa;lw.prototype.getTileUrlFunction=lw.prototype.Ya; +lw.prototype.getUrls=lw.prototype.Za;lw.prototype.setTileLoadFunction=lw.prototype.cb;lw.prototype.setTileUrlFunction=lw.prototype.La;lw.prototype.setUrl=lw.prototype.Na;lw.prototype.setUrls=lw.prototype.Ua;lw.prototype.getTileGrid=lw.prototype.Ga;lw.prototype.refresh=lw.prototype.pa;lw.prototype.getAttributions=lw.prototype.ra;lw.prototype.getLogo=lw.prototype.qa;lw.prototype.getProjection=lw.prototype.sa;lw.prototype.getState=lw.prototype.V;lw.prototype.setAttributions=lw.prototype.ka; +lw.prototype.get=lw.prototype.get;lw.prototype.getKeys=lw.prototype.K;lw.prototype.getProperties=lw.prototype.L;lw.prototype.set=lw.prototype.set;lw.prototype.setProperties=lw.prototype.C;lw.prototype.unset=lw.prototype.P;lw.prototype.changed=lw.prototype.u;lw.prototype.dispatchEvent=lw.prototype.b;lw.prototype.getRevision=lw.prototype.H;lw.prototype.on=lw.prototype.D;lw.prototype.once=lw.prototype.I;lw.prototype.un=lw.prototype.G;lw.prototype.unByKey=lw.prototype.J;Q.prototype.getAttributions=Q.prototype.ra; +Q.prototype.getLogo=Q.prototype.qa;Q.prototype.getProjection=Q.prototype.sa;Q.prototype.getState=Q.prototype.V;Q.prototype.refresh=Q.prototype.pa;Q.prototype.setAttributions=Q.prototype.ka;Q.prototype.get=Q.prototype.get;Q.prototype.getKeys=Q.prototype.K;Q.prototype.getProperties=Q.prototype.L;Q.prototype.set=Q.prototype.set;Q.prototype.setProperties=Q.prototype.C;Q.prototype.unset=Q.prototype.P;Q.prototype.changed=Q.prototype.u;Q.prototype.dispatchEvent=Q.prototype.b;Q.prototype.getRevision=Q.prototype.H; +Q.prototype.on=Q.prototype.D;Q.prototype.once=Q.prototype.I;Q.prototype.un=Q.prototype.G;Q.prototype.unByKey=Q.prototype.J;Y.prototype.addFeature=Y.prototype.qb;Y.prototype.addFeatures=Y.prototype.Ec;Y.prototype.clear=Y.prototype.clear;Y.prototype.forEachFeature=Y.prototype.sg;Y.prototype.forEachFeatureInExtent=Y.prototype.tb;Y.prototype.forEachFeatureIntersectingExtent=Y.prototype.tg;Y.prototype.getFeaturesCollection=Y.prototype.Ag;Y.prototype.getFeatures=Y.prototype.je; +Y.prototype.getFeaturesAtCoordinate=Y.prototype.zg;Y.prototype.getFeaturesInExtent=Y.prototype.af;Y.prototype.getClosestFeatureToCoordinate=Y.prototype.vg;Y.prototype.getExtent=Y.prototype.O;Y.prototype.getFeatureById=Y.prototype.yg;Y.prototype.getFormat=Y.prototype.xh;Y.prototype.getUrl=Y.prototype.yh;Y.prototype.removeFeature=Y.prototype.kb;Y.prototype.getAttributions=Y.prototype.ra;Y.prototype.getLogo=Y.prototype.qa;Y.prototype.getProjection=Y.prototype.sa;Y.prototype.getState=Y.prototype.V; +Y.prototype.refresh=Y.prototype.pa;Y.prototype.setAttributions=Y.prototype.ka;Y.prototype.get=Y.prototype.get;Y.prototype.getKeys=Y.prototype.K;Y.prototype.getProperties=Y.prototype.L;Y.prototype.set=Y.prototype.set;Y.prototype.setProperties=Y.prototype.C;Y.prototype.unset=Y.prototype.P;Y.prototype.changed=Y.prototype.u;Y.prototype.dispatchEvent=Y.prototype.b;Y.prototype.getRevision=Y.prototype.H;Y.prototype.on=Y.prototype.D;Y.prototype.once=Y.prototype.I;Y.prototype.un=Y.prototype.G; +Y.prototype.unByKey=Y.prototype.J;rl.prototype.getAttributions=rl.prototype.ra;rl.prototype.getLogo=rl.prototype.qa;rl.prototype.getProjection=rl.prototype.sa;rl.prototype.getState=rl.prototype.V;rl.prototype.refresh=rl.prototype.pa;rl.prototype.setAttributions=rl.prototype.ka;rl.prototype.get=rl.prototype.get;rl.prototype.getKeys=rl.prototype.K;rl.prototype.getProperties=rl.prototype.L;rl.prototype.set=rl.prototype.set;rl.prototype.setProperties=rl.prototype.C;rl.prototype.unset=rl.prototype.P; +rl.prototype.changed=rl.prototype.u;rl.prototype.dispatchEvent=rl.prototype.b;rl.prototype.getRevision=rl.prototype.H;rl.prototype.on=rl.prototype.D;rl.prototype.once=rl.prototype.I;rl.prototype.un=rl.prototype.G;rl.prototype.unByKey=rl.prototype.J;qw.prototype.getAttributions=qw.prototype.ra;qw.prototype.getLogo=qw.prototype.qa;qw.prototype.getProjection=qw.prototype.sa;qw.prototype.getState=qw.prototype.V;qw.prototype.refresh=qw.prototype.pa;qw.prototype.setAttributions=qw.prototype.ka; +qw.prototype.get=qw.prototype.get;qw.prototype.getKeys=qw.prototype.K;qw.prototype.getProperties=qw.prototype.L;qw.prototype.set=qw.prototype.set;qw.prototype.setProperties=qw.prototype.C;qw.prototype.unset=qw.prototype.P;qw.prototype.changed=qw.prototype.u;qw.prototype.dispatchEvent=qw.prototype.b;qw.prototype.getRevision=qw.prototype.H;qw.prototype.on=qw.prototype.D;qw.prototype.once=qw.prototype.I;qw.prototype.un=qw.prototype.G;qw.prototype.unByKey=qw.prototype.J;yl.prototype.getAttributions=yl.prototype.ra; +yl.prototype.getLogo=yl.prototype.qa;yl.prototype.getProjection=yl.prototype.sa;yl.prototype.getState=yl.prototype.V;yl.prototype.refresh=yl.prototype.pa;yl.prototype.setAttributions=yl.prototype.ka;yl.prototype.get=yl.prototype.get;yl.prototype.getKeys=yl.prototype.K;yl.prototype.getProperties=yl.prototype.L;yl.prototype.set=yl.prototype.set;yl.prototype.setProperties=yl.prototype.C;yl.prototype.unset=yl.prototype.P;yl.prototype.changed=yl.prototype.u;yl.prototype.dispatchEvent=yl.prototype.b; +yl.prototype.getRevision=yl.prototype.H;yl.prototype.on=yl.prototype.D;yl.prototype.once=yl.prototype.I;yl.prototype.un=yl.prototype.G;yl.prototype.unByKey=yl.prototype.J;rw.prototype.getAttributions=rw.prototype.ra;rw.prototype.getLogo=rw.prototype.qa;rw.prototype.getProjection=rw.prototype.sa;rw.prototype.getState=rw.prototype.V;rw.prototype.refresh=rw.prototype.pa;rw.prototype.setAttributions=rw.prototype.ka;rw.prototype.get=rw.prototype.get;rw.prototype.getKeys=rw.prototype.K; +rw.prototype.getProperties=rw.prototype.L;rw.prototype.set=rw.prototype.set;rw.prototype.setProperties=rw.prototype.C;rw.prototype.unset=rw.prototype.P;rw.prototype.changed=rw.prototype.u;rw.prototype.dispatchEvent=rw.prototype.b;rw.prototype.getRevision=rw.prototype.H;rw.prototype.on=rw.prototype.D;rw.prototype.once=rw.prototype.I;rw.prototype.un=rw.prototype.G;rw.prototype.unByKey=rw.prototype.J;tl.prototype.type=tl.prototype.type;tl.prototype.target=tl.prototype.target; +tl.prototype.preventDefault=tl.prototype.preventDefault;tl.prototype.stopPropagation=tl.prototype.stopPropagation;sw.prototype.getAttributions=sw.prototype.ra;sw.prototype.getLogo=sw.prototype.qa;sw.prototype.getProjection=sw.prototype.sa;sw.prototype.getState=sw.prototype.V;sw.prototype.refresh=sw.prototype.pa;sw.prototype.setAttributions=sw.prototype.ka;sw.prototype.get=sw.prototype.get;sw.prototype.getKeys=sw.prototype.K;sw.prototype.getProperties=sw.prototype.L;sw.prototype.set=sw.prototype.set; +sw.prototype.setProperties=sw.prototype.C;sw.prototype.unset=sw.prototype.P;sw.prototype.changed=sw.prototype.u;sw.prototype.dispatchEvent=sw.prototype.b;sw.prototype.getRevision=sw.prototype.H;sw.prototype.on=sw.prototype.D;sw.prototype.once=sw.prototype.I;sw.prototype.un=sw.prototype.G;sw.prototype.unByKey=sw.prototype.J;om.prototype.getAttributions=om.prototype.ra;om.prototype.getLogo=om.prototype.qa;om.prototype.getProjection=om.prototype.sa;om.prototype.getState=om.prototype.V; +om.prototype.refresh=om.prototype.pa;om.prototype.setAttributions=om.prototype.ka;om.prototype.get=om.prototype.get;om.prototype.getKeys=om.prototype.K;om.prototype.getProperties=om.prototype.L;om.prototype.set=om.prototype.set;om.prototype.setProperties=om.prototype.C;om.prototype.unset=om.prototype.P;om.prototype.changed=om.prototype.u;om.prototype.dispatchEvent=om.prototype.b;om.prototype.getRevision=om.prototype.H;om.prototype.on=om.prototype.D;om.prototype.once=om.prototype.I; +om.prototype.un=om.prototype.G;om.prototype.unByKey=om.prototype.J;tw.prototype.getAttributions=tw.prototype.ra;tw.prototype.getLogo=tw.prototype.qa;tw.prototype.getProjection=tw.prototype.sa;tw.prototype.getState=tw.prototype.V;tw.prototype.refresh=tw.prototype.pa;tw.prototype.setAttributions=tw.prototype.ka;tw.prototype.get=tw.prototype.get;tw.prototype.getKeys=tw.prototype.K;tw.prototype.getProperties=tw.prototype.L;tw.prototype.set=tw.prototype.set;tw.prototype.setProperties=tw.prototype.C; +tw.prototype.unset=tw.prototype.P;tw.prototype.changed=tw.prototype.u;tw.prototype.dispatchEvent=tw.prototype.b;tw.prototype.getRevision=tw.prototype.H;tw.prototype.on=tw.prototype.D;tw.prototype.once=tw.prototype.I;tw.prototype.un=tw.prototype.G;tw.prototype.unByKey=tw.prototype.J;zw.prototype.setRenderReprojectionEdges=zw.prototype.lb;zw.prototype.setTileGridForProjection=zw.prototype.mb;zw.prototype.getTileLoadFunction=zw.prototype.Xa;zw.prototype.getTileUrlFunction=zw.prototype.Ya; +zw.prototype.getUrls=zw.prototype.Za;zw.prototype.setTileLoadFunction=zw.prototype.cb;zw.prototype.setTileUrlFunction=zw.prototype.La;zw.prototype.setUrl=zw.prototype.Na;zw.prototype.setUrls=zw.prototype.Ua;zw.prototype.getTileGrid=zw.prototype.Ga;zw.prototype.refresh=zw.prototype.pa;zw.prototype.getAttributions=zw.prototype.ra;zw.prototype.getLogo=zw.prototype.qa;zw.prototype.getProjection=zw.prototype.sa;zw.prototype.getState=zw.prototype.V;zw.prototype.setAttributions=zw.prototype.ka; +zw.prototype.get=zw.prototype.get;zw.prototype.getKeys=zw.prototype.K;zw.prototype.getProperties=zw.prototype.L;zw.prototype.set=zw.prototype.set;zw.prototype.setProperties=zw.prototype.C;zw.prototype.unset=zw.prototype.P;zw.prototype.changed=zw.prototype.u;zw.prototype.dispatchEvent=zw.prototype.b;zw.prototype.getRevision=zw.prototype.H;zw.prototype.on=zw.prototype.D;zw.prototype.once=zw.prototype.I;zw.prototype.un=zw.prototype.G;zw.prototype.unByKey=zw.prototype.J; +xw.prototype.setRenderReprojectionEdges=xw.prototype.lb;xw.prototype.setTileGridForProjection=xw.prototype.mb;xw.prototype.getTileLoadFunction=xw.prototype.Xa;xw.prototype.getTileUrlFunction=xw.prototype.Ya;xw.prototype.getUrls=xw.prototype.Za;xw.prototype.setTileLoadFunction=xw.prototype.cb;xw.prototype.setTileUrlFunction=xw.prototype.La;xw.prototype.setUrl=xw.prototype.Na;xw.prototype.setUrls=xw.prototype.Ua;xw.prototype.getTileGrid=xw.prototype.Ga;xw.prototype.refresh=xw.prototype.pa; +xw.prototype.getAttributions=xw.prototype.ra;xw.prototype.getLogo=xw.prototype.qa;xw.prototype.getProjection=xw.prototype.sa;xw.prototype.getState=xw.prototype.V;xw.prototype.setAttributions=xw.prototype.ka;xw.prototype.get=xw.prototype.get;xw.prototype.getKeys=xw.prototype.K;xw.prototype.getProperties=xw.prototype.L;xw.prototype.set=xw.prototype.set;xw.prototype.setProperties=xw.prototype.C;xw.prototype.unset=xw.prototype.P;xw.prototype.changed=xw.prototype.u;xw.prototype.dispatchEvent=xw.prototype.b; +xw.prototype.getRevision=xw.prototype.H;xw.prototype.on=xw.prototype.D;xw.prototype.once=xw.prototype.I;xw.prototype.un=xw.prototype.G;xw.prototype.unByKey=xw.prototype.J;Cw.prototype.getAttributions=Cw.prototype.ra;Cw.prototype.getLogo=Cw.prototype.qa;Cw.prototype.getProjection=Cw.prototype.sa;Cw.prototype.getState=Cw.prototype.V;Cw.prototype.refresh=Cw.prototype.pa;Cw.prototype.setAttributions=Cw.prototype.ka;Cw.prototype.get=Cw.prototype.get;Cw.prototype.getKeys=Cw.prototype.K; +Cw.prototype.getProperties=Cw.prototype.L;Cw.prototype.set=Cw.prototype.set;Cw.prototype.setProperties=Cw.prototype.C;Cw.prototype.unset=Cw.prototype.P;Cw.prototype.changed=Cw.prototype.u;Cw.prototype.dispatchEvent=Cw.prototype.b;Cw.prototype.getRevision=Cw.prototype.H;Cw.prototype.on=Cw.prototype.D;Cw.prototype.once=Cw.prototype.I;Cw.prototype.un=Cw.prototype.G;Cw.prototype.unByKey=Cw.prototype.J;Hw.prototype.type=Hw.prototype.type;Hw.prototype.target=Hw.prototype.target; +Hw.prototype.preventDefault=Hw.prototype.preventDefault;Hw.prototype.stopPropagation=Hw.prototype.stopPropagation;Mw.prototype.setRenderReprojectionEdges=Mw.prototype.lb;Mw.prototype.setTileGridForProjection=Mw.prototype.mb;Mw.prototype.getTileLoadFunction=Mw.prototype.Xa;Mw.prototype.getTileUrlFunction=Mw.prototype.Ya;Mw.prototype.getUrls=Mw.prototype.Za;Mw.prototype.setTileLoadFunction=Mw.prototype.cb;Mw.prototype.setTileUrlFunction=Mw.prototype.La;Mw.prototype.setUrl=Mw.prototype.Na; +Mw.prototype.setUrls=Mw.prototype.Ua;Mw.prototype.getTileGrid=Mw.prototype.Ga;Mw.prototype.refresh=Mw.prototype.pa;Mw.prototype.getAttributions=Mw.prototype.ra;Mw.prototype.getLogo=Mw.prototype.qa;Mw.prototype.getProjection=Mw.prototype.sa;Mw.prototype.getState=Mw.prototype.V;Mw.prototype.setAttributions=Mw.prototype.ka;Mw.prototype.get=Mw.prototype.get;Mw.prototype.getKeys=Mw.prototype.K;Mw.prototype.getProperties=Mw.prototype.L;Mw.prototype.set=Mw.prototype.set;Mw.prototype.setProperties=Mw.prototype.C; +Mw.prototype.unset=Mw.prototype.P;Mw.prototype.changed=Mw.prototype.u;Mw.prototype.dispatchEvent=Mw.prototype.b;Mw.prototype.getRevision=Mw.prototype.H;Mw.prototype.on=Mw.prototype.D;Mw.prototype.once=Mw.prototype.I;Mw.prototype.un=Mw.prototype.G;Mw.prototype.unByKey=Mw.prototype.J;Ow.prototype.setRenderReprojectionEdges=Ow.prototype.lb;Ow.prototype.setTileGridForProjection=Ow.prototype.mb;Ow.prototype.getTileLoadFunction=Ow.prototype.Xa;Ow.prototype.getTileUrlFunction=Ow.prototype.Ya; +Ow.prototype.getUrls=Ow.prototype.Za;Ow.prototype.setTileLoadFunction=Ow.prototype.cb;Ow.prototype.setTileUrlFunction=Ow.prototype.La;Ow.prototype.setUrl=Ow.prototype.Na;Ow.prototype.setUrls=Ow.prototype.Ua;Ow.prototype.getTileGrid=Ow.prototype.Ga;Ow.prototype.refresh=Ow.prototype.pa;Ow.prototype.getAttributions=Ow.prototype.ra;Ow.prototype.getLogo=Ow.prototype.qa;Ow.prototype.getProjection=Ow.prototype.sa;Ow.prototype.getState=Ow.prototype.V;Ow.prototype.setAttributions=Ow.prototype.ka; +Ow.prototype.get=Ow.prototype.get;Ow.prototype.getKeys=Ow.prototype.K;Ow.prototype.getProperties=Ow.prototype.L;Ow.prototype.set=Ow.prototype.set;Ow.prototype.setProperties=Ow.prototype.C;Ow.prototype.unset=Ow.prototype.P;Ow.prototype.changed=Ow.prototype.u;Ow.prototype.dispatchEvent=Ow.prototype.b;Ow.prototype.getRevision=Ow.prototype.H;Ow.prototype.on=Ow.prototype.D;Ow.prototype.once=Ow.prototype.I;Ow.prototype.un=Ow.prototype.G;Ow.prototype.unByKey=Ow.prototype.J;Qw.prototype.getTileGrid=Qw.prototype.Ga; +Qw.prototype.refresh=Qw.prototype.pa;Qw.prototype.getAttributions=Qw.prototype.ra;Qw.prototype.getLogo=Qw.prototype.qa;Qw.prototype.getProjection=Qw.prototype.sa;Qw.prototype.getState=Qw.prototype.V;Qw.prototype.setAttributions=Qw.prototype.ka;Qw.prototype.get=Qw.prototype.get;Qw.prototype.getKeys=Qw.prototype.K;Qw.prototype.getProperties=Qw.prototype.L;Qw.prototype.set=Qw.prototype.set;Qw.prototype.setProperties=Qw.prototype.C;Qw.prototype.unset=Qw.prototype.P;Qw.prototype.changed=Qw.prototype.u; +Qw.prototype.dispatchEvent=Qw.prototype.b;Qw.prototype.getRevision=Qw.prototype.H;Qw.prototype.on=Qw.prototype.D;Qw.prototype.once=Qw.prototype.I;Qw.prototype.un=Qw.prototype.G;Qw.prototype.unByKey=Qw.prototype.J;Rw.prototype.setRenderReprojectionEdges=Rw.prototype.lb;Rw.prototype.setTileGridForProjection=Rw.prototype.mb;Rw.prototype.getTileLoadFunction=Rw.prototype.Xa;Rw.prototype.getTileUrlFunction=Rw.prototype.Ya;Rw.prototype.getUrls=Rw.prototype.Za;Rw.prototype.setTileLoadFunction=Rw.prototype.cb; +Rw.prototype.setTileUrlFunction=Rw.prototype.La;Rw.prototype.setUrl=Rw.prototype.Na;Rw.prototype.setUrls=Rw.prototype.Ua;Rw.prototype.getTileGrid=Rw.prototype.Ga;Rw.prototype.refresh=Rw.prototype.pa;Rw.prototype.getAttributions=Rw.prototype.ra;Rw.prototype.getLogo=Rw.prototype.qa;Rw.prototype.getProjection=Rw.prototype.sa;Rw.prototype.getState=Rw.prototype.V;Rw.prototype.setAttributions=Rw.prototype.ka;Rw.prototype.get=Rw.prototype.get;Rw.prototype.getKeys=Rw.prototype.K; +Rw.prototype.getProperties=Rw.prototype.L;Rw.prototype.set=Rw.prototype.set;Rw.prototype.setProperties=Rw.prototype.C;Rw.prototype.unset=Rw.prototype.P;Rw.prototype.changed=Rw.prototype.u;Rw.prototype.dispatchEvent=Rw.prototype.b;Rw.prototype.getRevision=Rw.prototype.H;Rw.prototype.on=Rw.prototype.D;Rw.prototype.once=Rw.prototype.I;Rw.prototype.un=Rw.prototype.G;Rw.prototype.unByKey=Rw.prototype.J;pg.prototype.type=pg.prototype.type;pg.prototype.target=pg.prototype.target; +pg.prototype.preventDefault=pg.prototype.preventDefault;pg.prototype.stopPropagation=pg.prototype.stopPropagation;Sw.prototype.getTileGrid=Sw.prototype.Ga;Sw.prototype.refresh=Sw.prototype.pa;Sw.prototype.getAttributions=Sw.prototype.ra;Sw.prototype.getLogo=Sw.prototype.qa;Sw.prototype.getProjection=Sw.prototype.sa;Sw.prototype.getState=Sw.prototype.V;Sw.prototype.setAttributions=Sw.prototype.ka;Sw.prototype.get=Sw.prototype.get;Sw.prototype.getKeys=Sw.prototype.K;Sw.prototype.getProperties=Sw.prototype.L; +Sw.prototype.set=Sw.prototype.set;Sw.prototype.setProperties=Sw.prototype.C;Sw.prototype.unset=Sw.prototype.P;Sw.prototype.changed=Sw.prototype.u;Sw.prototype.dispatchEvent=Sw.prototype.b;Sw.prototype.getRevision=Sw.prototype.H;Sw.prototype.on=Sw.prototype.D;Sw.prototype.once=Sw.prototype.I;Sw.prototype.un=Sw.prototype.G;Sw.prototype.unByKey=Sw.prototype.J;Ww.prototype.setRenderReprojectionEdges=Ww.prototype.lb;Ww.prototype.setTileGridForProjection=Ww.prototype.mb; +Ww.prototype.getTileLoadFunction=Ww.prototype.Xa;Ww.prototype.getTileUrlFunction=Ww.prototype.Ya;Ww.prototype.getUrls=Ww.prototype.Za;Ww.prototype.setTileLoadFunction=Ww.prototype.cb;Ww.prototype.setTileUrlFunction=Ww.prototype.La;Ww.prototype.setUrl=Ww.prototype.Na;Ww.prototype.setUrls=Ww.prototype.Ua;Ww.prototype.getTileGrid=Ww.prototype.Ga;Ww.prototype.refresh=Ww.prototype.pa;Ww.prototype.getAttributions=Ww.prototype.ra;Ww.prototype.getLogo=Ww.prototype.qa;Ww.prototype.getProjection=Ww.prototype.sa; +Ww.prototype.getState=Ww.prototype.V;Ww.prototype.setAttributions=Ww.prototype.ka;Ww.prototype.get=Ww.prototype.get;Ww.prototype.getKeys=Ww.prototype.K;Ww.prototype.getProperties=Ww.prototype.L;Ww.prototype.set=Ww.prototype.set;Ww.prototype.setProperties=Ww.prototype.C;Ww.prototype.unset=Ww.prototype.P;Ww.prototype.changed=Ww.prototype.u;Ww.prototype.dispatchEvent=Ww.prototype.b;Ww.prototype.getRevision=Ww.prototype.H;Ww.prototype.on=Ww.prototype.D;Ww.prototype.once=Ww.prototype.I; +Ww.prototype.un=Ww.prototype.G;Ww.prototype.unByKey=Ww.prototype.J;lm.prototype.type=lm.prototype.type;lm.prototype.target=lm.prototype.target;lm.prototype.preventDefault=lm.prototype.preventDefault;lm.prototype.stopPropagation=lm.prototype.stopPropagation;Am.prototype.getTileLoadFunction=Am.prototype.Xa;Am.prototype.getTileUrlFunction=Am.prototype.Ya;Am.prototype.getUrls=Am.prototype.Za;Am.prototype.setTileLoadFunction=Am.prototype.cb;Am.prototype.setTileUrlFunction=Am.prototype.La; +Am.prototype.setUrl=Am.prototype.Na;Am.prototype.setUrls=Am.prototype.Ua;Am.prototype.getTileGrid=Am.prototype.Ga;Am.prototype.refresh=Am.prototype.pa;Am.prototype.getAttributions=Am.prototype.ra;Am.prototype.getLogo=Am.prototype.qa;Am.prototype.getProjection=Am.prototype.sa;Am.prototype.getState=Am.prototype.V;Am.prototype.setAttributions=Am.prototype.ka;Am.prototype.get=Am.prototype.get;Am.prototype.getKeys=Am.prototype.K;Am.prototype.getProperties=Am.prototype.L;Am.prototype.set=Am.prototype.set; +Am.prototype.setProperties=Am.prototype.C;Am.prototype.unset=Am.prototype.P;Am.prototype.changed=Am.prototype.u;Am.prototype.dispatchEvent=Am.prototype.b;Am.prototype.getRevision=Am.prototype.H;Am.prototype.on=Am.prototype.D;Am.prototype.once=Am.prototype.I;Am.prototype.un=Am.prototype.G;Am.prototype.unByKey=Am.prototype.J;Z.prototype.setRenderReprojectionEdges=Z.prototype.lb;Z.prototype.setTileGridForProjection=Z.prototype.mb;Z.prototype.getTileLoadFunction=Z.prototype.Xa; +Z.prototype.getTileUrlFunction=Z.prototype.Ya;Z.prototype.getUrls=Z.prototype.Za;Z.prototype.setTileLoadFunction=Z.prototype.cb;Z.prototype.setTileUrlFunction=Z.prototype.La;Z.prototype.setUrl=Z.prototype.Na;Z.prototype.setUrls=Z.prototype.Ua;Z.prototype.getTileGrid=Z.prototype.Ga;Z.prototype.refresh=Z.prototype.pa;Z.prototype.getAttributions=Z.prototype.ra;Z.prototype.getLogo=Z.prototype.qa;Z.prototype.getProjection=Z.prototype.sa;Z.prototype.getState=Z.prototype.V;Z.prototype.setAttributions=Z.prototype.ka; +Z.prototype.get=Z.prototype.get;Z.prototype.getKeys=Z.prototype.K;Z.prototype.getProperties=Z.prototype.L;Z.prototype.set=Z.prototype.set;Z.prototype.setProperties=Z.prototype.C;Z.prototype.unset=Z.prototype.P;Z.prototype.changed=Z.prototype.u;Z.prototype.dispatchEvent=Z.prototype.b;Z.prototype.getRevision=Z.prototype.H;Z.prototype.on=Z.prototype.D;Z.prototype.once=Z.prototype.I;Z.prototype.un=Z.prototype.G;Z.prototype.unByKey=Z.prototype.J;dx.prototype.setRenderReprojectionEdges=dx.prototype.lb; +dx.prototype.setTileGridForProjection=dx.prototype.mb;dx.prototype.getTileLoadFunction=dx.prototype.Xa;dx.prototype.getTileUrlFunction=dx.prototype.Ya;dx.prototype.getUrls=dx.prototype.Za;dx.prototype.setTileLoadFunction=dx.prototype.cb;dx.prototype.setTileUrlFunction=dx.prototype.La;dx.prototype.setUrl=dx.prototype.Na;dx.prototype.setUrls=dx.prototype.Ua;dx.prototype.getTileGrid=dx.prototype.Ga;dx.prototype.refresh=dx.prototype.pa;dx.prototype.getAttributions=dx.prototype.ra; +dx.prototype.getLogo=dx.prototype.qa;dx.prototype.getProjection=dx.prototype.sa;dx.prototype.getState=dx.prototype.V;dx.prototype.setAttributions=dx.prototype.ka;dx.prototype.get=dx.prototype.get;dx.prototype.getKeys=dx.prototype.K;dx.prototype.getProperties=dx.prototype.L;dx.prototype.set=dx.prototype.set;dx.prototype.setProperties=dx.prototype.C;dx.prototype.unset=dx.prototype.P;dx.prototype.changed=dx.prototype.u;dx.prototype.dispatchEvent=dx.prototype.b;dx.prototype.getRevision=dx.prototype.H; +dx.prototype.on=dx.prototype.D;dx.prototype.once=dx.prototype.I;dx.prototype.un=dx.prototype.G;dx.prototype.unByKey=dx.prototype.J;ew.prototype.getTileCoord=ew.prototype.i;ki.prototype.changed=ki.prototype.u;ki.prototype.dispatchEvent=ki.prototype.b;ki.prototype.getRevision=ki.prototype.H;ki.prototype.on=ki.prototype.D;ki.prototype.once=ki.prototype.I;ki.prototype.un=ki.prototype.G;ki.prototype.unByKey=ki.prototype.J;xn.prototype.changed=xn.prototype.u;xn.prototype.dispatchEvent=xn.prototype.b; +xn.prototype.getRevision=xn.prototype.H;xn.prototype.on=xn.prototype.D;xn.prototype.once=xn.prototype.I;xn.prototype.un=xn.prototype.G;xn.prototype.unByKey=xn.prototype.J;An.prototype.changed=An.prototype.u;An.prototype.dispatchEvent=An.prototype.b;An.prototype.getRevision=An.prototype.H;An.prototype.on=An.prototype.D;An.prototype.once=An.prototype.I;An.prototype.un=An.prototype.G;An.prototype.unByKey=An.prototype.J;Gn.prototype.changed=Gn.prototype.u;Gn.prototype.dispatchEvent=Gn.prototype.b; +Gn.prototype.getRevision=Gn.prototype.H;Gn.prototype.on=Gn.prototype.D;Gn.prototype.once=Gn.prototype.I;Gn.prototype.un=Gn.prototype.G;Gn.prototype.unByKey=Gn.prototype.J;In.prototype.changed=In.prototype.u;In.prototype.dispatchEvent=In.prototype.b;In.prototype.getRevision=In.prototype.H;In.prototype.on=In.prototype.D;In.prototype.once=In.prototype.I;In.prototype.un=In.prototype.G;In.prototype.unByKey=In.prototype.J;Im.prototype.changed=Im.prototype.u;Im.prototype.dispatchEvent=Im.prototype.b; +Im.prototype.getRevision=Im.prototype.H;Im.prototype.on=Im.prototype.D;Im.prototype.once=Im.prototype.I;Im.prototype.un=Im.prototype.G;Im.prototype.unByKey=Im.prototype.J;Jm.prototype.changed=Jm.prototype.u;Jm.prototype.dispatchEvent=Jm.prototype.b;Jm.prototype.getRevision=Jm.prototype.H;Jm.prototype.on=Jm.prototype.D;Jm.prototype.once=Jm.prototype.I;Jm.prototype.un=Jm.prototype.G;Jm.prototype.unByKey=Jm.prototype.J;Km.prototype.changed=Km.prototype.u;Km.prototype.dispatchEvent=Km.prototype.b; +Km.prototype.getRevision=Km.prototype.H;Km.prototype.on=Km.prototype.D;Km.prototype.once=Km.prototype.I;Km.prototype.un=Km.prototype.G;Km.prototype.unByKey=Km.prototype.J;Mm.prototype.changed=Mm.prototype.u;Mm.prototype.dispatchEvent=Mm.prototype.b;Mm.prototype.getRevision=Mm.prototype.H;Mm.prototype.on=Mm.prototype.D;Mm.prototype.once=Mm.prototype.I;Mm.prototype.un=Mm.prototype.G;Mm.prototype.unByKey=Mm.prototype.J;Bk.prototype.changed=Bk.prototype.u;Bk.prototype.dispatchEvent=Bk.prototype.b; +Bk.prototype.getRevision=Bk.prototype.H;Bk.prototype.on=Bk.prototype.D;Bk.prototype.once=Bk.prototype.I;Bk.prototype.un=Bk.prototype.G;Bk.prototype.unByKey=Bk.prototype.J;qm.prototype.changed=qm.prototype.u;qm.prototype.dispatchEvent=qm.prototype.b;qm.prototype.getRevision=qm.prototype.H;qm.prototype.on=qm.prototype.D;qm.prototype.once=qm.prototype.I;qm.prototype.un=qm.prototype.G;qm.prototype.unByKey=qm.prototype.J;rm.prototype.changed=rm.prototype.u;rm.prototype.dispatchEvent=rm.prototype.b; +rm.prototype.getRevision=rm.prototype.H;rm.prototype.on=rm.prototype.D;rm.prototype.once=rm.prototype.I;rm.prototype.un=rm.prototype.G;rm.prototype.unByKey=rm.prototype.J;tm.prototype.changed=tm.prototype.u;tm.prototype.dispatchEvent=tm.prototype.b;tm.prototype.getRevision=tm.prototype.H;tm.prototype.on=tm.prototype.D;tm.prototype.once=tm.prototype.I;tm.prototype.un=tm.prototype.G;tm.prototype.unByKey=tm.prototype.J;Em.prototype.changed=Em.prototype.u;Em.prototype.dispatchEvent=Em.prototype.b; +Em.prototype.getRevision=Em.prototype.H;Em.prototype.on=Em.prototype.D;Em.prototype.once=Em.prototype.I;Em.prototype.un=Em.prototype.G;Em.prototype.unByKey=Em.prototype.J;ci.prototype.type=ci.prototype.type;ci.prototype.target=ci.prototype.target;ci.prototype.preventDefault=ci.prototype.preventDefault;ci.prototype.stopPropagation=ci.prototype.stopPropagation;Ig.prototype.type=Ig.prototype.type;Ig.prototype.target=Ig.prototype.target;Ig.prototype.preventDefault=Ig.prototype.preventDefault; +Ig.prototype.stopPropagation=Ig.prototype.stopPropagation;$h.prototype.get=$h.prototype.get;$h.prototype.getKeys=$h.prototype.K;$h.prototype.getProperties=$h.prototype.L;$h.prototype.set=$h.prototype.set;$h.prototype.setProperties=$h.prototype.C;$h.prototype.unset=$h.prototype.P;$h.prototype.changed=$h.prototype.u;$h.prototype.dispatchEvent=$h.prototype.b;$h.prototype.getRevision=$h.prototype.H;$h.prototype.on=$h.prototype.D;$h.prototype.once=$h.prototype.I;$h.prototype.un=$h.prototype.G; +$h.prototype.unByKey=$h.prototype.J;di.prototype.getExtent=di.prototype.O;di.prototype.getMaxResolution=di.prototype.Ib;di.prototype.getMinResolution=di.prototype.Jb;di.prototype.getOpacity=di.prototype.Lb;di.prototype.getVisible=di.prototype.wb;di.prototype.getZIndex=di.prototype.Mb;di.prototype.setExtent=di.prototype.ac;di.prototype.setMaxResolution=di.prototype.ic;di.prototype.setMinResolution=di.prototype.jc;di.prototype.setOpacity=di.prototype.bc;di.prototype.setVisible=di.prototype.cc; +di.prototype.setZIndex=di.prototype.dc;di.prototype.get=di.prototype.get;di.prototype.getKeys=di.prototype.K;di.prototype.getProperties=di.prototype.L;di.prototype.set=di.prototype.set;di.prototype.setProperties=di.prototype.C;di.prototype.unset=di.prototype.P;di.prototype.changed=di.prototype.u;di.prototype.dispatchEvent=di.prototype.b;di.prototype.getRevision=di.prototype.H;di.prototype.on=di.prototype.D;di.prototype.once=di.prototype.I;di.prototype.un=di.prototype.G;di.prototype.unByKey=di.prototype.J; +H.prototype.setMap=H.prototype.setMap;H.prototype.setSource=H.prototype.Ac;H.prototype.getExtent=H.prototype.O;H.prototype.getMaxResolution=H.prototype.Ib;H.prototype.getMinResolution=H.prototype.Jb;H.prototype.getOpacity=H.prototype.Lb;H.prototype.getVisible=H.prototype.wb;H.prototype.getZIndex=H.prototype.Mb;H.prototype.setExtent=H.prototype.ac;H.prototype.setMaxResolution=H.prototype.ic;H.prototype.setMinResolution=H.prototype.jc;H.prototype.setOpacity=H.prototype.bc;H.prototype.setVisible=H.prototype.cc; +H.prototype.setZIndex=H.prototype.dc;H.prototype.get=H.prototype.get;H.prototype.getKeys=H.prototype.K;H.prototype.getProperties=H.prototype.L;H.prototype.set=H.prototype.set;H.prototype.setProperties=H.prototype.C;H.prototype.unset=H.prototype.P;H.prototype.changed=H.prototype.u;H.prototype.dispatchEvent=H.prototype.b;H.prototype.getRevision=H.prototype.H;H.prototype.on=H.prototype.D;H.prototype.once=H.prototype.I;H.prototype.un=H.prototype.G;H.prototype.unByKey=H.prototype.J; +W.prototype.getSource=W.prototype.da;W.prototype.getStyle=W.prototype.M;W.prototype.getStyleFunction=W.prototype.N;W.prototype.setStyle=W.prototype.l;W.prototype.setMap=W.prototype.setMap;W.prototype.setSource=W.prototype.Ac;W.prototype.getExtent=W.prototype.O;W.prototype.getMaxResolution=W.prototype.Ib;W.prototype.getMinResolution=W.prototype.Jb;W.prototype.getOpacity=W.prototype.Lb;W.prototype.getVisible=W.prototype.wb;W.prototype.getZIndex=W.prototype.Mb;W.prototype.setExtent=W.prototype.ac; +W.prototype.setMaxResolution=W.prototype.ic;W.prototype.setMinResolution=W.prototype.jc;W.prototype.setOpacity=W.prototype.bc;W.prototype.setVisible=W.prototype.cc;W.prototype.setZIndex=W.prototype.dc;W.prototype.get=W.prototype.get;W.prototype.getKeys=W.prototype.K;W.prototype.getProperties=W.prototype.L;W.prototype.set=W.prototype.set;W.prototype.setProperties=W.prototype.C;W.prototype.unset=W.prototype.P;W.prototype.changed=W.prototype.u;W.prototype.dispatchEvent=W.prototype.b; +W.prototype.getRevision=W.prototype.H;W.prototype.on=W.prototype.D;W.prototype.once=W.prototype.I;W.prototype.un=W.prototype.G;W.prototype.unByKey=W.prototype.J;Uj.prototype.setMap=Uj.prototype.setMap;Uj.prototype.setSource=Uj.prototype.Ac;Uj.prototype.getExtent=Uj.prototype.O;Uj.prototype.getMaxResolution=Uj.prototype.Ib;Uj.prototype.getMinResolution=Uj.prototype.Jb;Uj.prototype.getOpacity=Uj.prototype.Lb;Uj.prototype.getVisible=Uj.prototype.wb;Uj.prototype.getZIndex=Uj.prototype.Mb; +Uj.prototype.setExtent=Uj.prototype.ac;Uj.prototype.setMaxResolution=Uj.prototype.ic;Uj.prototype.setMinResolution=Uj.prototype.jc;Uj.prototype.setOpacity=Uj.prototype.bc;Uj.prototype.setVisible=Uj.prototype.cc;Uj.prototype.setZIndex=Uj.prototype.dc;Uj.prototype.get=Uj.prototype.get;Uj.prototype.getKeys=Uj.prototype.K;Uj.prototype.getProperties=Uj.prototype.L;Uj.prototype.set=Uj.prototype.set;Uj.prototype.setProperties=Uj.prototype.C;Uj.prototype.unset=Uj.prototype.P;Uj.prototype.changed=Uj.prototype.u; +Uj.prototype.dispatchEvent=Uj.prototype.b;Uj.prototype.getRevision=Uj.prototype.H;Uj.prototype.on=Uj.prototype.D;Uj.prototype.once=Uj.prototype.I;Uj.prototype.un=Uj.prototype.G;Uj.prototype.unByKey=Uj.prototype.J;Kj.prototype.getExtent=Kj.prototype.O;Kj.prototype.getMaxResolution=Kj.prototype.Ib;Kj.prototype.getMinResolution=Kj.prototype.Jb;Kj.prototype.getOpacity=Kj.prototype.Lb;Kj.prototype.getVisible=Kj.prototype.wb;Kj.prototype.getZIndex=Kj.prototype.Mb;Kj.prototype.setExtent=Kj.prototype.ac; +Kj.prototype.setMaxResolution=Kj.prototype.ic;Kj.prototype.setMinResolution=Kj.prototype.jc;Kj.prototype.setOpacity=Kj.prototype.bc;Kj.prototype.setVisible=Kj.prototype.cc;Kj.prototype.setZIndex=Kj.prototype.dc;Kj.prototype.get=Kj.prototype.get;Kj.prototype.getKeys=Kj.prototype.K;Kj.prototype.getProperties=Kj.prototype.L;Kj.prototype.set=Kj.prototype.set;Kj.prototype.setProperties=Kj.prototype.C;Kj.prototype.unset=Kj.prototype.P;Kj.prototype.changed=Kj.prototype.u;Kj.prototype.dispatchEvent=Kj.prototype.b; +Kj.prototype.getRevision=Kj.prototype.H;Kj.prototype.on=Kj.prototype.D;Kj.prototype.once=Kj.prototype.I;Kj.prototype.un=Kj.prototype.G;Kj.prototype.unByKey=Kj.prototype.J;Vj.prototype.setMap=Vj.prototype.setMap;Vj.prototype.setSource=Vj.prototype.Ac;Vj.prototype.getExtent=Vj.prototype.O;Vj.prototype.getMaxResolution=Vj.prototype.Ib;Vj.prototype.getMinResolution=Vj.prototype.Jb;Vj.prototype.getOpacity=Vj.prototype.Lb;Vj.prototype.getVisible=Vj.prototype.wb;Vj.prototype.getZIndex=Vj.prototype.Mb; +Vj.prototype.setExtent=Vj.prototype.ac;Vj.prototype.setMaxResolution=Vj.prototype.ic;Vj.prototype.setMinResolution=Vj.prototype.jc;Vj.prototype.setOpacity=Vj.prototype.bc;Vj.prototype.setVisible=Vj.prototype.cc;Vj.prototype.setZIndex=Vj.prototype.dc;Vj.prototype.get=Vj.prototype.get;Vj.prototype.getKeys=Vj.prototype.K;Vj.prototype.getProperties=Vj.prototype.L;Vj.prototype.set=Vj.prototype.set;Vj.prototype.setProperties=Vj.prototype.C;Vj.prototype.unset=Vj.prototype.P;Vj.prototype.changed=Vj.prototype.u; +Vj.prototype.dispatchEvent=Vj.prototype.b;Vj.prototype.getRevision=Vj.prototype.H;Vj.prototype.on=Vj.prototype.D;Vj.prototype.once=Vj.prototype.I;Vj.prototype.un=Vj.prototype.G;Vj.prototype.unByKey=Vj.prototype.J;I.prototype.getSource=I.prototype.da;I.prototype.getStyle=I.prototype.M;I.prototype.getStyleFunction=I.prototype.N;I.prototype.setStyle=I.prototype.l;I.prototype.setMap=I.prototype.setMap;I.prototype.setSource=I.prototype.Ac;I.prototype.getExtent=I.prototype.O; +I.prototype.getMaxResolution=I.prototype.Ib;I.prototype.getMinResolution=I.prototype.Jb;I.prototype.getOpacity=I.prototype.Lb;I.prototype.getVisible=I.prototype.wb;I.prototype.getZIndex=I.prototype.Mb;I.prototype.setExtent=I.prototype.ac;I.prototype.setMaxResolution=I.prototype.ic;I.prototype.setMinResolution=I.prototype.jc;I.prototype.setOpacity=I.prototype.bc;I.prototype.setVisible=I.prototype.cc;I.prototype.setZIndex=I.prototype.dc;I.prototype.get=I.prototype.get;I.prototype.getKeys=I.prototype.K; +I.prototype.getProperties=I.prototype.L;I.prototype.set=I.prototype.set;I.prototype.setProperties=I.prototype.C;I.prototype.unset=I.prototype.P;I.prototype.changed=I.prototype.u;I.prototype.dispatchEvent=I.prototype.b;I.prototype.getRevision=I.prototype.H;I.prototype.on=I.prototype.D;I.prototype.once=I.prototype.I;I.prototype.un=I.prototype.G;I.prototype.unByKey=I.prototype.J;Mi.prototype.get=Mi.prototype.get;Mi.prototype.getKeys=Mi.prototype.K;Mi.prototype.getProperties=Mi.prototype.L; +Mi.prototype.set=Mi.prototype.set;Mi.prototype.setProperties=Mi.prototype.C;Mi.prototype.unset=Mi.prototype.P;Mi.prototype.changed=Mi.prototype.u;Mi.prototype.dispatchEvent=Mi.prototype.b;Mi.prototype.getRevision=Mi.prototype.H;Mi.prototype.on=Mi.prototype.D;Mi.prototype.once=Mi.prototype.I;Mi.prototype.un=Mi.prototype.G;Mi.prototype.unByKey=Mi.prototype.J;Qi.prototype.getActive=Qi.prototype.f;Qi.prototype.getMap=Qi.prototype.l;Qi.prototype.setActive=Qi.prototype.i;Qi.prototype.get=Qi.prototype.get; +Qi.prototype.getKeys=Qi.prototype.K;Qi.prototype.getProperties=Qi.prototype.L;Qi.prototype.set=Qi.prototype.set;Qi.prototype.setProperties=Qi.prototype.C;Qi.prototype.unset=Qi.prototype.P;Qi.prototype.changed=Qi.prototype.u;Qi.prototype.dispatchEvent=Qi.prototype.b;Qi.prototype.getRevision=Qi.prototype.H;Qi.prototype.on=Qi.prototype.D;Qi.prototype.once=Qi.prototype.I;Qi.prototype.un=Qi.prototype.G;Qi.prototype.unByKey=Qi.prototype.J;av.prototype.getActive=av.prototype.f;av.prototype.getMap=av.prototype.l; +av.prototype.setActive=av.prototype.i;av.prototype.get=av.prototype.get;av.prototype.getKeys=av.prototype.K;av.prototype.getProperties=av.prototype.L;av.prototype.set=av.prototype.set;av.prototype.setProperties=av.prototype.C;av.prototype.unset=av.prototype.P;av.prototype.changed=av.prototype.u;av.prototype.dispatchEvent=av.prototype.b;av.prototype.getRevision=av.prototype.H;av.prototype.on=av.prototype.D;av.prototype.once=av.prototype.I;av.prototype.un=av.prototype.G;av.prototype.unByKey=av.prototype.J; +dv.prototype.type=dv.prototype.type;dv.prototype.target=dv.prototype.target;dv.prototype.preventDefault=dv.prototype.preventDefault;dv.prototype.stopPropagation=dv.prototype.stopPropagation;oj.prototype.type=oj.prototype.type;oj.prototype.target=oj.prototype.target;oj.prototype.preventDefault=oj.prototype.preventDefault;oj.prototype.stopPropagation=oj.prototype.stopPropagation;aj.prototype.getActive=aj.prototype.f;aj.prototype.getMap=aj.prototype.l;aj.prototype.setActive=aj.prototype.i; +aj.prototype.get=aj.prototype.get;aj.prototype.getKeys=aj.prototype.K;aj.prototype.getProperties=aj.prototype.L;aj.prototype.set=aj.prototype.set;aj.prototype.setProperties=aj.prototype.C;aj.prototype.unset=aj.prototype.P;aj.prototype.changed=aj.prototype.u;aj.prototype.dispatchEvent=aj.prototype.b;aj.prototype.getRevision=aj.prototype.H;aj.prototype.on=aj.prototype.D;aj.prototype.once=aj.prototype.I;aj.prototype.un=aj.prototype.G;aj.prototype.unByKey=aj.prototype.J;pj.prototype.getActive=pj.prototype.f; +pj.prototype.getMap=pj.prototype.l;pj.prototype.setActive=pj.prototype.i;pj.prototype.get=pj.prototype.get;pj.prototype.getKeys=pj.prototype.K;pj.prototype.getProperties=pj.prototype.L;pj.prototype.set=pj.prototype.set;pj.prototype.setProperties=pj.prototype.C;pj.prototype.unset=pj.prototype.P;pj.prototype.changed=pj.prototype.u;pj.prototype.dispatchEvent=pj.prototype.b;pj.prototype.getRevision=pj.prototype.H;pj.prototype.on=pj.prototype.D;pj.prototype.once=pj.prototype.I;pj.prototype.un=pj.prototype.G; +pj.prototype.unByKey=pj.prototype.J;dj.prototype.getActive=dj.prototype.f;dj.prototype.getMap=dj.prototype.l;dj.prototype.setActive=dj.prototype.i;dj.prototype.get=dj.prototype.get;dj.prototype.getKeys=dj.prototype.K;dj.prototype.getProperties=dj.prototype.L;dj.prototype.set=dj.prototype.set;dj.prototype.setProperties=dj.prototype.C;dj.prototype.unset=dj.prototype.P;dj.prototype.changed=dj.prototype.u;dj.prototype.dispatchEvent=dj.prototype.b;dj.prototype.getRevision=dj.prototype.H; +dj.prototype.on=dj.prototype.D;dj.prototype.once=dj.prototype.I;dj.prototype.un=dj.prototype.G;dj.prototype.unByKey=dj.prototype.J;fv.prototype.getActive=fv.prototype.f;fv.prototype.getMap=fv.prototype.l;fv.prototype.setActive=fv.prototype.i;fv.prototype.get=fv.prototype.get;fv.prototype.getKeys=fv.prototype.K;fv.prototype.getProperties=fv.prototype.L;fv.prototype.set=fv.prototype.set;fv.prototype.setProperties=fv.prototype.C;fv.prototype.unset=fv.prototype.P;fv.prototype.changed=fv.prototype.u; +fv.prototype.dispatchEvent=fv.prototype.b;fv.prototype.getRevision=fv.prototype.H;fv.prototype.on=fv.prototype.D;fv.prototype.once=fv.prototype.I;fv.prototype.un=fv.prototype.G;fv.prototype.unByKey=fv.prototype.J;hj.prototype.getActive=hj.prototype.f;hj.prototype.getMap=hj.prototype.l;hj.prototype.setActive=hj.prototype.i;hj.prototype.get=hj.prototype.get;hj.prototype.getKeys=hj.prototype.K;hj.prototype.getProperties=hj.prototype.L;hj.prototype.set=hj.prototype.set;hj.prototype.setProperties=hj.prototype.C; +hj.prototype.unset=hj.prototype.P;hj.prototype.changed=hj.prototype.u;hj.prototype.dispatchEvent=hj.prototype.b;hj.prototype.getRevision=hj.prototype.H;hj.prototype.on=hj.prototype.D;hj.prototype.once=hj.prototype.I;hj.prototype.un=hj.prototype.G;hj.prototype.unByKey=hj.prototype.J;uj.prototype.getGeometry=uj.prototype.W;uj.prototype.getActive=uj.prototype.f;uj.prototype.getMap=uj.prototype.l;uj.prototype.setActive=uj.prototype.i;uj.prototype.get=uj.prototype.get;uj.prototype.getKeys=uj.prototype.K; +uj.prototype.getProperties=uj.prototype.L;uj.prototype.set=uj.prototype.set;uj.prototype.setProperties=uj.prototype.C;uj.prototype.unset=uj.prototype.P;uj.prototype.changed=uj.prototype.u;uj.prototype.dispatchEvent=uj.prototype.b;uj.prototype.getRevision=uj.prototype.H;uj.prototype.on=uj.prototype.D;uj.prototype.once=uj.prototype.I;uj.prototype.un=uj.prototype.G;uj.prototype.unByKey=uj.prototype.J;jv.prototype.type=jv.prototype.type;jv.prototype.target=jv.prototype.target; +jv.prototype.preventDefault=jv.prototype.preventDefault;jv.prototype.stopPropagation=jv.prototype.stopPropagation;kv.prototype.getActive=kv.prototype.f;kv.prototype.getMap=kv.prototype.l;kv.prototype.setActive=kv.prototype.i;kv.prototype.get=kv.prototype.get;kv.prototype.getKeys=kv.prototype.K;kv.prototype.getProperties=kv.prototype.L;kv.prototype.set=kv.prototype.set;kv.prototype.setProperties=kv.prototype.C;kv.prototype.unset=kv.prototype.P;kv.prototype.changed=kv.prototype.u; +kv.prototype.dispatchEvent=kv.prototype.b;kv.prototype.getRevision=kv.prototype.H;kv.prototype.on=kv.prototype.D;kv.prototype.once=kv.prototype.I;kv.prototype.un=kv.prototype.G;kv.prototype.unByKey=kv.prototype.J;vj.prototype.getActive=vj.prototype.f;vj.prototype.getMap=vj.prototype.l;vj.prototype.setActive=vj.prototype.i;vj.prototype.get=vj.prototype.get;vj.prototype.getKeys=vj.prototype.K;vj.prototype.getProperties=vj.prototype.L;vj.prototype.set=vj.prototype.set;vj.prototype.setProperties=vj.prototype.C; +vj.prototype.unset=vj.prototype.P;vj.prototype.changed=vj.prototype.u;vj.prototype.dispatchEvent=vj.prototype.b;vj.prototype.getRevision=vj.prototype.H;vj.prototype.on=vj.prototype.D;vj.prototype.once=vj.prototype.I;vj.prototype.un=vj.prototype.G;vj.prototype.unByKey=vj.prototype.J;xj.prototype.getActive=xj.prototype.f;xj.prototype.getMap=xj.prototype.l;xj.prototype.setActive=xj.prototype.i;xj.prototype.get=xj.prototype.get;xj.prototype.getKeys=xj.prototype.K;xj.prototype.getProperties=xj.prototype.L; +xj.prototype.set=xj.prototype.set;xj.prototype.setProperties=xj.prototype.C;xj.prototype.unset=xj.prototype.P;xj.prototype.changed=xj.prototype.u;xj.prototype.dispatchEvent=xj.prototype.b;xj.prototype.getRevision=xj.prototype.H;xj.prototype.on=xj.prototype.D;xj.prototype.once=xj.prototype.I;xj.prototype.un=xj.prototype.G;xj.prototype.unByKey=xj.prototype.J;Av.prototype.type=Av.prototype.type;Av.prototype.target=Av.prototype.target;Av.prototype.preventDefault=Av.prototype.preventDefault; +Av.prototype.stopPropagation=Av.prototype.stopPropagation;Bv.prototype.getActive=Bv.prototype.f;Bv.prototype.getMap=Bv.prototype.l;Bv.prototype.setActive=Bv.prototype.i;Bv.prototype.get=Bv.prototype.get;Bv.prototype.getKeys=Bv.prototype.K;Bv.prototype.getProperties=Bv.prototype.L;Bv.prototype.set=Bv.prototype.set;Bv.prototype.setProperties=Bv.prototype.C;Bv.prototype.unset=Bv.prototype.P;Bv.prototype.changed=Bv.prototype.u;Bv.prototype.dispatchEvent=Bv.prototype.b;Bv.prototype.getRevision=Bv.prototype.H; +Bv.prototype.on=Bv.prototype.D;Bv.prototype.once=Bv.prototype.I;Bv.prototype.un=Bv.prototype.G;Bv.prototype.unByKey=Bv.prototype.J;zj.prototype.getActive=zj.prototype.f;zj.prototype.getMap=zj.prototype.l;zj.prototype.setActive=zj.prototype.i;zj.prototype.get=zj.prototype.get;zj.prototype.getKeys=zj.prototype.K;zj.prototype.getProperties=zj.prototype.L;zj.prototype.set=zj.prototype.set;zj.prototype.setProperties=zj.prototype.C;zj.prototype.unset=zj.prototype.P;zj.prototype.changed=zj.prototype.u; +zj.prototype.dispatchEvent=zj.prototype.b;zj.prototype.getRevision=zj.prototype.H;zj.prototype.on=zj.prototype.D;zj.prototype.once=zj.prototype.I;zj.prototype.un=zj.prototype.G;zj.prototype.unByKey=zj.prototype.J;Bj.prototype.getActive=Bj.prototype.f;Bj.prototype.getMap=Bj.prototype.l;Bj.prototype.setActive=Bj.prototype.i;Bj.prototype.get=Bj.prototype.get;Bj.prototype.getKeys=Bj.prototype.K;Bj.prototype.getProperties=Bj.prototype.L;Bj.prototype.set=Bj.prototype.set;Bj.prototype.setProperties=Bj.prototype.C; +Bj.prototype.unset=Bj.prototype.P;Bj.prototype.changed=Bj.prototype.u;Bj.prototype.dispatchEvent=Bj.prototype.b;Bj.prototype.getRevision=Bj.prototype.H;Bj.prototype.on=Bj.prototype.D;Bj.prototype.once=Bj.prototype.I;Bj.prototype.un=Bj.prototype.G;Bj.prototype.unByKey=Bj.prototype.J;Fj.prototype.getActive=Fj.prototype.f;Fj.prototype.getMap=Fj.prototype.l;Fj.prototype.setActive=Fj.prototype.i;Fj.prototype.get=Fj.prototype.get;Fj.prototype.getKeys=Fj.prototype.K;Fj.prototype.getProperties=Fj.prototype.L; +Fj.prototype.set=Fj.prototype.set;Fj.prototype.setProperties=Fj.prototype.C;Fj.prototype.unset=Fj.prototype.P;Fj.prototype.changed=Fj.prototype.u;Fj.prototype.dispatchEvent=Fj.prototype.b;Fj.prototype.getRevision=Fj.prototype.H;Fj.prototype.on=Fj.prototype.D;Fj.prototype.once=Fj.prototype.I;Fj.prototype.un=Fj.prototype.G;Fj.prototype.unByKey=Fj.prototype.J;Ov.prototype.type=Ov.prototype.type;Ov.prototype.target=Ov.prototype.target;Ov.prototype.preventDefault=Ov.prototype.preventDefault; +Ov.prototype.stopPropagation=Ov.prototype.stopPropagation;Pv.prototype.getActive=Pv.prototype.f;Pv.prototype.getMap=Pv.prototype.l;Pv.prototype.setActive=Pv.prototype.i;Pv.prototype.get=Pv.prototype.get;Pv.prototype.getKeys=Pv.prototype.K;Pv.prototype.getProperties=Pv.prototype.L;Pv.prototype.set=Pv.prototype.set;Pv.prototype.setProperties=Pv.prototype.C;Pv.prototype.unset=Pv.prototype.P;Pv.prototype.changed=Pv.prototype.u;Pv.prototype.dispatchEvent=Pv.prototype.b;Pv.prototype.getRevision=Pv.prototype.H; +Pv.prototype.on=Pv.prototype.D;Pv.prototype.once=Pv.prototype.I;Pv.prototype.un=Pv.prototype.G;Pv.prototype.unByKey=Pv.prototype.J;Sv.prototype.getActive=Sv.prototype.f;Sv.prototype.getMap=Sv.prototype.l;Sv.prototype.setActive=Sv.prototype.i;Sv.prototype.get=Sv.prototype.get;Sv.prototype.getKeys=Sv.prototype.K;Sv.prototype.getProperties=Sv.prototype.L;Sv.prototype.set=Sv.prototype.set;Sv.prototype.setProperties=Sv.prototype.C;Sv.prototype.unset=Sv.prototype.P;Sv.prototype.changed=Sv.prototype.u; +Sv.prototype.dispatchEvent=Sv.prototype.b;Sv.prototype.getRevision=Sv.prototype.H;Sv.prototype.on=Sv.prototype.D;Sv.prototype.once=Sv.prototype.I;Sv.prototype.un=Sv.prototype.G;Sv.prototype.unByKey=Sv.prototype.J;Wv.prototype.type=Wv.prototype.type;Wv.prototype.target=Wv.prototype.target;Wv.prototype.preventDefault=Wv.prototype.preventDefault;Wv.prototype.stopPropagation=Wv.prototype.stopPropagation;Xv.prototype.getActive=Xv.prototype.f;Xv.prototype.getMap=Xv.prototype.l;Xv.prototype.setActive=Xv.prototype.i; +Xv.prototype.get=Xv.prototype.get;Xv.prototype.getKeys=Xv.prototype.K;Xv.prototype.getProperties=Xv.prototype.L;Xv.prototype.set=Xv.prototype.set;Xv.prototype.setProperties=Xv.prototype.C;Xv.prototype.unset=Xv.prototype.P;Xv.prototype.changed=Xv.prototype.u;Xv.prototype.dispatchEvent=Xv.prototype.b;Xv.prototype.getRevision=Xv.prototype.H;Xv.prototype.on=Xv.prototype.D;Xv.prototype.once=Xv.prototype.I;Xv.prototype.un=Xv.prototype.G;Xv.prototype.unByKey=Xv.prototype.J;dd.prototype.get=dd.prototype.get; +dd.prototype.getKeys=dd.prototype.K;dd.prototype.getProperties=dd.prototype.L;dd.prototype.set=dd.prototype.set;dd.prototype.setProperties=dd.prototype.C;dd.prototype.unset=dd.prototype.P;dd.prototype.changed=dd.prototype.u;dd.prototype.dispatchEvent=dd.prototype.b;dd.prototype.getRevision=dd.prototype.H;dd.prototype.on=dd.prototype.D;dd.prototype.once=dd.prototype.I;dd.prototype.un=dd.prototype.G;dd.prototype.unByKey=dd.prototype.J;sd.prototype.getClosestPoint=sd.prototype.ub; +sd.prototype.getExtent=sd.prototype.O;sd.prototype.rotate=sd.prototype.rotate;sd.prototype.simplify=sd.prototype.yb;sd.prototype.transform=sd.prototype.hb;sd.prototype.get=sd.prototype.get;sd.prototype.getKeys=sd.prototype.K;sd.prototype.getProperties=sd.prototype.L;sd.prototype.set=sd.prototype.set;sd.prototype.setProperties=sd.prototype.C;sd.prototype.unset=sd.prototype.P;sd.prototype.changed=sd.prototype.u;sd.prototype.dispatchEvent=sd.prototype.b;sd.prototype.getRevision=sd.prototype.H; +sd.prototype.on=sd.prototype.D;sd.prototype.once=sd.prototype.I;sd.prototype.un=sd.prototype.G;sd.prototype.unByKey=sd.prototype.J;Ou.prototype.getFirstCoordinate=Ou.prototype.Fb;Ou.prototype.getLastCoordinate=Ou.prototype.Gb;Ou.prototype.getLayout=Ou.prototype.Hb;Ou.prototype.rotate=Ou.prototype.rotate;Ou.prototype.getClosestPoint=Ou.prototype.ub;Ou.prototype.getExtent=Ou.prototype.O;Ou.prototype.simplify=Ou.prototype.yb;Ou.prototype.get=Ou.prototype.get;Ou.prototype.getKeys=Ou.prototype.K; +Ou.prototype.getProperties=Ou.prototype.L;Ou.prototype.set=Ou.prototype.set;Ou.prototype.setProperties=Ou.prototype.C;Ou.prototype.unset=Ou.prototype.P;Ou.prototype.changed=Ou.prototype.u;Ou.prototype.dispatchEvent=Ou.prototype.b;Ou.prototype.getRevision=Ou.prototype.H;Ou.prototype.on=Ou.prototype.D;Ou.prototype.once=Ou.prototype.I;Ou.prototype.un=Ou.prototype.G;Ou.prototype.unByKey=Ou.prototype.J;Do.prototype.getClosestPoint=Do.prototype.ub;Do.prototype.getExtent=Do.prototype.O; +Do.prototype.rotate=Do.prototype.rotate;Do.prototype.simplify=Do.prototype.yb;Do.prototype.transform=Do.prototype.hb;Do.prototype.get=Do.prototype.get;Do.prototype.getKeys=Do.prototype.K;Do.prototype.getProperties=Do.prototype.L;Do.prototype.set=Do.prototype.set;Do.prototype.setProperties=Do.prototype.C;Do.prototype.unset=Do.prototype.P;Do.prototype.changed=Do.prototype.u;Do.prototype.dispatchEvent=Do.prototype.b;Do.prototype.getRevision=Do.prototype.H;Do.prototype.on=Do.prototype.D; +Do.prototype.once=Do.prototype.I;Do.prototype.un=Do.prototype.G;Do.prototype.unByKey=Do.prototype.J;Kd.prototype.getFirstCoordinate=Kd.prototype.Fb;Kd.prototype.getLastCoordinate=Kd.prototype.Gb;Kd.prototype.getLayout=Kd.prototype.Hb;Kd.prototype.rotate=Kd.prototype.rotate;Kd.prototype.getClosestPoint=Kd.prototype.ub;Kd.prototype.getExtent=Kd.prototype.O;Kd.prototype.simplify=Kd.prototype.yb;Kd.prototype.transform=Kd.prototype.hb;Kd.prototype.get=Kd.prototype.get;Kd.prototype.getKeys=Kd.prototype.K; +Kd.prototype.getProperties=Kd.prototype.L;Kd.prototype.set=Kd.prototype.set;Kd.prototype.setProperties=Kd.prototype.C;Kd.prototype.unset=Kd.prototype.P;Kd.prototype.changed=Kd.prototype.u;Kd.prototype.dispatchEvent=Kd.prototype.b;Kd.prototype.getRevision=Kd.prototype.H;Kd.prototype.on=Kd.prototype.D;Kd.prototype.once=Kd.prototype.I;Kd.prototype.un=Kd.prototype.G;Kd.prototype.unByKey=Kd.prototype.J;T.prototype.getFirstCoordinate=T.prototype.Fb;T.prototype.getLastCoordinate=T.prototype.Gb; +T.prototype.getLayout=T.prototype.Hb;T.prototype.rotate=T.prototype.rotate;T.prototype.getClosestPoint=T.prototype.ub;T.prototype.getExtent=T.prototype.O;T.prototype.simplify=T.prototype.yb;T.prototype.transform=T.prototype.hb;T.prototype.get=T.prototype.get;T.prototype.getKeys=T.prototype.K;T.prototype.getProperties=T.prototype.L;T.prototype.set=T.prototype.set;T.prototype.setProperties=T.prototype.C;T.prototype.unset=T.prototype.P;T.prototype.changed=T.prototype.u;T.prototype.dispatchEvent=T.prototype.b; +T.prototype.getRevision=T.prototype.H;T.prototype.on=T.prototype.D;T.prototype.once=T.prototype.I;T.prototype.un=T.prototype.G;T.prototype.unByKey=T.prototype.J;U.prototype.getFirstCoordinate=U.prototype.Fb;U.prototype.getLastCoordinate=U.prototype.Gb;U.prototype.getLayout=U.prototype.Hb;U.prototype.rotate=U.prototype.rotate;U.prototype.getClosestPoint=U.prototype.ub;U.prototype.getExtent=U.prototype.O;U.prototype.simplify=U.prototype.yb;U.prototype.transform=U.prototype.hb;U.prototype.get=U.prototype.get; +U.prototype.getKeys=U.prototype.K;U.prototype.getProperties=U.prototype.L;U.prototype.set=U.prototype.set;U.prototype.setProperties=U.prototype.C;U.prototype.unset=U.prototype.P;U.prototype.changed=U.prototype.u;U.prototype.dispatchEvent=U.prototype.b;U.prototype.getRevision=U.prototype.H;U.prototype.on=U.prototype.D;U.prototype.once=U.prototype.I;U.prototype.un=U.prototype.G;U.prototype.unByKey=U.prototype.J;so.prototype.getFirstCoordinate=so.prototype.Fb;so.prototype.getLastCoordinate=so.prototype.Gb; +so.prototype.getLayout=so.prototype.Hb;so.prototype.rotate=so.prototype.rotate;so.prototype.getClosestPoint=so.prototype.ub;so.prototype.getExtent=so.prototype.O;so.prototype.simplify=so.prototype.yb;so.prototype.transform=so.prototype.hb;so.prototype.get=so.prototype.get;so.prototype.getKeys=so.prototype.K;so.prototype.getProperties=so.prototype.L;so.prototype.set=so.prototype.set;so.prototype.setProperties=so.prototype.C;so.prototype.unset=so.prototype.P;so.prototype.changed=so.prototype.u; +so.prototype.dispatchEvent=so.prototype.b;so.prototype.getRevision=so.prototype.H;so.prototype.on=so.prototype.D;so.prototype.once=so.prototype.I;so.prototype.un=so.prototype.G;so.prototype.unByKey=so.prototype.J;to.prototype.getFirstCoordinate=to.prototype.Fb;to.prototype.getLastCoordinate=to.prototype.Gb;to.prototype.getLayout=to.prototype.Hb;to.prototype.rotate=to.prototype.rotate;to.prototype.getClosestPoint=to.prototype.ub;to.prototype.getExtent=to.prototype.O;to.prototype.simplify=to.prototype.yb; +to.prototype.transform=to.prototype.hb;to.prototype.get=to.prototype.get;to.prototype.getKeys=to.prototype.K;to.prototype.getProperties=to.prototype.L;to.prototype.set=to.prototype.set;to.prototype.setProperties=to.prototype.C;to.prototype.unset=to.prototype.P;to.prototype.changed=to.prototype.u;to.prototype.dispatchEvent=to.prototype.b;to.prototype.getRevision=to.prototype.H;to.prototype.on=to.prototype.D;to.prototype.once=to.prototype.I;to.prototype.un=to.prototype.G;to.prototype.unByKey=to.prototype.J; +D.prototype.getFirstCoordinate=D.prototype.Fb;D.prototype.getLastCoordinate=D.prototype.Gb;D.prototype.getLayout=D.prototype.Hb;D.prototype.rotate=D.prototype.rotate;D.prototype.getClosestPoint=D.prototype.ub;D.prototype.getExtent=D.prototype.O;D.prototype.simplify=D.prototype.yb;D.prototype.transform=D.prototype.hb;D.prototype.get=D.prototype.get;D.prototype.getKeys=D.prototype.K;D.prototype.getProperties=D.prototype.L;D.prototype.set=D.prototype.set;D.prototype.setProperties=D.prototype.C; +D.prototype.unset=D.prototype.P;D.prototype.changed=D.prototype.u;D.prototype.dispatchEvent=D.prototype.b;D.prototype.getRevision=D.prototype.H;D.prototype.on=D.prototype.D;D.prototype.once=D.prototype.I;D.prototype.un=D.prototype.G;D.prototype.unByKey=D.prototype.J;F.prototype.getFirstCoordinate=F.prototype.Fb;F.prototype.getLastCoordinate=F.prototype.Gb;F.prototype.getLayout=F.prototype.Hb;F.prototype.rotate=F.prototype.rotate;F.prototype.getClosestPoint=F.prototype.ub;F.prototype.getExtent=F.prototype.O; +F.prototype.simplify=F.prototype.yb;F.prototype.transform=F.prototype.hb;F.prototype.get=F.prototype.get;F.prototype.getKeys=F.prototype.K;F.prototype.getProperties=F.prototype.L;F.prototype.set=F.prototype.set;F.prototype.setProperties=F.prototype.C;F.prototype.unset=F.prototype.P;F.prototype.changed=F.prototype.u;F.prototype.dispatchEvent=F.prototype.b;F.prototype.getRevision=F.prototype.H;F.prototype.on=F.prototype.D;F.prototype.once=F.prototype.I;F.prototype.un=F.prototype.G; +F.prototype.unByKey=F.prototype.J;vs.prototype.get=vs.prototype.get;vs.prototype.getKeys=vs.prototype.K;vs.prototype.getProperties=vs.prototype.L;vs.prototype.set=vs.prototype.set;vs.prototype.setProperties=vs.prototype.C;vs.prototype.unset=vs.prototype.P;vs.prototype.changed=vs.prototype.u;vs.prototype.dispatchEvent=vs.prototype.b;vs.prototype.getRevision=vs.prototype.H;vs.prototype.on=vs.prototype.D;vs.prototype.once=vs.prototype.I;vs.prototype.un=vs.prototype.G;vs.prototype.unByKey=vs.prototype.J; +ws.prototype.get=ws.prototype.get;ws.prototype.getKeys=ws.prototype.K;ws.prototype.getProperties=ws.prototype.L;ws.prototype.set=ws.prototype.set;ws.prototype.setProperties=ws.prototype.C;ws.prototype.unset=ws.prototype.P;ws.prototype.changed=ws.prototype.u;ws.prototype.dispatchEvent=ws.prototype.b;ws.prototype.getRevision=ws.prototype.H;ws.prototype.on=ws.prototype.D;ws.prototype.once=ws.prototype.I;ws.prototype.un=ws.prototype.G;ws.prototype.unByKey=ws.prototype.J;xs.prototype.get=xs.prototype.get; +xs.prototype.getKeys=xs.prototype.K;xs.prototype.getProperties=xs.prototype.L;xs.prototype.set=xs.prototype.set;xs.prototype.setProperties=xs.prototype.C;xs.prototype.unset=xs.prototype.P;xs.prototype.changed=xs.prototype.u;xs.prototype.dispatchEvent=xs.prototype.b;xs.prototype.getRevision=xs.prototype.H;xs.prototype.on=xs.prototype.D;xs.prototype.once=xs.prototype.I;xs.prototype.un=xs.prototype.G;xs.prototype.unByKey=xs.prototype.J;ss.prototype.get=ss.prototype.get;ss.prototype.getKeys=ss.prototype.K; +ss.prototype.getProperties=ss.prototype.L;ss.prototype.set=ss.prototype.set;ss.prototype.setProperties=ss.prototype.C;ss.prototype.unset=ss.prototype.P;ss.prototype.changed=ss.prototype.u;ss.prototype.dispatchEvent=ss.prototype.b;ss.prototype.getRevision=ss.prototype.H;ss.prototype.on=ss.prototype.D;ss.prototype.once=ss.prototype.I;ss.prototype.un=ss.prototype.G;ss.prototype.unByKey=ss.prototype.J;ys.prototype.get=ys.prototype.get;ys.prototype.getKeys=ys.prototype.K;ys.prototype.getProperties=ys.prototype.L; +ys.prototype.set=ys.prototype.set;ys.prototype.setProperties=ys.prototype.C;ys.prototype.unset=ys.prototype.P;ys.prototype.changed=ys.prototype.u;ys.prototype.dispatchEvent=ys.prototype.b;ys.prototype.getRevision=ys.prototype.H;ys.prototype.on=ys.prototype.D;ys.prototype.once=ys.prototype.I;ys.prototype.un=ys.prototype.G;ys.prototype.unByKey=ys.prototype.J;zs.prototype.get=zs.prototype.get;zs.prototype.getKeys=zs.prototype.K;zs.prototype.getProperties=zs.prototype.L;zs.prototype.set=zs.prototype.set; +zs.prototype.setProperties=zs.prototype.C;zs.prototype.unset=zs.prototype.P;zs.prototype.changed=zs.prototype.u;zs.prototype.dispatchEvent=zs.prototype.b;zs.prototype.getRevision=zs.prototype.H;zs.prototype.on=zs.prototype.D;zs.prototype.once=zs.prototype.I;zs.prototype.un=zs.prototype.G;zs.prototype.unByKey=zs.prototype.J;us.prototype.get=us.prototype.get;us.prototype.getKeys=us.prototype.K;us.prototype.getProperties=us.prototype.L;us.prototype.set=us.prototype.set;us.prototype.setProperties=us.prototype.C; +us.prototype.unset=us.prototype.P;us.prototype.changed=us.prototype.u;us.prototype.dispatchEvent=us.prototype.b;us.prototype.getRevision=us.prototype.H;us.prototype.on=us.prototype.D;us.prototype.once=us.prototype.I;us.prototype.un=us.prototype.G;us.prototype.unByKey=us.prototype.J;As.prototype.get=As.prototype.get;As.prototype.getKeys=As.prototype.K;As.prototype.getProperties=As.prototype.L;As.prototype.set=As.prototype.set;As.prototype.setProperties=As.prototype.C;As.prototype.unset=As.prototype.P; +As.prototype.changed=As.prototype.u;As.prototype.dispatchEvent=As.prototype.b;As.prototype.getRevision=As.prototype.H;As.prototype.on=As.prototype.D;As.prototype.once=As.prototype.I;As.prototype.un=As.prototype.G;As.prototype.unByKey=As.prototype.J;Bs.prototype.get=Bs.prototype.get;Bs.prototype.getKeys=Bs.prototype.K;Bs.prototype.getProperties=Bs.prototype.L;Bs.prototype.set=Bs.prototype.set;Bs.prototype.setProperties=Bs.prototype.C;Bs.prototype.unset=Bs.prototype.P;Bs.prototype.changed=Bs.prototype.u; +Bs.prototype.dispatchEvent=Bs.prototype.b;Bs.prototype.getRevision=Bs.prototype.H;Bs.prototype.on=Bs.prototype.D;Bs.prototype.once=Bs.prototype.I;Bs.prototype.un=Bs.prototype.G;Bs.prototype.unByKey=Bs.prototype.J;Cs.prototype.get=Cs.prototype.get;Cs.prototype.getKeys=Cs.prototype.K;Cs.prototype.getProperties=Cs.prototype.L;Cs.prototype.set=Cs.prototype.set;Cs.prototype.setProperties=Cs.prototype.C;Cs.prototype.unset=Cs.prototype.P;Cs.prototype.changed=Cs.prototype.u;Cs.prototype.dispatchEvent=Cs.prototype.b; +Cs.prototype.getRevision=Cs.prototype.H;Cs.prototype.on=Cs.prototype.D;Cs.prototype.once=Cs.prototype.I;Cs.prototype.un=Cs.prototype.G;Cs.prototype.unByKey=Cs.prototype.J;Ds.prototype.get=Ds.prototype.get;Ds.prototype.getKeys=Ds.prototype.K;Ds.prototype.getProperties=Ds.prototype.L;Ds.prototype.set=Ds.prototype.set;Ds.prototype.setProperties=Ds.prototype.C;Ds.prototype.unset=Ds.prototype.P;Ds.prototype.changed=Ds.prototype.u;Ds.prototype.dispatchEvent=Ds.prototype.b;Ds.prototype.getRevision=Ds.prototype.H; +Ds.prototype.on=Ds.prototype.D;Ds.prototype.once=Ds.prototype.I;Ds.prototype.un=Ds.prototype.G;Ds.prototype.unByKey=Ds.prototype.J;Es.prototype.get=Es.prototype.get;Es.prototype.getKeys=Es.prototype.K;Es.prototype.getProperties=Es.prototype.L;Es.prototype.set=Es.prototype.set;Es.prototype.setProperties=Es.prototype.C;Es.prototype.unset=Es.prototype.P;Es.prototype.changed=Es.prototype.u;Es.prototype.dispatchEvent=Es.prototype.b;Es.prototype.getRevision=Es.prototype.H;Es.prototype.on=Es.prototype.D; +Es.prototype.once=Es.prototype.I;Es.prototype.un=Es.prototype.G;Es.prototype.unByKey=Es.prototype.J;Fs.prototype.get=Fs.prototype.get;Fs.prototype.getKeys=Fs.prototype.K;Fs.prototype.getProperties=Fs.prototype.L;Fs.prototype.set=Fs.prototype.set;Fs.prototype.setProperties=Fs.prototype.C;Fs.prototype.unset=Fs.prototype.P;Fs.prototype.changed=Fs.prototype.u;Fs.prototype.dispatchEvent=Fs.prototype.b;Fs.prototype.getRevision=Fs.prototype.H;Fs.prototype.on=Fs.prototype.D;Fs.prototype.once=Fs.prototype.I; +Fs.prototype.un=Fs.prototype.G;Fs.prototype.unByKey=Fs.prototype.J;Gs.prototype.get=Gs.prototype.get;Gs.prototype.getKeys=Gs.prototype.K;Gs.prototype.getProperties=Gs.prototype.L;Gs.prototype.set=Gs.prototype.set;Gs.prototype.setProperties=Gs.prototype.C;Gs.prototype.unset=Gs.prototype.P;Gs.prototype.changed=Gs.prototype.u;Gs.prototype.dispatchEvent=Gs.prototype.b;Gs.prototype.getRevision=Gs.prototype.H;Gs.prototype.on=Gs.prototype.D;Gs.prototype.once=Gs.prototype.I;Gs.prototype.un=Gs.prototype.G; +Gs.prototype.unByKey=Gs.prototype.J;Hs.prototype.get=Hs.prototype.get;Hs.prototype.getKeys=Hs.prototype.K;Hs.prototype.getProperties=Hs.prototype.L;Hs.prototype.set=Hs.prototype.set;Hs.prototype.setProperties=Hs.prototype.C;Hs.prototype.unset=Hs.prototype.P;Hs.prototype.changed=Hs.prototype.u;Hs.prototype.dispatchEvent=Hs.prototype.b;Hs.prototype.getRevision=Hs.prototype.H;Hs.prototype.on=Hs.prototype.D;Hs.prototype.once=Hs.prototype.I;Hs.prototype.un=Hs.prototype.G;Hs.prototype.unByKey=Hs.prototype.J; +Is.prototype.get=Is.prototype.get;Is.prototype.getKeys=Is.prototype.K;Is.prototype.getProperties=Is.prototype.L;Is.prototype.set=Is.prototype.set;Is.prototype.setProperties=Is.prototype.C;Is.prototype.unset=Is.prototype.P;Is.prototype.changed=Is.prototype.u;Is.prototype.dispatchEvent=Is.prototype.b;Is.prototype.getRevision=Is.prototype.H;Is.prototype.on=Is.prototype.D;Is.prototype.once=Is.prototype.I;Is.prototype.un=Is.prototype.G;Is.prototype.unByKey=Is.prototype.J;Js.prototype.get=Js.prototype.get; +Js.prototype.getKeys=Js.prototype.K;Js.prototype.getProperties=Js.prototype.L;Js.prototype.set=Js.prototype.set;Js.prototype.setProperties=Js.prototype.C;Js.prototype.unset=Js.prototype.P;Js.prototype.changed=Js.prototype.u;Js.prototype.dispatchEvent=Js.prototype.b;Js.prototype.getRevision=Js.prototype.H;Js.prototype.on=Js.prototype.D;Js.prototype.once=Js.prototype.I;Js.prototype.un=Js.prototype.G;Js.prototype.unByKey=Js.prototype.J;Ks.prototype.get=Ks.prototype.get;Ks.prototype.getKeys=Ks.prototype.K; +Ks.prototype.getProperties=Ks.prototype.L;Ks.prototype.set=Ks.prototype.set;Ks.prototype.setProperties=Ks.prototype.C;Ks.prototype.unset=Ks.prototype.P;Ks.prototype.changed=Ks.prototype.u;Ks.prototype.dispatchEvent=Ks.prototype.b;Ks.prototype.getRevision=Ks.prototype.H;Ks.prototype.on=Ks.prototype.D;Ks.prototype.once=Ks.prototype.I;Ks.prototype.un=Ks.prototype.G;Ks.prototype.unByKey=Ks.prototype.J;bp.prototype.readFeatures=bp.prototype.Ca;cp.prototype.readFeatures=cp.prototype.Ca; +cp.prototype.readFeatures=cp.prototype.Ca;Jf.prototype.get=Jf.prototype.get;Jf.prototype.getKeys=Jf.prototype.K;Jf.prototype.getProperties=Jf.prototype.L;Jf.prototype.set=Jf.prototype.set;Jf.prototype.setProperties=Jf.prototype.C;Jf.prototype.unset=Jf.prototype.P;Jf.prototype.changed=Jf.prototype.u;Jf.prototype.dispatchEvent=Jf.prototype.b;Jf.prototype.getRevision=Jf.prototype.H;Jf.prototype.on=Jf.prototype.D;Jf.prototype.once=Jf.prototype.I;Jf.prototype.un=Jf.prototype.G;Jf.prototype.unByKey=Jf.prototype.J; +qg.prototype.getMap=qg.prototype.i;qg.prototype.setMap=qg.prototype.setMap;qg.prototype.setTarget=qg.prototype.c;qg.prototype.get=qg.prototype.get;qg.prototype.getKeys=qg.prototype.K;qg.prototype.getProperties=qg.prototype.L;qg.prototype.set=qg.prototype.set;qg.prototype.setProperties=qg.prototype.C;qg.prototype.unset=qg.prototype.P;qg.prototype.changed=qg.prototype.u;qg.prototype.dispatchEvent=qg.prototype.b;qg.prototype.getRevision=qg.prototype.H;qg.prototype.on=qg.prototype.D; +qg.prototype.once=qg.prototype.I;qg.prototype.un=qg.prototype.G;qg.prototype.unByKey=qg.prototype.J;Bg.prototype.getMap=Bg.prototype.i;Bg.prototype.setMap=Bg.prototype.setMap;Bg.prototype.setTarget=Bg.prototype.c;Bg.prototype.get=Bg.prototype.get;Bg.prototype.getKeys=Bg.prototype.K;Bg.prototype.getProperties=Bg.prototype.L;Bg.prototype.set=Bg.prototype.set;Bg.prototype.setProperties=Bg.prototype.C;Bg.prototype.unset=Bg.prototype.P;Bg.prototype.changed=Bg.prototype.u;Bg.prototype.dispatchEvent=Bg.prototype.b; +Bg.prototype.getRevision=Bg.prototype.H;Bg.prototype.on=Bg.prototype.D;Bg.prototype.once=Bg.prototype.I;Bg.prototype.un=Bg.prototype.G;Bg.prototype.unByKey=Bg.prototype.J;Cg.prototype.getMap=Cg.prototype.i;Cg.prototype.setMap=Cg.prototype.setMap;Cg.prototype.setTarget=Cg.prototype.c;Cg.prototype.get=Cg.prototype.get;Cg.prototype.getKeys=Cg.prototype.K;Cg.prototype.getProperties=Cg.prototype.L;Cg.prototype.set=Cg.prototype.set;Cg.prototype.setProperties=Cg.prototype.C;Cg.prototype.unset=Cg.prototype.P; +Cg.prototype.changed=Cg.prototype.u;Cg.prototype.dispatchEvent=Cg.prototype.b;Cg.prototype.getRevision=Cg.prototype.H;Cg.prototype.on=Cg.prototype.D;Cg.prototype.once=Cg.prototype.I;Cg.prototype.un=Cg.prototype.G;Cg.prototype.unByKey=Cg.prototype.J;Sn.prototype.getMap=Sn.prototype.i;Sn.prototype.setMap=Sn.prototype.setMap;Sn.prototype.setTarget=Sn.prototype.c;Sn.prototype.get=Sn.prototype.get;Sn.prototype.getKeys=Sn.prototype.K;Sn.prototype.getProperties=Sn.prototype.L;Sn.prototype.set=Sn.prototype.set; +Sn.prototype.setProperties=Sn.prototype.C;Sn.prototype.unset=Sn.prototype.P;Sn.prototype.changed=Sn.prototype.u;Sn.prototype.dispatchEvent=Sn.prototype.b;Sn.prototype.getRevision=Sn.prototype.H;Sn.prototype.on=Sn.prototype.D;Sn.prototype.once=Sn.prototype.I;Sn.prototype.un=Sn.prototype.G;Sn.prototype.unByKey=Sn.prototype.J;tg.prototype.getMap=tg.prototype.i;tg.prototype.setMap=tg.prototype.setMap;tg.prototype.setTarget=tg.prototype.c;tg.prototype.get=tg.prototype.get;tg.prototype.getKeys=tg.prototype.K; +tg.prototype.getProperties=tg.prototype.L;tg.prototype.set=tg.prototype.set;tg.prototype.setProperties=tg.prototype.C;tg.prototype.unset=tg.prototype.P;tg.prototype.changed=tg.prototype.u;tg.prototype.dispatchEvent=tg.prototype.b;tg.prototype.getRevision=tg.prototype.H;tg.prototype.on=tg.prototype.D;tg.prototype.once=tg.prototype.I;tg.prototype.un=tg.prototype.G;tg.prototype.unByKey=tg.prototype.J;Xn.prototype.getMap=Xn.prototype.i;Xn.prototype.setMap=Xn.prototype.setMap;Xn.prototype.setTarget=Xn.prototype.c; +Xn.prototype.get=Xn.prototype.get;Xn.prototype.getKeys=Xn.prototype.K;Xn.prototype.getProperties=Xn.prototype.L;Xn.prototype.set=Xn.prototype.set;Xn.prototype.setProperties=Xn.prototype.C;Xn.prototype.unset=Xn.prototype.P;Xn.prototype.changed=Xn.prototype.u;Xn.prototype.dispatchEvent=Xn.prototype.b;Xn.prototype.getRevision=Xn.prototype.H;Xn.prototype.on=Xn.prototype.D;Xn.prototype.once=Xn.prototype.I;Xn.prototype.un=Xn.prototype.G;Xn.prototype.unByKey=Xn.prototype.J;vg.prototype.getMap=vg.prototype.i; +vg.prototype.setMap=vg.prototype.setMap;vg.prototype.setTarget=vg.prototype.c;vg.prototype.get=vg.prototype.get;vg.prototype.getKeys=vg.prototype.K;vg.prototype.getProperties=vg.prototype.L;vg.prototype.set=vg.prototype.set;vg.prototype.setProperties=vg.prototype.C;vg.prototype.unset=vg.prototype.P;vg.prototype.changed=vg.prototype.u;vg.prototype.dispatchEvent=vg.prototype.b;vg.prototype.getRevision=vg.prototype.H;vg.prototype.on=vg.prototype.D;vg.prototype.once=vg.prototype.I;vg.prototype.un=vg.prototype.G; +vg.prototype.unByKey=vg.prototype.J;ao.prototype.getMap=ao.prototype.i;ao.prototype.setMap=ao.prototype.setMap;ao.prototype.setTarget=ao.prototype.c;ao.prototype.get=ao.prototype.get;ao.prototype.getKeys=ao.prototype.K;ao.prototype.getProperties=ao.prototype.L;ao.prototype.set=ao.prototype.set;ao.prototype.setProperties=ao.prototype.C;ao.prototype.unset=ao.prototype.P;ao.prototype.changed=ao.prototype.u;ao.prototype.dispatchEvent=ao.prototype.b;ao.prototype.getRevision=ao.prototype.H; +ao.prototype.on=ao.prototype.D;ao.prototype.once=ao.prototype.I;ao.prototype.un=ao.prototype.G;ao.prototype.unByKey=ao.prototype.J;go.prototype.getMap=go.prototype.i;go.prototype.setMap=go.prototype.setMap;go.prototype.setTarget=go.prototype.c;go.prototype.get=go.prototype.get;go.prototype.getKeys=go.prototype.K;go.prototype.getProperties=go.prototype.L;go.prototype.set=go.prototype.set;go.prototype.setProperties=go.prototype.C;go.prototype.unset=go.prototype.P;go.prototype.changed=go.prototype.u; +go.prototype.dispatchEvent=go.prototype.b;go.prototype.getRevision=go.prototype.H;go.prototype.on=go.prototype.D;go.prototype.once=go.prototype.I;go.prototype.un=go.prototype.G;go.prototype.unByKey=go.prototype.J; return OPENLAYERS.ol; })); |
